From 55bd60be32f1ee59c01b1663d798d4356ace5f47 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Thu, 14 Dec 2023 02:27:26 +0000 Subject: [PATCH] Macro. Find the declaration to introspect by URI and name, when from elements. This makes the output more compact. This also allows to introspect declarations that are otherwise hard to reference, such as functions. I will add more in following CLs. Change-Id: I4775beca6aac5e642028b05f40aac31b079ba9de Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/341391 Commit-Queue: Konstantin Shcheglov Reviewed-by: Brian Wilkerson Reviewed-by: Phil Quitslund --- .../lib/src/summary2/macro_application.dart | 5 +- .../lib/src/summary2/macro_declarations.dart | 64 +- .../test/src/summary/macro/introspect.dart | 52 + pkg/analyzer/test/src/summary/macro_test.dart | 1319 ++++++----------- 4 files changed, 536 insertions(+), 904 deletions(-) diff --git a/pkg/analyzer/lib/src/summary2/macro_application.dart b/pkg/analyzer/lib/src/summary2/macro_application.dart index 1647954f55e..06d61edef49 100644 --- a/pkg/analyzer/lib/src/summary2/macro_application.dart +++ b/pkg/analyzer/lib/src/summary2/macro_application.dart @@ -904,9 +904,8 @@ class _DefinitionPhaseIntrospector extends _DeclarationPhaseIntrospector @override Future declarationOf( covariant macro.Identifier identifier, - ) { - // TODO(scheglov): implement declarationOf - throw UnimplementedError(); + ) async { + return declarationBuilder.declarationOf(identifier); } @override diff --git a/pkg/analyzer/lib/src/summary2/macro_declarations.dart b/pkg/analyzer/lib/src/summary2/macro_declarations.dart index aed9dc51791..77b64aed342 100644 --- a/pkg/analyzer/lib/src/summary2/macro_declarations.dart +++ b/pkg/analyzer/lib/src/summary2/macro_declarations.dart @@ -105,6 +105,26 @@ class DeclarationBuilder { throw UnimplementedError('${node.runtimeType}'); } + /// See [macro.DefinitionPhaseIntrospector.declarationOf]. + macro.DeclarationImpl declarationOf(macro.Identifier identifier) { + if (identifier is! IdentifierImpl) { + throw ArgumentError('Not analyzer identifier.'); + } + + final element = identifier.element; + if (element == null) { + throw ArgumentError('Identifier without element.'); + } + + final node = nodeOfElement(element); + if (node != null) { + // TODO(scheglov): implement + throw UnimplementedError(); + } else { + return fromElement.declarationOf(element); + } + } + macro.TypeAnnotation inferOmittedType( macro.OmittedTypeAnnotation omittedType, ) { @@ -437,10 +457,40 @@ class DeclarationBuilderFromElement { return _constructorMap[element] ??= _constructorElement(element); } + /// See [macro.DefinitionPhaseIntrospector.declarationOf]. + macro.DeclarationImpl declarationOf(Element element) { + switch (element) { + case FunctionElementImpl(): + return functionElement(element); + default: + // TODO(scheglov): other elements + return typeDeclarationOf(element); + } + } + macro.FieldDeclarationImpl fieldElement(FieldElementImpl element) { return _fieldMap[element] ??= _fieldElement(element); } + FunctionDeclarationImpl functionElement(ExecutableElementImpl element) { + return FunctionDeclarationImpl._( + element: element, + id: macro.RemoteInstance.uniqueId, + identifier: identifier(element), + library: library(element), + metadata: _buildMetadata(element), + hasBody: !element.isAbstract, + hasExternal: element.isExternal, + isGetter: element is PropertyAccessorElementImpl && element.isGetter, + isOperator: element.isOperator, + isSetter: element is PropertyAccessorElementImpl && element.isSetter, + namedParameters: _namedFormalParameters(element.parameters), + positionalParameters: _positionalFormalParameters(element.parameters), + returnType: _dartType(element.returnType), + typeParameters: element.typeParameters.map(_typeParameter).toList(), + ); + } + macro.IdentifierImpl identifier(Element element) { final name = switch (element) { PropertyAccessorElement(isSetter: true) => element.displayName, @@ -483,12 +533,14 @@ class DeclarationBuilderFromElement { /// See [macro.DeclarationPhaseIntrospector.typeDeclarationOf]. macro.TypeDeclarationImpl typeDeclarationOf(Element element) { - if (element is ClassElementImpl) { - return classElement(element); - } else if (element is MixinElementImpl) { - return mixinElement(element); - } else { - throw ArgumentError('element: $element'); + switch (element) { + case ClassElementImpl(): + return classElement(element); + case MixinElementImpl(): + return mixinElement(element); + default: + // TODO(scheglov): other elements + throw ArgumentError('element: $element'); } } diff --git a/pkg/analyzer/test/src/summary/macro/introspect.dart b/pkg/analyzer/test/src/summary/macro/introspect.dart index 6b87763cd6a..c6033aa60d0 100644 --- a/pkg/analyzer/test/src/summary/macro/introspect.dart +++ b/pkg/analyzer/test/src/summary/macro/introspect.dart @@ -131,6 +131,58 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart'; } } +/*macro*/ class IntrospectDeclaration implements FunctionDefinitionMacro { + final String uriStr; + final String name; + final bool withUnnamedConstructor; + + IntrospectDeclaration({ + required this.uriStr, + required this.name, + this.withUnnamedConstructor = false, + }); + + @override + Future buildDefinitionForFunction(declaration, builder) async { + final buffer = StringBuffer(); + final sink = TreeStringSink( + sink: buffer, + indent: '', + ); + + final printer = _Printer( + sink: sink, + withMetadata: true, + withUnnamedConstructor: withUnnamedConstructor, + introspector: builder, + withDetailsFor: {name}, + ); + + // ignore: deprecated_member_use + final identifier = await builder.resolveIdentifier( + Uri.parse(uriStr), + name, + ); + final declaration = await builder.declarationOf(identifier); + switch (declaration) { + case ClassDeclaration(): + await printer.writeClassDeclaration(declaration); + case FunctionDeclaration(): + await printer.writeFunctionDeclaration(declaration); + case MixinDeclaration(): + await printer.writeMixinDeclaration(declaration); + default: + throw UnimplementedError('${declaration.runtimeType}'); + } + + final text = buffer.toString(); + + builder.augment( + FunctionBodyCode.fromString('=> r"""$text""";'), + ); + } +} + /// Wrapper around a [StringSink] for writing tree structures. class TreeStringSink { final StringSink _sink; diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart index 5090d09a69a..2ae307bf827 100644 --- a/pkg/analyzer/test/src/summary/macro_test.dart +++ b/pkg/analyzer/test/src/summary/macro_test.dart @@ -3242,28 +3242,16 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -class X { - @Introspect( - withDetailsFor: {'A'}, - withUnnamedConstructor: true, - ) - A? foo; -} -''', r''' -foo - type: A? - class A - superclass: Object - constructors - - flags: hasBody isStatic - returnType: A - named - flags: hasBody isFactory isStatic - returnType: A + await _assertIntrospectText('A', withUnnamedConstructor: true, r''' +class A + superclass: Object + constructors + + flags: hasBody isStatic + returnType: A + named + flags: hasBody isFactory isStatic + returnType: A '''); } @@ -3277,32 +3265,16 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -class X { - @Introspect( - withDetailsFor: {'A'}, - withMetadata: true, - withUnnamedConstructor: true, - ) - A? foo; -} -''', r''' -foo - metadata - ConstructorMetadataAnnotation - type: Introspect - type: A? - class A - superclass: Object - constructors - - flags: hasBody isStatic - metadata - IdentifierMetadataAnnotation - identifier: a - returnType: A + await _assertIntrospectText('A', withUnnamedConstructor: true, r''' +class A + superclass: Object + constructors + + flags: hasBody isStatic + metadata + IdentifierMetadataAnnotation + identifier: a + returnType: A '''); } @@ -3313,25 +3285,13 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -class X { - @Introspect( - withDetailsFor: {'A'}, - withUnnamedConstructor: true, - ) - A? foo; -} -''', r''' -foo - type: A? - class A - superclass: Object - constructors - named - flags: hasBody isStatic - returnType: A + await _assertIntrospectText('A', withUnnamedConstructor: true, r''' +class A + superclass: Object + constructors + named + flags: hasBody isStatic + returnType: A '''); } @@ -3342,32 +3302,20 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -class X { - @Introspect( - withDetailsFor: {'A'}, - withUnnamedConstructor: true, - ) - A? foo; -} -''', r''' -foo - type: A? - class A - superclass: Object - constructors - - flags: hasBody isStatic - namedParameters - a - flags: isNamed isRequired - type: int - b - flags: isNamed - type: String? - returnType: A + await _assertIntrospectText('A', withUnnamedConstructor: true, r''' +class A + superclass: Object + constructors + + flags: hasBody isStatic + namedParameters + a + flags: isNamed isRequired + type: int + b + flags: isNamed + type: String? + returnType: A '''); } @@ -3378,31 +3326,19 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -class X { - @Introspect( - withDetailsFor: {'A'}, - withUnnamedConstructor: true, - ) - A? foo; -} -''', r''' -foo - type: A? - class A - superclass: Object - constructors - - flags: hasBody isStatic - positionalParameters - a - flags: isRequired - type: int - b - type: String? - returnType: A + await _assertIntrospectText('A', withUnnamedConstructor: true, r''' +class A + superclass: Object + constructors + + flags: hasBody isStatic + positionalParameters + a + flags: isRequired + type: int + b + type: String? + returnType: A '''); } @@ -3413,22 +3349,13 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - fields - foo - flags: hasExternal - type: int + await _assertIntrospectText('A', r''' +class A + superclass: Object + fields + foo + flags: hasExternal + type: int '''); } @@ -3439,22 +3366,13 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - fields - foo - flags: hasFinal - type: int + await _assertIntrospectText('A', r''' +class A + superclass: Object + fields + foo + flags: hasFinal + type: int '''); } @@ -3465,22 +3383,13 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - fields - foo - flags: hasLate - type: int + await _assertIntrospectText('A', r''' +class A + superclass: Object + fields + foo + flags: hasLate + type: int '''); } @@ -3491,22 +3400,13 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - fields - foo - flags: isStatic - type: int + await _assertIntrospectText('A', r''' +class A + superclass: Object + fields + foo + flags: isStatic + type: int '''); } @@ -3520,28 +3420,15 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X - metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - superclass: Object - fields - foo - metadata - IdentifierMetadataAnnotation - identifier: a - type: int? + await _assertIntrospectText('A', r''' +class A + superclass: Object + fields + foo + metadata + IdentifierMetadataAnnotation + identifier: a + type: int? '''); } @@ -3559,28 +3446,15 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X - metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - superclass: Object - fields - foo - metadata - IdentifierMetadataAnnotation - identifier: a - type: int? + await _assertIntrospectText('A', uriStr: 'package:test/b.dart', r''' +class A + superclass: Object + fields + foo + metadata + IdentifierMetadataAnnotation + identifier: a + type: int? '''); } @@ -3601,25 +3475,16 @@ augment class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - fields - foo - flags: hasFinal - type: int - bar - flags: hasFinal - type: int + await _assertIntrospectText('A', r''' +class A + superclass: Object + fields + foo + flags: hasFinal + type: int + bar + flags: hasFinal + type: int '''); } @@ -3628,19 +3493,10 @@ class X abstract class A {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - flags: hasAbstract - superclass: Object + await _assertIntrospectText('A', r''' +class A + flags: hasAbstract + superclass: Object '''); } @@ -3651,22 +3507,13 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody isGetter - returnType: int + await _assertIntrospectText('A', r''' +class A + superclass: Object + methods + foo + flags: hasBody isGetter + returnType: int '''); } @@ -3677,21 +3524,12 @@ class B {} class C implements A, B {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'C'}, -) -class X extends C {} -''', r''' -class X - superclass: C - class C - superclass: Object - interfaces - A - B + await _assertIntrospectText('C', r''' +class C + superclass: Object + interfaces + A + B '''); } @@ -3713,27 +3551,14 @@ library augment 'a.dart'; augment class A {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X + await _assertIntrospectText('A', r''' +class A metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - metadata - IdentifierMetadataAnnotation - identifier: a - IdentifierMetadataAnnotation - identifier: b - superclass: Object + IdentifierMetadataAnnotation + identifier: a + IdentifierMetadataAnnotation + identifier: b + superclass: Object '''); } @@ -3747,26 +3572,13 @@ class A { class B {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'B'}, - withMetadata: true, -) -class X extends B {} -''', r''' -class X + await _assertIntrospectText('B', r''' +class B metadata ConstructorMetadataAnnotation - type: Introspect - superclass: B - class B - metadata - ConstructorMetadataAnnotation - type: A - constructorName: named - superclass: Object + type: A + constructorName: named + superclass: Object '''); } @@ -3784,26 +3596,13 @@ import 'a.dart'; class B {} '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'B'}, - withMetadata: true, -) -class X extends B {} -''', r''' -class X + await _assertIntrospectText('B', uriStr: 'package:test/b.dart', r''' +class B metadata ConstructorMetadataAnnotation - type: Introspect - superclass: B - class B - metadata - ConstructorMetadataAnnotation - type: A - constructorName: named - superclass: Object + type: A + constructorName: named + superclass: Object '''); } @@ -3821,26 +3620,13 @@ import 'a.dart' as prefix; class B {} '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'B'}, - withMetadata: true, -) -class X extends B {} -''', r''' -class X + await _assertIntrospectText('B', uriStr: 'package:test/b.dart', r''' +class B metadata ConstructorMetadataAnnotation - type: Introspect - superclass: B - class B - metadata - ConstructorMetadataAnnotation - type: A - constructorName: named - superclass: Object + type: A + constructorName: named + superclass: Object '''); } @@ -3854,25 +3640,12 @@ class A { class B {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'B'}, - withMetadata: true, -) -class X extends B {} -''', r''' -class X + await _assertIntrospectText('B', r''' +class B metadata ConstructorMetadataAnnotation - type: Introspect - superclass: B - class B - metadata - ConstructorMetadataAnnotation - type: A - superclass: Object + type: A + superclass: Object '''); } @@ -3890,25 +3663,12 @@ import 'a.dart'; class B {} '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'B'}, - withMetadata: true, -) -class X extends B {} -''', r''' -class X + await _assertIntrospectText('B', uriStr: 'package:test/b.dart', r''' +class B metadata ConstructorMetadataAnnotation - type: Introspect - superclass: B - class B - metadata - ConstructorMetadataAnnotation - type: A - superclass: Object + type: A + superclass: Object '''); } @@ -3926,25 +3686,12 @@ import 'a.dart' as prefix; class B {} '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'B'}, - withMetadata: true, -) -class X extends B {} -''', r''' -class X + await _assertIntrospectText('B', uriStr: 'package:test/b.dart', r''' +class B metadata ConstructorMetadataAnnotation - type: Introspect - superclass: B - class B - metadata - ConstructorMetadataAnnotation - type: A - superclass: Object + type: A + superclass: Object '''); } @@ -3956,25 +3703,12 @@ const a = 0; class A {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X + await _assertIntrospectText('A', r''' +class A metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - metadata - IdentifierMetadataAnnotation - identifier: a - superclass: Object + IdentifierMetadataAnnotation + identifier: a + superclass: Object '''); } @@ -3990,25 +3724,12 @@ import 'a.dart'; class A {} '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X + await _assertIntrospectText('A', uriStr: 'package:test/b.dart', r''' +class A metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - metadata - IdentifierMetadataAnnotation - identifier: a - superclass: Object + IdentifierMetadataAnnotation + identifier: a + superclass: Object '''); } @@ -4024,25 +3745,12 @@ import 'a.dart' as prefix; class A {} '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X + await _assertIntrospectText('A', uriStr: 'package:test/b.dart', r''' +class A metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - metadata - IdentifierMetadataAnnotation - identifier: a - superclass: Object + IdentifierMetadataAnnotation + identifier: a + superclass: Object '''); } @@ -4053,22 +3761,13 @@ abstract class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - flags: hasAbstract - superclass: Object - methods - foo - returnType: void + await _assertIntrospectText('A', r''' +class A + flags: hasAbstract + superclass: Object + methods + foo + returnType: void '''); } @@ -4079,22 +3778,13 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody hasExternal - returnType: void + await _assertIntrospectText('A', r''' +class A + superclass: Object + methods + foo + flags: hasBody hasExternal + returnType: void '''); } @@ -4105,22 +3795,13 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody isStatic - returnType: void + await _assertIntrospectText('A', r''' +class A + superclass: Object + methods + foo + flags: hasBody isStatic + returnType: void '''); } @@ -4138,29 +3819,16 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X - metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody - metadata - IdentifierMetadataAnnotation - identifier: a - returnType: void + await _assertIntrospectText('A', uriStr: 'package:test/b.dart', r''' +class A + superclass: Object + methods + foo + flags: hasBody + metadata + IdentifierMetadataAnnotation + identifier: a + returnType: void '''); } @@ -4171,29 +3839,20 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody - namedParameters - a - flags: isNamed isRequired - type: int - b - flags: isNamed - type: String? - returnType: void + await _assertIntrospectText('A', r''' +class A + superclass: Object + methods + foo + flags: hasBody + namedParameters + a + flags: isNamed isRequired + type: int + b + flags: isNamed + type: String? + returnType: void '''); } @@ -4210,33 +3869,20 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X - metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody - namedParameters - x - flags: isNamed isRequired - metadata - IdentifierMetadataAnnotation - identifier: a - type: int - returnType: void + await _assertIntrospectText('A', uriStr: 'package:test/b.dart', r''' +class A + superclass: Object + methods + foo + flags: hasBody + namedParameters + x + flags: isNamed isRequired + metadata + IdentifierMetadataAnnotation + identifier: a + type: int + returnType: void '''); } @@ -4247,28 +3893,19 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody - positionalParameters - a - flags: isRequired - type: int - b - type: String? - returnType: void + await _assertIntrospectText('A', r''' +class A + superclass: Object + methods + foo + flags: hasBody + positionalParameters + a + flags: isRequired + type: int + b + type: String? + returnType: void '''); } @@ -4285,33 +3922,20 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X - metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody - positionalParameters - x - flags: isRequired - metadata - IdentifierMetadataAnnotation - identifier: a - type: int - returnType: void + await _assertIntrospectText('A', uriStr: 'package:test/b.dart', r''' +class A + superclass: Object + methods + foo + flags: hasBody + positionalParameters + x + flags: isRequired + metadata + IdentifierMetadataAnnotation + identifier: a + type: int + returnType: void '''); } @@ -4332,25 +3956,16 @@ augment class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody - returnType: void - bar - flags: hasBody - returnType: void + await _assertIntrospectText('A', r''' +class A + superclass: Object + methods + foo + flags: hasBody + returnType: void + bar + flags: hasBody + returnType: void '''); } @@ -4361,21 +3976,12 @@ mixin M2 {} class C with M1, M2 {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'C'}, -) -class X extends C {} -''', r''' -class X - superclass: C - class C - superclass: Object - mixins - M1 - M2 + await _assertIntrospectText('C', r''' +class C + superclass: Object + mixins + M1 + M2 '''); } @@ -4386,26 +3992,17 @@ class A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - methods - foo - flags: hasBody isSetter - positionalParameters - value - flags: isRequired - type: int - returnType: void + await _assertIntrospectText('A', r''' +class A + superclass: Object + methods + foo + flags: hasBody isSetter + positionalParameters + value + flags: isRequired + type: int + returnType: void '''); } @@ -4415,24 +4012,11 @@ class A {} class B extends A {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A', 'B'}, -) -class X extends B {} -''', r''' -class X - superclass: B - class B - superclass: A - class A - superclass: Object - typeParameters - T - typeParameters - U + await _assertIntrospectText('B', r''' +class B + superclass: A + typeParameters + U '''); } @@ -4441,22 +4025,13 @@ class X class A> {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X extends A {} -''', r''' -class X - superclass: A - class A - superclass: Object - typeParameters - T - U - bound: List + await _assertIntrospectText('A', r''' +class A + superclass: Object + typeParameters + T + U + bound: List '''); } @@ -4467,24 +4042,14 @@ mixin A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X with A {} -''', r''' -class X - mixins - A - mixin A - superclassConstraints - Object - fields - foo - flags: hasFinal - type: int + await _assertIntrospectText('A', r''' +mixin A + superclassConstraints + Object + fields + foo + flags: hasFinal + type: int '''); } @@ -4498,30 +4063,16 @@ mixin A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X with A {} -''', r''' -class X - metadata - ConstructorMetadataAnnotation - type: Introspect - mixins - A - mixin A - superclassConstraints - Object - fields - foo - metadata - IdentifierMetadataAnnotation - identifier: a - type: int? + await _assertIntrospectText('A', r''' +mixin A + superclassConstraints + Object + fields + foo + metadata + IdentifierMetadataAnnotation + identifier: a + type: int? '''); } @@ -4539,30 +4090,16 @@ mixin A { } '''); - await _assertIntrospectText(r''' -import 'b.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X with A {} -''', r''' -class X - metadata - ConstructorMetadataAnnotation - type: Introspect - mixins - A - mixin A - superclassConstraints - Object - fields - foo - metadata - IdentifierMetadataAnnotation - identifier: a - type: int? + await _assertIntrospectText('A', uriStr: 'package:test/b.dart', r''' +mixin A + superclassConstraints + Object + fields + foo + metadata + IdentifierMetadataAnnotation + identifier: a + type: int? '''); } @@ -4573,24 +4110,14 @@ mixin A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X with A {} -''', r''' -class X - mixins - A - mixin A - superclassConstraints - Object - methods - foo - flags: hasBody isGetter - returnType: int + await _assertIntrospectText('A', r''' +mixin A + superclassConstraints + Object + methods + foo + flags: hasBody isGetter + returnType: int '''); } @@ -4612,28 +4139,15 @@ library augment 'a.dart'; augment mixin A {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X extends A {} -''', r''' -class X + await _assertIntrospectText('A', r''' +mixin A metadata - ConstructorMetadataAnnotation - type: Introspect - superclass: A - mixin A - metadata - IdentifierMetadataAnnotation - identifier: a - IdentifierMetadataAnnotation - identifier: b - superclassConstraints - Object + IdentifierMetadataAnnotation + identifier: a + IdentifierMetadataAnnotation + identifier: b + superclassConstraints + Object '''); } @@ -4645,27 +4159,13 @@ const a = 0; mixin A {} '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, - withMetadata: true, -) -class X with A {} -''', r''' -class X + await _assertIntrospectText('A', r''' +mixin A metadata - ConstructorMetadataAnnotation - type: Introspect - mixins - A - mixin A - metadata - IdentifierMetadataAnnotation - identifier: a - superclassConstraints - Object + IdentifierMetadataAnnotation + identifier: a + superclassConstraints + Object '''); } @@ -4676,24 +4176,14 @@ mixin A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X with A {} -''', r''' -class X - mixins - A - mixin A - superclassConstraints - Object - methods - foo - flags: hasBody - returnType: void + await _assertIntrospectText('A', r''' +mixin A + superclassConstraints + Object + methods + foo + flags: hasBody + returnType: void '''); } @@ -4704,36 +4194,75 @@ mixin A { } '''); - await _assertIntrospectText(r''' -import 'a.dart'; - -@Introspect( - withDetailsFor: {'A'}, -) -class X with A {} -''', r''' -class X - mixins - A - mixin A - superclassConstraints - Object - methods - foo - flags: hasBody isSetter - positionalParameters - value - flags: isRequired - type: int - returnType: void + await _assertIntrospectText('A', r''' +mixin A + superclassConstraints + Object + methods + foo + flags: hasBody isSetter + positionalParameters + value + flags: isRequired + type: int + returnType: void '''); } - /// Checks the textual dump of the introspection information in [code]. - Future _assertIntrospectText(String code, String expected) async { - var actual = await _getIntrospectText(code); + test_unit_function() async { + newFile('$testPackageLibPath/a.dart', r''' +void foo() {} +'''); + + await _assertIntrospectText('foo', r''' +foo + flags: hasBody + returnType: void +'''); + } + + Future _assertIntrospectText( + String name, + String expected, { + String uriStr = 'package:test/a.dart', + bool withUnnamedConstructor = false, + }) async { + newFile( + '$testPackageLibPath/introspect.dart', + _getMacroCode('introspect.dart'), + ); + + var library = await buildLibrary(''' +import '$uriStr'; +import 'introspect.dart'; + +@IntrospectDeclaration( + uriStr: '$uriStr', + name: '$name', + withUnnamedConstructor: $withUnnamedConstructor, +) +void _starter() {} +'''); + + if (library.macroDiagnostics.isNotEmpty) { + failWithLibraryText(library); + } + + final generated = _getMacroGeneratedCode(library); + + final regExp = RegExp(r'=> r"""(.+)""";', dotAll: true); + final match = regExp.firstMatch(generated); + final actual = match?.group(1); + + if (actual == null) { + print('-------- Generated --------'); + print('$generated---------------------------'); + fail('No introspection result.'); + } + if (actual != expected) { - print(actual); + print('-------- Actual --------'); + print('$actual------------------------'); NodeTextExpectationsCollector.add(actual); } expect(actual, expected);