| 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) =>
|
|
|