Chromium Code Reviews| Index: pkg/analysis_server/lib/src/analysis_server.dart |
| diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart |
| index d608c6ad2bb6dff33c52a4d64d2fef936e40ddfb..4e81022dbc5890b930763a549f4c943c7459e0d4 100644 |
| --- a/pkg/analysis_server/lib/src/analysis_server.dart |
| +++ b/pkg/analysis_server/lib/src/analysis_server.dart |
| @@ -12,8 +12,8 @@ import 'package:analysis_server/src/channel.dart'; |
| import 'package:analysis_server/src/constants.dart'; |
| import 'package:analysis_server/src/context_directory_manager.dart'; |
| import 'package:analysis_server/src/domain_analysis.dart'; |
| -import 'package:analysis_server/src/operation/operation_analysis.dart'; |
| import 'package:analysis_server/src/operation/operation.dart'; |
| +import 'package:analysis_server/src/operation/operation_analysis.dart'; |
| import 'package:analysis_server/src/operation/operation_queue.dart'; |
| import 'package:analysis_server/src/package_map_provider.dart'; |
| import 'package:analysis_server/src/package_uri_resolver.dart'; |
| @@ -22,12 +22,12 @@ import 'package:analysis_server/src/resource.dart'; |
| import 'package:analyzer/src/generated/ast.dart'; |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/error.dart'; |
| -import 'package:analyzer/src/generated/source.dart'; |
| +import 'package:analyzer/src/generated/index.dart'; |
| +import 'package:analyzer/src/generated/java_engine.dart'; |
| import 'package:analyzer/src/generated/sdk.dart'; |
| import 'package:analyzer/src/generated/sdk_io.dart'; |
| +import 'package:analyzer/src/generated/source.dart'; |
| import 'package:analyzer/src/generated/source_io.dart'; |
| -import 'package:analyzer/src/generated/java_engine.dart'; |
| -import 'package:analyzer/src/generated/index.dart'; |
| /** |
| @@ -36,61 +36,7 @@ import 'package:analyzer/src/generated/index.dart'; |
| */ |
| final DirectoryBasedDartSdk SHARED_SDK = DirectoryBasedDartSdk.defaultSdk; |
| -class AnalysisServerContextDirectoryManager extends ContextDirectoryManager { |
| - final AnalysisServer analysisServer; |
| - |
| - /** |
| - * The default options used to create new analysis contexts. |
| - */ |
| - AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl(); |
| - |
| - AnalysisServerContextDirectoryManager( |
| - this.analysisServer, ResourceProvider resourceProvider, |
| - PackageMapProvider packageMapProvider) |
| - : super(resourceProvider, packageMapProvider); |
| - |
| - @override |
| - void addContext(Folder folder, Map<String, List<Folder>> packageMap) { |
| - AnalysisContext context = AnalysisEngine.instance.createAnalysisContext(); |
| - analysisServer.folderMap[folder] = context; |
| - context.sourceFactory = _createSourceFactory(packageMap); |
| - context.analysisOptions = new AnalysisOptionsImpl.con1(defaultOptions); |
| - analysisServer.schedulePerformAnalysisOperation(context); |
| - } |
| - |
| - @override |
| - void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { |
| - AnalysisContext context = analysisServer.folderMap[contextFolder]; |
| - context.applyChanges(changeSet); |
| - analysisServer.schedulePerformAnalysisOperation(context); |
| - } |
| - |
| - @override |
| - void removeContext(Folder folder) { |
| - analysisServer.folderMap.remove(folder); |
| - } |
| - |
| - @override |
| - void updateContextPackageMap(Folder contextFolder, |
| - Map<String, List<Folder>> packageMap) { |
| - AnalysisContext context = analysisServer.folderMap[contextFolder]; |
| - context.sourceFactory = _createSourceFactory(packageMap); |
| - analysisServer.schedulePerformAnalysisOperation(context); |
| - } |
| - |
| - /** |
| - * Set up a [SourceFactory] that resolves packages using the given |
| - * [packageMap]. |
| - */ |
| - SourceFactory _createSourceFactory(Map<String, List<Folder>> packageMap) { |
| - List<UriResolver> resolvers = <UriResolver>[ |
| - new DartUriResolver(analysisServer.defaultSdk), |
| - new ResourceUriResolver(resourceProvider), |
| - new PackageMapUriResolver(resourceProvider, packageMap) |
| - ]; |
| - return new SourceFactory(resolvers); |
| - } |
| -} |
| +typedef void OptionUpdater(AnalysisOptionsImpl options); |
| /** |
| * Instances of the class [AnalysisServer] implement a server that listens on a |
| @@ -141,8 +87,8 @@ class AnalysisServer { |
| /** |
| * A table mapping [Folder]s to the [AnalysisContext]s associated with them. |
| */ |
| - final Map<Folder, AnalysisContext> folderMap = |
| - new HashMap<Folder, AnalysisContext>(); |
| + final Map<Folder, AnalysisContext> folderMap = new HashMap<Folder, |
|
Brian Wilkerson
2014/07/02 13:58:06
You probably have no control, but I liked the old
scheglov
2014/07/02 17:33:09
Yes, we need to improve formatter.
Rolled back for
|
| + AnalysisContext>(); |
| /** |
| * A queue of the operations to perform in this server. |
| @@ -181,11 +127,11 @@ class AnalysisServer { |
| * running a full analysis server. |
| */ |
| AnalysisServer(this.channel, ResourceProvider resourceProvider, |
| - PackageMapProvider packageMapProvider, this.index, |
| - {this.rethrowExceptions: true}) { |
| + PackageMapProvider packageMapProvider, this.index, {this.rethrowExceptions: |
|
Brian Wilkerson
2014/07/02 13:58:06
I liked the old formatting better here too.
|
| + true}) { |
| operationQueue = new ServerOperationQueue(this); |
| - contextDirectoryManager = new AnalysisServerContextDirectoryManager( |
| - this, resourceProvider, packageMapProvider); |
| + contextDirectoryManager = new AnalysisServerContextDirectoryManager(this, |
| + resourceProvider, packageMapProvider); |
| AnalysisEngine.instance.logger = new AnalysisLogger(); |
| running = true; |
| Notification notification = new Notification(SERVER_CONNECTED); |
| @@ -194,90 +140,6 @@ class AnalysisServer { |
| } |
| /** |
| - * Schedules execution of the given [ServerOperation]. |
| - */ |
| - void scheduleOperation(ServerOperation operation) { |
| - bool wasEmpty = operationQueue.isEmpty; |
| - addOperation(operation); |
| - if (wasEmpty) { |
| - _schedulePerformOperation(); |
| - } |
| - } |
| - |
| - /** |
| - * Schedules analysis of the given context. |
| - */ |
| - void schedulePerformAnalysisOperation(AnalysisContext context) { |
| - scheduleOperation(new PerformAnalysisOperation(context, false)); |
| - } |
| - |
| - /** |
| - * Send the given [notification] to the client. |
| - */ |
| - void sendNotification(Notification notification) { |
| - channel.sendNotification(notification); |
| - } |
| - |
| - /** |
| - * Set the priority files to the given [files]. |
| - */ |
| - void setPriorityFiles(Request request, List<String> files) { |
| - Map<AnalysisContext, List<Source>> sourceMap = |
| - new HashMap<AnalysisContext, List<Source>>(); |
| - List<String> unanalyzed = new List<String>(); |
| - files.forEach((file) { |
| - AnalysisContext analysisContext = _getAnalysisContext(file); |
| - if (analysisContext == null) { |
| - unanalyzed.add(file); |
| - } else { |
| - List<Source> sourceList = sourceMap[analysisContext]; |
| - if (sourceList == null) { |
| - sourceList = <Source>[]; |
| - sourceMap[analysisContext] = sourceList; |
| - } |
| - sourceList.add(_getSource(file)); |
| - } |
| - }); |
| - if (unanalyzed.isNotEmpty) { |
| - StringBuffer buffer = new StringBuffer(); |
| - buffer.writeAll(unanalyzed, ', '); |
| - throw new RequestFailure(new Response.unanalyzedPriorityFiles(request, |
| - buffer.toString())); |
| - } |
| - folderMap.forEach((Folder folder, AnalysisContext context) { |
| - List<Source> sourceList = sourceMap[context]; |
| - if (sourceList == null) { |
| - sourceList = Source.EMPTY_ARRAY; |
| - } |
| - context.analysisPriorityOrder = sourceList; |
| - }); |
| - } |
| - |
| - /** |
| - * Use the given updaters to update the values of the options in every |
| - * existing analysis context. |
| - */ |
| - void updateOptions(List<OptionUpdater> optionUpdaters) { |
| - // |
| - // Update existing contexts. |
| - // |
| - folderMap.forEach((Folder folder, AnalysisContext context) { |
| - AnalysisOptionsImpl options = new AnalysisOptionsImpl.con1(context.analysisOptions); |
| - optionUpdaters.forEach((OptionUpdater optionUpdater) { |
| - optionUpdater(options); |
| - }); |
| - context.analysisOptions = options; |
| - }); |
| - // |
| - // Update the defaults used to create new contexts. |
| - // |
| - AnalysisOptionsImpl options = contextDirectoryManager.defaultOptions; |
| - optionUpdaters.forEach((OptionUpdater optionUpdater) { |
| - optionUpdater(options); |
| - }); |
| - } |
| - |
| - /** |
| * Adds the given [ServerOperation] to the queue, but does not schedule |
| * operations execution. |
| */ |
| @@ -301,22 +163,32 @@ class AnalysisServer { |
| running = false; |
| } |
| -// TODO(brianwilkerson) Add the following method after 'prioritySources' has |
| -// been added to InternalAnalysisContext. |
| -// /** |
| -// * Return a list containing the full names of all of the sources that are |
| -// * priority sources. |
| -// */ |
| -// List<String> getPriorityFiles() { |
| -// List<String> priorityFiles = new List<String>(); |
| -// folderMap.values.forEach((ContextDirectory directory) { |
| -// InternalAnalysisContext context = directory.context; |
| -// context.prioritySources.forEach((Source source) { |
| -// priorityFiles.add(source.fullName); |
| -// }); |
| -// }); |
| -// return priorityFiles; |
| -// } |
| + /** |
| + * Returns the [CompilationUnit] of the Dart file with the given [path] that |
| + * should be used to resend notifications for already resolved unit. |
| + * Returns `null` if the file is not a part of any context, library has not |
| + * been yet resolved, or any problem happened. |
| + */ |
| + CompilationUnit getResolvedCompilationUnitToResendNotification(String path) { |
| + // prepare AnalysisContext |
| + AnalysisContext context = getAnalysisContext(path); |
| + if (context == null) { |
| + return null; |
| + } |
| + // prepare sources |
| + Source unitSource = getSource(path); |
| + List<Source> librarySources = context.getLibrariesContaining(unitSource); |
| + if (librarySources.isEmpty) { |
| + return null; |
| + } |
| + // if library has not been resolved yet, the unit will be resolved later |
| + Source librarySource = librarySources[0]; |
| + if (context.getLibraryElement(librarySource) == null) { |
| + return null; |
| + } |
| + // if library has been already resolved, resolve unit |
| + return context.resolveCompilationUnit2(unitSource, librarySource); |
| + } |
| /** |
| * Handle a [request] that was read from the communication channel. |
| @@ -354,6 +226,23 @@ class AnalysisServer { |
| return false; |
| } |
| +// TODO(brianwilkerson) Add the following method after 'prioritySources' has |
| +// been added to InternalAnalysisContext. |
| +// /** |
| +// * Return a list containing the full names of all of the sources that are |
| +// * priority sources. |
| +// */ |
| +// List<String> getPriorityFiles() { |
| +// List<String> priorityFiles = new List<String>(); |
| +// folderMap.values.forEach((ContextDirectory directory) { |
| +// InternalAnalysisContext context = directory.context; |
| +// context.prioritySources.forEach((Source source) { |
| +// priorityFiles.add(source.fullName); |
| +// }); |
| +// }); |
| +// return priorityFiles; |
| +// } |
| + |
| /** |
| * Perform the next available [ServerOperation]. |
| */ |
| @@ -374,8 +263,7 @@ class AnalysisServer { |
| } catch (exception, stackTrace) { |
| AnalysisEngine.instance.logger.logError("${exception}\n${stackTrace}"); |
| if (rethrowExceptions) { |
| - throw new AnalysisException( |
| - 'Unexpected exception during analysis', |
| + throw new AnalysisException('Unexpected exception during analysis', |
| new CaughtException(exception, stackTrace)); |
| } |
| } finally { |
| @@ -388,6 +276,31 @@ class AnalysisServer { |
| } |
| /** |
| + * Schedules execution of the given [ServerOperation]. |
| + */ |
| + void scheduleOperation(ServerOperation operation) { |
| + bool wasEmpty = operationQueue.isEmpty; |
| + addOperation(operation); |
| + if (wasEmpty) { |
| + _schedulePerformOperation(); |
| + } |
| + } |
| + |
| + /** |
| + * Schedules analysis of the given context. |
| + */ |
| + void schedulePerformAnalysisOperation(AnalysisContext context) { |
| + scheduleOperation(new PerformAnalysisOperation(context, false)); |
| + } |
| + |
| + /** |
| + * Send the given [notification] to the client. |
| + */ |
| + void sendNotification(Notification notification) { |
| + channel.sendNotification(notification); |
| + } |
| + |
| + /** |
| * Send status notification to the client. The `operation` is the operation |
| * being performed or `null` if analysis is complete. |
| */ |
| @@ -417,52 +330,29 @@ class AnalysisServer { |
| * So, we can start working in parallel on adding services and improving |
| * projects/contexts support. |
| */ |
| - void setAnalysisRoots(String requestId, |
| - List<String> includedPaths, |
| - List<String> excludedPaths) { |
| + void setAnalysisRoots(String requestId, List<String> includedPaths, |
| + List<String> excludedPaths) { |
| try { |
| contextDirectoryManager.setRoots(includedPaths, excludedPaths); |
| } on UnimplementedError catch (e) { |
| - throw new RequestFailure( |
| - new Response.unsupportedFeature( |
| - requestId, e.message)); |
| + throw new RequestFailure(new Response.unsupportedFeature(requestId, |
| + e.message)); |
| } |
| } |
| /** |
| - * Implementation for `analysis.updateContent`. |
| - */ |
| - void updateContent(Map<String, ContentChange> changes) { |
| - changes.forEach((file, change) { |
| - AnalysisContext analysisContext = _getAnalysisContext(file); |
| - // TODO(paulberry): handle the case where a file is referred to by more |
| - // than one context (e.g package A depends on package B using a local |
| - // path, user has both packages open for editing in separate contexts, |
| - // and user modifies a file in package B). |
| - if (analysisContext != null) { |
| - Source source = _getSource(file); |
| - if (change.offset == null) { |
| - analysisContext.setContents(source, change.content); |
| - } else { |
| - analysisContext.setChangedContents(source, change.content, |
| - change.offset, change.oldLength, change.newLength); |
| - } |
| - schedulePerformAnalysisOperation(analysisContext); |
| - } |
| - }); |
| - } |
| - |
| - /** |
| * Implementation for `analysis.setSubscriptions`. |
| */ |
| - void setAnalysisSubscriptions(Map<AnalysisService, Set<String>> subscriptions) { |
| + void setAnalysisSubscriptions(Map<AnalysisService, |
| + Set<String>> subscriptions) { |
| // send notifications for already analyzed sources |
| subscriptions.forEach((service, Set<String> newFiles) { |
| Set<String> oldFiles = analysisServices[service]; |
| - Set<String> todoFiles = oldFiles != null ? newFiles.difference(oldFiles) : newFiles; |
| + Set<String> todoFiles = oldFiles != null ? newFiles.difference(oldFiles) : |
| + newFiles; |
| for (String file in todoFiles) { |
| - Source source = _getSource(file); |
| - AnalysisContext context = _getAnalysisContext(file); |
| + Source source = getSource(file); |
| + AnalysisContext context = getAnalysisContext(file); |
| // errors |
| if (service == AnalysisService.ERRORS) { |
| LineInfo lineInfo = context.getLineInfo(source); |
| @@ -471,7 +361,8 @@ class AnalysisServer { |
| } |
| // Dart unit notifications. |
| if (AnalysisEngine.isDartFileName(file)) { |
| - CompilationUnit dartUnit = getResolvedCompilationUnitToResendNotification(file); |
| + CompilationUnit dartUnit = |
| + getResolvedCompilationUnitToResendNotification(file); |
| if (dartUnit != null) { |
| switch (service) { |
| case AnalysisService.HIGHLIGHTS: |
| @@ -482,7 +373,8 @@ class AnalysisServer { |
| sendAnalysisNotificationNavigation(this, file, dartUnit); |
| break; |
| case AnalysisService.OUTLINE: |
| - sendAnalysisNotificationOutline(this, context, source, dartUnit); |
| + sendAnalysisNotificationOutline(this, context, source, |
| + dartUnit); |
| break; |
| } |
| } |
| @@ -494,51 +386,45 @@ class AnalysisServer { |
| } |
| /** |
| - * Return the [AnalysisContext] that is used to analyze the given [path]. |
| - * Return `null` if there is no such context. |
| + * Set the priority files to the given [files]. |
| */ |
| - AnalysisContext _getAnalysisContext(String path) { |
| - for (Folder folder in folderMap.keys) { |
| - if (path.startsWith(folder.path)) { |
| - return folderMap[folder]; |
| + void setPriorityFiles(Request request, List<String> files) { |
| + Map<AnalysisContext, List<Source>> sourceMap = new HashMap<AnalysisContext, |
| + List<Source>>(); |
| + List<String> unanalyzed = new List<String>(); |
| + files.forEach((file) { |
| + AnalysisContext analysisContext = getAnalysisContext(file); |
| + if (analysisContext == null) { |
| + unanalyzed.add(file); |
| + } else { |
| + List<Source> sourceList = sourceMap[analysisContext]; |
| + if (sourceList == null) { |
| + sourceList = <Source>[]; |
| + sourceMap[analysisContext] = sourceList; |
| + } |
| + sourceList.add(getSource(file)); |
| } |
| + }); |
| + if (unanalyzed.isNotEmpty) { |
| + StringBuffer buffer = new StringBuffer(); |
| + buffer.writeAll(unanalyzed, ', '); |
| + throw new RequestFailure(new Response.unanalyzedPriorityFiles(request, |
| + buffer.toString())); |
| } |
| - return null; |
| - } |
| - |
| - /** |
| - * Return the [Source] of the Dart file with the given [path]. |
| - */ |
| - Source _getSource(String path) { |
| - File file = contextDirectoryManager.resourceProvider.getResource(path); |
| - return file.createSource(UriKind.FILE_URI); |
| + folderMap.forEach((Folder folder, AnalysisContext context) { |
| + List<Source> sourceList = sourceMap[context]; |
| + if (sourceList == null) { |
| + sourceList = Source.EMPTY_ARRAY; |
| + } |
| + context.analysisPriorityOrder = sourceList; |
| + }); |
| } |
| /** |
| - * Returns the [CompilationUnit] of the Dart file with the given [path] that |
| - * should be used to resend notifications for already resolved unit. |
| - * Returns `null` if the file is not a part of any context, library has not |
| - * been yet resolved, or any problem happened. |
| + * Return `true` if all operations have been performed in this [AnalysisServer]. |
| */ |
| - CompilationUnit getResolvedCompilationUnitToResendNotification(String path) { |
| - // prepare AnalysisContext |
| - AnalysisContext context = _getAnalysisContext(path); |
| - if (context == null) { |
| - return null; |
| - } |
| - // prepare sources |
| - Source unitSource = _getSource(path); |
| - List<Source> librarySources = context.getLibrariesContaining(unitSource); |
| - if (librarySources.isEmpty) { |
| - return null; |
| - } |
| - // if library has not been resolved yet, the unit will be resolved later |
| - Source librarySource = librarySources[0]; |
| - if (context.getLibraryElement(librarySource) == null) { |
| - return null; |
| - } |
| - // if library has been already resolved, resolve unit |
| - return context.resolveCompilationUnit2(unitSource, librarySource); |
| + bool test_areOperationsFinished() { |
| + return operationQueue.isEmpty; |
| } |
| /** |
| @@ -547,12 +433,12 @@ class AnalysisServer { |
| */ |
| CompilationUnit test_getResolvedCompilationUnit(String path) { |
| // prepare AnalysisContext |
| - AnalysisContext context = _getAnalysisContext(path); |
| + AnalysisContext context = getAnalysisContext(path); |
| if (context == null) { |
| return null; |
| } |
| // prepare sources |
| - Source unitSource = _getSource(path); |
| + Source unitSource = getSource(path); |
| List<Source> librarySources = context.getLibrariesContaining(unitSource); |
| if (librarySources.isEmpty) { |
| return null; |
| @@ -562,10 +448,72 @@ class AnalysisServer { |
| } |
| /** |
| - * Return `true` if all operations have been performed in this [AnalysisServer]. |
| + * Implementation for `analysis.updateContent`. |
| */ |
| - bool test_areOperationsFinished() { |
| - return operationQueue.isEmpty; |
| + void updateContent(Map<String, ContentChange> changes) { |
| + changes.forEach((file, change) { |
| + AnalysisContext analysisContext = getAnalysisContext(file); |
| + // TODO(paulberry): handle the case where a file is referred to by more |
| + // than one context (e.g package A depends on package B using a local |
| + // path, user has both packages open for editing in separate contexts, |
| + // and user modifies a file in package B). |
| + if (analysisContext != null) { |
| + Source source = getSource(file); |
| + if (change.offset == null) { |
| + analysisContext.setContents(source, change.content); |
| + } else { |
| + analysisContext.setChangedContents(source, change.content, |
| + change.offset, change.oldLength, change.newLength); |
| + } |
| + schedulePerformAnalysisOperation(analysisContext); |
| + } |
| + }); |
| + } |
| + |
| + /** |
| + * Use the given updaters to update the values of the options in every |
| + * existing analysis context. |
| + */ |
| + void updateOptions(List<OptionUpdater> optionUpdaters) { |
| + // |
| + // Update existing contexts. |
| + // |
| + folderMap.forEach((Folder folder, AnalysisContext context) { |
| + AnalysisOptionsImpl options = new AnalysisOptionsImpl.con1( |
| + context.analysisOptions); |
| + optionUpdaters.forEach((OptionUpdater optionUpdater) { |
| + optionUpdater(options); |
| + }); |
| + context.analysisOptions = options; |
| + }); |
| + // |
| + // Update the defaults used to create new contexts. |
| + // |
| + AnalysisOptionsImpl options = contextDirectoryManager.defaultOptions; |
| + optionUpdaters.forEach((OptionUpdater optionUpdater) { |
| + optionUpdater(options); |
| + }); |
| + } |
| + |
| + /** |
| + * Return the [AnalysisContext] that is used to analyze the given [path]. |
| + * Return `null` if there is no such context. |
| + */ |
| + AnalysisContext getAnalysisContext(String path) { |
| + for (Folder folder in folderMap.keys) { |
| + if (path.startsWith(folder.path)) { |
| + return folderMap[folder]; |
| + } |
| + } |
| + return null; |
| + } |
| + |
| + /** |
| + * Return the [Source] of the Dart file with the given [path]. |
| + */ |
| + Source getSource(String path) { |
| + File file = contextDirectoryManager.resourceProvider.getResource(path); |
| + return file.createSource(UriKind.FILE_URI); |
| } |
| /** |
| @@ -577,24 +525,77 @@ class AnalysisServer { |
| } |
| +class AnalysisServerContextDirectoryManager extends ContextDirectoryManager { |
| + final AnalysisServer analysisServer; |
| + |
| + /** |
| + * The default options used to create new analysis contexts. |
| + */ |
| + AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl(); |
| + |
| + AnalysisServerContextDirectoryManager(this.analysisServer, |
| + ResourceProvider resourceProvider, PackageMapProvider packageMapProvider) |
| + : super(resourceProvider, packageMapProvider); |
| + |
| + @override |
| + void addContext(Folder folder, Map<String, List<Folder>> packageMap) { |
| + AnalysisContext context = AnalysisEngine.instance.createAnalysisContext(); |
| + analysisServer.folderMap[folder] = context; |
| + context.sourceFactory = _createSourceFactory(packageMap); |
| + context.analysisOptions = new AnalysisOptionsImpl.con1(defaultOptions); |
| + analysisServer.schedulePerformAnalysisOperation(context); |
| + } |
| + |
| + @override |
| + void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { |
| + AnalysisContext context = analysisServer.folderMap[contextFolder]; |
| + context.applyChanges(changeSet); |
| + analysisServer.schedulePerformAnalysisOperation(context); |
| + } |
| + |
| + @override |
| + void removeContext(Folder folder) { |
| + analysisServer.folderMap.remove(folder); |
| + } |
| + |
| + @override |
| + void updateContextPackageMap(Folder contextFolder, Map<String, |
| + List<Folder>> packageMap) { |
| + AnalysisContext context = analysisServer.folderMap[contextFolder]; |
| + context.sourceFactory = _createSourceFactory(packageMap); |
| + analysisServer.schedulePerformAnalysisOperation(context); |
| + } |
| + |
| + /** |
| + * Set up a [SourceFactory] that resolves packages using the given |
| + * [packageMap]. |
| + */ |
| + SourceFactory _createSourceFactory(Map<String, List<Folder>> packageMap) { |
| + List<UriResolver> resolvers = <UriResolver>[new DartUriResolver( |
| + analysisServer.defaultSdk), new ResourceUriResolver(resourceProvider), |
| + new PackageMapUriResolver(resourceProvider, packageMap)]; |
| + return new SourceFactory(resolvers); |
| + } |
| +} |
| + |
| + |
| /** |
| * An enumeration of the services provided by the analysis domain. |
| */ |
| class AnalysisService extends Enum2<AnalysisService> { |
| static const AnalysisService ERRORS = const AnalysisService('ERRORS', 0); |
| - static const AnalysisService HIGHLIGHTS = const AnalysisService('HIGHLIGHTS', 1); |
| - static const AnalysisService NAVIGATION = const AnalysisService('NAVIGATION', 2); |
| + static const AnalysisService HIGHLIGHTS = const AnalysisService('HIGHLIGHTS', |
| + 1); |
| + static const AnalysisService NAVIGATION = const AnalysisService('NAVIGATION', |
| + 2); |
| static const AnalysisService OUTLINE = const AnalysisService('OUTLINE', 3); |
| - static const List<AnalysisService> VALUES = |
| - const [ERRORS, HIGHLIGHTS, NAVIGATION, OUTLINE]; |
| + static const List<AnalysisService> VALUES = const [ERRORS, HIGHLIGHTS, |
| + NAVIGATION, OUTLINE]; |
| const AnalysisService(String name, int ordinal) : super(name, ordinal); |
| } |
| - |
| -typedef void OptionUpdater(AnalysisOptionsImpl options); |
| - |
| /** |
| * An enumeration of the services provided by the server domain. |
| */ |