[analysis_server] Don't use Dart analysis driver to obtain LineInfos for non-Dart files
Change-Id: I80eead30caecf855385b5cc6c2cd7995de8a9349
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/223880
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 10e4cf9..d2bd74d 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -65,8 +65,9 @@
final unit = await path.mapResult(requireResolvedUnit);
final lineInfo = await unit.map(
- // If we don't have a unit, we can still try to obtain the line info for
- // plugin contributors.
+ // If we don't have a unit, we can still try to obtain the line info from
+ // the server (this could be because the file is non-Dart, such as YAML or
+ // another handled by a plugin).
(error) => path.mapResult(getLineInfo),
(unit) => success(unit.lineInfo),
);
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 55a9da8..e4e8d17 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -261,12 +261,23 @@
capabilitiesComputer.performDynamicRegistration();
}
- /// Return the LineInfo for the file with the given [path]. The file is
- /// analyzed in one of the analysis drivers to which the file was added,
- /// otherwise in the first driver, otherwise `null` is returned.
+ /// Return a [LineInfo] for the file with the given [path].
+ ///
+ /// If the file does not exist or cannot be read, returns `null`.
+ ///
+ /// This method supports non-Dart files but uses the current content of the
+ /// file which may not be the latest analyzed version of the file if it was
+ /// recently modified, so using the lineInfo from an analyzed result may be
+ /// preferable.
LineInfo? getLineInfo(String path) {
- var result = getAnalysisDriver(path)?.getFileSync(path);
- return result is FileResult ? result.lineInfo : null;
+ try {
+ final content = resourceProvider.getFile(path).readAsStringSync();
+ return LineInfo.fromContent(content);
+ } on FileSystemException {
+ // If the file does not exist or cannot be read, return null to allow
+ // the caller to decide how to handle this.
+ return null;
+ }
}
/// Gets the version of a document known to the server, returning a
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart
index ffabd19..8a26c20 100644
--- a/pkg/analysis_server/lib/src/lsp/mapping.dart
+++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -23,6 +23,7 @@
import 'package:analyzer/dart/analysis/results.dart' as server;
import 'package:analyzer/error/error.dart' as server;
import 'package:analyzer/source/line_info.dart' as server;
+import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/source/source_range.dart' as server;
import 'package:analyzer/src/dart/analysis/search.dart' as server
show DeclarationKind;
@@ -123,8 +124,11 @@
edits
.map((e) => FileEditInformation(
server.getVersionedDocumentIdentifier(e.file),
- // We should never produce edits for a file with no LineInfo.
- server.getLineInfo(e.file)!,
+ // If we expect to create the file, server.getLineInfo() won't
+ // provide a LineInfo so create one from empty contents.
+ e.fileStamp == -1
+ ? LineInfo.fromContent('')
+ : server.getLineInfo(e.file)!,
e.edits,
// fileStamp == 1 is used by the server to indicate the file needs creating.
newFile: e.fileStamp == -1,