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

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

Issue 1243893002: Separate the API's used by ContextManager. (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 fb1c3b4f5976cff18bd9f68d078ed152c813840c..a57ad14582428c0cd45d08b9d50c312e901e0a5f 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -32,9 +32,133 @@ import 'package:yaml/yaml.dart';
* Class that maintains a mapping from included/excluded paths to a set of
* folders that should correspond to analysis contexts.
*/
-abstract class AbstractContextManager implements ContextManager {
+abstract class ContextManager {
+ // TODO(brianwilkerson) Support:
+ // setting the default analysis options
+ // setting the default content cache
+ // setting the default SDK
+ // maintaining AnalysisContext.folderMap (or remove it)
+ // telling server when a context has been added or removed (see onContextsChanged)
+ // telling server when a context needs to be re-analyzed
+ // notifying the client when results should be flushed
+ // using analyzeFileFunctions to determine which files to analyze
+ //
+ // TODO(brianwilkerson) Move this class to a public library.
+
+ /**
+ * Get the callback interface used to create, destroy, and update contexts.
+ */
+ ContextManagerCallbacks get callbacks;
+
+ /**
+ * Set the callback interface used to create, destroy, and update contexts.
+ */
+ void set callbacks(ContextManagerCallbacks value);
+
+ /**
+ * Return the list of excluded paths (folders and files) most recently passed
+ * to [setRoots].
+ */
+ List<String> get excludedPaths;
+
+ /**
+ * Return the list of included paths (folders and files) most recently passed
+ * to [setRoots].
+ */
+ List<String> get includedPaths;
+
+ /**
+ * Return a list containing all of the contexts contained in the given
+ * [analysisRoot].
+ */
+ List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot);
+
+ /**
+ * Return `true` if the given absolute [path] is in one of the current
+ * root folders and is not excluded.
+ */
+ bool isInAnalysisRoot(String path);
/**
+ * Rebuild the set of contexts from scratch based on the data last sent to
+ * [setRoots]. Only contexts contained in the given list of analysis [roots]
+ * will be rebuilt, unless the list is `null`, in which case every context
+ * will be rebuilt.
+ */
+ void refresh(List<Resource> roots);
+
+ /**
+ * Change the set of paths which should be used as starting points to
+ * determine the context directories.
+ */
+ void setRoots(List<String> includedPaths, List<String> excludedPaths,
+ Map<String, String> packageRoots);
+}
+
+/**
+ * Callback interface used by [ContextManager] to (a) request that contexts be
+ * created, destroyed or updated, (b) inform the client when "pub list"
+ * operations are in progress, and (c) determine which files should be
+ * analyzed.
+ *
+ * TODO(paulberry): eliminate this interface, and instead have [ContextManager]
+ * operations return data structures describing how context state should be
+ * modified.
+ */
+abstract class ContextManagerCallbacks {
+ /**
+ * Create and return a new analysis context.
+ */
+ AnalysisContext addContext(
+ Folder folder, UriResolver packageUriResolver, Packages packages);
+
+ /**
+ * Called when the set of files associated with a context have changed (or
+ * some of those files have been modified). [changeSet] is the set of
+ * changes that need to be applied to the context.
+ */
+ void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
+
+ /**
+ * Called when the ContextManager is about to start computing the package
+ * map.
+ */
+ void beginComputePackageMap() {
+ // By default, do nothing.
+ }
+
+ /**
+ * Called when the ContextManager has finished computing the package map.
+ */
+ void endComputePackageMap() {
+ // By default, do nothing.
+ }
+
+ /**
+ * Remove the context associated with the given [folder]. [flushedFiles] is
+ * a list of the files which will be "orphaned" by removing this context
+ * (they will no longer be analyzed by any context).
+ */
+ void removeContext(Folder folder, List<String> flushedFiles);
+
+ /**
+ * Return `true` if the given [file] should be analyzed.
+ */
+ bool shouldFileBeAnalyzed(File file);
+
+ /**
+ * Called when the package map for a context has changed.
+ */
+ void updateContextPackageUriResolver(
+ Folder contextFolder, UriResolver packageUriResolver, Packages packages);
+}
+
+/**
+ * Class that maintains a mapping from included/excluded paths to a set of
+ * folders that should correspond to analysis contexts.
+ */
+class ContextManagerImpl implements ContextManager {
+ /**
* Temporary flag to hide WIP .packages support (DEP 5).
*/
static bool ENABLE_PACKAGESPEC_SUPPORT = false;
@@ -120,54 +244,14 @@ abstract class AbstractContextManager implements ContextManager {
*/
final InstrumentationService _instrumentationService;
- AbstractContextManager(this.resourceProvider, this.packageResolverProvider,
+ @override
+ ContextManagerCallbacks callbacks;
+
+ ContextManagerImpl(this.resourceProvider, this.packageResolverProvider,
this._packageMapProvider, this._instrumentationService) {
pathContext = resourceProvider.pathContext;
}
- /**
- * Create and return a new analysis context.
- */
- AnalysisContext addContext(
- Folder folder, UriResolver packageUriResolver, Packages packages);
-
- /**
- * Called when the set of files associated with a context have changed (or
- * some of those files have been modified). [changeSet] is the set of
- * changes that need to be applied to the context.
- */
- void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
-
- /**
- * We are about to start computing the package map.
- */
- void beginComputePackageMap() {
- // Do nothing.
- }
-
- /**
- * Compute the set of files that are being flushed, this is defined as
- * the set of sources in the removed context (context.sources), that are
- * orphaned by this context being removed (no other context includes this
- * file.)
- */
- List<String> computeFlushedFiles(Folder folder) {
- AnalysisContext context = _contexts[folder].context;
- HashSet<String> flushedFiles = new HashSet<String>();
- for (Source source in context.sources) {
- flushedFiles.add(source.fullName);
- }
- for (_ContextInfo contextInfo in _contexts.values) {
- AnalysisContext contextN = contextInfo.context;
- if (context != contextN) {
- for (Source source in contextN.sources) {
- flushedFiles.remove(source.fullName);
- }
- }
- }
- return flushedFiles.toList(growable: false);
- }
-
@override
List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot) {
List<AnalysisContext> contexts = <AnalysisContext>[];
@@ -179,13 +263,6 @@ abstract class AbstractContextManager implements ContextManager {
return contexts;
}
- /**
- * We have finished computing the package map.
- */
- void endComputePackageMap() {
- // Do nothing.
- }
-
@override
bool isInAnalysisRoot(String path) {
// check if excluded
@@ -241,11 +318,6 @@ abstract class AbstractContextManager implements ContextManager {
setRoots(includedPaths, excludedPaths, packageRoots);
}
- /**
- * Remove the context associated with the given [folder].
- */
- void removeContext(Folder folder);
-
/// Sets the [ignorePatterns] for the context [folder].
void setIgnorePatternsForContext(Folder folder, List<String> ignorePatterns) {
_ContextInfo info = _contexts[folder];
@@ -331,28 +403,17 @@ abstract class AbstractContextManager implements ContextManager {
info.sources.remove(path);
changeSet.removedSource(source);
});
- applyChangesToContext(folder, changeSet);
+ callbacks.applyChangesToContext(folder, changeSet);
});
// add previously excluded sources
_contexts.forEach((folder, info) {
ChangeSet changeSet = new ChangeSet();
_addPreviouslyExcludedSources(info, changeSet, folder, oldExcludedPaths);
- applyChangesToContext(folder, changeSet);
+ callbacks.applyChangesToContext(folder, changeSet);
});
}
/**
- * Return `true` if the given [file] should be analyzed.
- */
- bool shouldFileBeAnalyzed(File file);
-
- /**
- * Called when the package map for a context has changed.
- */
- void updateContextPackageUriResolver(
- Folder contextFolder, UriResolver packageUriResolver, Packages packages);
-
- /**
* Resursively adds all Dart and HTML files to the [changeSet].
*/
void _addPreviouslyExcludedSources(_ContextInfo info, ChangeSet changeSet,
@@ -377,7 +438,7 @@ abstract class AbstractContextManager implements ContextManager {
// add files, recurse into folders
if (child is File) {
// ignore if should not be analyzed at all
- if (!shouldFileBeAnalyzed(child)) {
+ if (!callbacks.shouldFileBeAnalyzed(child)) {
continue;
}
// ignore if was not excluded
@@ -422,7 +483,7 @@ abstract class AbstractContextManager implements ContextManager {
}
// add files, recurse into folders
if (child is File) {
- if (shouldFileBeAnalyzed(child)) {
+ if (callbacks.shouldFileBeAnalyzed(child)) {
Source source = createSourceInContext(info.context, child);
changeSet.addedSource(source);
info.sources[path] = source;
@@ -457,10 +518,33 @@ abstract class AbstractContextManager implements ContextManager {
if (packagespec.exists) {
Packages packages = _readPackagespec(packagespec);
if (packages != null) {
- updateContextPackageUriResolver(folder, null, packages);
+ callbacks.updateContextPackageUriResolver(folder, null, packages);
+ }
+ }
+ }
+ }
+
+ /**
+ * Compute the set of files that are being flushed, this is defined as
+ * the set of sources in the removed context (context.sources), that are
+ * orphaned by this context being removed (no other context includes this
+ * file.)
+ */
+ List<String> _computeFlushedFiles(Folder folder) {
+ AnalysisContext context = _contexts[folder].context;
+ HashSet<String> flushedFiles = new HashSet<String>();
+ for (Source source in context.sources) {
+ flushedFiles.add(source.fullName);
+ }
+ for (_ContextInfo contextInfo in _contexts.values) {
+ AnalysisContext contextN = contextInfo.context;
+ if (context != contextN) {
+ for (Source source in contextN.sources) {
+ flushedFiles.remove(source.fullName);
}
}
}
+ return flushedFiles.toList(growable: false);
}
/**
@@ -496,7 +580,7 @@ abstract class AbstractContextManager implements ContextManager {
//TODO(danrubel) remove this if it will never be called
return new PackageUriResolver([packagesDir]);
} else {
- beginComputePackageMap();
+ callbacks.beginComputePackageMap();
if (packageResolverProvider != null) {
UriResolver resolver = packageResolverProvider(folder);
if (resolver != null) {
@@ -508,7 +592,7 @@ abstract class AbstractContextManager implements ContextManager {
packageMapInfo =
_packageMapProvider.computePackageMap(folder, info.packageMapInfo);
});
- endComputePackageMap();
+ callbacks.endComputePackageMap();
for (String dependencyPath in packageMapInfo.dependencies) {
Resource resource = resourceProvider.getResource(dependencyPath);
if (resource is File) {
@@ -568,7 +652,7 @@ abstract class AbstractContextManager implements ContextManager {
packageUriResolver = _computePackageUriResolver(folder, info);
}
- info.context = addContext(folder, packageUriResolver, packages);
+ info.context = callbacks.addContext(folder, packageUriResolver, packages);
info.context.name = folder.path;
} catch (_) {
info.changeSubscription.cancel();
@@ -640,7 +724,7 @@ abstract class AbstractContextManager implements ContextManager {
_ContextInfo info = _createContext(folder, pubspecFile, children);
ChangeSet changeSet = new ChangeSet();
_addSourceFiles(changeSet, folder, info);
- applyChangesToContext(folder, changeSet);
+ callbacks.applyChangesToContext(folder, changeSet);
return info;
}
@@ -651,7 +735,7 @@ abstract class AbstractContextManager implements ContextManager {
_ContextInfo info = _contexts[folder];
info.changeSubscription.cancel();
_cancelDependencySubscriptions(info);
- removeContext(folder);
+ callbacks.removeContext(folder, _computeFlushedFiles(folder));
_contexts.remove(folder);
}
@@ -676,7 +760,7 @@ abstract class AbstractContextManager implements ContextManager {
newInfo.sources[path] = source;
changeSet.addedSource(source);
});
- applyChangesToContext(newFolder, changeSet);
+ callbacks.applyChangesToContext(newFolder, changeSet);
}
// update old context
{
@@ -685,7 +769,7 @@ abstract class AbstractContextManager implements ContextManager {
oldInfo.sources.remove(path);
changeSet.removedSource(source);
});
- applyChangesToContext(oldInfo.folder, changeSet);
+ callbacks.applyChangesToContext(oldInfo.folder, changeSet);
}
}
@@ -759,11 +843,11 @@ abstract class AbstractContextManager implements ContextManager {
// that case don't add it.
if (resource is File) {
File file = resource;
- if (shouldFileBeAnalyzed(file)) {
+ if (callbacks.shouldFileBeAnalyzed(file)) {
ChangeSet changeSet = new ChangeSet();
Source source = createSourceInContext(info.context, file);
changeSet.addedSource(source);
- applyChangesToContext(folder, changeSet);
+ callbacks.applyChangesToContext(folder, changeSet);
info.sources[path] = source;
}
}
@@ -810,7 +894,7 @@ abstract class AbstractContextManager implements ContextManager {
sources.forEach((Source source) {
changeSet.removedSource(source);
});
- applyChangesToContext(folder, changeSet);
+ callbacks.applyChangesToContext(folder, changeSet);
info.sources.remove(path);
}
break;
@@ -821,7 +905,7 @@ abstract class AbstractContextManager implements ContextManager {
sources.forEach((Source source) {
changeSet.changedSource(source);
});
- applyChangesToContext(folder, changeSet);
+ callbacks.applyChangesToContext(folder, changeSet);
}
break;
}
@@ -882,7 +966,7 @@ abstract class AbstractContextManager implements ContextManager {
parentInfo.sources[path] = source;
changeSet.addedSource(source);
});
- applyChangesToContext(parentInfo.folder, changeSet);
+ callbacks.applyChangesToContext(parentInfo.folder, changeSet);
}
}
@@ -909,7 +993,8 @@ abstract class AbstractContextManager implements ContextManager {
// "pub list" is in progress is just going to get thrown away anyhow.
UriResolver packageUriResolver =
_computePackageUriResolver(info.folder, info);
- updateContextPackageUriResolver(info.folder, packageUriResolver, null);
+ callbacks.updateContextPackageUriResolver(
+ info.folder, packageUriResolver, null);
}
/**
@@ -929,73 +1014,6 @@ abstract class AbstractContextManager implements ContextManager {
}
/**
- * Class that maintains a mapping from included/excluded paths to a set of
- * folders that should correspond to analysis contexts.
- */
-abstract class ContextManager {
- // TODO(brianwilkerson) Support:
- // setting the default analysis options
- // setting the default content cache
- // setting the default SDK
- // maintaining AnalysisContext.folderMap (or remove it)
- // telling server when a context has been added or removed (see onContextsChanged)
- // telling server when a context needs to be re-analyzed
- // notifying the client when results should be flushed
- // using analyzeFileFunctions to determine which files to analyze
- //
- // TODO(brianwilkerson) Move this class to a public library.
-
-// /**
-// * The default options used to create new analysis contexts.
-// */
-// AnalysisOptionsImpl get defaultOptions;
-
- /**
- * Return the list of excluded paths (folders and files) most recently passed
- * to [setRoots].
- */
- List<String> get excludedPaths;
-
- /**
- * Return the list of included paths (folders and files) most recently passed
- * to [setRoots].
- */
- List<String> get includedPaths;
-
-// /**
-// * A stream that is notified when contexts are added or removed.
-// */
-// Stream<ContextsChangedEvent> get onContextsChanged;
-
- /**
- * Return a list containing all of the contexts contained in the given
- * [analysisRoot].
- */
- List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot);
-
- /**
- * Return `true` if the given absolute [path] is in one of the current
- * root folders and is not excluded.
- */
- bool isInAnalysisRoot(String path);
-
- /**
- * Rebuild the set of contexts from scratch based on the data last sent to
- * [setRoots]. Only contexts contained in the given list of analysis [roots]
- * will be rebuilt, unless the list is `null`, in which case every context
- * will be rebuilt.
- */
- void refresh(List<Resource> roots);
-
- /**
- * Change the set of paths which should be used as starting points to
- * determine the context directories.
- */
- void setRoots(List<String> includedPaths, List<String> excludedPaths,
- Map<String, String> packageRoots);
-}
-
-/**
* An indication that one or more contexts were added, changed, or removed.
*
* The lists of [added], [changed] and [removed] contexts will not contain
@@ -1123,7 +1141,7 @@ class _ContextInfo {
bool ignored(String path) => pathFilter.ignored(path);
/**
- * Returns `true` if [path] is the package description file for this context
+ * Returns `true` if [path] is the package description file for this context
* (pubspec.yaml or .packages).
*/
bool isPathToPackageDescription(String path) =>

Powered by Google App Engine
This is Rietveld 408576698