Semantic highlighting for enums.

Change-Id: Ib3e4aceec56b6bdd28b38a317c4c3981db87b7d1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/232680
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2022-02-11 18:50:57 +00:00 committed by Commit Bot
parent 32876877ae
commit b62949ea1d
2 changed files with 218 additions and 15 deletions

View file

@ -253,8 +253,7 @@ class DartUnitHighlightsComputer {
// prepare type
HighlightRegionType? type;
if (element is FieldElement) {
var enclosingElement = element.enclosingElement;
if (enclosingElement is ClassElement && enclosingElement.isEnum) {
if (element.isEnumConstant) {
type = HighlightRegionType.ENUM_CONSTANT;
} else if (element.isStatic) {
type = HighlightRegionType.STATIC_FIELD_DECLARATION;
@ -268,12 +267,12 @@ class DartUnitHighlightsComputer {
}
if (element is PropertyAccessorElement) {
var accessor = element;
var enclosingElement = element.enclosingElement;
if (accessor.variable is TopLevelVariableElement) {
var variable = accessor.variable;
if (variable is TopLevelVariableElement) {
type = accessor.isGetter
? HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE
: HighlightRegionType.TOP_LEVEL_SETTER_REFERENCE;
} else if (enclosingElement is ClassElement && enclosingElement.isEnum) {
} else if (variable is FieldElement && variable.isEnumConstant) {
type = HighlightRegionType.ENUM_CONSTANT;
} else if (accessor.isStatic) {
type = accessor.isGetter
@ -697,6 +696,15 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
constructorName.name!, HighlightRegionType.CONSTRUCTOR_TEAR_OFF);
}
@override
void visitConstructorSelector(ConstructorSelector node) {
computer._addRegion_node(
node.name,
HighlightRegionType.CONSTRUCTOR,
);
node.visitChildren(this);
}
@override
void visitContinueStatement(ContinueStatement node) {
computer._addRegion_token(node.continueKeyword, HighlightRegionType.KEYWORD,
@ -726,6 +734,15 @@ class _DartUnitHighlightsComputerVisitor extends RecursiveAstVisitor<void> {
super.visitDoubleLiteral(node);
}
@override
void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
computer._addRegion_node(
node.name,
HighlightRegionType.ENUM_CONSTANT,
);
node.visitChildren(this);
}
@override
void visitEnumDeclaration(EnumDeclaration node) {
computer._addRegion_token(node.enumKeyword, HighlightRegionType.KEYWORD);

View file

@ -656,9 +656,164 @@ class A {
assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'f = 1');
}
Future<void> test_ENUM() async {
Future<void> test_enum_constant() async {
addTestFile('''
enum MyEnum {AAA, BBB}
void f() {
MyEnum.AAA;
MyEnum.BBB;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA;');
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB;');
}
Future<void> test_enum_constructor() async {
addTestFile('''
const a = 0;
enum E<T> {
v<int>.named(a); // 1
E.named(T a); // 2
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'v<');
assertHasRegion(HighlightRegionType.CLASS, 'int>');
assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'named(a)');
assertHasRegion(HighlightRegionType.TOP_LEVEL_GETTER_REFERENCE, 'a); // 1');
assertHasRegion(HighlightRegionType.ENUM, 'E.named');
assertHasRegion(HighlightRegionType.CONSTRUCTOR, 'named(T');
assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T a');
assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'a); // 2');
}
Future<void> test_enum_field_instance() async {
addTestFile('''
enum E {
v;
final int a = 0;
E(this.a);
}
void f(E e) {
e.a;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.CLASS, 'int ');
assertHasRegion(HighlightRegionType.INSTANCE_FIELD_DECLARATION, 'a = 0');
assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'a);');
assertHasRegion(HighlightRegionType.INSTANCE_GETTER_REFERENCE, 'a;');
}
Future<void> test_enum_field_static() async {
addTestFile('''
enum E {
v;
static final int a = 0;
}
void f() {
E.a;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.CLASS, 'int ');
assertHasRegion(HighlightRegionType.STATIC_FIELD_DECLARATION, 'a = 0');
assertHasRegion(HighlightRegionType.STATIC_GETTER_REFERENCE, 'a;');
}
Future<void> test_enum_getter_instance() async {
addTestFile('''
enum E {
v;
int get foo => 0;
}
void f(E e) {
e.foo;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.CLASS, 'int get');
assertHasRegion(HighlightRegionType.INSTANCE_GETTER_DECLARATION, 'foo =>');
assertHasRegion(HighlightRegionType.INSTANCE_GETTER_REFERENCE, 'foo;');
}
Future<void> test_enum_getter_static() async {
addTestFile('''
enum E {
v;
static int get foo => 0;
}
void f() {
E.foo;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.CLASS, 'int get');
assertHasRegion(HighlightRegionType.STATIC_GETTER_DECLARATION, 'foo =>');
assertHasRegion(HighlightRegionType.STATIC_GETTER_REFERENCE, 'foo;');
}
Future<void> test_enum_method_instance() async {
addTestFile('''
enum E {
v;
int foo(int a) {
return a;
}
}
void f(E e) {
e.foo();
e.foo;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.CLASS, 'int foo');
assertHasRegion(HighlightRegionType.INSTANCE_METHOD_DECLARATION, 'foo(int');
assertHasRegion(HighlightRegionType.CLASS, 'int a');
assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'a)');
assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'a;');
assertHasRegion(HighlightRegionType.INSTANCE_METHOD_REFERENCE, 'foo();');
assertHasRegion(HighlightRegionType.INSTANCE_METHOD_TEAR_OFF, 'foo;');
}
Future<void> test_enum_method_static() async {
addTestFile('''
enum E {
v;
static int foo(int a) {
return a;
}
}
void f() {
E.foo();
E.foo;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.CLASS, 'int foo');
assertHasRegion(HighlightRegionType.STATIC_METHOD_DECLARATION, 'foo(int');
assertHasRegion(HighlightRegionType.CLASS, 'int a');
assertHasRegion(HighlightRegionType.PARAMETER_DECLARATION, 'a)');
assertHasRegion(HighlightRegionType.PARAMETER_REFERENCE, 'a;');
assertHasRegion(HighlightRegionType.STATIC_METHOD_REFERENCE, 'foo();');
assertHasRegion(HighlightRegionType.STATIC_METHOD_TEAR_OFF, 'foo;');
}
Future<void> test_enum_name() async {
addTestFile('''
enum MyEnum {A, B, C}
MyEnum value;
''');
await prepareHighlights();
@ -666,19 +821,50 @@ MyEnum value;
assertHasRegion(HighlightRegionType.ENUM, 'MyEnum value;');
}
Future<void> test_ENUM_CONSTANT() async {
Future<void> test_enum_setter_instance() async {
addTestFile('''
enum MyEnum {AAA, BBB}
void f() {
print(MyEnum.AAA);
print(MyEnum.BBB);
enum E {
v;
set foo(int _) {}
}
void f(E e) {
e.foo = 0;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA, ');
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB}');
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'AAA);');
assertHasRegion(HighlightRegionType.ENUM_CONSTANT, 'BBB);');
assertHasRegion(HighlightRegionType.CLASS, 'int _');
assertHasRegion(HighlightRegionType.INSTANCE_SETTER_DECLARATION, 'foo(int');
assertHasRegion(HighlightRegionType.INSTANCE_SETTER_REFERENCE, 'foo = 0;');
}
Future<void> test_enum_setter_static() async {
addTestFile('''
enum E {
v;
static set foo(int _) {}
}
void f() {
E.foo = 0;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.CLASS, 'int _');
assertHasRegion(HighlightRegionType.STATIC_SETTER_DECLARATION, 'foo(int');
assertHasRegion(HighlightRegionType.STATIC_SETTER_REFERENCE, 'foo = 0;');
}
Future<void> test_enum_typeParameter() async {
addTestFile('''
enum E<T> {
v;
T? foo() => null;
}
''');
await prepareHighlights();
assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T>');
assertHasRegion(HighlightRegionType.TYPE_PARAMETER, 'T?');
}
Future<void> test_EXTENSION() async {