Extension type. Include into 'occurrences' notification.

Change-Id: Ibfe62a4916c9b991e5d407e239d82ad8eb90b5ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/323923
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Phil Quitslund <pquitslund@google.com>
diff --git a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
index 87e141e..7e46e0a 100644
--- a/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
+++ b/pkg/analysis_server/lib/src/domains/analysis/occurrences_dart.dart
@@ -44,6 +44,15 @@
   }
 
   @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    if (node.name case final name?) {
+      _addOccurrence(node.declaredElement!, name.offset);
+    }
+
+    super.visitConstructorDeclaration(node);
+  }
+
+  @override
   void visitDeclaredIdentifier(DeclaredIdentifier node) {
     _addOccurrence(node.declaredElement!, node.name.offset);
 
@@ -72,6 +81,13 @@
   }
 
   @override
+  void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) {
+    _addOccurrence(node.declaredElement!, node.name.offset);
+
+    super.visitExtensionTypeDeclaration(node);
+  }
+
+  @override
   void visitFieldFormalParameter(FieldFormalParameter node) {
     final declaredElement = node.declaredElement;
     if (declaredElement is FieldFormalParameterElement) {
@@ -124,6 +140,15 @@
   }
 
   @override
+  void visitRepresentationDeclaration(RepresentationDeclaration node) {
+    if (node.constructorName case final constructorName?) {
+      _addOccurrence(node.constructorElement!, constructorName.name.offset);
+    }
+
+    super.visitRepresentationDeclaration(node);
+  }
+
+  @override
   void visitSimpleFormalParameter(SimpleFormalParameter node) {
     final nameToken = node.name;
     if (nameToken != null) {
diff --git a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart b/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
index 77ea645..ab21e21 100644
--- a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
@@ -30,6 +30,7 @@
   Future<void> assertOccurrences(
     String content, {
     required ElementKind? kind,
+    String? elementName,
   }) async {
     final code = TestCode.parse(content);
     addTestFile(code.code);
@@ -41,7 +42,7 @@
     findRegion(sourceRange.offset, sourceRange.length, true);
 
     expect(testOccurrences.element.kind, kind);
-    expect(testOccurrences.element.name, range.text);
+    expect(testOccurrences.element.name, elementName ?? range.text);
     expect(testOccurrences.offsets,
         containsAll(code.ranges.map((r) => r.sourceRange.offset)));
   }
@@ -202,6 +203,92 @@
     );
   }
 
+  Future<void> test_extensionType() async {
+    await assertOccurrences(
+      kind: ElementKind.EXTENSION_TYPE,
+      '''
+extension type /*[0*/E/*0]*/(int it) {}
+
+void f(/*[1*/E/*1]*/ e) {}
+''',
+    );
+  }
+
+  Future<void> test_extensionType_constructor_primary() async {
+    await assertOccurrences(
+      kind: ElementKind.CONSTRUCTOR,
+      elementName: 'E.named',
+      '''
+extension type E./*[0*/named/*0]*/(int it) {}
+
+void f() {
+  E./*[1*/named/*1]*/(0);
+}
+''',
+    );
+  }
+
+  Future<void> test_extensionType_constructor_secondary() async {
+    await assertOccurrences(
+      kind: ElementKind.CONSTRUCTOR,
+      elementName: 'E.named',
+      '''
+extension type E(int it) {
+  E./*[0*/named/*0]*/() : this(0);
+}
+
+void f() {
+  E./*[1*/named/*1]*/();
+}
+''',
+    );
+  }
+
+  Future<void> test_extensionType_getter() async {
+    await assertOccurrences(
+      kind: ElementKind.FIELD,
+      '''
+extension type E(int it) {
+  int get /*[0*/foo/*0]*/ => 0;
+}
+
+void f(E e) {
+  e./*[1*/foo/*1]*/;
+}
+''',
+    );
+  }
+
+  Future<void> test_extensionType_method() async {
+    await assertOccurrences(
+      kind: ElementKind.METHOD,
+      '''
+extension type E(int it) {
+  void /*[0*/foo/*0]*/() {}
+}
+
+void f(E e) {
+  e./*[1*/foo/*1]*/();
+}
+''',
+    );
+  }
+
+  Future<void> test_extensionType_setter() async {
+    await assertOccurrences(
+      kind: ElementKind.FIELD,
+      '''
+extension type E(int it) {
+  set /*[0*/foo/*0]*/(int _) {}
+}
+
+void f(E e) {
+  e./*[1*/foo/*1]*/ = 0;
+}
+''',
+    );
+  }
+
   Future<void> test_field() async {
     await assertOccurrences(
       kind: ElementKind.FIELD,