From cdd9e43b2cf6b16746dae5497061c63f6ec17963 Mon Sep 17 00:00:00 2001 From: Kallen Tu Date: Tue, 27 Dec 2022 23:24:40 +0000 Subject: [PATCH] [analysis_server] Add semantic highlighting for sealed class modifier. Enable the 'sealed-class' experiment for the highlighting test and add the highlighting for the modifier. Change-Id: I6affdab506c29ab9d92b2d6315a93d09396bafaa Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/277201 Reviewed-by: Samuel Rawlins Commit-Queue: Kallen Tu --- .../lib/src/computer/computer_highlights.dart | 3 +++ .../notification_highlights2_test.dart | 21 +++++++++++++++++++ pkg/analyzer/lib/dart/ast/ast.dart | 15 +++++++++++-- pkg/analyzer/lib/src/dart/ast/ast.dart | 10 +++++++-- 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/pkg/analysis_server/lib/src/computer/computer_highlights.dart b/pkg/analysis_server/lib/src/computer/computer_highlights.dart index 05ef0fb7ffc..bad482894f4 100644 --- a/pkg/analysis_server/lib/src/computer/computer_highlights.dart +++ b/pkg/analysis_server/lib/src/computer/computer_highlights.dart @@ -664,6 +664,7 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor { void visitClassDeclaration(ClassDeclaration node) { computer._addRegion_token( node.abstractKeyword, HighlightRegionType.BUILT_IN); + computer._addRegion_token(node.sealedKeyword, HighlightRegionType.BUILT_IN); computer._addRegion_token(node.classKeyword, HighlightRegionType.KEYWORD); computer._addRegion_token(node.name, HighlightRegionType.CLASS); super.visitClassDeclaration(node); @@ -673,6 +674,7 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor { void visitClassTypeAlias(ClassTypeAlias node) { computer._addRegion_token( node.abstractKeyword, HighlightRegionType.BUILT_IN); + computer._addRegion_token(node.sealedKeyword, HighlightRegionType.BUILT_IN); super.visitClassTypeAlias(node); } @@ -1079,6 +1081,7 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor { @override void visitMixinDeclaration(MixinDeclaration node) { + computer._addRegion_token(node.sealedKeyword, HighlightRegionType.BUILT_IN); computer._addRegion_token(node.mixinKeyword, HighlightRegionType.BUILT_IN); super.visitMixinDeclaration(node); } diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart index 0a7e6bcc575..d7407a14b67 100644 --- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart +++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart @@ -8,6 +8,7 @@ import 'package:analysis_server/protocol/protocol.dart'; import 'package:analysis_server/protocol/protocol_constants.dart'; import 'package:analysis_server/protocol/protocol_generated.dart'; import 'package:analyzer/source/source_range.dart'; +import 'package:analyzer/src/dart/analysis/experiments.dart'; import 'package:analyzer/src/test_utilities/test_code_format.dart'; import 'package:analyzer_plugin/protocol/protocol_common.dart'; import 'package:collection/collection.dart'; @@ -25,6 +26,10 @@ void main() { @reflectiveTest class AnalysisNotificationHighlightsTest extends HighlightsTestSupport { + @override + List get experiments => + [...super.experiments, EnableString.sealed_class]; + void assertHighlightText(TestCode testCode, int index, String expected) { var actual = _getHighlightText(testCode, index); if (actual != expected) { @@ -364,6 +369,22 @@ void f() { assertNoRegion(HighlightRegionType.BUILT_IN, 'of = 2'); } + Future test_BUILT_IN_sealed() async { + addTestFile(''' +sealed class A {} +sealed mixin M {} +sealed class B = Object with M; +void f() { + var sealed = 42; +} +'''); + await prepareHighlights(); + assertHasRegion(HighlightRegionType.BUILT_IN, 'sealed class A'); + assertHasRegion(HighlightRegionType.BUILT_IN, 'sealed mixin M'); + assertHasRegion(HighlightRegionType.BUILT_IN, 'sealed class B'); + assertNoRegion(HighlightRegionType.BUILT_IN, 'sealed = 42'); + } + Future test_BUILT_IN_set() async { addTestFile(''' set aaa(x) {} diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart index b6a9cbd3cdf..3ba12f9b56f 100644 --- a/pkg/analyzer/lib/dart/ast/ast.dart +++ b/pkg/analyzer/lib/dart/ast/ast.dart @@ -1001,10 +1001,12 @@ abstract class ClassAugmentationDeclaration /// The declaration of a class. /// /// classDeclaration ::= -/// 'abstract'? 'class' name [TypeParameterList]? +/// classModifiers? 'class' name [TypeParameterList]? /// [ExtendsClause]? [WithClause]? [ImplementsClause]? /// '{' [ClassMember]* '}' /// +/// classModifiers ::= 'sealed' | 'abstract' +/// /// Clients may not extend, implement or mix-in this class. abstract class ClassDeclaration implements ClassOrAugmentationDeclaration { @override @@ -1090,6 +1092,9 @@ abstract class ClassOrAugmentationDeclaration /// Returns the right curly bracket. Token get rightBracket; + /// Return the 'sealed' keyword, or `null` if the keyword was absent. + Token? get sealedKeyword; + /// Returns the type parameters for the class, or `null` if the class does /// not have any type parameters. TypeParameterList? get typeParameters; @@ -1127,6 +1132,9 @@ abstract class ClassTypeAlias implements TypeAlias { /// implements clause. ImplementsClause? get implementsClause; + /// Return the 'sealed' keyword, or `null` if the keyword was absent. + Token? get sealedKeyword; + /// Return the name of the superclass of the class being declared. NamedType get superclass; @@ -3752,7 +3760,7 @@ abstract class MixinAugmentationDeclaration /// The declaration of a mixin. /// /// mixinDeclaration ::= -/// 'mixin' name [TypeParameterList]? +/// 'sealed'? 'mixin' name [TypeParameterList]? /// [OnClause]? [ImplementsClause]? '{' [ClassMember]* '}' /// /// Clients may not extend, implement or mix-in this class. @@ -3821,6 +3829,9 @@ abstract class MixinOrAugmentationDeclaration /// Returns the right curly bracket. Token get rightBracket; + /// Return the 'sealed' keyword, or `null` if the keyword was absent. + Token? get sealedKeyword; + /// Returns the type parameters for the mixin, or `null` if the mixin does /// not have any type parameters. TypeParameterList? get typeParameters; diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index 893bb1d71f2..058ebce8079 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -1891,10 +1891,13 @@ class ChildEntity { /// The declaration of a class. /// /// classDeclaration ::= -/// 'abstract'? 'class' [SimpleIdentifier] [TypeParameterList]? +/// classModifiers? 'class' [SimpleIdentifier] [TypeParameterList]? /// ([ExtendsClause] [WithClause]?)? /// [ImplementsClause]? /// '{' [ClassMember]* '}' +/// +/// classModifiers ::= 'sealed' | 'abstract' +/// class ClassDeclarationImpl extends NamedCompilationUnitMemberImpl implements ClassDeclaration { /// The 'abstract' keyword, or `null` if the keyword was absent. @@ -1908,6 +1911,7 @@ class ClassDeclarationImpl extends NamedCompilationUnitMemberImpl final Token? inlineKeyword; /// The 'sealed' keyword, or `null` if the keyword was absent. + @override final Token? sealedKeyword; /// The 'augment' keyword, or `null` if the keyword was absent. @@ -2127,6 +2131,7 @@ class ClassTypeAliasImpl extends TypeAliasImpl implements ClassTypeAlias { /// The token for the 'sealed' keyword, or `null` if this is not defining a /// sealed class. + @override final Token? sealedKeyword; /// The token for the 'augment' keyword, or `null` if this is not defining an @@ -8918,7 +8923,7 @@ class MethodInvocationImpl extends InvocationExpressionImpl /// The declaration of a mixin. /// /// mixinDeclaration ::= -/// metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]? +/// 'sealed'? metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]? /// [RequiresClause]? [ImplementsClause]? '{' [ClassMember]* '}' class MixinDeclarationImpl extends NamedCompilationUnitMemberImpl implements MixinDeclaration { @@ -8926,6 +8931,7 @@ class MixinDeclarationImpl extends NamedCompilationUnitMemberImpl final Token? augmentKeyword; /// Return the 'sealed' keyword, or `null` if the keyword was absent. + @override final Token? sealedKeyword; @override