Enable declarations tracker for LSP to support dart doc macros
Change-Id: I614be91ecf7a1afc377afeee70e559cff324dc61
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/102368
Commit-Queue: Danny Tuppeny <dantup@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index a48bca9..ca242a8 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -54,7 +54,6 @@
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
@@ -147,12 +146,6 @@
PerformanceLog _analysisPerformanceLogger;
- ByteStore byteStore;
- nd.AnalysisDriverScheduler analysisDriverScheduler;
-
- DeclarationsTracker declarationsTracker;
- DeclarationsTrackerData declarationsTrackerData;
-
/// The controller for [onAnalysisSetChanged].
final StreamController _onAnalysisSetChangedController =
new StreamController.broadcast(sync: true);
@@ -374,13 +367,6 @@
resourceProvider.pathContext.normalize(path) == path;
}
- /// Notify the declarations tracker that the file with the given [path] was
- /// changed - added, updated, or removed. Schedule processing of the file.
- void notifyDeclarationsTracker(String path) {
- declarationsTracker.changeFile(path);
- analysisDriverScheduler.notify(null);
- }
-
/// Read all files, resolve all URIs, and perform required analysis in
/// all current analysis drivers.
void reanalyze() {
@@ -509,7 +495,7 @@
throw new RequestFailure(
new Response.unsupportedFeature(requestId, e.message));
}
- _addContextsToDeclarationsTracker();
+ addContextsToDeclarationsTracker();
}
/// Implementation for `analysis.setSubscriptions`.
@@ -691,13 +677,6 @@
// });
}
- void _addContextsToDeclarationsTracker() {
- for (var driver in driverMap.values) {
- declarationsTracker.addContext(driver.analysisContext);
- driver.resetUriResolution();
- }
- }
-
/// Return the path to the location of the byte store on disk, or `null` if
/// there is no on-disk byte store.
String _getByteStorePath() {
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 3ed2774..c56a762 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -8,6 +8,7 @@
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/context_manager.dart';
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
import 'package:analysis_server/src/server/diagnostic_server.dart';
import 'package:analysis_server/src/services/correction/namespace.dart';
import 'package:analysis_server/src/services/search/element_visitors.dart';
@@ -27,7 +28,9 @@
import 'package:analyzer/src/dart/analysis/status.dart' as nd;
import 'package:analyzer/src/dart/ast/element_locator.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
import 'package:analyzer/src/util/glob.dart';
/// Implementations of [AbstractAnalysisServer] implement a server that listens
@@ -40,6 +43,13 @@
/// context directories.
ContextManager contextManager;
+ ByteStore byteStore;
+
+ nd.AnalysisDriverScheduler analysisDriverScheduler;
+
+ DeclarationsTracker declarationsTracker;
+ DeclarationsTrackerData declarationsTrackerData;
+
/// The DiagnosticServer for this AnalysisServer. If available, it can be used
/// to start an http diagnostics server or return the port for an existing
/// server.
@@ -124,6 +134,13 @@
return new DateTime.now().difference(start);
}
+ void addContextsToDeclarationsTracker() {
+ for (var driver in driverMap.values) {
+ declarationsTracker.addContext(driver.analysisContext);
+ driver.resetUriResolution();
+ }
+ }
+
/// If the state location can be accessed, return the file byte store,
/// otherwise return the memory byte store.
ByteStore createByteStore(ResourceProvider resourceProvider) {
@@ -170,6 +187,13 @@
return null;
}
+ DartdocDirectiveInfo getDartdocDirectiveInfoFor(ResolvedUnitResult result) {
+ return declarationsTracker
+ .getContext(result.session.analysisContext)
+ ?.dartdocDirectiveInfo ??
+ new DartdocDirectiveInfo();
+ }
+
/// 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.
@@ -260,4 +284,11 @@
.getResult(path, sendCachedToStream: sendCachedToStream)
.catchError((_) => null);
}
+
+ /// Notify the declarations tracker that the file with the given [path] was
+ /// changed - added, updated, or removed. Schedule processing of the file.
+ void notifyDeclarationsTracker(String path) {
+ declarationsTracker.changeFile(path);
+ analysisDriverScheduler.notify(null);
+ }
}
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index e967188..78f7301 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -21,7 +21,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart' as engine;
import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
import 'package:analyzer/src/generated/engine.dart' as engine;
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -89,7 +88,7 @@
List<HoverInformation> hovers = <HoverInformation>[];
if (unit != null) {
HoverInformation hoverInformation = new DartUnitHoverComputer(
- _getDartdocDirectiveInfoFor(result), unit, params.offset)
+ server.getDartdocDirectiveInfoFor(result), unit, params.offset)
.compute();
if (hoverInformation != null) {
hovers.add(hoverInformation);
@@ -279,7 +278,7 @@
// Ensure the offset provided is a valid location in the file.
final unit = result.unit;
final computer = new DartUnitSignatureComputer(
- _getDartdocDirectiveInfoFor(result), unit, params.offset);
+ server.getDartdocDirectiveInfoFor(result), unit, params.offset);
if (!computer.offsetIsValid) {
server.sendResponse(new Response.getSignatureInvalidOffset(request));
return;
@@ -509,12 +508,4 @@
server.updateOptions(updaters);
return new AnalysisUpdateOptionsResult().toResponse(request.id);
}
-
- DartdocDirectiveInfo _getDartdocDirectiveInfoFor(ResolvedUnitResult result) {
- // TODO(brianwilkerson) Consider moving this to AnalysisServer.
- return server.declarationsTracker
- .getContext(result.session.analysisContext)
- ?.dartdocDirectiveInfo ??
- new DartdocDirectiveInfo();
- }
}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
index 6e2ee05..bd70948 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_hover.dart
@@ -14,7 +14,6 @@
import 'package:analysis_server/src/lsp/mapping.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
class HoverHandler extends MessageHandler<TextDocumentPositionParams, Hover> {
HoverHandler(LspAnalysisServer server) : super(server);
@@ -88,14 +87,7 @@
ErrorOr<Hover> _getHover(ResolvedUnitResult unit, int offset) {
final hover = new DartUnitHoverComputer(
- // TODO(brianwilkerson) Add declarationsTracker to server in order to
- // enable dartdoc processing.
-// server.declarationsTracker
-// .getContext(unit.session.analysisContext)
-// .dartdocDirectiveInfo,
- new DartdocDirectiveInfo(),
- unit.unit,
- offset)
+ server.getDartdocDirectiveInfoFor(unit), unit.unit, offset)
.compute();
return success(toHover(unit.lineInfo, hover));
}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
index 90ef021..cde88c9 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_signature_help.dart
@@ -10,7 +10,6 @@
import 'package:analysis_server/src/lsp/handlers/handlers.dart';
import 'package:analysis_server/src/lsp/lsp_analysis_server.dart';
import 'package:analysis_server/src/lsp/mapping.dart';
-import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
class SignatureHelpHandler
extends MessageHandler<TextDocumentPositionParams, SignatureHelp> {
@@ -34,12 +33,7 @@
return offset.mapResult((offset) {
final computer = new DartUnitSignatureComputer(
- // TODO(brianwilkerson) Add declarationsTracker to server in order to
- // enable dartdoc processing.
-// server.declarationsTracker
-// .getContext(unit.result.session.analysisContext)
-// .dartdocDirectiveInfo,
- new DartdocDirectiveInfo(),
+ server.getDartdocDirectiveInfoFor(unit.result),
unit.result.unit,
offset);
if (!computer.offsetIsValid) {
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 d543a25..e8f5112 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -16,6 +16,7 @@
import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/domain_completion.dart'
show CompletionDomainHandler;
+import 'package:analysis_server/src/domains/completion/available_suggestions.dart';
import 'package:analysis_server/src/lsp/channel/lsp_channel.dart';
import 'package:analysis_server/src/lsp/constants.dart';
import 'package:analysis_server/src/lsp/handlers/handler_states.dart';
@@ -36,7 +37,6 @@
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
import 'package:analyzer/src/dart/analysis/file_state.dart' as nd;
import 'package:analyzer/src/dart/analysis/performance_logger.dart';
@@ -44,6 +44,7 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/plugin/resolver_provider.dart';
+import 'package:analyzer/src/services/available_declarations.dart';
import 'package:watcher/watcher.dart';
/**
@@ -115,10 +116,6 @@
PerformanceLog _analysisPerformanceLogger;
- ByteStore byteStore;
-
- nd.AnalysisDriverScheduler analysisDriverScheduler;
-
ServerStateMessageHandler messageHandler;
int nextRequestId = 1;
@@ -151,6 +148,8 @@
ResolverProvider packageResolverProvider: null,
}) : super(options, diagnosticServer, baseResourceProvider) {
messageHandler = new UninitializedStateMessageHandler(this);
+ // TODO(dantup): This code is almost identical to AnalysisServer, consider
+ // moving it the base class that already holds many of these fields.
defaultContextOptions.generateImplicitErrors = false;
defaultContextOptions.useFastaParser = options.useFastaParser;
@@ -173,6 +172,11 @@
analysisDriverScheduler.status.listen(sendStatusNotification);
analysisDriverScheduler.start();
+ declarationsTracker = DeclarationsTracker(byteStore, resourceProvider);
+ declarationsTrackerData = DeclarationsTrackerData(declarationsTracker);
+ analysisDriverScheduler.outOfBandWorker =
+ CompletionLibrariesWorker(declarationsTracker);
+
contextManager = new ContextManagerImpl(
resourceProvider,
sdkManager,
@@ -443,8 +447,10 @@
}
void setAnalysisRoots(List<String> includedPaths) {
+ declarationsTracker.discardContexts();
final uniquePaths = HashSet<String>.of(includedPaths ?? const []);
contextManager.setRoots(uniquePaths.toList(), [], {});
+ addContextsToDeclarationsTracker();
}
/**
@@ -488,7 +494,7 @@
..addAll(addedPaths ?? const [])
..removeAll(removedPaths ?? const []);
- contextManager.setRoots(newPaths.toList(), [], {});
+ setAnalysisRoots(newPaths.toList());
}
void updateOverlay(String path, String contents) {
@@ -499,6 +505,8 @@
resourceProvider.removeOverlay(path);
}
driverMap.values.forEach((driver) => driver.changeFile(path));
+
+ notifyDeclarationsTracker(path);
}
_updateDriversPriorityFiles() {
@@ -589,7 +597,8 @@
@override
void broadcastWatchEvent(WatchEvent event) {
- // TODO: implement broadcastWatchEvent
+ analysisServer.notifyDeclarationsTracker(event.path);
+ // TODO: implement plugin broadcastWatchEvent
}
@override
diff --git a/pkg/analysis_server/test/lsp/hover_test.dart b/pkg/analysis_server/test/lsp/hover_test.dart
index fa3e520..6b9be51 100644
--- a/pkg/analysis_server/test/lsp/hover_test.dart
+++ b/pkg/analysis_server/test/lsp/hover_test.dart
@@ -18,6 +18,27 @@
@reflectiveTest
class HoverTest extends AbstractLspAnalysisServerTest {
+ test_dartDoc_macros() async {
+ final content = '''
+ /// {@template template_name}
+ /// This is shared content.
+ /// {@endtemplate}
+ const String foo = null;
+
+ /// {@macro template_name}
+ const String [[f^oo2]] = null;
+ ''';
+
+ final initialAnalysis = waitForAnalysisComplete();
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await initialAnalysis;
+ var hover = await getHover(mainFileUri, positionFromMarker(content));
+ expect(hover, isNotNull);
+ expect(hover.range, equals(rangeFromMarkers(content)));
+ expect(_getStringContents(hover), endsWith('This is shared content.'));
+ }
+
test_hover_bad_position() async {
await initialize();
await openFile(mainFileUri, '');
diff --git a/pkg/analysis_server/test/lsp/signature_help_test.dart b/pkg/analysis_server/test/lsp/signature_help_test.dart
index 4471683..b791ddd 100644
--- a/pkg/analysis_server/test/lsp/signature_help_test.dart
+++ b/pkg/analysis_server/test/lsp/signature_help_test.dart
@@ -262,6 +262,37 @@
);
}
+ test_dartDocMacro() async {
+ final content = '''
+ /// {@template template_name}
+ /// This is shared content.
+ /// {@endtemplate}
+ const String bar = null;
+
+ /// {@macro template_name}
+ foo(String s, int i) {
+ foo(^);
+ }
+ ''';
+ final expectedLabel = 'foo(String s, int i)';
+ final expectedDoc = 'This is shared content.';
+
+ final initialAnalysis = waitForAnalysisComplete();
+ await initialize();
+ await openFile(mainFileUri, withoutMarkers(content));
+ await initialAnalysis;
+ await testSignature(
+ content,
+ expectedLabel,
+ expectedDoc,
+ [
+ new ParameterInformation('String s', null),
+ new ParameterInformation('int i', null),
+ ],
+ expectedFormat: null,
+ );
+ }
+
test_unopenFile() async {
final content = '''
/// Does foo.