[DAS] Fixes coloring for record fields access in extension

Fixes: https://github.com/dart-lang/sdk/issues/60625

Change-Id: Idce84fbdc9b58b2e91c2e40a058bf466e8d5fb65
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/426342
Auto-Submit: Felipe Morschel <git@fmorschel.dev>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
index 41ad6df..30fa6ef 100644
--- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart
@@ -28,6 +28,7 @@
 import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/ast/extensions.dart';
 import 'package:analyzer/src/dart/element/extensions.dart';
+import 'package:analyzer/src/utilities/extensions/ast.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 
 /// A computer for [HighlightRegion]s and LSP [SemanticTokenInfo] in a Dart [CompilationUnit].
@@ -292,11 +293,16 @@
       } else {
         type = HighlightRegionType.INSTANCE_SETTER_REFERENCE;
       }
-    } else if (element == null &&
-        parent is PropertyAccess &&
-        nameToken == parent.propertyName.token) {
+    } else if (element == null) {
+      DartType? staticType;
+      if (parent is PropertyAccess && nameToken == parent.propertyName.token) {
+        staticType = parent.realTarget.staticType;
+      } else if (parent.enclosingInstanceElement case ExtensionElement(
+        :var extendedType,
+      ) when parent is! PrefixedIdentifier) {
+        staticType = extendedType;
+      }
       // Handle tokens that are references to record fields.
-      var staticType = parent.realTarget.staticType;
       if (staticType is RecordType) {
         type =
             staticType.fieldByName(nameToken.lexeme) != null
diff --git a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
index 9921502..951a08b 100644
--- a/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
+++ b/pkg/analysis_server/test/lsp/semantic_tokens_test.dart
@@ -1492,6 +1492,34 @@
     await _initializeAndVerifyTokens(content, expected);
   }
 
+  Future<void> test_namedRecordFields_extension() async {
+    var content = '''
+extension on ({int field,}) {
+  get other => field + this.field;
+}
+''';
+
+    var expected = [
+      _Token('extension', SemanticTokenTypes.keyword),
+      _Token('on', SemanticTokenTypes.keyword),
+      _Token('int', SemanticTokenTypes.class_),
+      _Token('get', SemanticTokenTypes.keyword),
+      _Token('other', SemanticTokenTypes.property, [
+        SemanticTokenModifiers.declaration,
+        CustomSemanticTokenModifiers.instance,
+      ]),
+      _Token('field', SemanticTokenTypes.property, [
+        CustomSemanticTokenModifiers.instance,
+      ]),
+      _Token('this', SemanticTokenTypes.keyword),
+      _Token('field', SemanticTokenTypes.property, [
+        CustomSemanticTokenModifiers.instance,
+      ]),
+    ];
+
+    await _initializeAndVerifyTokens(content, expected);
+  }
+
   Future<void> test_never() async {
     var content = '''
 Never f() => throw '';
@@ -1847,6 +1875,34 @@
     await _initializeAndVerifyTokens(content, expected);
   }
 
+  Future<void> test_positionalRecordFields_extension() async {
+    var content = r'''
+extension on (int field, double,) {
+  get other => $1 + $2;
+}
+''';
+
+    var expected = [
+      _Token('extension', SemanticTokenTypes.keyword),
+      _Token('on', SemanticTokenTypes.keyword),
+      _Token('int', SemanticTokenTypes.class_),
+      _Token('double', SemanticTokenTypes.class_),
+      _Token('get', SemanticTokenTypes.keyword),
+      _Token('other', SemanticTokenTypes.property, [
+        SemanticTokenModifiers.declaration,
+        CustomSemanticTokenModifiers.instance,
+      ]),
+      _Token(r'$1', SemanticTokenTypes.property, [
+        CustomSemanticTokenModifiers.instance,
+      ]),
+      _Token(r'$2', SemanticTokenTypes.property, [
+        CustomSemanticTokenModifiers.instance,
+      ]),
+    ];
+
+    await _initializeAndVerifyTokens(content, expected);
+  }
+
   Future<void> test_range() async {
     var content = '''
 /// class docs