Extension type. Create navigation regions for primary constructor and representation field.

Change-Id: I491780daa376941d031bba6dd7da60655ec3e76e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324765
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 48f8d11..3489263 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -836,7 +836,6 @@
   Future<void> test_extensionType() async {
     addTestFile('''
 extension type A(int it) {
-  A.named() : this(0);
   void foo() {
     it; // foo()
   }
@@ -845,24 +844,82 @@
 void f(A a) {
   A.it; // f()
   A(0);
-  A.named();
   a.foo();
   A.bar();
 }
 ''');
     await prepareNavigation();
     assertHasRegion('int it');
-    assertHasRegionTarget('this(0)', 'A(int it');
     assertHasRegionTarget('it; // foo()', 'it) {');
     assertHasRegionTarget('A a)', 'A(int');
     assertHasRegionTarget('it; // f()', 'it) {');
     assertHasRegionTarget('A(0);', 'A(int');
-    assertHasRegionTarget('named();', 'named() :');
     assertHasRegionTarget('foo();', 'foo() {');
     assertHasRegionTarget('A.bar()', 'A(int');
     assertHasRegionTarget('bar();', 'bar() {}');
   }
 
+  Future<void> test_extensionType_primaryConstructor_named() async {
+    addTestFile('''
+extension type A.named(int it) {
+  A.other() : this.named(0);
+}
+
+void f() {
+  A.named(1);
+}
+''');
+    await prepareNavigation();
+    assertHasRegionTarget('A.named(int', 'A.named(int');
+    assertHasRegionTarget('named(int', 'named(int');
+    assertHasRegion('int it');
+    assertHasRegionTarget('it) {', 'it) {');
+    assertHasRegionTarget('this.named(0)', 'named(int');
+    assertHasRegionTarget('named(0)', 'named(int');
+    assertHasRegionTarget('A.named(1)', 'A.named(int');
+    assertHasRegionTarget('named(1)', 'named(int');
+  }
+
+  Future<void> test_extensionType_primaryConstructor_unnamed() async {
+    addTestFile('''
+extension type A(int it) {
+  A.other() : this(0);
+}
+
+void f() {
+  A(1);
+  A.new(2);
+}
+''');
+    await prepareNavigation();
+    assertHasRegionTarget('A(int', 'A(int');
+    assertHasRegion('int it');
+    assertHasRegionTarget('it) {', 'it) {');
+    assertHasRegionTarget('this(0)', 'A(int');
+    assertHasRegionTarget('A(1)', 'A(int');
+    assertHasRegionTarget('new(2)', 'A(int');
+  }
+
+  Future<void> test_extensionType_secondaryConstructor_named() async {
+    addTestFile('''
+extension type A(int it) {
+  A.named() : this(0);
+  A.other() : this.named(1);
+}
+
+void f() {
+  A.named(2);
+}
+''');
+    await prepareNavigation();
+    assertHasRegionTarget('A.named() :', 'A(int');
+    assertHasRegionTarget('named() :', 'named() :');
+    assertHasRegionTarget('this.named(1)', 'named() :');
+    assertHasRegionTarget('named(1)', 'named() :');
+    assertHasRegionTarget('A.named(2)', 'A(int');
+    assertHasRegionTarget('named(2)', 'named() :');
+  }
+
   Future<void> test_functionReference_className_staticMethod() async {
     addTestFile('''
 class A {
diff --git a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
index d5c0cbc..0f2a6b4 100644
--- a/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/navigation/navigation_dart.dart
@@ -432,6 +432,12 @@
   }
 
   @override
+  void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
+    computer._addRegionForToken(node.name, node.declaredElement);
+    super.visitExtensionTypeDeclaration(node);
+  }
+
+  @override
   void visitFieldFormalParameter(FieldFormalParameter node) {
     final element = node.declaredElement;
     if (element is FieldFormalParameterElementImpl) {
@@ -560,6 +566,15 @@
   }
 
   @override
+  void visitRepresentationDeclaration(RepresentationDeclaration node) {
+    if (node.constructorName?.name case final constructorName?) {
+      computer._addRegionForToken(constructorName, node.constructorElement);
+    }
+    computer._addRegionForToken(node.fieldName, node.fieldElement);
+    super.visitRepresentationDeclaration(node);
+  }
+
+  @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     final nameToken = node.name;
     if (nameToken != null) {