Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(516)

Unified Diff: pkg/analysis_server/lib/src/context_manager.dart

Issue 1258473003: Introduce FolderDisposition class hierarchy for use in ContextManagerCallback. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/lib/src/context_manager.dart
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index c12453c131fb36493585150d86432f388be227da..d4cb5cee9a35be98423b956748714cb7a1592296 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -244,10 +244,10 @@ abstract class ContextManager {
*/
abstract class ContextManagerCallbacks {
/**
- * Create and return a new analysis context.
+ * Create and return a new analysis context, allowing [disposition] to govern
+ * details of how the context is to be created.
*/
- AnalysisContext addContext(
- Folder folder, UriResolver packageUriResolver, Packages packages);
+ AnalysisContext addContext(Folder folder, FolderDisposition disposition);
/**
* Called when the set of files associated with a context have changed (or
@@ -284,10 +284,10 @@ abstract class ContextManagerCallbacks {
bool shouldFileBeAnalyzed(File file);
/**
- * Called when the package map for a context has changed.
+ * Called when the disposition for a context has changed.
*/
void updateContextPackageUriResolver(
- Folder contextFolder, UriResolver packageUriResolver, Packages packages);
+ Folder contextFolder, FolderDisposition disposition);
}
/**
@@ -533,7 +533,7 @@ class ContextManagerImpl implements ContextManager {
String newPackageRoot = normalizedPackageRoots[info.folder.path];
if (info.packageRoot != newPackageRoot) {
info.packageRoot = newPackageRoot;
- _recomputePackageUriResolver(info);
+ _recomputeFolderDisposition(info);
}
}
// create new contexts
@@ -677,7 +677,8 @@ class ContextManagerImpl implements ContextManager {
if (packagespec.exists) {
Packages packages = _readPackagespec(packagespec);
if (packages != null) {
- callbacks.updateContextPackageUriResolver(folder, null, packages);
+ callbacks.updateContextPackageUriResolver(
+ folder, new PackagesFileDisposition(packages));
}
}
}
@@ -707,11 +708,10 @@ class ContextManagerImpl implements ContextManager {
}
/**
- * Compute the appropriate package URI resolver for [folder], and store
- * dependency information in [info]. Return `null` if no package map can
- * be computed.
+ * Compute the appropriate [FolderDisposition] for [folder], and store
+ * dependency information in [info].
*/
- UriResolver _computePackageUriResolver(Folder folder, ContextInfo info) {
+ FolderDisposition _computeFolderDisposition(Folder folder, ContextInfo info) {
_cancelDependencySubscriptions(info);
if (info.packageRoot != null) {
info.packageMapInfo = null;
@@ -736,20 +736,20 @@ class ContextManagerImpl implements ContextManager {
packageMap[file.getName()] = <Folder>[res];
}
}
- return new PackageMapUriResolver(resourceProvider, packageMap);
+ return new PackageMapDisposition(packageMap);
}
// The package root does not exist (or is not a folder). Since
// [setRoots] ignores any package roots that don't exist (or aren't
// folders), the only way we should be able to get here is due to a race
// condition. In any case, the package root folder is gone, so we can't
// resolve packages.
- return null;
+ return new NoPackageFolderDisposition();
} else {
callbacks.beginComputePackageMap();
if (packageResolverProvider != null) {
UriResolver resolver = packageResolverProvider(folder);
if (resolver != null) {
- return resolver;
+ return new CustomPackageResolverDisposition(resolver);
}
}
OptimizingPubPackageMapInfo packageMapInfo;
@@ -766,7 +766,7 @@ class ContextManagerImpl implements ContextManager {
if (info.packageMapInfo != null &&
info.packageMapInfo.isChangedDependency(
dependencyPath, resourceProvider)) {
- _recomputePackageUriResolver(info);
+ _recomputeFolderDisposition(info);
}
}, onError: (error, StackTrace stackTrace) {
// Gracefully degrade if file is or becomes unwatchable
@@ -779,12 +779,9 @@ class ContextManagerImpl implements ContextManager {
}
info.packageMapInfo = packageMapInfo;
if (packageMapInfo.packageMap == null) {
- return null;
+ return new NoPackageFolderDisposition();
}
- return new PackageMapUriResolver(
- resourceProvider, packageMapInfo.packageMap);
- // TODO(paulberry): if any of the dependencies is outside of [folder],
- // we'll need to watch their parent folders as well.
+ return new PackageMapDisposition(packageMapInfo.packageMap);
}
}
@@ -802,22 +799,22 @@ class ContextManagerImpl implements ContextManager {
_handleWatchEvent(folder, info, event);
});
try {
- Packages packages;
- UriResolver packageUriResolver;
+ FolderDisposition disposition;
if (ENABLE_PACKAGESPEC_SUPPORT) {
// Try .packages first.
if (pathos.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
- packages = _readPackagespec(packagespecFile);
+ Packages packages = _readPackagespec(packagespecFile);
+ disposition = new PackagesFileDisposition(packages);
}
}
// Next resort to a package uri resolver.
- if (packages == null) {
- packageUriResolver = _computePackageUriResolver(folder, info);
+ if (disposition == null) {
+ disposition = _computeFolderDisposition(folder, info);
}
- info.context = callbacks.addContext(folder, packageUriResolver, packages);
+ info.context = callbacks.addContext(folder, disposition);
info.context.name = folder.path;
} catch (_) {
info.changeSubscription.cancel();
@@ -1093,7 +1090,7 @@ class ContextManagerImpl implements ContextManager {
if (info.packageMapInfo != null &&
info.packageMapInfo.isChangedDependency(path, resourceProvider)) {
- _recomputePackageUriResolver(info);
+ _recomputeFolderDisposition(info);
}
}
@@ -1161,18 +1158,17 @@ class ContextManagerImpl implements ContextManager {
}
/**
- * Recompute the package URI resolver for the context described by [info],
+ * Recompute the [FolderDisposition] for the context described by [info],
* and update the client appropriately.
*/
- void _recomputePackageUriResolver(ContextInfo info) {
+ void _recomputeFolderDisposition(ContextInfo info) {
// TODO(paulberry): when computePackageMap is changed into an
// asynchronous API call, we'll want to suspend analysis for this context
// while we're rerunning "pub list", since any analysis we complete while
// "pub list" is in progress is just going to get thrown away anyhow.
- UriResolver packageUriResolver =
- _computePackageUriResolver(info.folder, info);
- callbacks.updateContextPackageUriResolver(
- info.folder, packageUriResolver, null);
+ FolderDisposition disposition =
+ _computeFolderDisposition(info.folder, info);
+ callbacks.updateContextPackageUriResolver(info.folder, disposition);
}
/**
@@ -1222,3 +1218,106 @@ class ContextsChangedEvent {
this.changed: AnalysisContext.EMPTY_LIST,
this.removed: AnalysisContext.EMPTY_LIST});
}
+
+/**
+ * Concrete [FolderDisposition] object indicating that the context for a given
+ * folder should resolve package URIs using a custom URI resolver.
+ */
+class CustomPackageResolverDisposition extends FolderDisposition {
+ /**
+ * The [UriResolver] that should be used to resolve package URIs.
+ */
+ UriResolver resolver;
+
+ CustomPackageResolverDisposition(this.resolver);
+
+ @override
+ Packages get packages => null;
+
+ @override
+ Iterable<UriResolver> createPackageUriResolvers(
+ ResourceProvider resourceProvider) => <UriResolver>[resolver];
+}
+
+/**
+ * An instance of the class [FolderDisposition] represents the information
+ * gathered by the [ContextManagerImpl] to determine how to create an
+ * [AnalysisContext] for a given folder.
+ *
+ * Note: [ContextManagerImpl] may use equality testing and hash codes to
+ * determine when two folders should share the same context, so derived classes
+ * may need to override operator== and hashCode() if object identity is
+ * insufficient.
+ *
+ * TODO(paulberry): consider adding a flag to indicate that it is not necessary
+ * to recurse into the given folder looking for additional contexts to create
+ * or files to analyze (this could help avoid unnecessarily weighing down the
+ * system with file watchers).
+ */
+abstract class FolderDisposition {
+ /**
+ * If contexts governed by this [FolderDisposition] should resolve packages
+ * using the ".packages" file mechanism (DEP 5), retrieve the [Packages]
+ * object that resulted from parsing the ".packages" file.
+ */
+ Packages get packages;
+
+ /**
+ * Create all the [UriResolver]s which should be used to resolve packages in
+ * contexts governed by this [FolderDisposition].
+ *
+ * [resourceProvider] is provided since it is needed to construct most
+ * [UriResolver]s.
+ */
+ Iterable<UriResolver> createPackageUriResolvers(
+ ResourceProvider resourceProvider);
+}
+
+/**
+ * Concrete [FolderDisposition] object indicating that the context for a given
+ * folder should not resolve "package:" URIs at all.
+ *
+ * TODO(paulberry): consider making this a singleton object (which would cause
+ * all folders that don't resolve "package:" URIs to share the same context).
+ */
+class NoPackageFolderDisposition extends FolderDisposition {
+ @override
+ Packages get packages => null;
+
+ @override
+ Iterable<UriResolver> createPackageUriResolvers(
+ ResourceProvider resourceProvider) => const <UriResolver>[];
+}
+
+/**
+ * Concrete [FolderDisposition] object indicating that the context for a given
+ * folder should resolve packages using a package map.
+ */
+class PackageMapDisposition extends FolderDisposition {
+ final Map<String, List<Folder>> packageMap;
+
+ PackageMapDisposition(this.packageMap);
+
+ @override
+ Packages get packages => null;
+
+ @override
+ Iterable<UriResolver> createPackageUriResolvers(
+ ResourceProvider resourceProvider) =>
+ <UriResolver>[new PackageMapUriResolver(resourceProvider, packageMap)];
+}
+
+/**
+ * Concrete [FolderDisposition] object indicating that the context for a given
+ * folder should resolve packages using a ".packages" file.
+ */
+class PackagesFileDisposition extends FolderDisposition {
+ @override
+ final Packages packages;
+
+ PackagesFileDisposition(this.packages) {}
+
+ @override
+ Iterable<UriResolver> createPackageUriResolvers(
+ ResourceProvider resourceProvider) => const <UriResolver>[];
+}
« no previous file with comments | « pkg/analysis_server/lib/src/analysis_server.dart ('k') | pkg/analysis_server/test/context_manager_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698