| 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 f3f98f1b3c0b25620faf6d1034de9687e1f64101..d235f1bf957821945df084cab09d8a69603d82a1 100644
|
| --- a/pkg/analysis_server/lib/src/analysis_server.dart
|
| +++ b/pkg/analysis_server/lib/src/analysis_server.dart
|
| @@ -35,13 +35,11 @@ import 'package:analysis_server/src/server/diagnostic_server.dart';
|
| import 'package:analysis_server/src/services/correction/namespace.dart';
|
| import 'package:analysis_server/src/services/index/index.dart';
|
| import 'package:analysis_server/src/services/search/search_engine.dart';
|
| -import 'package:analysis_server/src/services/search/search_engine_internal.dart';
|
| import 'package:analysis_server/src/services/search/search_engine_internal2.dart';
|
| import 'package:analysis_server/src/single_context_manager.dart';
|
| import 'package:analysis_server/src/utilities/null_string_sink.dart';
|
| import 'package:analyzer/context/context_root.dart';
|
| import 'package:analyzer/dart/ast/ast.dart';
|
| -import 'package:analyzer/dart/ast/standard_resolution_map.dart';
|
| import 'package:analyzer/dart/element/element.dart';
|
| import 'package:analyzer/exception/exception.dart';
|
| import 'package:analyzer/file_system/file_system.dart';
|
| @@ -50,7 +48,6 @@ import 'package:analyzer/instrumentation/instrumentation.dart';
|
| import 'package:analyzer/plugin/resolver_provider.dart';
|
| import 'package:analyzer/source/pub_package_map_provider.dart';
|
| import 'package:analyzer/src/context/builder.dart';
|
| -import 'package:analyzer/src/dart/analysis/ast_provider_context.dart';
|
| import 'package:analyzer/src/dart/analysis/ast_provider_driver.dart';
|
| import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
|
| import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
|
| @@ -62,9 +59,7 @@ import 'package:analyzer/src/generated/sdk.dart';
|
| import 'package:analyzer/src/generated/source.dart';
|
| import 'package:analyzer/src/generated/source_io.dart';
|
| import 'package:analyzer/src/generated/utilities_general.dart';
|
| -import 'package:analyzer/src/task/dart.dart';
|
| import 'package:analyzer/src/util/glob.dart';
|
| -import 'package:analyzer/task/dart.dart';
|
| import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
|
| import 'package:front_end/src/base/performace_logger.dart';
|
| import 'package:front_end/src/incremental/byte_store.dart';
|
| @@ -281,11 +276,6 @@ class AnalysisServer {
|
| StreamController<ChangeNotice> _onFileAnalyzedController;
|
|
|
| /**
|
| - * The controller used to notify others when priority sources change.
|
| - */
|
| - StreamController<PriorityChangeEvent> _onPriorityChangeController;
|
| -
|
| - /**
|
| * True if any exceptions thrown by analysis should be propagated up the call
|
| * stack.
|
| */
|
| @@ -469,8 +459,7 @@ class AnalysisServer {
|
| packageMapProvider,
|
| analyzedFilesGlobs,
|
| instrumentationService,
|
| - defaultContextOptions,
|
| - options.enableNewAnalysisDriver);
|
| + defaultContextOptions);
|
| }
|
| this.fileResolverProvider = fileResolverProvider;
|
| this.packageResolverProvider = packageResolverProvider;
|
| @@ -484,8 +473,6 @@ class AnalysisServer {
|
| _onFileAddedController = new StreamController.broadcast();
|
| // temporary plugin support:
|
| _onFileChangedController = new StreamController.broadcast();
|
| - _onPriorityChangeController =
|
| - new StreamController<PriorityChangeEvent>.broadcast();
|
| running = true;
|
| onAnalysisStarted.first.then((_) {
|
| onAnalysisComplete.then((_) {
|
| @@ -494,11 +481,7 @@ class AnalysisServer {
|
| });
|
| });
|
| _setupIndexInvalidation();
|
| - if (options.enableNewAnalysisDriver) {
|
| - searchEngine = new SearchEngineImpl2(driverMap.values);
|
| - } else if (index != null) {
|
| - searchEngine = new SearchEngineImpl(index, getAstProvider);
|
| - }
|
| + searchEngine = new SearchEngineImpl2(driverMap.values);
|
| Notification notification = new ServerConnectedParams(VERSION, io.pid,
|
| sessionId: instrumentationService.sessionId)
|
| .toNotification();
|
| @@ -592,12 +575,6 @@ class AnalysisServer {
|
| Stream get onFileChanged => _onFileChangedController.stream;
|
|
|
| /**
|
| - * The stream that is notified when priority sources change.
|
| - */
|
| - Stream<PriorityChangeEvent> get onPriorityChange =>
|
| - _onPriorityChangeController.stream;
|
| -
|
| - /**
|
| * The [Future] that completes when the next operation is performed.
|
| */
|
| Future get test_onOperationPerformed {
|
| @@ -665,31 +642,6 @@ class AnalysisServer {
|
| }
|
|
|
| /**
|
| - * Return the preferred [AnalysisContext] for analyzing the given [path].
|
| - * This will be the context that explicitly contains the path, if any such
|
| - * context exists, otherwise it will be the first analysis context that
|
| - * implicitly analyzes it. Return `null` if no context is analyzing the
|
| - * path.
|
| - */
|
| - AnalysisContext getAnalysisContext(String path) {
|
| - return getContextSourcePair(path).context;
|
| - }
|
| -
|
| - /**
|
| - * Return any [AnalysisContext] that is analyzing the given [source], either
|
| - * explicitly or implicitly. Return `null` if there is no such context.
|
| - */
|
| - AnalysisContext getAnalysisContextForSource(Source source) {
|
| - for (AnalysisContext context in analysisContexts) {
|
| - SourceKind kind = context.getKindOf(source);
|
| - if (kind != SourceKind.UNKNOWN) {
|
| - return context;
|
| - }
|
| - }
|
| - return null;
|
| - }
|
| -
|
| - /**
|
| * Return an analysis driver to which the file with the given [path] is
|
| * added if one exists, otherwise a driver in which the file was analyzed if
|
| * one exists, otherwise the first driver, otherwise `null`.
|
| @@ -737,33 +689,8 @@ class AnalysisServer {
|
| * Return the [AstProvider] for the given [path].
|
| */
|
| AstProvider getAstProvider(String path) {
|
| - if (options.enableNewAnalysisDriver) {
|
| - var analysisDriver = getAnalysisDriver(path);
|
| - return new AstProviderForDriver(analysisDriver);
|
| - } else {
|
| - var analysisContext = getAnalysisContext(path);
|
| - return new AstProviderForContext(analysisContext);
|
| - }
|
| - }
|
| -
|
| - CompilationUnitElement getCompilationUnitElement(String file) {
|
| - ContextSourcePair pair = getContextSourcePair(file);
|
| - if (pair == null) {
|
| - return null;
|
| - }
|
| - // prepare AnalysisContext and Source
|
| - AnalysisContext context = pair.context;
|
| - Source unitSource = pair.source;
|
| - if (context == null || unitSource == null) {
|
| - return null;
|
| - }
|
| - // get element in the first library
|
| - List<Source> librarySources = context.getLibrariesContaining(unitSource);
|
| - if (!librarySources.isNotEmpty) {
|
| - return null;
|
| - }
|
| - Source librarySource = librarySources.first;
|
| - return context.getCompilationUnitElement(unitSource, librarySource);
|
| + nd.AnalysisDriver analysisDriver = getAnalysisDriver(path);
|
| + return new AstProviderForDriver(analysisDriver);
|
| }
|
|
|
| /**
|
| @@ -793,68 +720,6 @@ class AnalysisServer {
|
| }
|
|
|
| /**
|
| - * Return the primary [ContextSourcePair] representing the given [path].
|
| - *
|
| - * The [AnalysisContext] of this pair will be the context that explicitly
|
| - * contains the path, if any such context exists, otherwise it will be the
|
| - * first context that implicitly analyzes it.
|
| - *
|
| - * If the [path] is not analyzed by any context, a [ContextSourcePair] with
|
| - * a `null` context and a `file` [Source] is returned.
|
| - *
|
| - * If the [path] doesn't represent a file, a [ContextSourcePair] with a `null`
|
| - * context and `null` [Source] is returned.
|
| - *
|
| - * Does not return `null`.
|
| - */
|
| - ContextSourcePair getContextSourcePair(String path) {
|
| - // try SDK
|
| - {
|
| - DartSdk sdk = findSdk();
|
| - if (sdk != null) {
|
| - Uri uri = resourceProvider.pathContext.toUri(path);
|
| - Source sdkSource = sdk.fromFileUri(uri);
|
| - if (sdkSource != null) {
|
| - return new ContextSourcePair(sdk.context, sdkSource);
|
| - }
|
| - }
|
| - }
|
| - // try to find the deep-most containing context
|
| - Resource resource = resourceProvider.getResource(path);
|
| - if (resource is! File) {
|
| - return new ContextSourcePair(null, null);
|
| - }
|
| - File file = resource;
|
| - {
|
| - AnalysisContext containingContext = getContainingContext(path);
|
| - if (containingContext != null) {
|
| - Source source =
|
| - ContextManagerImpl.createSourceInContext(containingContext, file);
|
| - return new ContextSourcePair(containingContext, source);
|
| - }
|
| - }
|
| - // try to find a context that analysed the file
|
| - for (AnalysisContext context in analysisContexts) {
|
| - Source source = ContextManagerImpl.createSourceInContext(context, file);
|
| - SourceKind kind = context.getKindOf(source);
|
| - if (kind != SourceKind.UNKNOWN) {
|
| - return new ContextSourcePair(context, source);
|
| - }
|
| - }
|
| - // try to find a context for which the file is a priority source
|
| - for (InternalAnalysisContext context in analysisContexts) {
|
| - List<Source> sources = context.getSourcesWithFullName(path);
|
| - if (sources.isNotEmpty) {
|
| - Source source = sources.first;
|
| - return new ContextSourcePair(context, source);
|
| - }
|
| - }
|
| - // file-based source
|
| - Source fileSource = file.createSource();
|
| - return new ContextSourcePair(null, fileSource);
|
| - }
|
| -
|
| - /**
|
| * Return a [Future] that completes with the [Element] at the given
|
| * [offset] of the given [file], or with `null` if there is no node at the
|
| * [offset] or the node does not have an element.
|
| @@ -889,44 +754,13 @@ class AnalysisServer {
|
| }
|
|
|
| /**
|
| - * Return an analysis error info containing the array of all of the errors and
|
| - * the line info associated with [file].
|
| - *
|
| - * Returns `null` if [file] does not belong to any [AnalysisContext], or the
|
| - * file does not exist.
|
| - *
|
| - * The array of errors will be empty if there are no errors in [file]. The
|
| - * errors contained in the array can be incomplete.
|
| - *
|
| - * This method does not wait for all errors to be computed, and returns just
|
| - * the current state.
|
| - */
|
| - AnalysisErrorInfo getErrors(String file) {
|
| - ContextSourcePair contextSource = getContextSourcePair(file);
|
| - AnalysisContext context = contextSource.context;
|
| - Source source = contextSource.source;
|
| - if (context == null) {
|
| - return null;
|
| - }
|
| - if (!context.exists(source)) {
|
| - return null;
|
| - }
|
| - return context.getErrors(source);
|
| - }
|
| -
|
| - /**
|
| * Return a [Future] that completes with the resolved [AstNode] at the
|
| * given [offset] of the given [file], or with `null` if there is no node as
|
| * the [offset].
|
| */
|
| Future<AstNode> getNodeAtOffset(String file, int offset) async {
|
| - CompilationUnit unit;
|
| - if (options.enableNewAnalysisDriver) {
|
| - nd.AnalysisResult result = await getAnalysisResult(file);
|
| - unit = result?.unit;
|
| - } else {
|
| - unit = await getResolvedCompilationUnit(file);
|
| - }
|
| + nd.AnalysisResult result = await getAnalysisResult(file);
|
| + CompilationUnit unit = result?.unit;
|
| if (unit != null) {
|
| return new NodeLocator(offset).searchWithin(unit);
|
| }
|
| @@ -939,23 +773,8 @@ class AnalysisServer {
|
| * Dart file or cannot be resolved.
|
| */
|
| Future<CompilationUnit> getResolvedCompilationUnit(String path) async {
|
| - if (options.enableNewAnalysisDriver) {
|
| - nd.AnalysisResult result = await getAnalysisResult(path);
|
| - return result?.unit;
|
| - }
|
| - ContextSourcePair contextSource = getContextSourcePair(path);
|
| - AnalysisContext context = contextSource.context;
|
| - if (context == null) {
|
| - return null;
|
| - }
|
| - return runWithActiveContext(context, () {
|
| - Source unitSource = contextSource.source;
|
| - List<Source> librarySources = context.getLibrariesContaining(unitSource);
|
| - for (Source librarySource in librarySources) {
|
| - return context.resolveCompilationUnit2(unitSource, librarySource);
|
| - }
|
| - return null;
|
| - });
|
| + nd.AnalysisResult result = await getAnalysisResult(path);
|
| + return result?.unit;
|
| }
|
|
|
| // TODO(brianwilkerson) Add the following method after 'prioritySources' has
|
| @@ -1044,43 +863,6 @@ class AnalysisServer {
|
| }
|
|
|
| /**
|
| - * Returns a [Future] completing when [file] has been completely analyzed, in
|
| - * particular, all its errors have been computed. The future is completed
|
| - * with an [AnalysisDoneReason] indicating what caused the file's analysis to
|
| - * be considered complete.
|
| - *
|
| - * If the given file doesn't belong to any context, null is returned.
|
| - *
|
| - * TODO(scheglov) this method should be improved.
|
| - *
|
| - * 1. The analysis context should be told to analyze this particular file ASAP.
|
| - *
|
| - * 2. We should complete the future as soon as the file is analyzed (not wait
|
| - * until the context is completely finished)
|
| - */
|
| - Future<AnalysisDoneReason> onFileAnalysisComplete(String file) {
|
| - // prepare AnalysisContext
|
| - AnalysisContext context = getAnalysisContext(file);
|
| - if (context == null) {
|
| - return null;
|
| - }
|
| - // done if everything is already analyzed
|
| - if (isAnalysisComplete()) {
|
| - return new Future.value(AnalysisDoneReason.COMPLETE);
|
| - }
|
| - // schedule context analysis
|
| - schedulePerformAnalysisOperation(context);
|
| - // associate with the context completer
|
| - Completer<AnalysisDoneReason> completer =
|
| - contextAnalysisDoneCompleters[context];
|
| - if (completer == null) {
|
| - completer = new Completer<AnalysisDoneReason>();
|
| - contextAnalysisDoneCompleters[context] = completer;
|
| - }
|
| - return completer.future;
|
| - }
|
| -
|
| - /**
|
| * Perform the next available [ServerOperation].
|
| */
|
| void performOperation() {
|
| @@ -1341,85 +1123,16 @@ class AnalysisServer {
|
| if (notificationManager != null) {
|
| notificationManager.setSubscriptions(subscriptions);
|
| }
|
| - if (options.enableNewAnalysisDriver) {
|
| - this.analysisServices = subscriptions;
|
| - Set<String> allNewFiles =
|
| - subscriptions.values.expand((files) => files).toSet();
|
| - for (String file in allNewFiles) {
|
| - // The result will be produced by the "results" stream with
|
| - // the fully resolved unit, and processed with sending analysis
|
| - // notifications as it happens after content changes.
|
| - if (AnalysisEngine.isDartFileName(file)) {
|
| - getAnalysisResult(file);
|
| - }
|
| - }
|
| - return;
|
| - }
|
| - // 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;
|
| - for (String file in todoFiles) {
|
| - if (contextManager.isIgnored(file)) {
|
| - continue;
|
| - }
|
| - // prepare context
|
| - ContextSourcePair contextSource = getContextSourcePair(file);
|
| - AnalysisContext context = contextSource.context;
|
| - if (context == null) {
|
| - continue;
|
| - }
|
| - Source source = contextSource.source;
|
| - // Ensure that if the AST is flushed / not ready, it will be
|
| - // computed eventually.
|
| - if (AnalysisEngine.isDartFileName(file)) {
|
| - (context as InternalAnalysisContext).ensureResolvedDartUnits(source);
|
| - }
|
| - // Send notifications that don't directly take an AST.
|
| - switch (service) {
|
| - case AnalysisService.NAVIGATION:
|
| - sendAnalysisNotificationNavigation(this, context, source);
|
| - continue;
|
| - case AnalysisService.OCCURRENCES:
|
| - sendAnalysisNotificationOccurrences(this, context, source);
|
| - continue;
|
| - }
|
| - // Dart unit notifications.
|
| - if (AnalysisEngine.isDartFileName(file)) {
|
| - // TODO(scheglov) This way to get resolved information is very Dart
|
| - // specific. OTOH as it is planned now Angular results are not
|
| - // flushable.
|
| - CompilationUnit dartUnit =
|
| - _getResolvedCompilationUnitToResendNotification(context, source);
|
| - if (dartUnit != null) {
|
| - switch (service) {
|
| - case AnalysisService.HIGHLIGHTS:
|
| - sendAnalysisNotificationHighlights(this, file, dartUnit);
|
| - break;
|
| - case AnalysisService.OUTLINE:
|
| - AnalysisContext context = resolutionMap
|
| - .elementDeclaredByCompilationUnit(dartUnit)
|
| - .context;
|
| - LineInfo lineInfo = context.getLineInfo(source);
|
| - SourceKind kind = context.getKindOf(source);
|
| - sendAnalysisNotificationOutline(
|
| - this, file, lineInfo, kind, dartUnit);
|
| - break;
|
| - case AnalysisService.OVERRIDES:
|
| - sendAnalysisNotificationOverrides(this, file, dartUnit);
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - });
|
| - // remember new subscriptions
|
| this.analysisServices = subscriptions;
|
| - // special case for implemented elements
|
| - if (analysisServices.containsKey(AnalysisService.IMPLEMENTED) &&
|
| - isAnalysisComplete()) {
|
| - _scheduleAnalysisImplementedNotification();
|
| + Set<String> allNewFiles =
|
| + subscriptions.values.expand((files) => files).toSet();
|
| + for (String file in allNewFiles) {
|
| + // The result will be produced by the "results" stream with
|
| + // the fully resolved unit, and processed with sending analysis
|
| + // notifications as it happens after content changes.
|
| + if (AnalysisEngine.isDartFileName(file)) {
|
| + getAnalysisResult(file);
|
| + }
|
| }
|
| }
|
|
|
| @@ -1446,83 +1159,12 @@ class AnalysisServer {
|
| * Set the priority files to the given [files].
|
| */
|
| void setPriorityFiles(String requestId, List<String> files) {
|
| - if (options.enableNewAnalysisDriver) {
|
| - priorityFiles.clear();
|
| - priorityFiles.addAll(files);
|
| - // Set priority files in drivers.
|
| - driverMap.values.forEach((driver) {
|
| - driver.priorityFiles = files;
|
| - });
|
| - return;
|
| - }
|
| - // Note: when a file is a priority file, that information needs to be
|
| - // propagated to all contexts that analyze the file, so that all contexts
|
| - // will be able to do incremental resolution of the file. See
|
| - // dartbug.com/22209.
|
| - Map<AnalysisContext, List<Source>> sourceMap =
|
| - new HashMap<AnalysisContext, List<Source>>();
|
| - List<String> unanalyzed = new List<String>();
|
| - Source firstSource = null;
|
| - files.forEach((String file) {
|
| - if (contextManager.isIgnored(file)) {
|
| - unanalyzed.add(file);
|
| - return;
|
| - }
|
| - // Prepare the context/source pair.
|
| - ContextSourcePair contextSource = getContextSourcePair(file);
|
| - AnalysisContext preferredContext = contextSource.context;
|
| - Source source = contextSource.source;
|
| - // Try to make the file analyzable.
|
| - // If it is not in any context yet, add it to the first one which
|
| - // could use it, e.g. imports its package, even if not the library.
|
| - if (preferredContext == null) {
|
| - Resource resource = resourceProvider.getResource(file);
|
| - if (resource is File && resource.exists) {
|
| - for (AnalysisContext context in analysisContexts) {
|
| - Uri uri = context.sourceFactory.restoreUri(source);
|
| - if (uri.scheme != 'file') {
|
| - preferredContext = context;
|
| - source =
|
| - ContextManagerImpl.createSourceInContext(context, resource);
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - }
|
| - // Fill the source map.
|
| - bool contextFound = false;
|
| - if (preferredContext != null) {
|
| - sourceMap.putIfAbsent(preferredContext, () => <Source>[]).add(source);
|
| - contextFound = true;
|
| - }
|
| - for (AnalysisContext context in analysisContexts) {
|
| - if (context != preferredContext &&
|
| - context.getKindOf(source) != SourceKind.UNKNOWN) {
|
| - sourceMap.putIfAbsent(context, () => <Source>[]).add(source);
|
| - contextFound = true;
|
| - }
|
| - }
|
| - if (firstSource == null) {
|
| - firstSource = source;
|
| - }
|
| - if (!contextFound) {
|
| - unanalyzed.add(file);
|
| - }
|
| - });
|
| - if (unanalyzed.isNotEmpty) {
|
| - StringBuffer buffer = new StringBuffer();
|
| - buffer.writeAll(unanalyzed, ', ');
|
| - throw new RequestFailure(
|
| - new Response.unanalyzedPriorityFiles(requestId, buffer.toString()));
|
| - }
|
| - sourceMap.forEach((context, List<Source> sourceList) {
|
| - context.analysisPriorityOrder = sourceList;
|
| - // Schedule the context for analysis so that it has the opportunity to
|
| - // cache the AST's for the priority sources as soon as possible.
|
| - schedulePerformAnalysisOperation(context);
|
| + priorityFiles.clear();
|
| + priorityFiles.addAll(files);
|
| + // Set priority files in drivers.
|
| + driverMap.values.forEach((driver) {
|
| + driver.priorityFiles = files;
|
| });
|
| - operationQueue.reschedule();
|
| - _onPriorityChangeController.add(new PriorityChangeEvent(firstSource));
|
| }
|
|
|
| /**
|
| @@ -1546,15 +1188,6 @@ class AnalysisServer {
|
| });
|
| }
|
|
|
| - void test_flushAstStructures(String file) {
|
| - if (AnalysisEngine.isDartFileName(file)) {
|
| - ContextSourcePair contextSource = getContextSourcePair(file);
|
| - InternalAnalysisContext context = contextSource.context;
|
| - Source source = contextSource.source;
|
| - context.test_flushAstStructures(source);
|
| - }
|
| - }
|
| -
|
| /**
|
| * Performs all scheduled analysis operations.
|
| */
|
| @@ -1574,58 +1207,9 @@ class AnalysisServer {
|
| * Implementation for `analysis.updateContent`.
|
| */
|
| void updateContent(String id, Map<String, dynamic> changes) {
|
| - if (options.enableNewAnalysisDriver) {
|
| - changes.forEach((file, change) {
|
| - // Prepare the new contents.
|
| - String oldContents = fileContentOverlay[file];
|
| - String newContents;
|
| - if (change is AddContentOverlay) {
|
| - newContents = change.content;
|
| - } else if (change is ChangeContentOverlay) {
|
| - if (oldContents == null) {
|
| - // The client may only send a ChangeContentOverlay if there is
|
| - // already an existing overlay for the source.
|
| - throw new RequestFailure(new Response(id,
|
| - error: new RequestError(RequestErrorCode.INVALID_OVERLAY_CHANGE,
|
| - 'Invalid overlay change')));
|
| - }
|
| - try {
|
| - newContents = SourceEdit.applySequence(oldContents, change.edits);
|
| - } on RangeError {
|
| - throw new RequestFailure(new Response(id,
|
| - error: new RequestError(RequestErrorCode.INVALID_OVERLAY_CHANGE,
|
| - 'Invalid overlay change')));
|
| - }
|
| - } else if (change is RemoveContentOverlay) {
|
| - newContents = null;
|
| - } else {
|
| - // Protocol parsing should have ensured that we never get here.
|
| - throw new AnalysisException('Illegal change type');
|
| - }
|
| -
|
| - fileContentOverlay[file] = newContents;
|
| -
|
| - driverMap.values.forEach((driver) {
|
| - driver.changeFile(file);
|
| - });
|
| -
|
| - // temporary plugin support:
|
| - _onFileChangedController.add(file);
|
| -
|
| - // If the file did not exist, and is "overlay only", it still should be
|
| - // analyzed. Add it to driver to which it should have been added.
|
| - contextManager.getDriverFor(file)?.addFile(file);
|
| -
|
| - // TODO(scheglov) implement other cases
|
| - });
|
| - return;
|
| - }
|
| changes.forEach((file, change) {
|
| - ContextSourcePair contextSource = getContextSourcePair(file);
|
| - Source source = contextSource.source;
|
| - operationQueue.sourceAboutToChange(source);
|
| // Prepare the new contents.
|
| - String oldContents = overlayState.getContents(source);
|
| + String oldContents = fileContentOverlay[file];
|
| String newContents;
|
| if (change is AddContentOverlay) {
|
| newContents = change.content;
|
| @@ -1651,79 +1235,20 @@ class AnalysisServer {
|
| throw new AnalysisException('Illegal change type');
|
| }
|
|
|
| - AnalysisContext containingContext = getContainingContext(file);
|
| -
|
| - // Check for an implicitly added but missing source.
|
| - // (For example, the target of an import might not exist yet.)
|
| - // We need to do this before setContents, which changes the stamp.
|
| - bool wasMissing = containingContext?.getModificationStamp(source) == -1;
|
| -
|
| - overlayState.setContents(source, newContents);
|
| - // If the source does not exist, then it was an overlay-only one.
|
| - // Remove it from contexts.
|
| - if (newContents == null && !source.exists()) {
|
| - for (InternalAnalysisContext context in analysisContexts) {
|
| - List<Source> sources = context.getSourcesWithFullName(file);
|
| - ChangeSet changeSet = new ChangeSet();
|
| - sources.forEach(changeSet.removedSource);
|
| - context.applyChanges(changeSet);
|
| - schedulePerformAnalysisOperation(context);
|
| - }
|
| - return;
|
| - }
|
| - // Update all contexts.
|
| - bool anyContextUpdated = false;
|
| - for (InternalAnalysisContext context in analysisContexts) {
|
| - List<Source> sources = context.getSourcesWithFullName(file);
|
| - sources.forEach((Source source) {
|
| - anyContextUpdated = true;
|
| - if (context == containingContext && wasMissing) {
|
| - // Promote missing source to an explicitly added Source.
|
| - context.applyChanges(new ChangeSet()..addedSource(source));
|
| - schedulePerformAnalysisOperation(context);
|
| - }
|
| - if (context.handleContentsChanged(
|
| - source, oldContents, newContents, true)) {
|
| - schedulePerformAnalysisOperation(context);
|
| - } else {
|
| - // When the client sends any change for a source, we should resend
|
| - // subscribed notifications, even if there were no changes in the
|
| - // source contents.
|
| - // TODO(scheglov) consider checking if there are subscriptions.
|
| - if (AnalysisEngine.isDartFileName(file)) {
|
| - List<CompilationUnit> dartUnits =
|
| - context.ensureResolvedDartUnits(source);
|
| - if (dartUnits != null) {
|
| - AnalysisErrorInfo errorInfo = context.getErrors(source);
|
| - for (var dartUnit in dartUnits) {
|
| - scheduleNotificationOperations(
|
| - this,
|
| - source,
|
| - file,
|
| - errorInfo.lineInfo,
|
| - context,
|
| - null,
|
| - dartUnit,
|
| - errorInfo.errors);
|
| - scheduleIndexOperation(this, file, dartUnit);
|
| - }
|
| - } else {
|
| - schedulePerformAnalysisOperation(context);
|
| - }
|
| - }
|
| - }
|
| - });
|
| - }
|
| - // The source is not analyzed by any context, add to the containing one.
|
| - if (!anyContextUpdated) {
|
| - AnalysisContext context = contextSource.context;
|
| - if (context != null && source != null) {
|
| - ChangeSet changeSet = new ChangeSet();
|
| - changeSet.addedSource(source);
|
| - context.applyChanges(changeSet);
|
| - schedulePerformAnalysisOperation(context);
|
| - }
|
| - }
|
| + fileContentOverlay[file] = newContents;
|
| +
|
| + driverMap.values.forEach((driver) {
|
| + driver.changeFile(file);
|
| + });
|
| +
|
| + // temporary plugin support:
|
| + _onFileChangedController.add(file);
|
| +
|
| + // If the file did not exist, and is "overlay only", it still should be
|
| + // analyzed. Add it to driver to which it should have been added.
|
| + contextManager.getDriverFor(file)?.addFile(file);
|
| +
|
| + // TODO(scheglov) implement other cases
|
| });
|
| }
|
|
|
| @@ -1732,29 +1257,26 @@ class AnalysisServer {
|
| * existing analysis context.
|
| */
|
| void updateOptions(List<OptionUpdater> optionUpdaters) {
|
| - if (options.enableNewAnalysisDriver) {
|
| - // TODO(scheglov) implement for the new analysis driver
|
| - return;
|
| - }
|
| - //
|
| - // Update existing contexts.
|
| - //
|
| - for (AnalysisContext context in analysisContexts) {
|
| - AnalysisOptionsImpl options =
|
| - new AnalysisOptionsImpl.from(context.analysisOptions);
|
| - optionUpdaters.forEach((OptionUpdater optionUpdater) {
|
| - optionUpdater(options);
|
| - });
|
| - context.analysisOptions = options;
|
| - // TODO(brianwilkerson) As far as I can tell, this doesn't cause analysis
|
| - // to be scheduled for this context.
|
| - }
|
| - //
|
| - // Update the defaults used to create new contexts.
|
| - //
|
| - optionUpdaters.forEach((OptionUpdater optionUpdater) {
|
| - optionUpdater(defaultContextOptions);
|
| - });
|
| + // TODO(scheglov) implement for the new analysis driver
|
| +// //
|
| +// // Update existing contexts.
|
| +// //
|
| +// for (AnalysisContext context in analysisContexts) {
|
| +// AnalysisOptionsImpl options =
|
| +// new AnalysisOptionsImpl.from(context.analysisOptions);
|
| +// optionUpdaters.forEach((OptionUpdater optionUpdater) {
|
| +// optionUpdater(options);
|
| +// });
|
| +// context.analysisOptions = options;
|
| +// // TODO(brianwilkerson) As far as I can tell, this doesn't cause analysis
|
| +// // to be scheduled for this context.
|
| +// }
|
| +// //
|
| +// // Update the defaults used to create new contexts.
|
| +// //
|
| +// optionUpdaters.forEach((OptionUpdater optionUpdater) {
|
| +// optionUpdater(defaultContextOptions);
|
| +// });
|
| }
|
|
|
| void _computingPackageMap(bool computing) {
|
| @@ -1812,29 +1334,6 @@ class AnalysisServer {
|
| return contexts;
|
| }
|
|
|
| - /**
|
| - * Returns the [CompilationUnit] of the Dart file with the given [source] 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(
|
| - AnalysisContext context, Source source) {
|
| - List<Source> librarySources = context.getLibrariesContaining(source);
|
| - if (librarySources.isEmpty) {
|
| - return null;
|
| - }
|
| - // if library has not been resolved yet, the unit will be resolved later
|
| - Source librarySource = librarySources[0];
|
| - if (context.getResult(librarySource, LIBRARY_ELEMENT6) == null) {
|
| - return null;
|
| - }
|
| - // if library has been already resolved, resolve unit
|
| - return runWithActiveContext(context, () {
|
| - return context.resolveCompilationUnit2(source, librarySource);
|
| - });
|
| - }
|
| -
|
| bool _hasAnalysisServiceSubscription(AnalysisService service, String file) {
|
| return analysisServices[service]?.contains(file) ?? false;
|
| }
|
| @@ -1886,29 +1385,32 @@ class AnalysisServer {
|
| return;
|
| }
|
| onContextsChanged.listen((ContextsChangedEvent event) {
|
| - for (AnalysisContext context in event.added) {
|
| - context
|
| - .onResultChanged(RESOLVED_UNIT3)
|
| - .listen((ResultChangedEvent event) {
|
| - if (event.wasComputed) {
|
| - Object value = event.value;
|
| - if (value is CompilationUnit) {
|
| - index.indexDeclarations(value);
|
| - }
|
| - }
|
| - });
|
| - context
|
| - .onResultChanged(RESOLVED_UNIT)
|
| - .listen((ResultChangedEvent event) {
|
| - if (event.wasInvalidated) {
|
| - LibrarySpecificUnit target = event.target;
|
| - index.removeUnit(event.context, target.library, target.unit);
|
| - }
|
| - });
|
| - }
|
| - for (AnalysisContext context in event.removed) {
|
| - index.removeContext(context);
|
| - }
|
| + // TODO(brianwilkerson) `onContextsChanged` should never have anything
|
| + // written to it. Figure out whether we need something like this under the
|
| + // new analysis driver, and remove this method if not.
|
| +// for (AnalysisContext context in event.added) {
|
| +// context
|
| +// .onResultChanged(RESOLVED_UNIT3)
|
| +// .listen((ResultChangedEvent event) {
|
| +// if (event.wasComputed) {
|
| +// Object value = event.value;
|
| +// if (value is CompilationUnit) {
|
| +// index.indexDeclarations(value);
|
| +// }
|
| +// }
|
| +// });
|
| +// context
|
| +// .onResultChanged(RESOLVED_UNIT)
|
| +// .listen((ResultChangedEvent event) {
|
| +// if (event.wasInvalidated) {
|
| +// LibrarySpecificUnit target = event.target;
|
| +// index.removeUnit(event.context, target.library, target.unit);
|
| +// }
|
| +// });
|
| +// }
|
| +// for (AnalysisContext context in event.removed) {
|
| +// index.removeContext(context);
|
| +// }
|
| });
|
| }
|
| }
|
| @@ -1916,7 +1418,6 @@ class AnalysisServer {
|
| class AnalysisServerOptions {
|
| bool enableIncrementalResolutionApi = false;
|
| bool enableIncrementalResolutionValidation = false;
|
| - bool enableNewAnalysisDriver = false;
|
| bool useAnalysisHighlight2 = false;
|
| String fileReadMode = 'as-is';
|
| String newAnalysisDriverLog;
|
| @@ -2095,35 +1596,21 @@ class ServerContextManagerCallbacks extends ContextManagerCallbacks {
|
|
|
| @override
|
| void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
|
| - if (analysisServer.options.enableNewAnalysisDriver) {
|
| - nd.AnalysisDriver analysisDriver =
|
| - analysisServer.driverMap[contextFolder];
|
| - if (analysisDriver != null) {
|
| - changeSet.addedSources.forEach((source) {
|
| - analysisDriver.addFile(source.fullName);
|
| - // temporary plugin support:
|
| - analysisServer._onFileAddedController.add(source.fullName);
|
| - });
|
| - changeSet.changedSources.forEach((source) {
|
| - analysisDriver.changeFile(source.fullName);
|
| - // temporary plugin support:
|
| - analysisServer._onFileChangedController.add(source.fullName);
|
| - });
|
| - changeSet.removedSources.forEach((source) {
|
| - analysisDriver.removeFile(source.fullName);
|
| - });
|
| - }
|
| - } else {
|
| - AnalysisContext context = analysisServer.folderMap[contextFolder];
|
| - if (context != null) {
|
| - context.applyChanges(changeSet);
|
| - analysisServer.schedulePerformAnalysisOperation(context);
|
| - List<String> flushedFiles = new List<String>();
|
| - for (Source source in changeSet.removedSources) {
|
| - flushedFiles.add(source.fullName);
|
| - }
|
| - sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
|
| - }
|
| + nd.AnalysisDriver analysisDriver = analysisServer.driverMap[contextFolder];
|
| + if (analysisDriver != null) {
|
| + changeSet.addedSources.forEach((source) {
|
| + analysisDriver.addFile(source.fullName);
|
| + // temporary plugin support:
|
| + analysisServer._onFileAddedController.add(source.fullName);
|
| + });
|
| + changeSet.changedSources.forEach((source) {
|
| + analysisDriver.changeFile(source.fullName);
|
| + // temporary plugin support:
|
| + analysisServer._onFileChangedController.add(source.fullName);
|
| + });
|
| + changeSet.removedSources.forEach((source) {
|
| + analysisDriver.removeFile(source.fullName);
|
| + });
|
| }
|
| }
|
|
|
| @@ -2184,21 +1671,9 @@ class ServerContextManagerCallbacks extends ContextManagerCallbacks {
|
|
|
| @override
|
| void removeContext(Folder folder, List<String> flushedFiles) {
|
| - if (analysisServer.options.enableNewAnalysisDriver) {
|
| - sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
|
| - nd.AnalysisDriver driver = analysisServer.driverMap.remove(folder);
|
| - driver.dispose();
|
| - } else {
|
| - AnalysisContext context = analysisServer.folderMap.remove(folder);
|
| - sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
|
| -
|
| - analysisServer.operationQueue.contextRemoved(context);
|
| - analysisServer._onContextsChangedController
|
| - .add(new ContextsChangedEvent(removed: [context]));
|
| - analysisServer.sendContextAnalysisDoneNotifications(
|
| - context, AnalysisDoneReason.CONTEXT_REMOVED);
|
| - context.dispose();
|
| - }
|
| + sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
|
| + nd.AnalysisDriver driver = analysisServer.driverMap.remove(folder);
|
| + driver.dispose();
|
| }
|
|
|
| @override
|
|
|