Add ContextRoot.workspace, deprecated AnalysisContext.workspace, support included excludes in ContextLocatorImpl

Change-Id: Iecd324ad45b926ca6b0626f8bea4f479409154e8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/185499
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Konstantin Shcheglov
2021-02-19 02:15:40 +00:00
committed by commit-bot@chromium.org
parent f66d493afa
commit 9bfd416c45
22 changed files with 201 additions and 79 deletions
@@ -644,7 +644,12 @@ class ServerContextManagerCallbacks extends ContextManagerCallbacks {
@override
nd.AnalysisDriver addAnalysisDriver(Folder folder, ContextRoot contextRoot) {
var builder = createContextBuilder(folder);
var analysisDriver = builder.buildDriver(contextRoot);
var workspace = ContextBuilder.createWorkspace(
resourceProvider: resourceProvider,
options: builder.builderOptions,
rootPath: folder.path,
);
var analysisDriver = builder.buildDriver(contextRoot, workspace);
analysisDriver.results.listen((result) {
var notificationManager = analysisServer.notificationManager;
var path = result.path;
@@ -1566,7 +1566,7 @@ class ContextManagerImpl implements ContextManager {
/// Does nothing if the [driver] is not in a Bazel workspace.
void _watchBazelFilesIfNeeded(Folder folder, AnalysisDriver analysisDriver) {
if (!experimentalEnableBazelWatching) return;
var workspace = analysisDriver.analysisContext.workspace;
var workspace = analysisDriver.analysisContext.contextRoot.workspace;
if (workspace is BazelWorkspace &&
!bazelSubscriptions.containsKey(folder)) {
var subscription = workspace.bazelCandidateFiles.listen(
@@ -782,7 +782,12 @@ class LspServerContextManagerCallbacks extends ContextManagerCallbacks {
@override
nd.AnalysisDriver addAnalysisDriver(Folder folder, ContextRoot contextRoot) {
var builder = createContextBuilder(folder);
var analysisDriver = builder.buildDriver(contextRoot);
var workspace = ContextBuilder.createWorkspace(
resourceProvider: resourceProvider,
options: builder.builderOptions,
rootPath: folder.path,
);
var analysisDriver = builder.buildDriver(contextRoot, workspace);
final textDocumentCapabilities =
analysisServer.clientCapabilities?.textDocument;
final supportedDiagnosticTags = HashSet<DiagnosticTag>.of(
@@ -23,7 +23,7 @@ class TransformSetManager {
List<TransformSet> forLibrary(LibraryElement library) {
var transformSets = <TransformSet>[];
var analysisContext = library.session.analysisContext;
var workspace = analysisContext.workspace;
var workspace = analysisContext.contextRoot.workspace;
var libraryPath = library.source.fullName;
var package = workspace.findPackageFor(libraryPath);
if (package == null) {
@@ -2285,7 +2285,12 @@ class TestContextManagerCallbacks extends ContextManagerCallbacks {
builder.byteStore = MemoryByteStore();
builder.performanceLog = logger;
builder.fileContentOverlay = FileContentOverlay();
currentDriver = builder.buildDriver(contextRoot);
var workspace = ContextBuilder.createWorkspace(
resourceProvider: resourceProvider,
options: builder.builderOptions,
rootPath: path,
);
currentDriver = builder.buildDriver(contextRoot, workspace);
driverMap[path] = currentDriver;
currentDriver.exceptions.listen((ExceptionResult result) {
+1
View File
@@ -5,6 +5,7 @@
* Added `Resource.parent2` and deprecated `Resource.parent`.
* Added `Folder.isRoot`.
* Added `FolderExtension` with `withAncestors`.
* Added `ContextRoot.workspace`, deprecated `AnalysisContext.workspace`.
## 1.0.0
* Stable null safety release.
@@ -33,5 +33,6 @@ abstract class AnalysisContext {
Folder? get sdkRoot;
/// Return the workspace for containing the context root.
@Deprecated('Use contextRoot.workspace instead')
Workspace get workspace;
}
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/workspace/workspace.dart';
/// Information about the root directory associated with an analysis context.
///
@@ -43,6 +44,9 @@ abstract class ContextRoot {
/// The root directory containing the files to be analyzed.
Folder get root;
/// Return the workspace that contains this context root.
Workspace get workspace;
/// Return the absolute, normalized paths of all of the files that are
/// contained in this context. These are all of the files that are included
/// directly or indirectly by one or more of the [includedPaths] and that are
+11 -12
View File
@@ -5,7 +5,6 @@
import 'dart:collection';
import 'dart:core';
import 'package:analyzer/dart/analysis/context_locator.dart' as api;
import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
@@ -14,6 +13,7 @@ import 'package:analyzer/src/command_line/arguments.dart'
import 'package:analyzer/src/context/context_root.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/context_locator.dart';
import 'package:analyzer/src/dart/analysis/driver.dart'
show AnalysisDriver, AnalysisDriverScheduler;
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart'
@@ -110,16 +110,9 @@ class ContextBuilder {
/// Return an analysis driver that is configured correctly to analyze code in
/// the directory with the given [path].
AnalysisDriver buildDriver(ContextRoot contextRoot) {
AnalysisDriver buildDriver(ContextRoot contextRoot, Workspace workspace) {
String path = contextRoot.root;
Workspace workspace = ContextBuilder.createWorkspace(
resourceProvider: resourceProvider,
options: builderOptions,
rootPath: path,
lookForBazelBuildFileSubstitutes: lookForBazelBuildFileSubstitutes,
);
var options = getAnalysisOptions(path, workspace, contextRoot: contextRoot);
//_processAnalysisOptions(context, optionMap);
@@ -152,18 +145,18 @@ class ContextBuilder {
);
// Set API AnalysisContext for the driver.
var apiContextRoots = api.ContextLocator(
var apiContextRoots = ContextLocatorImpl(
resourceProvider: resourceProvider,
).locateRoots(
includedPaths: [contextRoot.root],
excludedPaths: contextRoot.exclude,
overrideWorkspace: workspace,
);
driver.configure(
analysisContext: api.DriverBasedAnalysisContext(
resourceProvider,
apiContextRoots.first,
driver,
workspace: workspace,
),
);
@@ -410,13 +403,19 @@ class ContextBuilder {
}
}
/// If [packages] is provided, it will be used for the [Workspace],
/// otherwise the packages file from [options] will be used, or discovered
/// from [rootPath].
///
/// TODO(scheglov) Make [packages] required, remove [options] and discovery.
static Workspace createWorkspace({
required ResourceProvider resourceProvider,
required ContextBuilderOptions options,
Packages? packages,
required String rootPath,
bool lookForBazelBuildFileSubstitutes = true,
}) {
var packages = ContextBuilder.createPackageMap(
packages ??= ContextBuilder.createPackageMap(
resourceProvider: resourceProvider,
options: options,
rootPath: rootPath,
@@ -90,7 +90,8 @@ class ContextBuilderImpl implements ContextBuilder {
old.ContextRoot oldContextRoot = old.ContextRoot(
contextRoot.root.path, contextRoot.excludedPaths.toList(),
pathContext: resourceProvider.pathContext);
AnalysisDriver driver = builder.buildDriver(oldContextRoot);
AnalysisDriver driver =
builder.buildDriver(oldContextRoot, contextRoot.workspace);
// AnalysisDriver reports results into streams.
// We need to drain these streams to avoid memory leak.
@@ -9,9 +9,14 @@ 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/analysis_options/analysis_options_provider.dart';
import 'package:analyzer/src/context/builder.dart' as old;
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/packages.dart';
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/util/yaml.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:glob/glob.dart';
import 'package:path/path.dart';
import 'package:yaml/yaml.dart';
@@ -40,12 +45,15 @@ class ContextLocatorImpl implements ContextLocator {
: resourceProvider =
resourceProvider ?? PhysicalResourceProvider.INSTANCE;
/// TODO(scheglov) Remove [overrideWorkspace] when DAS uses collection.
@override
List<ContextRoot> locateRoots(
{required List<String> includedPaths,
List<String>? excludedPaths,
String? optionsFile,
String? packagesFile}) {
List<ContextRoot> locateRoots({
required List<String> includedPaths,
List<String>? excludedPaths,
String? optionsFile,
String? packagesFile,
Workspace? overrideWorkspace,
}) {
//
// Compute the list of folders and files that are to be included.
//
@@ -95,8 +103,11 @@ class ContextLocatorImpl implements ContextLocator {
}
List<ContextRoot> roots = <ContextRoot>[];
for (Folder folder in includedFolders) {
ContextRootImpl root = ContextRootImpl(resourceProvider, folder);
root.packagesFile = defaultPackagesFile ?? _findPackagesFile(folder);
var rootPackagesFile = defaultPackagesFile ?? _findPackagesFile(folder);
var workspace =
overrideWorkspace ?? _createWorkspace(folder, rootPackagesFile);
var root = ContextRootImpl(resourceProvider, folder, workspace);
root.packagesFile = rootPackagesFile;
root.optionsFile = defaultOptionsFile ?? _findOptionsFile(folder);
root.included.add(folder);
root.excludedGlobs = _getExcludedGlobs(root);
@@ -108,8 +119,10 @@ class ContextLocatorImpl implements ContextLocator {
for (File file in includedFiles) {
Folder parent = file.parent2;
ContextRoot root = rootMap.putIfAbsent(parent, () {
ContextRootImpl root = ContextRootImpl(resourceProvider, parent);
root.packagesFile = defaultPackagesFile ?? _findPackagesFile(parent);
var rootPackagesFile = defaultPackagesFile ?? _findPackagesFile(parent);
var workspace = _createWorkspace(parent, rootPackagesFile);
var root = ContextRootImpl(resourceProvider, parent, workspace);
root.packagesFile = rootPackagesFile;
root.optionsFile = defaultOptionsFile ?? _findOptionsFile(parent);
roots.add(root);
return root;
@@ -167,8 +180,10 @@ class ContextLocatorImpl implements ContextLocator {
if (packagesFile != null) {
localPackagesFile = packagesFile;
}
ContextRootImpl root = ContextRootImpl(resourceProvider, folder);
root.packagesFile = localPackagesFile ?? containingRoot.packagesFile;
var rootPackagesFile = localPackagesFile ?? containingRoot.packagesFile;
var workspace = _createWorkspace(folder, rootPackagesFile);
var root = ContextRootImpl(resourceProvider, folder, workspace);
root.packagesFile = rootPackagesFile;
root.optionsFile = localOptionsFile ?? containingRoot.optionsFile;
root.included.add(folder);
containingRoot.excluded.add(folder);
@@ -229,6 +244,22 @@ class ContextLocatorImpl implements ContextLocator {
}
}
Workspace _createWorkspace(Folder folder, File? packagesFile) {
Packages packages;
if (packagesFile != null) {
packages = parsePackagesFile(resourceProvider, packagesFile);
} else {
packages = Packages.empty;
}
return old.ContextBuilder.createWorkspace(
resourceProvider: resourceProvider,
packages: packages,
options: ContextBuilderOptions(), // TODO(scheglov) remove it
rootPath: folder.path,
);
}
/// Return the analysis options file to be used to analyze files in the given
/// [folder], or `null` if there is no analysis options file in the given
/// folder or any parent folder.
@@ -262,9 +293,11 @@ class ContextLocatorImpl implements ContextLocator {
List<Glob> patterns = [];
File? optionsFile = root.optionsFile;
if (optionsFile != null) {
var doc = AnalysisOptionsProvider(
root.workspace.createSourceFactory(null, null))
.getOptionsFromFile(optionsFile);
try {
String content = optionsFile.readAsStringSync();
YamlNode doc = loadYamlNode(content);
if (doc is YamlMap) {
var analyzerOptions = getValue(doc, AnalyzerOptions.analyzer);
if (analyzerOptions is YamlMap) {
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:glob/glob.dart';
import 'package:path/path.dart';
@@ -15,6 +16,9 @@ class ContextRootImpl implements ContextRoot {
@override
final Folder root;
@override
final Workspace workspace;
@override
final List<Resource> included = [];
@@ -32,7 +36,7 @@ class ContextRootImpl implements ContextRoot {
File? packagesFile;
/// Initialize a newly created context root.
ContextRootImpl(this.resourceProvider, this.root);
ContextRootImpl(this.resourceProvider, this.root, this.workspace);
@override
Iterable<String> get excludedPaths =>
@@ -1508,7 +1508,7 @@ class AnalysisDriver implements AnalysisDriverGeneric {
_resourceProvider,
name,
sourceFactory,
analysisContext?.workspace,
analysisContext?.contextRoot.workspace,
analysisOptions,
declaredVariables,
_saltForUnlinked,
@@ -6,7 +6,6 @@ import 'package:analyzer/dart/analysis/analysis_context.dart';
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/session.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptions;
@@ -23,16 +22,14 @@ class DriverBasedAnalysisContext implements AnalysisContext {
/// The driver on which this context is based.
final AnalysisDriver driver;
/// The [Workspace] for this context, `null` if not yet created.
Workspace? _workspace;
/// Initialize a newly created context that uses the given [resourceProvider]
/// to access the file system and that is based on the given analysis
/// [driver].
DriverBasedAnalysisContext(
this.resourceProvider, this.contextRoot, this.driver,
{Workspace? workspace})
: _workspace = workspace {
this.resourceProvider,
this.contextRoot,
this.driver,
) {
driver.analysisContext = this;
}
@@ -51,17 +48,9 @@ class DriverBasedAnalysisContext implements AnalysisContext {
return null;
}
@Deprecated('Use contextRoot.workspace instead')
@override
Workspace get workspace {
return _workspace ??= _buildWorkspace();
}
Workspace _buildWorkspace() {
var path = contextRoot.root.path;
return ContextBuilder.createWorkspace(
resourceProvider: resourceProvider,
options: ContextBuilderOptions(),
rootPath: path,
);
return contextRoot.workspace;
}
}
@@ -8,7 +8,6 @@ import 'package:analyzer/dart/analysis/declared_variables.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/uri_converter.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
@@ -27,7 +26,6 @@ MicroContextObjects createMicroContextObjects({
required SourceFactory sourceFactory,
required ContextRootImpl root,
required ResourceProvider resourceProvider,
required Workspace workspace,
}) {
var declaredVariables = DeclaredVariables();
var synchronousSession = SynchronousSession(
@@ -52,7 +50,6 @@ MicroContextObjects createMicroContextObjects({
declaredVariables,
sourceFactory,
resourceProvider,
workspace: workspace,
);
analysisContext2.currentSession = analysisSession;
@@ -111,7 +108,6 @@ class _MicroAnalysisContextImpl implements AnalysisContext {
final DeclaredVariables declaredVariables;
final SourceFactory sourceFactory;
Workspace? _workspace;
_MicroAnalysisContextImpl(
this.fileResolver,
@@ -119,9 +115,8 @@ class _MicroAnalysisContextImpl implements AnalysisContext {
this.contextRoot,
this.declaredVariables,
this.sourceFactory,
this.resourceProvider, {
Workspace? workspace,
}) : _workspace = workspace;
this.resourceProvider,
);
@override
AnalysisOptionsImpl get analysisOptions {
@@ -131,22 +126,14 @@ class _MicroAnalysisContextImpl implements AnalysisContext {
@override
Folder? get sdkRoot => null;
@Deprecated('Use contextRoot.workspace instead')
@override
Workspace get workspace {
return _workspace ??= _buildWorkspace();
return contextRoot.workspace;
}
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
Workspace _buildWorkspace() {
var path = contextRoot.root.path;
return ContextBuilder.createWorkspace(
resourceProvider: resourceProvider,
options: ContextBuilderOptions(),
rootPath: path,
);
}
}
class _MicroAnalysisSessionImpl extends AnalysisSessionImpl {
@@ -442,7 +442,8 @@ class LibraryAnalyzer {
WorkspacePackage? _getPackage(CompilationUnit unit) {
final libraryPath = _library.source.fullName;
var workspace = unit.declaredElement!.session.analysisContext.workspace;
final session = unit.declaredElement!.session;
final workspace = session.analysisContext.contextRoot.workspace;
return workspace.findPackageFor(libraryPath);
}
@@ -465,7 +465,7 @@ class FileResolver {
if (contextObjects == null) {
var rootFolder = resourceProvider.getFolder(workspace.root);
var root = ContextRootImpl(resourceProvider, rootFolder);
var root = ContextRootImpl(resourceProvider, rootFolder, workspace);
root.included.add(rootFolder);
contextObjects = createMicroContextObjects(
@@ -474,7 +474,6 @@ class FileResolver {
sourceFactory: sourceFactory,
root: root,
resourceProvider: resourceProvider,
workspace: workspace,
);
libraryContext = _LibraryContext(
@@ -209,7 +209,7 @@ class DeclarationsContext {
}
var contextPathList = <String>[];
if (!_analysisContext.workspace.isBazel) {
if (!_analysisContext.contextRoot.workspace.isBazel) {
_Package? package;
for (var candidatePackage in _packages) {
if (candidatePackage.contains(path)) {
@@ -10,6 +10,7 @@ import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/workspace/basic.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -36,7 +37,8 @@ class ContextBuilderImplTest with ResourceProviderMixin {
void setUp() {
var folder = newFolder('/home/test');
contextBuilder = ContextBuilderImpl(resourceProvider: resourceProvider);
contextRoot = ContextRootImpl(resourceProvider, folder);
var workspace = BasicWorkspace.find(resourceProvider, {}, folder.path);
contextRoot = ContextRootImpl(resourceProvider, folder, workspace);
}
test_createContext_declaredVariables() {
@@ -571,6 +571,88 @@ analyzer:
]);
}
void test_locateRoots_options_withExclude_wholeFolder_includedOptions() {
Folder rootFolder = newFolder('/test/root');
File optionsFile = newFile(
'/test/root/${ContextLocatorImpl.ANALYSIS_OPTIONS_NAME}',
content: '''
include: has_excludes.yaml
''');
newFile('/test/root/has_excludes.yaml', content: '''
analyzer:
exclude:
- data/**
''');
File packagesFile = newPackagesFile('/test/root');
Folder dataFolder = newFolder('/test/root/data');
List<ContextRoot> roots =
contextLocator.locateRoots(includedPaths: [rootFolder.path]);
expect(roots, hasLength(1));
ContextRoot root = findRoot(roots, rootFolder);
expect(root.includedPaths, unorderedEquals([rootFolder.path]));
expect(root.excludedPaths, unorderedEquals([dataFolder.path]));
expect(root.optionsFile, optionsFile);
expect(root.packagesFile, packagesFile);
_assertNotAnalyzed(root, [
'/test/root/data/f.dart',
'/test/root/data/foo/f.dart',
]);
_assertAnalyzed(root, [
'/test/root/f.dart',
]);
}
void test_locateRoots_options_withExclude_wholeFolder_includedOptionsMerge() {
Folder rootFolder = newFolder('/test/root');
File optionsFile = newFile(
'/test/root/${ContextLocatorImpl.ANALYSIS_OPTIONS_NAME}',
content: '''
include: has_excludes.yaml
analyzer:
exclude:
- bar/**
''');
newFile('/test/root/has_excludes.yaml', content: '''
analyzer:
exclude:
- foo/**
''');
File packagesFile = newPackagesFile('/test/root');
Folder fooFolder = newFolder('/test/root/foo');
Folder barFolder = newFolder('/test/root/bar');
List<ContextRoot> roots =
contextLocator.locateRoots(includedPaths: [rootFolder.path]);
expect(roots, hasLength(1));
ContextRoot root = findRoot(roots, rootFolder);
expect(root.includedPaths, unorderedEquals([rootFolder.path]));
expect(
root.excludedPaths,
unorderedEquals([fooFolder.path, barFolder.path]),
);
expect(root.optionsFile, optionsFile);
expect(root.packagesFile, packagesFile);
_assertNotAnalyzed(root, [
'/test/root/foo/f.dart',
'/test/root/foo/aaa/f.dart',
'/test/root/bar/f.dart',
'/test/root/bar/aaa/f.dart',
]);
_assertAnalyzed(root, [
'/test/root/f.dart',
'/test/root/baz/f.dart',
]);
}
void test_locateRoots_options_withExclude_wholeFolder_withItsOptions() {
Folder rootFolder = newFolder('/test/root');
File optionsFile = newOptionsFile('/test/root', content: '''
@@ -5,6 +5,8 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/context_root.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/workspace/basic.dart';
import 'package:analyzer/src/workspace/workspace.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -18,12 +20,14 @@ main() {
class ContextRootTest with ResourceProviderMixin {
late final String rootPath;
late final Folder rootFolder;
late Workspace workspace;
late ContextRootImpl contextRoot;
void setUp() {
rootPath = convertPath('/test/root');
rootFolder = newFolder(rootPath);
contextRoot = ContextRootImpl(resourceProvider, rootFolder);
workspace = BasicWorkspace.find(resourceProvider, {}, rootPath);
contextRoot = ContextRootImpl(resourceProvider, rootFolder, workspace);
contextRoot.included.add(rootFolder);
}
@@ -84,7 +88,7 @@ class ContextRootTest with ResourceProviderMixin {
String bPath = convertPath('/test/root/lib/b.dart');
File aFile = getFile(aPath);
contextRoot = ContextRootImpl(resourceProvider, rootFolder);
contextRoot = ContextRootImpl(resourceProvider, rootFolder, workspace);
contextRoot.included.add(aFile);
expect(contextRoot.isAnalyzed(aPath), isTrue);
@@ -132,27 +132,27 @@ abstract class ContextResolutionTest
bool get retainDataForTesting => false;
void assertBasicWorkspaceFor(String path) {
var workspace = contextFor(path).workspace;
var workspace = contextFor(path).contextRoot.workspace;
expect(workspace, TypeMatcher<BasicWorkspace>());
}
void assertBazelWorkspaceFor(String path) {
var workspace = contextFor(path).workspace;
var workspace = contextFor(path).contextRoot.workspace;
expect(workspace, TypeMatcher<BazelWorkspace>());
}
void assertGnWorkspaceFor(String path) {
var workspace = contextFor(path).workspace;
var workspace = contextFor(path).contextRoot.workspace;
expect(workspace, TypeMatcher<GnWorkspace>());
}
void assertPackageBuildWorkspaceFor(String path) {
var workspace = contextFor(path).workspace;
var workspace = contextFor(path).contextRoot.workspace;
expect(workspace, TypeMatcher<PackageBuildWorkspace>());
}
void assertPubWorkspaceFor(String path) {
var workspace = contextFor(path).workspace;
var workspace = contextFor(path).contextRoot.workspace;
expect(workspace, TypeMatcher<PubWorkspace>());
}