Make ContextRoot part of the API to support the angular plugin, fix some bugs
Change-Id: I3f23d1712473c4e5522c441ac31e013516ae5f4d
Reviewed-on: https://dart-review.googlesource.com/43880
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/dart/analysis/context_locator.dart b/pkg/analyzer/lib/dart/analysis/context_locator.dart
index 9c7f979..ce4d07a 100644
--- a/pkg/analyzer/lib/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/dart/analysis/context_locator.dart
@@ -1,8 +1,9 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/analysis_context.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/context_locator.dart';
import 'package:meta/meta.dart';
@@ -11,6 +12,8 @@
* Determines the list of analysis contexts that can be used to analyze the
* files and folders that should be analyzed given a list of included files and
* folders and a list of excluded files and folders.
+ *
+ * Clients may not extend, implement or mix-in this class.
*/
abstract class ContextLocator {
/**
@@ -26,16 +29,43 @@
* files that are included by the list of [includedPaths] and not excluded by
* the list of [excludedPaths].
*
- * If the [packagesFile] is specified, then it is assumed to be the path to
- * the `.packages` file that should be used in place of the one that would be
+ * If an [optionsFile] is specified, then it is assumed to be the path to the
+ * `analysis_options.yaml` (or `.analysis_options`) file that should be used
+ * in place of the ones that would be found by looking in the directories
+ * containing the context roots.
+ *
+ * If a [packagesFile] is specified, then it is assumed to be the path to the
+ * `.packages` file that should be used in place of the one that would be
* found by looking in the directories containing the context roots.
*
* If the [sdkPath] is specified, then it is used as the path to the root of
* the SDK that should be used during analysis.
*/
+ @deprecated
List<AnalysisContext> locateContexts(
{@required List<String> includedPaths,
List<String> excludedPaths: const <String>[],
+ String optionsFile: null,
String packagesFile: null,
String sdkPath: null});
+
+ /**
+ * Return a list of the context roots that should be used to analyze the files
+ * that are included by the list of [includedPaths] and not excluded by the
+ * list of [excludedPaths].
+ *
+ * If an [optionsFile] is specified, then it is assumed to be the path to the
+ * `analysis_options.yaml` (or `.analysis_options`) file that should be used
+ * in place of the ones that would be found by looking in the directories
+ * containing the context roots.
+ *
+ * If a [packagesFile] is specified, then it is assumed to be the path to the
+ * `.packages` file that should be used in place of the one that would be
+ * found by looking in the directories containing the context roots.
+ */
+ List<ContextRoot> locateRoots(
+ {@required List<String> includedPaths,
+ List<String> excludedPaths: null,
+ String optionsFile: null,
+ String packagesFile: null});
}
diff --git a/pkg/analyzer/lib/dart/analysis/context_root.dart b/pkg/analyzer/lib/dart/analysis/context_root.dart
new file mode 100644
index 0000000..f710dbd
--- /dev/null
+++ b/pkg/analyzer/lib/dart/analysis/context_root.dart
@@ -0,0 +1,57 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/file_system/file_system.dart';
+
+/**
+ * Information about the root directory associated with an analysis context.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class ContextRoot {
+ /**
+ * A list of the files and directories within the root directory that should
+ * not be analyzed.
+ */
+ List<Resource> get excluded;
+
+ /**
+ * A collection of the absolute, normalized paths of files and directories
+ * within the root directory that should not be analyzed.
+ */
+ Iterable<String> get excludedPaths;
+
+ /**
+ * A list of the files and directories within the root directory that should
+ * be analyzed. If all of the files in the root directory (other than those
+ * that are explicitly excluded) should be analyzed, then this list will
+ * contain the root directory.
+ */
+ List<Resource> get included;
+
+ /**
+ * A collection of the absolute, normalized paths of files within the root
+ * directory that should be analyzed. If all of the files in the root
+ * directory (other than those that are explicitly excluded) should be
+ * analyzed, then this collection will contain the path of the root directory.
+ */
+ Iterable<String> get includedPaths;
+
+ /**
+ * The analysis options file that should be used when analyzing the files
+ * within this context root, or `null` if there is no options file.
+ */
+ File get optionsFile;
+
+ /**
+ * The packages file that should be used when analyzing the files within this
+ * context root, or `null` if there is no options file.
+ */
+ File get packagesFile;
+
+ /**
+ * The root directory containing the files to be analyzed.
+ */
+ Folder get root;
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 0a7ca25..e9fbaa9 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -1,4 +1,4 @@
-// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
@@ -7,11 +7,13 @@
import 'package:analyzer/context/context_root.dart' as old;
import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_locator.dart';
+import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart'
show PhysicalResourceProvider;
import 'package:analyzer/src/context/builder.dart'
show ContextBuilder, ContextBuilderOptions;
+import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriver, AnalysisDriverScheduler;
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
@@ -68,18 +70,22 @@
String get _defaultSdkPath =>
FolderBasedDartSdk.defaultSdkDirectory(resourceProvider).path;
+ @deprecated
@override
List<AnalysisContext> locateContexts(
{@required List<String> includedPaths,
List<String> excludedPaths: null,
+ String optionsFile: null,
String packagesFile: null,
String sdkPath: null}) {
- if (includedPaths == null || includedPaths.isEmpty) {
- throw new ArgumentError('There must be at least one included path');
+ List<ContextRoot> roots = locateRoots(
+ includedPaths: includedPaths,
+ excludedPaths: excludedPaths,
+ optionsFile: optionsFile,
+ packagesFile: packagesFile);
+ if (roots.isEmpty) {
+ return const <AnalysisContext>[];
}
- List<AnalysisContext> contextList = <AnalysisContext>[];
- List<ContextRoot> roots =
- locateRoots(includedPaths, excludedPaths: excludedPaths);
PerformanceLog performanceLog = new PerformanceLog(new StringBuffer());
AnalysisDriverScheduler scheduler =
new AnalysisDriverScheduler(performanceLog);
@@ -97,33 +103,33 @@
builder.byteStore = new MemoryByteStore();
builder.fileContentOverlay = new FileContentOverlay();
builder.performanceLog = performanceLog;
+ List<AnalysisContext> contextList = <AnalysisContext>[];
for (ContextRoot root in roots) {
old.ContextRoot contextRoot =
- new old.ContextRoot(root.root.path, root.excludedPaths);
+ new old.ContextRoot(root.root.path, root.excludedPaths.toList());
AnalysisDriver driver = builder.buildDriver(contextRoot);
DriverBasedAnalysisContext context =
new DriverBasedAnalysisContext(resourceProvider, driver);
- context.includedPaths = root.includedPaths;
- context.excludedPaths = root.excludedPaths;
+ context.includedPaths = root.includedPaths.toList();
+ context.excludedPaths = root.excludedPaths.toList();
contextList.add(context);
}
return contextList;
}
- /**
- * Return a list of the context roots that should be used to analyze the files
- * that are included by the list of [includedPaths] and not excluded by the
- * list of [excludedPaths].
- */
- @visibleForTesting
- List<ContextRoot> locateRoots(List<String> includedPaths,
- {List<String> excludedPaths}) {
+ @override
+ List<ContextRoot> locateRoots(
+ {@required List<String> includedPaths,
+ List<String> excludedPaths: null,
+ String optionsFile: null,
+ String packagesFile: null}) {
//
// Compute the list of folders and files that are to be included.
//
List<Folder> includedFolders = <Folder>[];
List<File> includedFiles = <File>[];
- _resourcesFromPaths(includedPaths, includedFolders, includedFiles);
+ _resourcesFromPaths(
+ includedPaths ?? const <String>[], includedFolders, includedFiles);
//
// Compute the list of folders and files that are to be excluded.
//
@@ -151,19 +157,42 @@
// analyzed. For each, walk the directory structure and figure out where to
// create context roots.
//
+ File defaultOptionsFile;
+ if (optionsFile != null) {
+ defaultOptionsFile = resourceProvider.getFile(optionsFile);
+ if (!defaultOptionsFile.exists) {
+ defaultOptionsFile = null;
+ }
+ }
+ File defaultPackagesFile;
+ if (packagesFile != null) {
+ defaultPackagesFile = resourceProvider.getFile(packagesFile);
+ if (!defaultPackagesFile.exists) {
+ defaultPackagesFile = null;
+ }
+ }
List<ContextRoot> roots = <ContextRoot>[];
for (Folder folder in includedFolders) {
- _createContextRoots(roots, folder, excludedFolders, null);
+ ContextRootImpl root = new ContextRootImpl(folder);
+ root.packagesFile = defaultPackagesFile ?? _findPackagesFile(folder);
+ root.optionsFile = defaultOptionsFile ?? _findOptionsFile(folder);
+ root.included.add(folder);
+ roots.add(root);
+ _createContextRootsIn(roots, folder, excludedFolders, root,
+ defaultOptionsFile, defaultPackagesFile);
}
+ Map<Folder, ContextRoot> rootMap = <Folder, ContextRoot>{};
for (File file in includedFiles) {
Folder parent = file.parent;
- ContextRoot root = new ContextRoot(file);
- root.packagesFile = _findPackagesFile(parent);
- root.optionsFile = _findOptionsFile(parent);
+ ContextRoot root = rootMap.putIfAbsent(parent, () {
+ ContextRootImpl root = new ContextRootImpl(parent);
+ root.packagesFile = defaultPackagesFile ?? _findPackagesFile(parent);
+ root.optionsFile = defaultOptionsFile ?? _findOptionsFile(parent);
+ roots.add(root);
+ return root;
+ });
root.included.add(file);
- roots.add(root);
}
-
return roots;
}
@@ -174,31 +203,74 @@
bool _containedInAny(Iterable<Folder> folders, Resource resource) =>
folders.any((Folder folder) => folder.contains(resource.path));
- void _createContextRoots(List<ContextRoot> roots, Folder folder,
- List<Folder> excludedFolders, ContextRoot containingRoot) {
+ /**
+ * If the given [folder] should be the root of a new analysis context, then
+ * create a new context root for it and add it to the list of context [roots].
+ * The [containingRoot] is the context root from an enclosing directory and is
+ * used to inherit configuration information that isn't overridden.
+ *
+ * If either the [optionsFile] or [packagesFile] is non-`null` then the given
+ * file will be used even if there is a local version of the file.
+ *
+ * For each directory within the given [folder] that is not in the list of
+ * [excludedFolders], recursively search for nested context roots.
+ */
+ void _createContextRoots(
+ List<ContextRoot> roots,
+ Folder folder,
+ List<Folder> excludedFolders,
+ ContextRoot containingRoot,
+ File optionsFile,
+ File packagesFile) {
//
- // Create a context root for the given [folder] is appropriate.
+ // If the options and packages files are allowed to be locally specified,
+ // then look to see whether they are.
//
- if (containingRoot == null) {
- ContextRoot root = new ContextRoot(folder);
- root.packagesFile = _findPackagesFile(folder);
- root.optionsFile = _findOptionsFile(folder);
+ File localOptionsFile;
+ if (optionsFile == null) {
+ localOptionsFile = _getOptionsFile(folder);
+ }
+ File localPackagesFile;
+ if (packagesFile == null) {
+ localPackagesFile = _getPackagesFile(folder);
+ }
+ //
+ // Create a context root for the given [folder] if at least one of the
+ // options and packages file is locally specified.
+ //
+ if (localPackagesFile != null || localOptionsFile != null) {
+ if (optionsFile != null) {
+ localOptionsFile = optionsFile;
+ }
+ if (packagesFile != null) {
+ localPackagesFile = packagesFile;
+ }
+ ContextRootImpl root = new ContextRootImpl(folder);
+ root.packagesFile = localPackagesFile ?? containingRoot.packagesFile;
+ root.optionsFile = localOptionsFile ?? containingRoot.optionsFile;
root.included.add(folder);
+ containingRoot.excluded.add(folder);
roots.add(root);
containingRoot = root;
- } else {
- File packagesFile = _getPackagesFile(folder);
- File optionsFile = _getOptionsFile(folder);
- if (packagesFile != null || optionsFile != null) {
- ContextRoot root = new ContextRoot(folder);
- root.packagesFile = packagesFile ?? containingRoot.packagesFile;
- root.optionsFile = optionsFile ?? containingRoot.optionsFile;
- root.included.add(folder);
- containingRoot.excluded.add(folder);
- roots.add(root);
- containingRoot = root;
- }
}
+ _createContextRootsIn(roots, folder, excludedFolders, containingRoot,
+ optionsFile, packagesFile);
+ }
+
+ /**
+ * For each directory within the given [folder] that is not in the list of
+ * [excludedFolders], recursively search for nested context roots.
+ *
+ * If either the [optionsFile] or [packagesFile] is non-`null` then the given
+ * file will be used even if there is a local version of the file.
+ */
+ void _createContextRootsIn(
+ List<ContextRoot> roots,
+ Folder folder,
+ List<Folder> excludedFolders,
+ ContextRoot containingRoot,
+ File optionsFile,
+ File packagesFile) {
//
// Check each of the subdirectories to see whether a context root needs to
// be added for it.
@@ -211,7 +283,8 @@
folder.shortName == PACKAGES_DIR_NAME) {
containingRoot.excluded.add(folder);
} else {
- _createContextRoots(roots, child, excludedFolders, containingRoot);
+ _createContextRoots(roots, child, excludedFolders, containingRoot,
+ optionsFile, packagesFile);
}
}
}
@@ -311,28 +384,3 @@
return sortedPaths;
}
}
-
-@visibleForTesting
-class ContextRoot {
- final Resource root;
- final List<Resource> included = <Resource>[];
- final List<Resource> excluded = <Resource>[];
- File packagesFile;
- File optionsFile;
-
- ContextRoot(this.root);
-
- List<String> get excludedPaths =>
- excluded.map((Resource folder) => folder.path).toList();
-
- @override
- int get hashCode => root.path.hashCode;
-
- List<String> get includedPaths =>
- included.map((Resource folder) => folder.path).toList();
-
- @override
- bool operator ==(Object other) {
- return other is ContextRoot && root.path == other.root.path;
- }
-}
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_root.dart b/pkg/analyzer/lib/src/dart/analysis/context_root.dart
new file mode 100644
index 0000000..607c9d2
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/context_root.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/analysis/context_root.dart';
+import 'package:analyzer/file_system/file_system.dart';
+
+/**
+ * An implementation of a context root.
+ */
+class ContextRootImpl implements ContextRoot {
+ @override
+ final Folder root;
+
+ @override
+ final List<Resource> included = <Resource>[];
+
+ @override
+ final List<Resource> excluded = <Resource>[];
+
+ @override
+ File optionsFile;
+
+ @override
+ File packagesFile;
+
+ /**
+ * Initialize a newly created context root.
+ */
+ ContextRootImpl(this.root);
+
+ @override
+ Iterable<String> get excludedPaths =>
+ excluded.map((Resource folder) => folder.path);
+
+ @override
+ int get hashCode => root.path.hashCode;
+
+ @override
+ Iterable<String> get includedPaths =>
+ included.map((Resource folder) => folder.path);
+
+ @override
+ bool operator ==(Object other) {
+ return other is ContextRoot && root.path == other.root.path;
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index 03356db..558b2a1 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -44,14 +44,16 @@
@override
Iterable<String> analyzedFiles() sync* {
for (String path in includedPaths) {
- Resource resource = resourceProvider.getResource(path);
- if (resource is File) {
- yield path;
- } else if (resource is Folder) {
- yield* _includedFilesInFolder(resource);
- } else {
- Type type = resource.runtimeType;
- throw new StateError('Unknown resource at path "$path" ($type)');
+ if (!_isExcluded(path)) {
+ Resource resource = resourceProvider.getResource(path);
+ if (resource is File) {
+ yield path;
+ } else if (resource is Folder) {
+ yield* _includedFilesInFolder(resource);
+ } else {
+ Type type = resource.runtimeType;
+ throw new StateError('Unknown resource at path "$path" ($type)');
+ }
}
}
}
@@ -67,14 +69,16 @@
*/
Iterable<String> _includedFilesInFolder(Folder folder) sync* {
for (Resource resource in folder.getChildren()) {
- if (resource is File) {
- yield resource.path;
- } else if (resource is Folder) {
- yield* _includedFilesInFolder(resource);
- } else {
- String path = resource.path;
- Type type = resource.runtimeType;
- throw new StateError('Unknown resource at path "$path" ($type)');
+ String path = resource.path;
+ if (!_isExcluded(path)) {
+ if (resource is File) {
+ yield path;
+ } else if (resource is Folder) {
+ yield* _includedFilesInFolder(resource);
+ } else {
+ Type type = resource.runtimeType;
+ throw new StateError('Unknown resource at path "$path" ($type)');
+ }
}
}
}
@@ -85,6 +89,11 @@
*/
bool _isExcluded(String path) {
Context context = resourceProvider.pathContext;
+ String name = context.basename(path);
+ if (name.startsWith('.') ||
+ (name == 'packages' && resourceProvider.getResource(path) is Folder)) {
+ return true;
+ }
for (String excludedPath in excludedPaths) {
if (context.isAbsolute(excludedPath)) {
if (context.isWithin(excludedPath, path)) {
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 029ad6b..b3f133b 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_locator_test.dart
@@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/context_locator.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
@@ -56,8 +57,8 @@
File outerPackagesFile = newPackagesFile('/test/outer');
Folder innerRootFolder = newFolder('/test/outer/examples/inner');
- List<ContextRoot> roots = contextLocator
- .locateRoots([outerRootFolder.path, innerRootFolder.path]);
+ List<ContextRoot> roots = contextLocator.locateRoots(
+ includedPaths: [outerRootFolder.path, innerRootFolder.path]);
expect(roots, hasLength(1));
ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -73,8 +74,8 @@
File outerPackagesFile = newPackagesFile('/test/outer');
File testFile = newFile('/test/outer/examples/inner/test.dart');
- List<ContextRoot> roots =
- contextLocator.locateRoots([outerRootFolder.path, testFile.path]);
+ List<ContextRoot> roots = contextLocator
+ .locateRoots(includedPaths: [outerRootFolder.path, testFile.path]);
expect(roots, hasLength(1));
ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -93,8 +94,8 @@
File outer2OptionsFile = newOptionsFile('/test/outer2');
File outer2PackagesFile = newPackagesFile('/test/outer2');
- List<ContextRoot> roots = contextLocator
- .locateRoots([outer1RootFolder.path, outer2RootFolder.path]);
+ List<ContextRoot> roots = contextLocator.locateRoots(
+ includedPaths: [outer1RootFolder.path, outer2RootFolder.path]);
expect(roots, hasLength(2));
ContextRoot outer1Root = findRoot(roots, outer1RootFolder);
@@ -119,8 +120,8 @@
File outer2PackagesFile = newPackagesFile('/test/outer2');
File testFile = newFile('/test/outer2/test.dart');
- List<ContextRoot> roots =
- contextLocator.locateRoots([outer1RootFolder.path, testFile.path]);
+ List<ContextRoot> roots = contextLocator
+ .locateRoots(includedPaths: [outer1RootFolder.path, testFile.path]);
expect(roots, hasLength(2));
ContextRoot outer1Root = findRoot(roots, outer1RootFolder);
@@ -129,7 +130,7 @@
expect(outer1Root.optionsFile, outer1OptionsFile);
expect(outer1Root.packagesFile, outer1PackagesFile);
- ContextRoot outer2Root = findRoot(roots, testFile);
+ ContextRoot outer2Root = findRoot(roots, testFile.parent);
expect(outer2Root.includedPaths, unorderedEquals([testFile.path]));
expect(outer2Root.excludedPaths, isEmpty);
expect(outer2Root.optionsFile, outer2OptionsFile);
@@ -161,21 +162,16 @@
File testFile1 = newFile('/test/root/test1.dart');
File testFile2 = newFile('/test/root/test2.dart');
- List<ContextRoot> roots =
- contextLocator.locateRoots([testFile1.path, testFile2.path]);
- expect(roots, hasLength(2));
+ List<ContextRoot> roots = contextLocator
+ .locateRoots(includedPaths: [testFile1.path, testFile2.path]);
+ expect(roots, hasLength(1));
- ContextRoot outer1Root = findRootFromIncluded(roots, testFile1.path);
- expect(outer1Root.includedPaths, unorderedEquals([testFile1.path]));
- expect(outer1Root.excludedPaths, isEmpty);
- expect(outer1Root.optionsFile, optionsFile);
- expect(outer1Root.packagesFile, packagesFile);
-
- ContextRoot outer2Root = findRootFromIncluded(roots, testFile2.path);
- expect(outer2Root.includedPaths, unorderedEquals([testFile2.path]));
- expect(outer2Root.excludedPaths, isEmpty);
- expect(outer2Root.optionsFile, optionsFile);
- expect(outer2Root.packagesFile, packagesFile);
+ ContextRoot root = findRootFromIncluded(roots, testFile1.path);
+ expect(
+ root.includedPaths, unorderedEquals([testFile1.path, testFile2.path]));
+ expect(root.excludedPaths, isEmpty);
+ expect(root.optionsFile, optionsFile);
+ expect(root.packagesFile, packagesFile);
}
void test_locateRoots_nested_excluded_dot() {
@@ -186,7 +182,7 @@
newOptionsFile('/test/outer/.examples/inner');
List<ContextRoot> roots =
- contextLocator.locateRoots([outerRootFolder.path]);
+ contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
expect(roots, hasLength(1));
ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -203,7 +199,8 @@
Folder excludedFolder = newFolder('/test/outer/examples');
newOptionsFile('/test/outer/examples/inner');
- List<ContextRoot> roots = contextLocator.locateRoots([outerRootFolder.path],
+ List<ContextRoot> roots = contextLocator.locateRoots(
+ includedPaths: [outerRootFolder.path],
excludedPaths: [excludedFolder.path]);
expect(roots, hasLength(1));
@@ -222,7 +219,7 @@
newOptionsFile('/test/outer/packages/inner');
List<ContextRoot> roots =
- contextLocator.locateRoots([outerRootFolder.path]);
+ contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
expect(roots, hasLength(1));
ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -242,7 +239,7 @@
File inner2PackagesFile = newPackagesFile('/test/outer/examples/inner2');
List<ContextRoot> roots =
- contextLocator.locateRoots([outerRootFolder.path]);
+ contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
expect(roots, hasLength(3));
ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -273,7 +270,7 @@
File innerOptionsFile = newOptionsFile('/test/outer/examples/inner');
List<ContextRoot> roots =
- contextLocator.locateRoots([outerRootFolder.path]);
+ contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
expect(roots, hasLength(2));
ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -289,6 +286,52 @@
expect(innerRoot.packagesFile, outerPackagesFile);
}
+ void test_locateRoots_nested_options_overriddenOptions() {
+ Folder outerRootFolder = newFolder('/test/outer');
+ newOptionsFile('/test/outer');
+ File outerPackagesFile = newPackagesFile('/test/outer');
+ newFolder('/test/outer/examples/inner');
+ newOptionsFile('/test/outer/examples/inner');
+ File overrideOptionsFile = newOptionsFile('/test/override');
+
+ List<ContextRoot> roots = contextLocator.locateRoots(
+ includedPaths: [outerRootFolder.path],
+ optionsFile: overrideOptionsFile.path);
+ expect(roots, hasLength(1));
+
+ ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+ expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+ expect(outerRoot.excludedPaths, isEmpty);
+ expect(outerRoot.optionsFile, overrideOptionsFile);
+ expect(outerRoot.packagesFile, outerPackagesFile);
+ }
+
+ void test_locateRoots_nested_options_overriddenPackages() {
+ Folder outerRootFolder = newFolder('/test/outer');
+ File outerOptionsFile = newOptionsFile('/test/outer');
+ newPackagesFile('/test/outer');
+ Folder innerRootFolder = newFolder('/test/outer/examples/inner');
+ File innerOptionsFile = newOptionsFile('/test/outer/examples/inner');
+ File overridePackagesFile = newPackagesFile('/test/override');
+
+ List<ContextRoot> roots = contextLocator.locateRoots(
+ includedPaths: [outerRootFolder.path],
+ packagesFile: overridePackagesFile.path);
+ expect(roots, hasLength(2));
+
+ ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+ expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+ expect(outerRoot.excludedPaths, unorderedEquals([innerRootFolder.path]));
+ expect(outerRoot.optionsFile, outerOptionsFile);
+ expect(outerRoot.packagesFile, overridePackagesFile);
+
+ ContextRoot innerRoot = findRoot(roots, innerRootFolder);
+ expect(innerRoot.includedPaths, unorderedEquals([innerRootFolder.path]));
+ expect(innerRoot.excludedPaths, isEmpty);
+ expect(innerRoot.optionsFile, innerOptionsFile);
+ expect(innerRoot.packagesFile, overridePackagesFile);
+ }
+
void test_locateRoots_nested_optionsAndPackages() {
Folder outerRootFolder = newFolder('/test/outer');
File outerOptionsFile = newOptionsFile('/test/outer');
@@ -298,7 +341,7 @@
File innerPackagesFile = newPackagesFile('/test/outer/examples/inner');
List<ContextRoot> roots =
- contextLocator.locateRoots([outerRootFolder.path]);
+ contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
expect(roots, hasLength(2));
ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -314,6 +357,29 @@
expect(innerRoot.packagesFile, innerPackagesFile);
}
+ void test_locateRoots_nested_optionsAndPackages_overriddenBoth() {
+ Folder outerRootFolder = newFolder('/test/outer');
+ newOptionsFile('/test/outer');
+ newPackagesFile('/test/outer');
+ newFolder('/test/outer/examples/inner');
+ newOptionsFile('/test/outer/examples/inner');
+ newPackagesFile('/test/outer/examples/inner');
+ File overrideOptionsFile = newOptionsFile('/test/override');
+ File overridePackagesFile = newPackagesFile('/test/override');
+
+ List<ContextRoot> roots = contextLocator.locateRoots(
+ includedPaths: [outerRootFolder.path],
+ optionsFile: overrideOptionsFile.path,
+ packagesFile: overridePackagesFile.path);
+ expect(roots, hasLength(1));
+
+ ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+ expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+ expect(outerRoot.excludedPaths, isEmpty);
+ expect(outerRoot.optionsFile, overrideOptionsFile);
+ expect(outerRoot.packagesFile, overridePackagesFile);
+ }
+
void test_locateRoots_nested_packages() {
Folder outerRootFolder = newFolder('/test/outer');
File outerOptionsFile = newOptionsFile('/test/outer');
@@ -322,7 +388,7 @@
File innerPackagesFile = newPackagesFile('/test/outer/examples/inner');
List<ContextRoot> roots =
- contextLocator.locateRoots([outerRootFolder.path]);
+ contextLocator.locateRoots(includedPaths: [outerRootFolder.path]);
expect(roots, hasLength(2));
ContextRoot outerRoot = findRoot(roots, outerRootFolder);
@@ -338,12 +404,59 @@
expect(innerRoot.packagesFile, innerPackagesFile);
}
+ void test_locateRoots_nested_packages_overriddenOptions() {
+ Folder outerRootFolder = newFolder('/test/outer');
+ newOptionsFile('/test/outer');
+ File outerPackagesFile = newPackagesFile('/test/outer');
+ Folder innerRootFolder = newFolder('/test/outer/examples/inner');
+ File innerPackagesFile = newPackagesFile('/test/outer/examples/inner');
+ File overrideOptionsFile = newOptionsFile('/test/override');
+
+ List<ContextRoot> roots = contextLocator.locateRoots(
+ includedPaths: [outerRootFolder.path],
+ optionsFile: overrideOptionsFile.path);
+ expect(roots, hasLength(2));
+
+ ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+ expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+ expect(outerRoot.excludedPaths, unorderedEquals([innerRootFolder.path]));
+ expect(outerRoot.optionsFile, overrideOptionsFile);
+ expect(outerRoot.packagesFile, outerPackagesFile);
+
+ ContextRoot innerRoot = findRoot(roots, innerRootFolder);
+ expect(innerRoot.includedPaths, unorderedEquals([innerRootFolder.path]));
+ expect(innerRoot.excludedPaths, isEmpty);
+ expect(innerRoot.optionsFile, overrideOptionsFile);
+ expect(innerRoot.packagesFile, innerPackagesFile);
+ }
+
+ void test_locateRoots_nested_packages_overriddenPackages() {
+ Folder outerRootFolder = newFolder('/test/outer');
+ File outerOptionsFile = newOptionsFile('/test/outer');
+ newPackagesFile('/test/outer');
+ newFolder('/test/outer/examples/inner');
+ newPackagesFile('/test/outer/examples/inner');
+ File overridePackagesFile = newPackagesFile('/test/override');
+
+ List<ContextRoot> roots = contextLocator.locateRoots(
+ includedPaths: [outerRootFolder.path],
+ packagesFile: overridePackagesFile.path);
+ expect(roots, hasLength(1));
+
+ ContextRoot outerRoot = findRoot(roots, outerRootFolder);
+ expect(outerRoot.includedPaths, unorderedEquals([outerRootFolder.path]));
+ expect(outerRoot.excludedPaths, isEmpty);
+ expect(outerRoot.optionsFile, outerOptionsFile);
+ expect(outerRoot.packagesFile, overridePackagesFile);
+ }
+
void test_locateRoots_single_dir_directOptions_directPackages() {
Folder rootFolder = newFolder('/test/root');
File optionsFile = newOptionsFile('/test/root');
File packagesFile = newPackagesFile('/test/root');
- List<ContextRoot> roots = contextLocator.locateRoots([rootFolder.path]);
+ List<ContextRoot> roots =
+ contextLocator.locateRoots(includedPaths: [rootFolder.path]);
expect(roots, hasLength(1));
ContextRoot package1Root = findRoot(roots, rootFolder);
@@ -358,7 +471,8 @@
File optionsFile = newOptionsFile('/test/root');
File packagesFile = newPackagesFile('/test');
- List<ContextRoot> roots = contextLocator.locateRoots([rootFolder.path]);
+ List<ContextRoot> roots =
+ contextLocator.locateRoots(includedPaths: [rootFolder.path]);
expect(roots, hasLength(1));
ContextRoot package1Root = findRoot(roots, rootFolder);
@@ -373,7 +487,8 @@
File optionsFile = newOptionsFile('/test');
File packagesFile = newPackagesFile('/test/root');
- List<ContextRoot> roots = contextLocator.locateRoots([rootFolder.path]);
+ List<ContextRoot> roots =
+ contextLocator.locateRoots(includedPaths: [rootFolder.path]);
expect(roots, hasLength(1));
ContextRoot package1Root = findRoot(roots, rootFolder);
@@ -388,7 +503,8 @@
File optionsFile = newOptionsFile('/test');
File packagesFile = newPackagesFile('/test');
- List<ContextRoot> roots = contextLocator.locateRoots([rootFolder.path]);
+ List<ContextRoot> roots =
+ contextLocator.locateRoots(includedPaths: [rootFolder.path]);
expect(roots, hasLength(1));
ContextRoot package1Root = findRoot(roots, rootFolder);
@@ -403,10 +519,11 @@
File packagesFile = newPackagesFile('/test/root');
File testFile = newFile('/test/root/test.dart');
- List<ContextRoot> roots = contextLocator.locateRoots([testFile.path]);
+ List<ContextRoot> roots =
+ contextLocator.locateRoots(includedPaths: [testFile.path]);
expect(roots, hasLength(1));
- ContextRoot package1Root = findRoot(roots, testFile);
+ ContextRoot package1Root = findRoot(roots, testFile.parent);
expect(package1Root.includedPaths, unorderedEquals([testFile.path]));
expect(package1Root.excludedPaths, isEmpty);
expect(package1Root.optionsFile, optionsFile);