From d2b5f5f8d97226b1caa8c7f598c12961cca735c8 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Wed, 3 Jan 2024 22:35:58 +0000 Subject: [PATCH] Macro. Introspection for EnumElement, tests. Change-Id: I0029abd3f0dbbfb68aaec7cc8a0f9197a45df218 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/344622 Commit-Queue: Konstantin Shcheglov Reviewed-by: Brian Wilkerson --- .../lib/src/summary2/macro_declarations.dart | 54 ++++- .../test/src/summary/macro/introspect.dart | 2 + pkg/analyzer/test/src/summary/macro_test.dart | 209 ++++++++++++++++++ 3 files changed, 262 insertions(+), 3 deletions(-) diff --git a/pkg/analyzer/lib/src/summary2/macro_declarations.dart b/pkg/analyzer/lib/src/summary2/macro_declarations.dart index 65a5c8c56cc..02359464713 100644 --- a/pkg/analyzer/lib/src/summary2/macro_declarations.dart +++ b/pkg/analyzer/lib/src/summary2/macro_declarations.dart @@ -514,6 +514,11 @@ class DeclarationBuilderFromElement { final Map _classMap = Map.identity(); + final Map _enumMap = Map.identity(); + + final Map _enumConstantMap = + Map.identity(); + final Map _extensionMap = Map.identity(); @@ -558,8 +563,6 @@ class DeclarationBuilderFromElement { switch (element) { case ConstructorElementImpl(): return constructorElement(element); - case ExtensionElementImpl(): - return extensionElement(element); case FieldElementImpl(): return fieldElement(element); case FunctionElementImpl(): @@ -580,6 +583,12 @@ class DeclarationBuilderFromElement { } } + EnumDeclarationImpl enumElement( + EnumElementImpl element, + ) { + return _enumMap[element] ??= _enumElement(element); + } + ExtensionDeclarationImpl extensionElement( ExtensionElementImpl element, ) { @@ -592,7 +601,11 @@ class DeclarationBuilderFromElement { return _extensionTypeMap[element] ??= _extensionTypeElement(element); } - macro.FieldDeclarationImpl fieldElement(FieldElementImpl element) { + macro.DeclarationImpl fieldElement(FieldElementImpl element) { + if (element.isEnumConstant) { + return _enumConstantMap[element] ??= _enumConstantElement(element); + } + return _fieldMap[element] ??= _fieldElement(element); } @@ -655,6 +668,10 @@ class DeclarationBuilderFromElement { switch (element) { case ClassElementImpl(): return classElement(element); + case EnumElementImpl(): + return enumElement(element); + case ExtensionElementImpl(): + return extensionElement(element); case ExtensionTypeElementImpl(): return extensionTypeElement(element); case MixinElementImpl(): @@ -750,6 +767,37 @@ class DeclarationBuilderFromElement { } } + EnumValueDeclarationImpl _enumConstantElement( + FieldElementImpl element, + ) { + final enclosing = element.enclosingElement as EnumElementImpl; + return EnumValueDeclarationImpl( + id: macro.RemoteInstance.uniqueId, + identifier: identifier(element), + library: library(element), + metadata: _buildMetadata(element), + definingEnum: identifier(enclosing), + // TODO(scheglov): restore, when added + // type: _typeAnnotationVariable(variableList.type, element), + element: element, + ); + } + + EnumDeclarationImpl _enumElement( + EnumElementImpl element, + ) { + return EnumDeclarationImpl._( + id: macro.RemoteInstance.uniqueId, + identifier: identifier(element), + library: library(element), + metadata: _buildMetadata(element), + typeParameters: element.typeParameters.map(_typeParameter).toList(), + interfaces: element.interfaces.map(_interfaceType).toList(), + mixins: element.mixins.map(_interfaceType).toList(), + element: element, + ); + } + ExtensionDeclarationImpl _extensionElement( ExtensionElementImpl element, ) { diff --git a/pkg/analyzer/test/src/summary/macro/introspect.dart b/pkg/analyzer/test/src/summary/macro/introspect.dart index 28be150ab6e..5d227cee3f7 100644 --- a/pkg/analyzer/test/src/summary/macro/introspect.dart +++ b/pkg/analyzer/test/src/summary/macro/introspect.dart @@ -817,6 +817,8 @@ class _Printer { switch (declaration) { case ClassDeclaration(): await writeClassDeclaration(declaration); + case EnumDeclaration(): + await writeEnumDeclaration(declaration); case MixinDeclaration(): await writeMixinDeclaration(declaration); default: diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart index 996241a99ca..e7fdec084ea 100644 --- a/pkg/analyzer/test/src/summary/macro_test.dart +++ b/pkg/analyzer/test/src/summary/macro_test.dart @@ -4879,6 +4879,182 @@ class C '''); } + test_enum_fields() async { + newFile('$testPackageLibPath/a.dart', r''' +enum A { + v(0); + final int foo; + const A(this.foo); +} +'''); + + await _assertIntrospectText('A', r''' +enum A + values + v + fields + foo + flags: hasFinal + type: int +'''); + } + + test_enum_getters() async { + newFile('$testPackageLibPath/a.dart', r''' +enum A { + v; + int get foo => 0; +} +'''); + + await _assertIntrospectText('A', r''' +enum A + values + v + methods + foo + flags: hasBody isGetter + returnType: int +'''); + } + + test_enum_interfaces() async { + newFile('$testPackageLibPath/a.dart', r''' +class A {} +class B {} + +enum X implements A, B { + v +} +'''); + + await _assertIntrospectText('X', r''' +enum X + interfaces + A + B + values + v +'''); + } + + test_enum_metadata() async { + newFile('$testPackageLibPath/a.dart', r''' +@a1 +@a2 +enum X { + v +} + +const a1 = 0; +const a2 = 0; +'''); + + await _assertIntrospectText('X', r''' +enum X + metadata + IdentifierMetadataAnnotation + identifier: a1 + IdentifierMetadataAnnotation + identifier: a2 + values + v +'''); + } + + test_enum_methods() async { + newFile('$testPackageLibPath/a.dart', r''' +enum A { + v; + void foo() {} +} +'''); + + await _assertIntrospectText('A', r''' +enum A + values + v + methods + foo + flags: hasBody + returnType: void +'''); + } + + test_enum_mixins() async { + newFile('$testPackageLibPath/a.dart', r''' +mixin A {} +mixin B {} + +enum X with A, B { + v +} +'''); + + await _assertIntrospectText('X', r''' +enum X + mixins + A + B + values + v +'''); + } + + test_enum_setters() async { + newFile('$testPackageLibPath/a.dart', r''' +enum A { + v; + set foo(int value) {} +} +'''); + + await _assertIntrospectText('A', r''' +enum A + values + v + methods + foo + flags: hasBody isSetter + positionalParameters + value + flags: isRequired + type: int + returnType: void +'''); + } + + test_enum_typeParameters() async { + newFile('$testPackageLibPath/a.dart', r''' +enum A { + v +} +'''); + + await _assertIntrospectText('A', r''' +enum A + typeParameters + T + values + v +'''); + } + + test_enum_values() async { + newFile('$testPackageLibPath/a.dart', r''' +enum X with A, B { + foo, bar +} +'''); + + await _assertIntrospectText('X', r''' +enum X + values + foo + bar +'''); + } + test_extension_getters() async { newFile('$testPackageLibPath/a.dart', r''' extension A on int { @@ -7011,6 +7187,25 @@ enum A '''); } + test_enum_mixins() async { + await _assertIntrospectText(r''' +mixin A {} +mixin B {} + +@Introspect() +enum X with A, B { + v +} +''', r''' +enum X + mixins + A + B + values + v +'''); + } + test_enum_setters() async { await _assertIntrospectText(r''' @Introspect() @@ -7048,6 +7243,20 @@ enum E '''); } + test_enum_values() async { + await _assertIntrospectText(r''' +@Introspect() +enum A { + foo, bar +} +''', r''' +enum A + values + foo + bar +'''); + } + test_enumValue() async { await _assertIntrospectText(r''' enum A {