From ce7164488aec6fc40b9a310a67aa408c628389d3 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Fri, 4 Aug 2023 19:13:43 +0000 Subject: [PATCH] Extension types. Semantic highlighting. Change-Id: I46cde8151965e209a230df811592f8498e93c218 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/318161 Reviewed-by: Phil Quitslund Commit-Queue: Konstantin Shcheglov --- pkg/analysis_server/doc/api.html | 2 +- .../lib/src/computer/computer_highlights.dart | 49 +++++++++++ .../notification_highlights2_test.dart | 83 +++++++++++++++++++ .../support/protocol_matchers.dart | 2 + .../java/types/HighlightRegionType.java | 2 + .../lib/src/protocol/protocol_common.dart | 7 ++ pkg/analyzer/lib/src/dart/ast/ast.dart | 1 + pkg/analyzer_plugin/doc/api.html | 2 +- .../lib/protocol/protocol_common.dart | 7 ++ .../support/protocol_matchers.dart | 2 + .../tool/spec/common_types_spec.html | 1 + 11 files changed, 156 insertions(+), 2 deletions(-) diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html index 6b9305a17ef..b792411dbfe 100644 --- a/pkg/analysis_server/doc/api.html +++ b/pkg/analysis_server/doc/api.html @@ -4763,7 +4763,7 @@ a:focus, a:hover {
ANNOTATION
BUILT_IN
CLASS
COMMENT_BLOCK
COMMENT_DOCUMENTATION
COMMENT_END_OF_LINE
CONSTRUCTOR
CONSTRUCTOR_TEAR_OFF
DIRECTIVE
DYNAMIC_TYPE

Deprecated - no longer sent.

-
DYNAMIC_LOCAL_VARIABLE_DECLARATION
DYNAMIC_LOCAL_VARIABLE_REFERENCE
DYNAMIC_PARAMETER_DECLARATION
DYNAMIC_PARAMETER_REFERENCE
ENUM
ENUM_CONSTANT
EXTENSION
FIELD
+
DYNAMIC_LOCAL_VARIABLE_DECLARATION
DYNAMIC_LOCAL_VARIABLE_REFERENCE
DYNAMIC_PARAMETER_DECLARATION
DYNAMIC_PARAMETER_REFERENCE
ENUM
ENUM_CONSTANT
EXTENSION
EXTENSION_TYPE
FIELD

Deprecated - no longer sent.

FIELD_STATIC
diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart index 853da0da638..8130e193606 100644 --- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart +++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart @@ -184,6 +184,8 @@ class DartUnitHighlightsComputer { semanticModifiers = {CustomSemanticTokenModifiers.constructor}; } else if (element is EnumElement) { type = HighlightRegionType.ENUM; + } else if (element is ExtensionTypeElement) { + type = HighlightRegionType.EXTENSION_TYPE; } else { type = HighlightRegionType.CLASS; if (parent is ConstructorDeclaration) { @@ -862,6 +864,27 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor { super.visitExtensionOverride(node); } + @override + void visitExtensionTypeDeclaration(ExtensionTypeDeclaration node) { + computer._addRegion_token( + node.extensionKeyword, + HighlightRegionType.BUILT_IN, + ); + + computer._addRegion_token( + node.typeKeyword, + HighlightRegionType.BUILT_IN, + ); + + computer._addRegion_token( + node.name, + HighlightRegionType.EXTENSION_TYPE, + semanticTokenModifiers: {SemanticTokenModifiers.declaration}, + ); + + super.visitExtensionTypeDeclaration(node); + } + @override void visitFieldDeclaration(FieldDeclaration node) { computer._addRegion_token( @@ -1269,6 +1292,32 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor { super.visitRecordTypeAnnotation(node); } + @override + void visitRepresentationConstructorName(RepresentationConstructorName node) { + computer._addRegion_token( + node.name, + HighlightRegionType.CONSTRUCTOR, + semanticTokenType: SemanticTokenTypes.method, + semanticTokenModifiers: { + CustomSemanticTokenModifiers.constructor, + SemanticTokenModifiers.declaration, + }, + ); + + super.visitRepresentationConstructorName(node); + } + + @override + void visitRepresentationDeclaration(RepresentationDeclaration node) { + computer._addRegion_token( + node.fieldName, + HighlightRegionType.INSTANCE_FIELD_DECLARATION, + semanticTokenModifiers: {SemanticTokenModifiers.declaration}, + ); + + super.visitRepresentationDeclaration(node); + } + @override void visitRethrowExpression(RethrowExpression node) { computer._addRegion_token(node.rethrowKeyword, HighlightRegionType.KEYWORD, diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart index 21bf24c967a..16fad28a651 100644 --- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart +++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart @@ -1099,6 +1099,25 @@ void f() { assertHasRegion(HighlightRegionType.EXTENSION, 'E.bar()'); } + Future test_extensionType() async { + final testCode = TestCode.parse(r''' +extension type A.named(int it) implements num {} +'''); + addTestFile(testCode.code); + await prepareHighlights(); + assertHighlightText(testCode, -1, r''' +0 + 9 |extension| BUILT_IN +10 + 4 |type| BUILT_IN +15 + 1 |A| EXTENSION_TYPE +17 + 1 |T| TYPE_PARAMETER +20 + 5 |named| CONSTRUCTOR +26 + 3 |int| CLASS +30 + 2 |it| INSTANCE_FIELD_DECLARATION +34 + 10 |implements| BUILT_IN +45 + 3 |num| CLASS +'''); + } + Future test_forEachPartsWithPattern_final() async { addTestFile(''' void f(List l) { @@ -1242,6 +1261,40 @@ class A { assertHasRegion(HighlightRegionType.INSTANCE_FIELD_REFERENCE, 'f);'); } + Future test_instanceCreation_class() async { + final testCode = TestCode.parse(r''' +class A { + A.named(int it); +} +void f() { + [!A.named(0)!]; +} +'''); + addTestFile(testCode.code); + await prepareHighlights(); + assertHighlightText(testCode, 0, r''' +44 + 1 |A| CONSTRUCTOR +46 + 5 |named| CONSTRUCTOR +52 + 1 |0| LITERAL_INTEGER +'''); + } + + Future test_instanceCreation_extensionType() async { + final testCode = TestCode.parse(r''' +extension type A.named(T it) {} +void f() { + [!A.named(0)!]; +} +'''); + addTestFile(testCode.code); + await prepareHighlights(); + assertHighlightText(testCode, 0, r''' +45 + 1 |A| CONSTRUCTOR +47 + 5 |named| CONSTRUCTOR +53 + 1 |0| LITERAL_INTEGER +'''); + } + Future test_KEYWORD() async { addTestFile(''' void f() { @@ -1617,6 +1670,19 @@ void g() { assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'a: 0'); } + Future test_namedType_extensionType() async { + final testCode = TestCode.parse(r''' +extension type A(T it) {} +void f([!A!] a) {} +'''); + addTestFile(testCode.code); + await prepareHighlights(); + assertHighlightText(testCode, 0, r''' +36 + 1 |A| EXTENSION_TYPE +38 + 3 |int| CLASS +'''); + } + Future test_PARAMETER() async { addTestFile(''' void f(int p) { @@ -1725,6 +1791,23 @@ void f(Object o) { assertHasRegion(HighlightRegionType.KEYWORD, 'var'); } + Future test_propertyAccess_extensionTypeName() async { + final testCode = TestCode.parse(r''' +extension type A.named(T it) { + static const V = 0; +} +void f() { + [!A.V!]; +} +'''); + addTestFile(testCode.code); + await prepareHighlights(); + assertHighlightText(testCode, 0, r''' +68 + 1 |A| EXTENSION_TYPE +70 + 1 |V| STATIC_GETTER_REFERENCE +'''); + } + Future test_recordTypeAnnotation_named() async { addTestFile(''' ({int f1, String f2})? r; diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart index b4b484853f1..224b886f43d 100644 --- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart +++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart @@ -807,6 +807,7 @@ final Matcher isHighlightRegion = LazyMatcher(() => MatchesJsonObject( /// ENUM /// ENUM_CONSTANT /// EXTENSION +/// EXTENSION_TYPE /// FIELD /// FIELD_STATIC /// FUNCTION @@ -891,6 +892,7 @@ final Matcher isHighlightRegionType = MatchesEnum('HighlightRegionType', [ 'ENUM', 'ENUM_CONSTANT', 'EXTENSION', + 'EXTENSION_TYPE', 'FIELD', 'FIELD_STATIC', 'FUNCTION', diff --git a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java index 56cdb49c97f..4a03008aab6 100644 --- a/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java +++ b/pkg/analysis_server/tool/spec/generated/java/types/HighlightRegionType.java @@ -52,6 +52,8 @@ public class HighlightRegionType { public static final String EXTENSION = "EXTENSION"; + public static final String EXTENSION_TYPE = "EXTENSION_TYPE"; + /** * Deprecated - no longer sent. */ diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart index 877607aa55e..815c4cabb6c 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_common.dart @@ -1897,6 +1897,7 @@ class HighlightRegion implements HasToJson { /// ENUM /// ENUM_CONSTANT /// EXTENSION +/// EXTENSION_TYPE /// FIELD /// FIELD_STATIC /// FUNCTION @@ -2015,6 +2016,9 @@ class HighlightRegionType implements Enum { static const HighlightRegionType EXTENSION = HighlightRegionType._('EXTENSION'); + static const HighlightRegionType EXTENSION_TYPE = + HighlightRegionType._('EXTENSION_TYPE'); + /// Deprecated - no longer sent. static const HighlightRegionType FIELD = HighlightRegionType._('FIELD'); @@ -2236,6 +2240,7 @@ class HighlightRegionType implements Enum { ENUM, ENUM_CONSTANT, EXTENSION, + EXTENSION_TYPE, FIELD, FIELD_STATIC, FUNCTION, @@ -2344,6 +2349,8 @@ class HighlightRegionType implements Enum { return ENUM_CONSTANT; case 'EXTENSION': return EXTENSION; + case 'EXTENSION_TYPE': + return EXTENSION_TYPE; case 'FIELD': return FIELD; case 'FIELD_STATIC': diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index 944f81a6915..f4e596cead8 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -6818,6 +6818,7 @@ final class ExtensionTypeDeclarationImpl extends NamedCompilationUnitMemberImpl super.visitChildren(visitor); typeParameters?.accept(visitor); representation.accept(visitor); + implementsClause?.accept(visitor); members.accept(visitor); } } diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html index e2d7a05785c..beb55a5606a 100644 --- a/pkg/analyzer_plugin/doc/api.html +++ b/pkg/analyzer_plugin/doc/api.html @@ -1419,7 +1419,7 @@ a:focus, a:hover {
ANNOTATION
BUILT_IN
CLASS
COMMENT_BLOCK
COMMENT_DOCUMENTATION
COMMENT_END_OF_LINE
CONSTRUCTOR
CONSTRUCTOR_TEAR_OFF
DIRECTIVE
DYNAMIC_TYPE

Deprecated - no longer sent.

-
DYNAMIC_LOCAL_VARIABLE_DECLARATION
DYNAMIC_LOCAL_VARIABLE_REFERENCE
DYNAMIC_PARAMETER_DECLARATION
DYNAMIC_PARAMETER_REFERENCE
ENUM
ENUM_CONSTANT
EXTENSION
FIELD
+
DYNAMIC_LOCAL_VARIABLE_DECLARATION
DYNAMIC_LOCAL_VARIABLE_REFERENCE
DYNAMIC_PARAMETER_DECLARATION
DYNAMIC_PARAMETER_REFERENCE
ENUM
ENUM_CONSTANT
EXTENSION
EXTENSION_TYPE
FIELD

Deprecated - no longer sent.

FIELD_STATIC
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart index 4987b67ec1f..6ea6d24a8a1 100644 --- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart +++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart @@ -1897,6 +1897,7 @@ class HighlightRegion implements HasToJson { /// ENUM /// ENUM_CONSTANT /// EXTENSION +/// EXTENSION_TYPE /// FIELD /// FIELD_STATIC /// FUNCTION @@ -2015,6 +2016,9 @@ class HighlightRegionType implements Enum { static const HighlightRegionType EXTENSION = HighlightRegionType._('EXTENSION'); + static const HighlightRegionType EXTENSION_TYPE = + HighlightRegionType._('EXTENSION_TYPE'); + /// Deprecated - no longer sent. static const HighlightRegionType FIELD = HighlightRegionType._('FIELD'); @@ -2236,6 +2240,7 @@ class HighlightRegionType implements Enum { ENUM, ENUM_CONSTANT, EXTENSION, + EXTENSION_TYPE, FIELD, FIELD_STATIC, FUNCTION, @@ -2344,6 +2349,8 @@ class HighlightRegionType implements Enum { return ENUM_CONSTANT; case 'EXTENSION': return EXTENSION; + case 'EXTENSION_TYPE': + return EXTENSION_TYPE; case 'FIELD': return FIELD; case 'FIELD_STATIC': diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart index 1d38dbd229b..f2ea620ef41 100644 --- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart +++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart @@ -382,6 +382,7 @@ final Matcher isHighlightRegion = LazyMatcher(() => MatchesJsonObject( /// ENUM /// ENUM_CONSTANT /// EXTENSION +/// EXTENSION_TYPE /// FIELD /// FIELD_STATIC /// FUNCTION @@ -466,6 +467,7 @@ final Matcher isHighlightRegionType = MatchesEnum('HighlightRegionType', [ 'ENUM', 'ENUM_CONSTANT', 'EXTENSION', + 'EXTENSION_TYPE', 'FIELD', 'FIELD_STATIC', 'FUNCTION', diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html index e570bc46233..516886a30c7 100644 --- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html +++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html @@ -736,6 +736,7 @@ ENUM ENUM_CONSTANT EXTENSION + EXTENSION_TYPE FIELD

Deprecated - no longer sent.