From cfdcfe2bfee9fb6080cddb895889331ec2a754b0 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Tue, 21 May 2019 18:43:36 +0000 Subject: [PATCH] Update DeclarationsTracker when a context options change. E.g. when .packages changes, we want to re-scan the context for new available libraries. We also don't want to discard all context, and resend everything. R=brianwilkerson@google.com Bug: https://github.com/Dart-Code/Dart-Code/issues/1723 Change-Id: I19ee71c1d021fb9bcda9d02d86b7cbb078704aa7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103320 Reviewed-by: Brian Wilkerson Commit-Queue: Konstantin Shcheglov --- .../lib/src/analysis_server.dart | 5 ++ .../lib/src/analysis_server_abstract.dart | 5 ++ .../lib/src/context_manager.dart | 6 ++ .../lib/src/lsp/lsp_analysis_server.dart | 55 ++++++++++--------- .../test/context_manager_test.dart | 3 + .../src/services/available_declarations.dart | 6 ++ 6 files changed, 55 insertions(+), 25 deletions(-) diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart index d24223c10a2..587adc42a22 100644 --- a/pkg/analysis_server/lib/src/analysis_server.dart +++ b/pkg/analysis_server/lib/src/analysis_server.dart @@ -891,6 +891,11 @@ class ServerContextManagerCallbacks extends ContextManagerCallbacks { analysisServer._onAnalysisSetChangedController.add(null); } + @override + void analysisOptionsUpdated(nd.AnalysisDriver driver) { + analysisServer.updateContextInDeclarationsTracker(driver); + } + @override void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { nd.AnalysisDriver analysisDriver = analysisServer.driverMap[contextFolder]; diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart index f3077180da4..d1aa497d954 100644 --- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart +++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart @@ -291,4 +291,9 @@ abstract class AbstractAnalysisServer { declarationsTracker?.changeFile(path); analysisDriverScheduler.notify(null); } + + void updateContextInDeclarationsTracker(nd.AnalysisDriver driver) { + declarationsTracker?.discardContext(driver.analysisContext); + declarationsTracker?.addContext(driver.analysisContext); + } } diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart index fa1d36f2662..dfb5db45a9d 100644 --- a/pkg/analysis_server/lib/src/context_manager.dart +++ b/pkg/analysis_server/lib/src/context_manager.dart @@ -354,6 +354,11 @@ abstract class ContextManagerCallbacks { */ void afterWatchEvent(WatchEvent event); + /** + * Called when analysis options or URI resolution in the [driver] are changed. + */ + void analysisOptionsUpdated(AnalysisDriver driver); + /** * 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 @@ -1630,6 +1635,7 @@ class ContextManagerImpl implements ContextManager { contextRoot: driver.contextRoot); SourceFactory factory = builder.createSourceFactory(contextRoot, options); driver.configure(analysisOptions: options, sourceFactory: factory); + callbacks.analysisOptionsUpdated(driver); } void _updateContextPackageUriResolver(Folder contextFolder) { diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart index 47bf58ed9d5..7fff986de0c 100644 --- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart +++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart @@ -88,9 +88,6 @@ class LspAnalysisServer extends AbstractAnalysisServer { */ RefactoringWorkspace _refactoringWorkspace; - RefactoringWorkspace get refactoringWorkspace => _refactoringWorkspace ??= - new RefactoringWorkspace(driverMap.values, searchEngine); - /** * The versions of each document known to the server (keyed by path), used to * send back to the client for server-initiated edits so that the client can @@ -199,6 +196,9 @@ class LspAnalysisServer extends AbstractAnalysisServer { Future get exited => channel.closed; + RefactoringWorkspace get refactoringWorkspace => _refactoringWorkspace ??= + new RefactoringWorkspace(driverMap.values, searchEngine); + addPriorityFile(String path) { final didAdd = priorityFiles.add(path); assert(didAdd); @@ -328,6 +328,28 @@ class LspAnalysisServer extends AbstractAnalysisServer { )); } + /// Logs an exception by sending it to the client (window/logMessage) and + /// recording it in a buffer on the server for diagnostics. + void logException(String message, exception, stackTrace) { + if (exception is CaughtException) { + stackTrace ??= exception.stackTrace; + } + + final fullError = stackTrace == null ? message : '$message\n$stackTrace'; + + // Log the full message since showMessage above may be truncated or formatted + // badly (eg. VS Code takes the newlines out). + logErrorToClient(fullError); + + // remember the last few exceptions + exceptions.add(new ServerException( + message, + exception, + stackTrace is StackTrace ? stackTrace : null, + false, + )); + } + void publishDiagnostics(String path, List errors) { final params = new PublishDiagnosticsParams(Uri.file(path).toString(), errors); @@ -416,28 +438,6 @@ class LspAnalysisServer extends AbstractAnalysisServer { logException(message, exception, stackTrace); } - /// Logs an exception by sending it to the client (window/logMessage) and - /// recording it in a buffer on the server for diagnostics. - void logException(String message, exception, stackTrace) { - if (exception is CaughtException) { - stackTrace ??= exception.stackTrace; - } - - final fullError = stackTrace == null ? message : '$message\n$stackTrace'; - - // Log the full message since showMessage above may be truncated or formatted - // badly (eg. VS Code takes the newlines out). - logErrorToClient(fullError); - - // remember the last few exceptions - exceptions.add(new ServerException( - message, - exception, - stackTrace is StackTrace ? stackTrace : null, - false, - )); - } - /// Send status notification to the client. The state of analysis is given by /// the [status] information. void sendStatusNotification(nd.AnalysisStatus status) { @@ -575,6 +575,11 @@ class LspServerContextManagerCallbacks extends ContextManagerCallbacks { // TODO: implement afterWatchEvent } + @override + void analysisOptionsUpdated(nd.AnalysisDriver driver) { + // TODO: implement analysisOptionsUpdated + } + @override void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { nd.AnalysisDriver analysisDriver = analysisServer.driverMap[contextFolder]; diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart index f30a1c34643..228ec3fa7fb 100644 --- a/pkg/analysis_server/test/context_manager_test.dart +++ b/pkg/analysis_server/test/context_manager_test.dart @@ -2518,6 +2518,9 @@ class TestContextManagerCallbacks extends ContextManagerCallbacks { @override void afterWatchEvent(WatchEvent event) {} + @override + void analysisOptionsUpdated(AnalysisDriver driver) {} + @override void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) { AnalysisDriver driver = driverMap[contextFolder.path]; diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart index 1f18466ad28..1d06d577af0 100644 --- a/pkg/analyzer/lib/src/services/available_declarations.dart +++ b/pkg/analyzer/lib/src/services/available_declarations.dart @@ -474,6 +474,12 @@ class DeclarationsTracker { _changedPaths.add(path); } + /// Discard the [analysisContext], but don't discard any libraries that it + /// might have in its dependencies. + void discardContext(AnalysisContext analysisContext) { + _contexts.remove(analysisContext); + } + /// Discard all contexts and libraries, notify the [changes] stream that /// these libraries are removed. void discardContexts() {