Macro. Introspect MethodDeclaration node.

Change-Id: I2d790cd82586db8686c92b30b7599c332b73a2be
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/331842
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/macro_declarations.dart b/pkg/analyzer/lib/src/summary2/macro_declarations.dart
index f779dcc..8fd21bf 100644
--- a/pkg/analyzer/lib/src/summary2/macro_declarations.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_declarations.dart
@@ -35,7 +35,10 @@
 }
 
 class DeclarationBuilder {
-  final DeclarationBuilderFromNode fromNode = DeclarationBuilderFromNode();
+  final Map<Uri, List<ast.Annotation>> libraryMetadataMap = {};
+
+  late final DeclarationBuilderFromNode fromNode =
+      DeclarationBuilderFromNode(this);
 
   final DeclarationBuilderFromElement fromElement =
       DeclarationBuilderFromElement();
@@ -44,7 +47,6 @@
   /// corresponding elements. So, we can access them uniformly via interfaces,
   /// mixins, etc.
   void transferToElements() {
-    // TODO(scheglov) Make sure that these are only declarations?
     for (final entry in fromNode._namedTypeMap.entries) {
       final element = entry.key.element;
       if (element != null) {
@@ -61,9 +63,13 @@
     for (final entry in fromNode._classMap.entries) {
       final element = entry.key.declaredElement!;
       final declaration = entry.value;
-      declaration.element = element;
       fromElement._classMap[element] = declaration;
     }
+    for (final entry in fromNode._methodMap.entries) {
+      final element = entry.key.declaredElement!;
+      final declaration = entry.value;
+      fromElement._methodMap[element] = declaration;
+    }
   }
 }
 
@@ -76,6 +82,9 @@
 
   final Map<FieldElement, FieldDeclarationImpl> _fieldMap = Map.identity();
 
+  final Map<ExecutableElement, MethodDeclarationImpl> _methodMap =
+      Map.identity();
+
   final Map<TypeParameterElement, macro.TypeParameterDeclarationImpl>
       _typeParameterMap = Map.identity();
 
@@ -103,8 +112,7 @@
           id: macro.RemoteInstance.uniqueId,
           languageVersion:
               macro.LanguageVersionImpl(version.major, version.minor),
-          // TODO: Provide metadata annotations.
-          metadata: const [],
+          metadata: _buildMetadata(element),
           uri: element.library!.source.uri,
           element: element);
       _libraryMap[element.library!] = library;
@@ -112,12 +120,21 @@
     return library;
   }
 
+  macro.MethodDeclarationImpl methodElement(MethodElement element) {
+    return _methodMap[element] ??= _methodElement(element);
+  }
+
   macro.TypeParameterDeclarationImpl typeParameter(
     TypeParameterElement element,
   ) {
     return _typeParameterMap[element] ??= _typeParameter(element);
   }
 
+  List<macro.MetadataAnnotationImpl> _buildMetadata(Element element) {
+    // TODO: Provide metadata annotations.
+    return const [];
+  }
+
   macro.TypeAnnotationImpl _dartType(DartType type) {
     switch (type) {
       case InterfaceType():
@@ -129,20 +146,28 @@
           identifier: identifier(type.element),
           typeArguments: const [],
         );
+      case VoidType():
+        return macro.NamedTypeAnnotationImpl(
+          id: macro.RemoteInstance.uniqueId,
+          identifier: macro.IdentifierImpl(
+            id: macro.RemoteInstance.uniqueId,
+            name: 'void',
+          ),
+          isNullable: false,
+          typeArguments: const [],
+        );
       default:
         throw UnimplementedError('(${type.runtimeType}) $type');
     }
   }
 
   FieldDeclarationImpl _fieldElement(FieldElement element) {
-    assert(!_fieldMap.containsKey(element));
     final enclosingClass = element.enclosingElement as ClassElement;
     return FieldDeclarationImpl(
       id: macro.RemoteInstance.uniqueId,
       identifier: identifier(element),
       library: library(element),
-      // TODO: Provide metadata annotations.
-      metadata: const [],
+      metadata: _buildMetadata(element),
       hasExternal: element.isExternal,
       hasFinal: element.isFinal,
       hasLate: element.isLate,
@@ -163,13 +188,11 @@
 
   IntrospectableClassDeclarationImpl _introspectableClassElement(
       ClassElement element) {
-    assert(!_classMap.containsKey(element));
     return IntrospectableClassDeclarationImpl._(
       id: macro.RemoteInstance.uniqueId,
       identifier: identifier(element),
       library: library(element),
-      // TODO: Provide metadata annotations.
-      metadata: const [],
+      metadata: _buildMetadata(element),
       typeParameters: element.typeParameters.map(_typeParameter).toList(),
       interfaces: element.interfaces.map(_interfaceType).toList(),
       hasAbstract: element.isAbstract,
@@ -181,7 +204,37 @@
       hasSealed: element.isSealed,
       mixins: element.mixins.map(_interfaceType).toList(),
       superclass: element.supertype.mapOrNull(_interfaceType),
-    )..element = element;
+      element: element,
+    );
+  }
+
+  MethodDeclarationImpl _methodElement(MethodElement element) {
+    final enclosingClass = element.enclosingElement as ClassElement;
+    return MethodDeclarationImpl._(
+      element: element,
+      id: macro.RemoteInstance.uniqueId,
+      identifier: identifier(element),
+      library: library(element),
+      metadata: _buildMetadata(element),
+      hasAbstract: false,
+      // hasBody: node.body is! ast.EmptyFunctionBody,
+      hasBody: true,
+      // hasExternal: node.externalKeyword != null,
+      hasExternal: false,
+      // isGetter: node.isGetter,
+      isGetter: false,
+      // isOperator: node.isOperator,
+      isOperator: false,
+      // isSetter: node.isSetter,
+      isSetter: false,
+      // isStatic: node.isStatic,
+      isStatic: element.isStatic,
+      namedParameters: [], // TODO(scheglov) implement
+      positionalParameters: [], // TODO(scheglov) implement
+      returnType: _dartType(element.returnType),
+      typeParameters: element.typeParameters.map(_typeParameter).toList(),
+      definingType: identifier(enclosingClass),
+    );
   }
 
   macro.TypeParameterDeclarationImpl _typeParameter(
@@ -191,14 +244,15 @@
       id: macro.RemoteInstance.uniqueId,
       identifier: identifier(element),
       library: library(element),
-      // TODO: Provide metadata annotations.
-      metadata: const [],
+      metadata: _buildMetadata(element),
       bound: element.bound.mapOrNull(_dartType),
     );
   }
 }
 
 class DeclarationBuilderFromNode {
+  final DeclarationBuilder declarationBuilder;
+
   final Map<ast.NamedType, IdentifierImpl> _namedTypeMap = Map.identity();
 
   final Map<Element, IdentifierImpl> _declaredIdentifierMap = Map.identity();
@@ -210,6 +264,8 @@
   final Map<ast.MethodDeclaration, MethodDeclarationImpl> _methodMap =
       Map.identity();
 
+  DeclarationBuilderFromNode(this.declarationBuilder);
+
   macro.ClassDeclarationImpl classDeclaration(
     ast.ClassDeclaration node,
   ) {
@@ -217,20 +273,26 @@
   }
 
   macro.LibraryImpl library(Element element) {
-    var library = _libraryMap[element.library];
-    if (library == null) {
-      final version = element.library!.languageVersion.effective;
-      library = LibraryImplFromElement(
-          id: macro.RemoteInstance.uniqueId,
-          languageVersion:
-              macro.LanguageVersionImpl(version.major, version.minor),
-          // TODO: Provide metadata annotations.
-          metadata: const [],
-          uri: element.library!.source.uri,
-          element: element);
-      _libraryMap[element.library!] = library;
+    final library = element.library!;
+
+    if (_libraryMap[library] case final result?) {
+      return result;
     }
-    return library;
+
+    final version = library.languageVersion.effective;
+    final uri = library.source.uri;
+    final metadataNodes = declarationBuilder.libraryMetadataMap[uri] ?? [];
+
+    return _libraryMap[library] = LibraryImplFromElement(
+      id: macro.RemoteInstance.uniqueId,
+      languageVersion: macro.LanguageVersionImpl(
+        version.major,
+        version.minor,
+      ),
+      metadata: _buildMetadata(metadataNodes),
+      uri: uri,
+      element: library,
+    );
   }
 
   macro.MethodDeclarationImpl methodDeclaration(
@@ -239,6 +301,13 @@
     return _methodMap[node] ??= _methodDeclaration(node);
   }
 
+  List<macro.MetadataAnnotationImpl> _buildMetadata(
+    List<ast.Annotation> elements,
+  ) {
+    // TODO: Provide metadata annotations.
+    return const [];
+  }
+
   macro.IdentifierImpl _declaredIdentifier(Token name, Element element) {
     return _declaredIdentifierMap[element] ??= _DeclaredIdentifierImpl(
       id: macro.RemoteInstance.uniqueId,
@@ -247,7 +316,32 @@
     );
   }
 
-  macro.FunctionTypeParameterImpl _formalParameter(
+  macro.ParameterDeclarationImpl _formalParameter(ast.FormalParameter node) {
+    if (node is ast.DefaultFormalParameter) {
+      node = node.parameter;
+    }
+
+    final macro.TypeAnnotationImpl typeAnnotation;
+    if (node is ast.SimpleFormalParameter) {
+      typeAnnotation = _typeAnnotation(node.type);
+    } else {
+      throw UnimplementedError('(${node.runtimeType}) $node');
+    }
+
+    final element = node.declaredElement!;
+
+    return macro.ParameterDeclarationImpl(
+      id: macro.RemoteInstance.uniqueId,
+      identifier: _declaredIdentifier(node.name!, element),
+      isNamed: node.isNamed,
+      isRequired: node.isRequired,
+      library: library(element),
+      metadata: _buildMetadata(node.metadata),
+      type: typeAnnotation,
+    );
+  }
+
+  macro.FunctionTypeParameterImpl _functionTypeFormalParameter(
     ast.FormalParameter node,
   ) {
     if (node is ast.DefaultFormalParameter) {
@@ -265,9 +359,8 @@
       id: macro.RemoteInstance.uniqueId,
       isNamed: node.isNamed,
       isRequired: node.isRequired,
+      metadata: _buildMetadata(node.metadata),
       name: node.name?.lexeme,
-      // TODO: Provide metadata annotations.
-      metadata: const [],
       type: typeAnnotation,
     );
   }
@@ -275,13 +368,12 @@
   IntrospectableClassDeclarationImpl _introspectableClassDeclaration(
     ast.ClassDeclaration node,
   ) {
-    assert(!_classMap.containsKey(node));
+    final element = node.declaredElement!;
     return IntrospectableClassDeclarationImpl._(
       id: macro.RemoteInstance.uniqueId,
-      identifier: _declaredIdentifier(node.name, node.declaredElement!),
-      library: library(node.declaredElement!),
-      // TODO: Provide metadata annotations.
-      metadata: const [],
+      identifier: _declaredIdentifier(node.name, element),
+      library: library(element),
+      metadata: _buildMetadata(node.metadata),
       typeParameters: _typeParameters(node.typeParameters),
       interfaces: _namedTypes(node.implementsClause?.interfaces),
       hasAbstract: node.abstractKeyword != null,
@@ -293,27 +385,28 @@
       hasSealed: node.sealedKeyword != null,
       mixins: _namedTypes(node.withClause?.mixinTypes),
       superclass: node.extendsClause?.superclass.mapOrNull(_namedType),
+      element: element,
     );
   }
 
   MethodDeclarationImpl _methodDeclaration(
     ast.MethodDeclaration node,
   ) {
-    assert(!_methodMap.containsKey(node));
-
     // TODO(scheglov) other parents
     final parentNode = node.parent as ast.ClassDeclaration;
     final parentElement = parentNode.declaredElement!;
     final typeElement = parentElement.augmentationTarget ?? parentElement;
     final definingType = _declaredIdentifier(parentNode.name, typeElement);
 
+    final element = node.declaredElement!;
+
     return MethodDeclarationImpl._(
-      element: node.declaredElement as MethodElement,
       id: macro.RemoteInstance.uniqueId,
-      identifier: _declaredIdentifier(node.name, node.declaredElement!),
-      library: library(node.declaredElement!),
-      // TODO: Provide metadata annotations.
-      metadata: const [],
+      definingType: definingType,
+      element: element,
+      identifier: _declaredIdentifier(node.name, element),
+      library: library(element),
+      metadata: _buildMetadata(node.metadata),
       hasAbstract: false,
       hasBody: node.body is! ast.EmptyFunctionBody,
       hasExternal: node.externalKeyword != null,
@@ -321,14 +414,26 @@
       isOperator: node.isOperator,
       isSetter: node.isSetter,
       isStatic: node.isStatic,
-      namedParameters: [], // TODO(scheglov) implement
-      positionalParameters: [], // TODO(scheglov) implement
+      namedParameters: _namedFormalParameters(node.parameters),
+      positionalParameters: _positionalFormalParameters(node.parameters),
       returnType: _typeAnnotation(node.returnType),
       typeParameters: _typeParameters(node.typeParameters),
-      definingType: definingType,
     );
   }
 
+  List<macro.ParameterDeclarationImpl> _namedFormalParameters(
+    ast.FormalParameterList? node,
+  ) {
+    if (node != null) {
+      return node.parameters
+          .where((e) => e.isNamed)
+          .map(_formalParameter)
+          .toList();
+    } else {
+      return const [];
+    }
+  }
+
   macro.NamedTypeAnnotationImpl _namedType(ast.NamedType node) {
     return macro.NamedTypeAnnotationImpl(
       id: macro.RemoteInstance.uniqueId,
@@ -356,6 +461,19 @@
     }
   }
 
+  List<macro.ParameterDeclarationImpl> _positionalFormalParameters(
+    ast.FormalParameterList? node,
+  ) {
+    if (node != null) {
+      return node.parameters
+          .where((e) => e.isPositional)
+          .map(_formalParameter)
+          .toList();
+    } else {
+      return const [];
+    }
+  }
+
   macro.TypeAnnotationImpl _typeAnnotation(ast.TypeAnnotation? node) {
     switch (node) {
       case null:
@@ -368,11 +486,11 @@
           isNullable: node.question != null,
           namedParameters: node.parameters.parameters
               .where((e) => e.isNamed)
-              .map(_formalParameter)
+              .map(_functionTypeFormalParameter)
               .toList(),
           positionalParameters: node.parameters.parameters
               .where((e) => e.isPositional)
-              .map(_formalParameter)
+              .map(_functionTypeFormalParameter)
               .toList(),
           returnType: _typeAnnotation(node.returnType),
           typeParameters: _typeParameters(node.typeParameters),
@@ -402,8 +520,7 @@
       id: macro.RemoteInstance.uniqueId,
       identifier: _declaredIdentifier(node.name, node.declaredElement!),
       library: library(node.declaredElement!),
-      // TODO: Provide metadata annotations.
-      metadata: const [],
+      metadata: _buildMetadata(node.metadata),
       bound: node.bound.mapOrNull(_typeAnnotation),
     );
   }
@@ -456,7 +573,7 @@
 
 class IntrospectableClassDeclarationImpl
     extends macro.IntrospectableClassDeclarationImpl {
-  late final ClassElement element;
+  final ClassElement element;
 
   IntrospectableClassDeclarationImpl._({
     required super.id,
@@ -474,6 +591,7 @@
     required super.hasSealed,
     required super.mixins,
     required super.superclass,
+    required this.element,
   });
 }
 
@@ -502,7 +620,7 @@
 }
 
 class MethodDeclarationImpl extends macro.MethodDeclarationImpl {
-  final MethodElement element;
+  final ExecutableElement element;
 
   MethodDeclarationImpl._({
     required super.id,
@@ -515,12 +633,12 @@
     required super.isGetter,
     required super.isOperator,
     required super.isSetter,
+    required super.isStatic,
     required super.namedParameters,
     required super.positionalParameters,
     required super.returnType,
     required super.typeParameters,
     required super.definingType,
-    required super.isStatic,
     required this.element,
   });
 }
diff --git a/pkg/analyzer/test/src/summary/macro/declaration_text.dart b/pkg/analyzer/test/src/summary/macro/declaration_text.dart
index f0f228d..ea8744a 100644
--- a/pkg/analyzer/test/src/summary/macro/declaration_text.dart
+++ b/pkg/analyzer/test/src/summary/macro/declaration_text.dart
@@ -8,7 +8,8 @@
 
 import 'introspect_shared.dart';
 
-/*macro*/ class DeclarationTextMacro implements ClassTypesMacro {
+/*macro*/ class DeclarationTextMacro
+    implements ClassTypesMacro, MethodTypesMacro {
   const DeclarationTextMacro();
 
   @override
@@ -24,6 +25,20 @@
       ),
     );
   }
+
+  @override
+  FutureOr<void> buildTypesForMethod(method, builder) {
+    final printer = _DeclarationPrinter();
+    printer.writeMethodDeclaration(method);
+    final text = printer._sink.toString();
+
+    builder.declareType(
+      'x',
+      DeclarationCode.fromString(
+        'const x = r"""$text""";',
+      ),
+    );
+  }
 }
 
 class _DeclarationPrinter {
@@ -48,6 +63,43 @@
     });
   }
 
+  void writeIndent() {
+    _sink.write(_indent);
+  }
+
+  /// TODO(scheglov) Copy TreeStringSink here
+  void writeIndentedLine(void Function() f) {
+    writeIndent();
+    f();
+    writeln();
+  }
+
+  void writeln([Object? object = '']) {
+    _sink.writeln(object);
+  }
+
+  void writeMethodDeclaration(MethodDeclaration e) {
+    _writelnWithIndent(e.identifier.name);
+
+    _withIndent(() {
+      _writeFlags({
+        'hasAbstract': e.hasAbstract,
+        'hasBody': e.hasBody,
+        'hasExternal': e.hasExternal,
+        'isGetter': e.isGetter,
+        'isOperator': e.isOperator,
+        'isSetter': e.isSetter,
+        'isStatic': e.isStatic,
+      });
+
+      _writeMetadata(e);
+      _writeNamedFormalParameters(e.namedParameters);
+      _writePositionalFormalParameters(e.positionalParameters);
+      _writeTypeAnnotation('returnType', e.returnType);
+      _writeTypeParameters(e.typeParameters);
+    });
+  }
+
   void _withIndent(void Function() f) {
     var savedIndent = _indent;
     _indent = '$savedIndent  ';
@@ -70,6 +122,30 @@
     }
   }
 
+  void _writeFlags(Map<String, bool> flags) {
+    if (flags.values.any((flag) => flag)) {
+      writeIndentedLine(() {
+        _sink.write('flags:');
+        for (final entry in flags.entries) {
+          if (entry.value) {
+            _sink.write(' ${entry.key}');
+          }
+        }
+      });
+    }
+  }
+
+  void _writeFormalParameter(ParameterDeclaration e) {
+    _writelnWithIndent(e.identifier.name);
+    _withIndent(() {
+      _writeFlags({
+        'isNamed': e.isNamed,
+        'isRequired': e.isRequired,
+      });
+      _writeTypeAnnotation('type', e.type);
+    });
+  }
+
   void _writeIf(bool flag, String str) {
     if (flag) {
       _sink.write(str);
@@ -85,6 +161,26 @@
     _sink.writeln(line);
   }
 
+  void _writeMetadata(Annotatable e) {
+    _writeElements('metadata', e.metadata, _writeMetadataAnnotation);
+  }
+
+  void _writeMetadataAnnotation(MetadataAnnotation e) {
+    // TODO(scheglov) implement
+  }
+
+  void _writeNamedFormalParameters(
+    Iterable<ParameterDeclaration> elements,
+  ) {
+    _writeElements('namedParameters', elements, _writeFormalParameter);
+  }
+
+  void _writePositionalFormalParameters(
+    Iterable<ParameterDeclaration> elements,
+  ) {
+    _writeElements('positionalParameters', elements, _writeFormalParameter);
+  }
+
   void _writeTypeAnnotation(String name, TypeAnnotation? type) {
     _sink.write(_indent);
     _sink.write('$name: ');
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index 460ecb6..dd6c89a 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -1412,8 +1412,116 @@
     return code.replaceAll('/*macro*/', 'macro');
   }
 
+  test_class_methodDeclaration_getter() async {
+    await _assertTypesPhaseIntrospectionText(r'''
+abstract class A {
+  @DeclarationTextMacro()
+  int get foo => 0;
+}
+''', r'''
+foo
+  flags: hasBody isGetter
+  returnType: int
+''');
+  }
+
+  test_class_methodDeclaration_method_hasBody_false() async {
+    await _assertTypesPhaseIntrospectionText(r'''
+abstract class A {
+  @DeclarationTextMacro()
+  void foo();
+}
+''', r'''
+foo
+  returnType: void
+''');
+  }
+
+  test_class_methodDeclaration_method_hasExternal() async {
+    await _assertTypesPhaseIntrospectionText(r'''
+abstract class A {
+  @DeclarationTextMacro()
+  external void foo();
+}
+''', r'''
+foo
+  flags: hasExternal
+  returnType: void
+''');
+  }
+
+  test_class_methodDeclaration_method_isStatic() async {
+    await _assertTypesPhaseIntrospectionText(r'''
+class A {
+  @DeclarationTextMacro()
+  static void foo() {}
+}
+''', r'''
+foo
+  flags: hasBody isStatic
+  returnType: void
+''');
+  }
+
+  test_class_methodDeclaration_method_namedParameters() async {
+    await _assertTypesPhaseIntrospectionText(r'''
+abstract class A {
+  @DeclarationTextMacro()
+  void foo({required int a, String? b}]) {}
+}
+''', r'''
+foo
+  flags: hasBody
+  namedParameters
+    a
+      flags: isNamed isRequired
+      type: int
+    b
+      flags: isNamed
+      type: String?
+  returnType: void
+''');
+  }
+
+  test_class_methodDeclaration_method_positionalParameters() async {
+    await _assertTypesPhaseIntrospectionText(r'''
+abstract class A {
+  @DeclarationTextMacro()
+  void foo(int a, [String? b]) {}
+}
+''', r'''
+foo
+  flags: hasBody
+  positionalParameters
+    a
+      flags: isRequired
+      type: int
+    b
+      type: String?
+  returnType: void
+''');
+  }
+
+  test_class_methodDeclaration_setter() async {
+    await _assertTypesPhaseIntrospectionText(r'''
+abstract class A {
+  @DeclarationTextMacro()
+  set foo(int value) {}
+}
+''', r'''
+foo
+  flags: hasBody isSetter
+  positionalParameters
+    value
+      flags: isRequired
+      type: int
+  returnType: OmittedType
+''');
+  }
+
   test_classDeclaration_interfaces() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A implements B, C<int, String> {}
 ''', r'''
 class A
@@ -1425,6 +1533,7 @@
 
   test_classDeclaration_isAbstract() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 abstract class A {}
 ''', r'''
 abstract class A
@@ -1433,6 +1542,7 @@
 
   test_classDeclaration_mixins() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A with B, C<int, String> {}
 ''', r'''
 class A
@@ -1444,6 +1554,7 @@
 
   test_classDeclaration_superclass() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B {}
 ''', r'''
 class A
@@ -1453,6 +1564,7 @@
 
   test_classDeclaration_superclass_nullable() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<int?> {}
 ''', r'''
 class A
@@ -1462,6 +1574,7 @@
 
   test_classDeclaration_superclass_typeArguments() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<String, List<int>> {}
 ''', r'''
 class A
@@ -1471,6 +1584,7 @@
 
   test_classDeclaration_typeParameters() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A<T, U extends List<T>> {}
 ''', r'''
 class A
@@ -1483,6 +1597,7 @@
 
   test_functionTypeAnnotation_formalParameters_namedOptional_simpleFormalParameter() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<void Function(int a, {int? b, int? c})> {}
 ''', r'''
 class A
@@ -1492,6 +1607,7 @@
 
   test_functionTypeAnnotation_formalParameters_namedRequired_simpleFormalParameter() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<void Function(int a, {required int b, required int c})> {}
 ''', r'''
 class A
@@ -1501,6 +1617,7 @@
 
   test_functionTypeAnnotation_formalParameters_positionalOptional_simpleFormalParameter() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<void Function(int a, [int b, int c])> {}
 ''', r'''
 class A
@@ -1511,6 +1628,7 @@
   /// TODO(scheglov) Tests for unnamed positional formal parameters.
   test_functionTypeAnnotation_formalParameters_positionalRequired_simpleFormalParameter() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<void Function(int a, double b)> {}
 ''', r'''
 class A
@@ -1520,6 +1638,7 @@
 
   test_functionTypeAnnotation_nullable() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<void Function()?> {}
 ''', r'''
 class A
@@ -1529,6 +1648,7 @@
 
   test_functionTypeAnnotation_returnType() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<void Function()> {}
 ''', r'''
 class A
@@ -1538,6 +1658,7 @@
 
   test_functionTypeAnnotation_returnType_omitted() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<Function()> {}
 ''', r'''
 class A
@@ -1547,6 +1668,7 @@
 
   test_functionTypeAnnotation_typeParameters() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends B<void Function<T, U extends num>()> {}
 ''', r'''
 class A
@@ -1556,6 +1678,7 @@
 
   test_namedTypeAnnotation_prefixed() async {
     await _assertTypesPhaseIntrospectionText(r'''
+@DeclarationTextMacro()
 class A extends prefix.B {}
 ''', r'''
 class A
@@ -1597,7 +1720,6 @@
     var library = await buildLibrary('''
 import 'declaration_text.dart';
 
-@DeclarationTextMacro()
 $declarationCode
 ''');