Support for navigation in macro with LSP.

Change-Id: I6c1e35f944a7e551882745e74c9570086bc53b56
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210422
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
index a9bc050..d203ef9 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
@@ -6,6 +6,7 @@
 import 'package:analysis_server/lsp_protocol/protocol_special.dart';
 import 'package:analysis_server/protocol/protocol_generated.dart'
     hide AnalysisGetNavigationParams;
+import 'package:analysis_server/src/domains/analysis/macro_files.dart';
 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';
@@ -15,6 +16,7 @@
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
+import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
 import 'package:analyzer_plugin/utilities/navigation/navigation_dart.dart';
 import 'package:collection/collection.dart';
 
@@ -54,8 +56,10 @@
     final result = await server.getResolvedUnit(path);
     final unit = result?.unit;
     if (result?.state == ResultState.VALID && unit != null) {
-      computeDartNavigation(
-          server.resourceProvider, collector, unit, offset, 0);
+      computeDartNavigation(server.resourceProvider, collector, unit, offset, 0,
+          analyzerConverter: AnalyzerConverter(
+              locationProvider: MacroElementLocationProvider(
+                  MacroFiles(server.resourceProvider))));
       collector.createRegions();
     }
 
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart
index f15c592..083158c 100644
--- a/pkg/analysis_server/test/lsp/definition_test.dart
+++ b/pkg/analysis_server/test/lsp/definition_test.dart
@@ -188,6 +188,71 @@
     );
   }
 
+  Future<void> test_macro_simpleIdentifier_getter() async {
+    final macroAnnotationsContents = '''
+library analyzer.macro.annotations;
+const observable = 0;
+''';
+
+    final mainContents = '''
+import 'macro_annotations.dart';
+
+class A {
+  @observable
+  int _foo = 0;
+}
+
+void f(A a) {
+  a.[[foo^]];
+}
+''';
+
+    final combinedContents = r'''
+import 'macro_annotations.dart';
+
+class A {
+  @observable
+  int _foo = 0;
+
+  int get [[foo]] => _foo;
+
+  set foo(int val) {
+    print('Setting foo to ${val}');
+    _foo = val;
+  }
+}
+
+void f(A a) {
+  a.[[foo^]];
+}
+''';
+
+    final macroAnnotationsFileUri =
+        Uri.file(join(projectFolderPath, 'lib', 'macro_annotations.dart'));
+    final pubspecFileUri = Uri.file(join(projectFolderPath, 'pubspec.yaml'));
+    final combinedFileUri = Uri.file(join(projectFolderPath, '.dart_tool',
+        'analyzer', 'macro', 'lib', 'main.dart'));
+
+    await initialize(
+        textDocumentCapabilities:
+            withLocationLinkSupport(emptyTextDocumentClientCapabilities));
+    await openFile(pubspecFileUri, '');
+    await openFile(
+        macroAnnotationsFileUri, withoutMarkers(macroAnnotationsContents));
+    await openFile(mainFileUri, withoutMarkers(mainContents));
+    final res = await getDefinitionAsLocationLinks(
+        mainFileUri, positionFromMarker(mainContents));
+
+    expect(res, hasLength(1));
+    final loc = res.single;
+    expect(loc.originSelectionRange, equals(rangeFromMarkers(mainContents)));
+    expect(loc.targetUri, equals(combinedFileUri.toString()));
+
+    final getFooRange = rangesFromMarkers(combinedContents)[0];
+    expect(loc.targetRange, equals(getFooRange));
+    expect(loc.targetSelectionRange, equals(getFooRange));
+  }
+
   Future<void> test_nonDartFile() async {
     newFile(pubspecFilePath, content: simplePubspecContent);
     await initialize();