Pick the most specific workspace from multiple workspace signals
Closes https://github.com/dart-lang/sdk/pull/49237
GitOrigin-RevId: a1db3bebcd4622bc31303781f5c9ba64167a0e6a
Change-Id: Ief3ef8a5c421ff20e817bf27dac96c1fc37da595
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/248020
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index ade3b53..af049b8 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -378,10 +378,12 @@
Workspace? workspace;
workspace = BazelWorkspace.find(resourceProvider, rootPath,
lookForBuildFileSubstitutes: false);
- workspace ??= GnWorkspace.find(resourceProvider, rootPath);
- workspace ??=
- PackageBuildWorkspace.find(resourceProvider, packages, rootPath);
- workspace ??= PubWorkspace.find(resourceProvider, packages, rootPath);
+ workspace = _mostSpecificWorkspace(
+ workspace, GnWorkspace.find(resourceProvider, rootPath));
+ workspace = _mostSpecificWorkspace(workspace,
+ PackageBuildWorkspace.find(resourceProvider, packages, rootPath));
+ workspace = _mostSpecificWorkspace(
+ workspace, PubWorkspace.find(resourceProvider, packages, rootPath));
workspace ??= BasicWorkspace.find(resourceProvider, packages, rootPath);
return workspace;
}
@@ -555,6 +557,20 @@
return true;
}
+
+ /// Pick a workspace with the most specific root. If the root of [first] is
+ /// non-null and is within the root of [second], return [second]. If any of
+ /// [first] and [second] is null, return the other one. If the roots aren't
+ /// within each other, return [first].
+ static Workspace? _mostSpecificWorkspace(
+ Workspace? first, Workspace? second) {
+ if (first == null) return second;
+ if (second == null) return first;
+ if (isWithin(first.root, second.root)) {
+ return second;
+ }
+ return first;
+ }
}
/// The packages [file] found for the [parent].
diff --git a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
index 9f757d0..70b8c34 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
@@ -290,6 +290,35 @@
expect(outerRoot.packagesFile, outerPackagesFile);
}
+ void
+ test_locateRoots_multiple_dirAndNestedDir_outerIsBazel_innerConfigurationFiles() {
+ var outerRootFolder = newFolder('/outer');
+ newFile('$outerRootFolder/WORKSPACE', '');
+ newBazelBuildFile('$outerRootFolder', '');
+ var innerRootFolder = newFolder('/outer/examples/inner');
+ var innerOptionsFile = newAnalysisOptionsYamlFile('$innerRootFolder', '');
+ var innerPackagesFile = newPackageConfigJsonFile('$innerRootFolder', '');
+ newPubspecYamlFile('$innerRootFolder', '');
+
+ var roots = contextLocator.locateRoots(
+ includedPaths: [outerRootFolder.path, innerRootFolder.path],
+ );
+ expect(roots, hasLength(2));
+
+ var outerRoot = findRoot(roots, outerRootFolder);
+ expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+ expect(outerRoot.excludedPaths, unorderedEquals([innerRootFolder.path]));
+ expect(outerRoot.optionsFile, isNull);
+ expect(outerRoot.packagesFile, isNull);
+
+ var innerRoot = findRoot(roots, innerRootFolder);
+ expect(innerRoot.workspace.root, equals(innerRootFolder.path));
+ expect(innerRoot.includedPaths, unorderedEquals([innerRootFolder.path]));
+ expect(innerRoot.excludedPaths, isEmpty);
+ expect(innerRoot.optionsFile, innerOptionsFile);
+ expect(innerRoot.packagesFile, innerPackagesFile);
+ }
+
void test_locateRoots_multiple_dirAndNestedFile_excludedByOptions() {
var rootPath = convertPath('/home/test');
var rootFolder = newFolder(rootPath);