Ensure LSP server clears diagnostics for removed files/analysis roots
Change-Id: I5eaa4141da499c5193253440e6913a0eb92ed533
Reviewed-on: https://dart-review.googlesource.com/c/88836
Commit-Queue: Danny Tuppeny <dantup@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
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 d53c2f7..782ecad 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -404,6 +404,17 @@
return contextManager.isInAnalysisRoot(file);
}
+ void publishDiagnostics(String path, List<Diagnostic> errors) {
+ final params =
+ new PublishDiagnosticsParams(Uri.file(path).toString(), errors);
+ final message = new NotificationMessage(
+ Method.textDocument_publishDiagnostics,
+ params,
+ jsonRpcVersion,
+ );
+ sendNotification(message);
+ }
+
void showError(String message) {
channel.sendNotification(new NotificationMessage(
Method.window_showMessage,
@@ -479,14 +490,7 @@
result.errors,
toDiagnostic);
- final params = new PublishDiagnosticsParams(
- Uri.file(result.path).toString(), serverErrors);
- final message = new NotificationMessage(
- Method.textDocument_publishDiagnostics,
- params,
- jsonRpcVersion,
- );
- analysisServer.sendNotification(message);
+ analysisServer.publishDiagnostics(result.path, serverErrors);
}
});
analysisDriver.exceptions.listen((nd.ExceptionResult result) {
@@ -524,7 +528,7 @@
@override
void applyFileRemoved(nd.AnalysisDriver driver, String file) {
driver.removeFile(file);
- // sendAnalysisNotificationFlushResults(analysisServer, [file]);
+ analysisServer.publishDiagnostics(file, []);
}
@override
@@ -567,8 +571,10 @@
@override
void removeContext(Folder folder, List<String> flushedFiles) {
- // sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
nd.AnalysisDriver driver = analysisServer.driverMap.remove(folder);
+ // Flush any errors for these files that the client may be displaying.
+ flushedFiles
+ ?.forEach((path) => analysisServer.publishDiagnostics(path, const []));
driver.dispose();
}
}
diff --git a/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart b/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
index 78c038d..fd0e3c0 100644
--- a/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
+++ b/pkg/analysis_server/test/lsp/change_workspace_folders_test.dart
@@ -72,4 +72,21 @@
unorderedEquals([workspaceFolder1Path]),
);
}
+
+ test_changeWorkspaceFolders_removeFlushesDiagnostics() async {
+ // Add our standard test project as well as a dummy project.
+ await initialize(workspaceFolders: [projectFolderUri, workspaceFolder1Uri]);
+
+ // Generate an error in the test project.
+ final firstDiagnosticsUpdate = waitForDiagnostics(mainFileUri);
+ await openFile(mainFileUri, 'String a = 1;');
+ final initialDiagnostics = await firstDiagnosticsUpdate;
+ expect(initialDiagnostics, hasLength(1));
+
+ // Ensure the error is removed if we removed the workspace folder.
+ final secondDiagnosticsUpdate = waitForDiagnostics(mainFileUri);
+ await changeWorkspaceFolders(remove: [projectFolderUri]);
+ final updatedDiagnostics = await secondDiagnosticsUpdate;
+ expect(updatedDiagnostics, hasLength(0));
+ }
}
diff --git a/pkg/analysis_server/test/lsp/diagnostic_test.dart b/pkg/analysis_server/test/lsp/diagnostic_test.dart
index bbddc00..802d3be 100644
--- a/pkg/analysis_server/test/lsp/diagnostic_test.dart
+++ b/pkg/analysis_server/test/lsp/diagnostic_test.dart
@@ -32,6 +32,21 @@
expect(updatedDiagnostics, hasLength(1));
}
+ test_deletedFile() async {
+ newFile(mainFilePath, content: 'String a = 1;');
+
+ final firstDiagnosticsUpdate = waitForDiagnostics(mainFileUri);
+ await initialize();
+ final originalDiagnostics = await firstDiagnosticsUpdate;
+ expect(originalDiagnostics, hasLength(1));
+
+ // Deleting the file should result in an update to remove the diagnostics.
+ final secondDiagnosticsUpdate = waitForDiagnostics(mainFileUri);
+ await deleteFile(mainFilePath);
+ final updatedDiagnostics = await secondDiagnosticsUpdate;
+ expect(updatedDiagnostics, hasLength(0));
+ }
+
test_initialAnalysis() async {
newFile(mainFilePath, content: 'String a = 1;');