Skip to content

Commit 12d9554

Browse files
DanTupCommit Queue
authored andcommitted
[analysis_server] Don't treat non-existent files the same as empty files when checking if didOpen changes content
This code assumed `driver?.fsState.getExistingFromPath(path)?.content` would be null for files that didn't exist, but actually we can get a `FileState` with `exists=false` and an empty string for `content`. We should not consider this equal to an empty file that was just opened. Fixes Dart-Code/Dart-Code#5269 Fixes #55318 Change-Id: I4334a002ef0fb9ff3a9423568faa6e0735369022 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/392142 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 082bc3d commit 12d9554

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,13 @@ class LspAnalysisServer extends AnalysisServer {
649649
// dependencies (so the optimization works for them) but below we use
650650
// `contextManager.driverFor` so we only add to the specific driver.
651651
var driver = getAnalysisDriver(path);
652+
var state = driver?.fsState.getExistingFromPath(path);
653+
// Content is updated if we have no state, we have state that does not exist
654+
// or the content differs. For a file with state that does not exist, the
655+
// content will be an empty string, so we must check exists to cover files
656+
// that are newly created with empty contents.
652657
var contentIsUpdated =
653-
driver?.fsState.getExistingFromPath(path)?.content != content;
658+
state == null || !state.exists || state.content != content;
654659

655660
if (contentIsUpdated) {
656661
_afterOverlayChanged(path, plugin.AddContentOverlay(content));

pkg/analysis_server/test/lsp/diagnostic_test.dart

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,29 @@ void f() {
192192
expect(diagnostic.message, contains('\nTry'));
193193
}
194194

195+
/// Verify that if a nonexistant file is imported, creating that file causes
196+
/// the uri_does_not_exist error to go away.
197+
///
198+
/// https://github.com/dart-lang/sdk/issues/55318
199+
Future<void> test_createAfterImport() async {
200+
var fooFilePath = join(projectFolderPath, 'lib', 'foo.dart');
201+
202+
await initialize();
203+
await openFile(mainFileUri, "import 'foo.dart';");
204+
await pumpEventQueue(times: 5000);
205+
206+
expect(diagnostics[mainFileUri]!.single.code, 'uri_does_not_exist');
207+
208+
// Create the file.
209+
await openFile(toUri(fooFilePath), '');
210+
211+
// Allow server to catch up.
212+
await pumpEventQueue(times: 5000);
213+
214+
// Expect the diagnostic is now for an unused import instead.
215+
expect(diagnostics[mainFileUri]!.single.code, 'unused_import');
216+
}
217+
195218
Future<void> test_deletedFile() async {
196219
newFile(mainFilePath, 'String a = 1;');
197220

@@ -568,6 +591,40 @@ void f(dynamic a) => a.foo();
568591
}
569592
}
570593

594+
/// Verify that when a file is renamed, if references to the new file are
595+
/// written into the documents before the new file is "created", it does not
596+
/// result in uri_does_not_exist errors that hang around.
597+
///
598+
/// https://github.com/Dart-Code/Dart-Code/issues/5269
599+
Future<void> test_rename_updatedImportsBeforeCreated() async {
600+
var oldFilePath = join(projectFolderPath, 'lib', 'old.dart');
601+
var newFilePath = join(projectFolderPath, 'lib', 'new.dart');
602+
newFile(oldFilePath, '');
603+
newFile(mainFilePath, '');
604+
605+
await initialize();
606+
await pumpEventQueue(times: 5000);
607+
608+
// Create a valid reference to the old file.
609+
await openFile(mainFileUri, "import 'old.dart';");
610+
await openFile(toUri(oldFilePath), '');
611+
await pumpEventQueue(times: 5000);
612+
613+
// Update the reference to the new file, update the overlays, and update
614+
// the disk.
615+
await replaceFile(2, mainFileUri, "import 'new.dart';");
616+
await closeFile(toUri(oldFilePath));
617+
await openFile(toUri(newFilePath), '');
618+
deleteFile(oldFilePath);
619+
newFile(newFilePath, '');
620+
621+
// Allow server to catch up.
622+
await waitForAnalysisComplete();
623+
624+
// Expect unused_import, not uri_does_not_exist.
625+
expect(diagnostics[mainFileUri]!.single.code, 'unused_import');
626+
}
627+
571628
/// Tests that diagnostic ordering is stable when minor changes are made to
572629
/// the file that does not alter the diagnostics besides extending their
573630
/// range and adding to their messages.

0 commit comments

Comments
 (0)