Macro. Support for TypeAliasDeclaration.

Change-Id: I4b85cfaf154591434729ba9ad5f94a6cfc2d1033
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/354060
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Jake Macdonald <jakemac@google.com>
This commit is contained in:
Konstantin Shcheglov 2024-02-23 19:55:10 +00:00 committed by Commit Queue
parent 9fa1c16029
commit 9018d41706
25 changed files with 399 additions and 7 deletions

View file

@ -264,3 +264,22 @@ abstract interface class ExtensionTypeDefinitionMacro implements Macro {
FutureOr<void> buildDefinitionForExtensionType(
ExtensionTypeDeclaration extension, TypeDefinitionBuilder builder);
}
/// The interface for [Macro]s that can be applied to any type alias
/// declaration, and want to contribute new type declarations to the program.
abstract interface class TypeAliasTypesMacro implements Macro {
FutureOr<void> buildTypesForTypeAlias(
TypeAliasDeclaration declaration,
TypeBuilder builder,
);
}
/// The interface for [Macro]s that can be applied to any type alias
/// declaration, and want to contribute new non-type declarations to the
/// program.
abstract interface class TypeAliasDeclarationsMacro implements Macro {
FutureOr<void> buildDeclarationsForTypeAlias(
TypeAliasDeclaration declaration,
DeclarationBuilder builder,
);
}

View file

@ -204,6 +204,7 @@ enum DeclarationKind {
library,
method,
mixinType,
typeAlias,
variable,
}

View file

@ -54,6 +54,8 @@ Future<MacroExecutionResult> executeTypesMacro(
target.identifier as IdentifierImpl, introspector));
case (EnumValueDeclaration target, EnumValueTypesMacro macro):
await macro.buildTypesForEnumValue(target, typeBuilder);
case (TypeAliasDeclaration target, TypeAliasTypesMacro macro):
await macro.buildTypesForTypeAlias(target, typeBuilder);
default:
throw new UnsupportedError('Unsupported macro type or invalid target:\n'
'macro: $macro\ntarget: $target');
@ -132,6 +134,8 @@ Future<MacroExecutionResult> executeDeclarationsMacro(Macro macro,
await macro.buildDeclarationsForFunction(target, topLevelBuilder);
case (VariableDeclaration target, VariableDeclarationsMacro macro):
await macro.buildDeclarationsForVariable(target, topLevelBuilder);
case (TypeAliasDeclaration target, TypeAliasDeclarationsMacro macro):
await macro.buildDeclarationsForTypeAlias(target, topLevelBuilder);
default:
throw new UnsupportedError('Unsupported macro type or invalid target:\n'
'macro: $macro\ntarget: $target');

View file

@ -193,6 +193,20 @@ class MacroInstanceIdentifierImpl implements MacroInstanceIdentifier {
interfaces |= interfaceMask;
}
}
case DeclarationKind.typeAlias:
switch (phase) {
case Phase.types:
if (macro is TypeAliasTypesMacro) {
interfaces |= interfaceMask;
}
case Phase.declarations:
if (macro is TypeAliasDeclarationsMacro) {
interfaces |= interfaceMask;
}
case Phase.definitions:
// Does not have definitions.
break;
}
case DeclarationKind.variable:
switch (phase) {
case Phase.types:

View file

@ -343,6 +343,22 @@ void main() {
'class MyExtensionTypeOnMyClass {}'));
});
test('on type aliases', () async {
var result = await executor.executeTypesPhase(
simpleMacroInstanceId,
Fixtures.myTypeAlias,
TestTypePhaseIntrospector(),
);
expect(result.enumValueAugmentations, isEmpty);
expect(result.typeAugmentations, isEmpty);
expect(
result.libraryAugmentations.single.debugString().toString(),
equalsIgnoringWhitespace(
'class MyTypeAliasAliasedTypeMyClass {}',
),
);
});
test('on mixins', () async {
var result = await executor.executeTypesPhase(
simpleMacroInstanceId,
@ -594,6 +610,23 @@ class LibraryInfo {
expect(result.libraryAugmentations, isEmpty);
});
test('on type aliases', () async {
var result = await executor.executeDeclarationsPhase(
simpleMacroInstanceId,
Fixtures.myTypeAlias,
Fixtures.testDeclarationPhaseIntrospector,
);
expect(result.enumValueAugmentations, isEmpty);
expect(result.libraryAugmentations, hasLength(1));
expect(
result.libraryAugmentations.single.debugString().toString(),
equalsIgnoringWhitespace(
'List<String> get aliasedTypeFieldNames;',
),
);
expect(result.typeAugmentations, isEmpty);
});
test('on mixins', () async {
var result = await executor.executeDeclarationsPhase(
simpleMacroInstanceId,

View file

@ -14,7 +14,8 @@ void main() {
test('shouldExecute', () {
for (var kind in DeclarationKind.values) {
for (var phase in Phase.values) {
var instance = instancesByKindAndPhase[kind]![phase]!;
var instance = instancesByKindAndPhase[kind]?[phase];
if (instance == null) continue;
for (var otherKind in DeclarationKind.values) {
for (var otherPhase in Phase.values) {
var expected = false;
@ -42,7 +43,8 @@ void main() {
test('supportsDeclarationKind', () {
for (var kind in DeclarationKind.values) {
for (var phase in Phase.values) {
var instance = instancesByKindAndPhase[kind]![phase]!;
var instance = instancesByKindAndPhase[kind]?[phase];
if (instance == null) continue;
for (var otherKind in DeclarationKind.values) {
var expected = false;
if (kind == otherKind) {
@ -154,6 +156,12 @@ final Map<DeclarationKind, Map<Phase, MacroInstanceIdentifierImpl>>
Phase.definitions: MacroInstanceIdentifierImpl(
FakeMixinDefinitionMacro(), RemoteInstance.uniqueId),
},
DeclarationKind.typeAlias: {
Phase.types: MacroInstanceIdentifierImpl(
FakeTypeAliasTypesMacro(), RemoteInstance.uniqueId),
Phase.declarations: MacroInstanceIdentifierImpl(
FakeTypeAliasDeclarationsMacro(), RemoteInstance.uniqueId),
},
DeclarationKind.variable: {
Phase.types: MacroInstanceIdentifierImpl(
FakeVariableTypesMacro(), RemoteInstance.uniqueId),
@ -254,3 +262,8 @@ class FakeLibraryDeclarationsMacro extends Fake
class FakeLibraryDefinitionMacro extends Fake
implements LibraryDefinitionMacro {}
class FakeTypeAliasTypesMacro extends Fake implements TypeAliasTypesMacro {}
class FakeTypeAliasDeclarationsMacro extends Fake
implements TypeAliasDeclarationsMacro {}

View file

@ -69,6 +69,8 @@ class SimpleMacro
MixinTypesMacro,
MixinDeclarationsMacro,
MixinDefinitionMacro,
TypeAliasTypesMacro,
TypeAliasDeclarationsMacro,
VariableTypesMacro,
VariableDeclarationsMacro,
VariableDefinitionMacro {
@ -715,6 +717,32 @@ class LibraryInfo {
'];',
]));
}
@override
FutureOr<void> buildTypesForTypeAlias(
TypeAliasDeclaration extensionType, TypeBuilder builder) {
final representationType = extensionType.aliasedType as NamedTypeAnnotation;
final name = '${extensionType.identifier.name}AliasedType'
'${representationType.identifier.name}';
builder.declareType(name, DeclarationCode.fromString('class $name {}'));
}
@override
FutureOr<void> buildDeclarationsForTypeAlias(
TypeAliasDeclaration extensionType, DeclarationBuilder builder) async {
final dartCoreList =
// ignore: deprecated_member_use_from_same_package
await builder.resolveIdentifier(Uri.parse('dart:core'), 'List');
final dartCoreString =
// ignore: deprecated_member_use_from_same_package
await builder.resolveIdentifier(Uri.parse('dart:core'), 'String');
builder.declareInLibrary(DeclarationCode.fromParts([
NamedTypeAnnotationCode(name: dartCoreList, typeArguments: [
NamedTypeAnnotationCode(name: dartCoreString),
]),
' get aliasedTypeFieldNames;',
]));
}
}
Future<FunctionBodyCode> _buildFunctionAugmentation(

View file

@ -687,6 +687,18 @@ class Fixtures {
typeParameters: [],
representationType: myClassType);
static final myTypeAlias = TypeAliasDeclarationImpl(
id: RemoteInstance.uniqueId,
identifier: IdentifierImpl(
id: RemoteInstance.uniqueId,
name: 'MyTypeAlias',
),
library: Fixtures.library,
metadata: [],
typeParameters: [],
aliasedType: myClassType,
);
static final myGeneratedExtensionMethod = MethodDeclarationImpl(
id: RemoteInstance.uniqueId,
identifier:

View file

@ -95,7 +95,7 @@ import 'package:meta/meta.dart';
// TODO(scheglov): Clean up the list of implicitly analyzed files.
class AnalysisDriver {
/// The version of data format, should be incremented on every format change.
static const int DATA_VERSION = 346;
static const int DATA_VERSION = 347;
/// The number of exception contexts allowed to write. Once this field is
/// zero, we stop writing any new exception contexts in this process.

View file

@ -125,6 +125,12 @@ class DeclarationByElementLocator extends UnifyingAstVisitor<void> {
if (node is VariableDeclaration && _hasOffset2(node.name)) {
result = node;
}
} else if (element is TypeAliasElement) {
if (node is GenericTypeAlias) {
if (_hasOffset2(node.name)) {
result = node;
}
}
}
if (result == null) {

View file

@ -6736,7 +6736,7 @@ class TopLevelVariableElementImpl extends PropertyInducingElementImpl
///
/// Clients may not extend, implement or mix-in this class.
class TypeAliasElementImpl extends _ExistingElementImpl
with TypeParameterizedElementMixin
with TypeParameterizedElementMixin, MacroTargetElement
implements TypeAliasElement {
/// Is `true` if the element has direct or indirect reference to itself
/// from anywhere except a class element or type parameter bounds.

View file

@ -932,12 +932,14 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
}
@override
void visitGenericTypeAlias(GenericTypeAlias node) {
void visitGenericTypeAlias(covariant GenericTypeAliasImpl node) {
var element = node.declaredElement as TypeAliasElementImpl;
_checkForBuiltInIdentifierAsName(
node.name, CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME);
_checkForMainFunction1(node.name, node.declaredElement!);
_checkForTypeAliasCannotReferenceItself(
node.name, node.declaredElement as TypeAliasElementImpl);
_reportMacroDiagnostics(element);
super.visitGenericTypeAlias(node);
}
@ -6420,6 +6422,8 @@ class _MacroTypeAnnotationLocationConverter {
TypeAnnotationLocation location,
) {
switch (location) {
case AliasedTypeLocation():
return _aliasedType(location);
case ElementTypeLocation():
var element = location.element;
return libraryVerificationContext.declarationByElement(element);
@ -6442,6 +6446,22 @@ class _MacroTypeAnnotationLocationConverter {
}
}
_MacroSyntacticTypeAnnotationLocation? _aliasedType(
AliasedTypeLocation location,
) {
var nodeLocation = convert(location.parent);
if (nodeLocation == null) {
return null;
}
var node = nodeLocation.entity;
switch (node) {
case GenericTypeAlias():
return nodeLocation.next(node.type);
default:
throw UnimplementedError('${node.runtimeType}');
}
}
_MacroSyntacticTypeAnnotationLocation? _extendsClause(
ExtendsClauseTypeLocation location,
) {

View file

@ -149,6 +149,7 @@ class Tag {
}
enum TypeAnnotationLocationKind {
aliasedType,
element,
extendsClause,
formalParameter,

View file

@ -2378,6 +2378,9 @@ class ResolutionReader {
TypeAnnotationLocation readTypeAnnotationLocation() {
var kind = readEnum(TypeAnnotationLocationKind.values);
switch (kind) {
case TypeAnnotationLocationKind.aliasedType:
var parent = readTypeAnnotationLocation();
return AliasedTypeLocation(parent);
case TypeAnnotationLocationKind.element:
var element = readElement()!;
return ElementTypeLocation(element);
@ -2603,6 +2606,7 @@ class TypeAliasElementLinkedData
element.metadata = reader._readAnnotationList(
unitElement: unitElement,
);
element.macroDiagnostics = reader.readMacroDiagnostics();
_readTypeParameters(reader, element.typeParameters);
element.aliasedElement = reader._readAliasedElement(unitElement);
element.aliasedType = reader.readRequiredType();

View file

@ -647,6 +647,7 @@ class BundleWriter {
TypeAliasElementFlags.write(_sink, element);
_resolutionSink._writeAnnotationList(element.metadata);
_resolutionSink.writeMacroDiagnostics(element.macroDiagnostics);
_writeTypeParameters(element.typeParameters, () {
_resolutionSink._writeAliasedElement(element.aliasedElement);
@ -982,6 +983,9 @@ class ResolutionSink extends _SummaryDataWriter {
void writeTypeAnnotationLocation(TypeAnnotationLocation location) {
switch (location) {
case AliasedTypeLocation():
writeEnum(TypeAnnotationLocationKind.aliasedType);
writeTypeAnnotationLocation(location.parent);
case ElementTypeLocation():
writeEnum(TypeAnnotationLocationKind.element);
writeElement(location.element);

View file

@ -218,8 +218,14 @@ class LibraryMacroApplier {
// TODO(scheglov): implement it
break;
case ast.GenericTypeAliasImpl():
// TODO(scheglov): implement it
break;
await _addAnnotations(
libraryElement: libraryElement,
container: container,
targetNode: declaration,
targetNodeElement: declaration.declaredElement,
targetDeclarationKind: macro.DeclarationKind.typeAlias,
annotations: declaration.metadata,
);
case ast.MixinDeclarationImpl():
final element = declaration.declaredElement!;
final declarationElement = element.augmented?.declaration ?? element;

View file

@ -129,6 +129,8 @@ class DeclarationBuilder {
return fromNode.methodDeclaration(node);
case ast.MixinDeclarationImpl():
return fromNode.mixinDeclaration(node);
case ast.GenericTypeAliasImpl():
return fromNode.typeAliasDeclaration(node);
case ast.VariableDeclaration():
return fromNode.variableDeclaration(node);
}
@ -579,6 +581,9 @@ class DeclarationBuilderFromElement {
final Map<ExecutableElement, MethodDeclarationImpl> _methodMap =
Map.identity();
final Map<TypeAliasElementImpl, TypeAliasDeclarationImpl> _typeAliasMap =
Map.identity();
final Map<TypeParameterElement, macro.TypeParameterDeclarationImpl>
_typeParameterDeclarationMap = Map.identity();
@ -707,6 +712,12 @@ class DeclarationBuilderFromElement {
return _variableMap[element] ??= _topLevelVariableElement(element);
}
macro.TypeAliasDeclarationImpl typeAliasElement(
TypeAliasElementImpl element,
) {
return _typeAliasMap[element] ??= _typeAliasElement(element);
}
/// See [macro.DeclarationPhaseIntrospector.typeDeclarationOf].
macro.TypeDeclarationImpl typeDeclarationOf(Element element) {
switch (element) {
@ -720,6 +731,8 @@ class DeclarationBuilderFromElement {
return extensionTypeElement(element);
case MixinElementImpl():
return mixinElement(element);
case TypeAliasElementImpl():
return typeAliasElement(element);
default:
// TODO(scheglov): other elements
throw macro.MacroImplementationExceptionImpl(
@ -1042,6 +1055,20 @@ class DeclarationBuilderFromElement {
);
}
TypeAliasDeclarationImpl _typeAliasElement(
TypeAliasElementImpl element,
) {
return TypeAliasDeclarationImpl._(
id: macro.RemoteInstance.uniqueId,
element: element,
identifier: identifier(element),
library: library(element),
metadata: _buildMetadata(element),
aliasedType: _dartType(element.aliasedType),
typeParameters: _typeParameterDeclarations(element.typeParameters),
);
}
macro.TypeParameterImpl _typeParameter(
TypeParameterElement element,
) {
@ -1439,6 +1466,22 @@ class DeclarationBuilderFromNode {
);
}
macro.TypeAliasDeclarationImpl typeAliasDeclaration(
ast.GenericTypeAliasImpl node,
) {
final element = node.declaredElement as TypeAliasElementImpl;
return TypeAliasDeclarationImpl._(
id: macro.RemoteInstance.uniqueId,
element: element,
identifier: _declaredIdentifier(node.name, element),
library: library(element),
metadata: _buildMetadata(element),
aliasedType: _typeAnnotationAliasedType(node),
typeParameters: _typeParameterDeclarations(node.typeParameters),
);
}
/// See [macro.DeclarationPhaseIntrospector.typeDeclarationOf].
macro.TypeDeclarationImpl typeDeclarationOf(ast.AstNode node) {
switch (node) {
@ -1791,6 +1834,17 @@ class DeclarationBuilderFromNode {
}
}
macro.TypeAnnotationImpl _typeAnnotationAliasedType(
ast.GenericTypeAliasImpl node,
) {
final element = node.declaredElement as TypeAliasElementImpl;
var location = AliasedTypeLocation(
ElementTypeLocation(element),
);
return _typeAnnotation(node.type, location);
}
macro.TypeAnnotationImpl _typeAnnotationFunctionReturnType(
ast.FunctionDeclaration node,
) {
@ -2206,6 +2260,22 @@ class MixinDeclarationImpl extends macro.MixinDeclarationImpl
});
}
class TypeAliasDeclarationImpl extends macro.TypeAliasDeclarationImpl
implements HasElement {
@override
final TypeAliasElementImpl element;
TypeAliasDeclarationImpl._({
required super.id,
required super.identifier,
required super.library,
required super.metadata,
required super.typeParameters,
required super.aliasedType,
required this.element,
});
}
abstract class TypeAnnotationWithLocation implements macro.TypeAnnotation {
TypeAnnotationLocation get location;
}

View file

@ -5,6 +5,12 @@
import 'package:_fe_analyzer_shared/src/macros/api.dart' as macro;
import 'package:analyzer/dart/element/element.dart';
final class AliasedTypeLocation extends TypeAnnotationLocation {
final TypeAnnotationLocation parent;
AliasedTypeLocation(this.parent);
}
final class ElementTypeLocation extends TypeAnnotationLocation {
final Element element;

View file

@ -273,6 +273,16 @@ typedef F = void Function();
expect(result, isNull);
}
test_genericTypeAlias() async {
await resolveTestCode(r'''
typedef A = List<int>;
''');
var element = findNode.genericTypeAlias('A').declaredElement!;
var result = await getElementDeclaration(element);
var node = result!.node as GenericTypeAlias;
expect(node.name.lexeme, 'A');
}
test_getter_class() async {
await resolveTestCode(r'''
class A {

View file

@ -743,6 +743,19 @@ class A {
]);
}
test_diagnostic_report_atTypeAnnotation_typeAlias_aliasedType() async {
await assertErrorsInCode('''
import 'diagnostic.dart';
@ReportAtTypeAnnotation([
'aliasedType',
])
typedef A = List<int>;
''', [
error(WarningCode.MACRO_WARNING, 85, 9),
]);
}
test_diagnostic_report_contextMessages_superClassMethods() async {
var a = newFile('$testPackageLibPath/a.dart', r'''
class A {

View file

@ -743,6 +743,9 @@ class _ElementWriter {
void _writeMacroDiagnostics(Element e) {
void writeTypeAnnotationLocation(TypeAnnotationLocation location) {
switch (location) {
case AliasedTypeLocation():
writeTypeAnnotationLocation(location.parent);
_sink.writelnWithIndent('AliasedTypeLocation');
case ElementTypeLocation():
_sink.writelnWithIndent('ElementTypeLocation');
_sink.withIndent(() {
@ -1370,6 +1373,8 @@ class _ElementWriter {
_writeReturnType(aliasedElement.returnType);
});
}
_writeMacroDiagnostics(e);
});
_assertNonSyntheticElementSelf(e);

View file

@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:_fe_analyzer_shared/src/macros/api.dart';
/*macro*/ class AskFieldsWillThrow implements ClassDefinitionMacro {
@ -144,6 +146,7 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart';
FunctionDeclarationsMacro,
FieldDeclarationsMacro,
MethodDeclarationsMacro,
TypeAliasDeclarationsMacro,
VariableDeclarationsMacro {
final List<String> pathList;
@ -169,6 +172,11 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart';
await _report(declaration, builder);
}
@override
Future<void> buildDeclarationsForTypeAlias(declaration, builder) async {
await _report(declaration, builder);
}
@override
buildDeclarationsForVariable(declaration, builder) async {
await _report(declaration, builder);
@ -248,6 +256,12 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart';
}
}
if (current is TypeAliasDeclaration) {
if (step == 'aliasedType') {
return current.aliasedType;
}
}
if (current is VariableDeclaration) {
if (step == 'variableType') {
return current.type;

View file

@ -19,6 +19,7 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart';
LibraryDeclarationsMacro,
MethodDeclarationsMacro,
MixinDeclarationsMacro,
TypeAliasDeclarationsMacro,
VariableDeclarationsMacro {
final Set<Object?> withDetailsFor;
final bool withMetadata;
@ -163,6 +164,16 @@ import 'package:_fe_analyzer_shared/src/macros/api.dart';
});
}
@override
Future<void> buildDeclarationsForTypeAlias(
TypeAliasDeclaration declaration,
DeclarationBuilder builder,
) async {
await _write(builder, declaration, (printer) async {
await printer.writeTypeAliasDeclaration(declaration);
});
}
@override
Future<void> buildDeclarationsForVariable(
VariableDeclaration declaration,
@ -438,6 +449,8 @@ class _Printer {
await writeFunctionDeclaration(declaration);
case MixinDeclaration():
await writeMixinDeclaration(declaration);
case TypeAliasDeclaration():
await writeTypeAliasDeclaration(declaration);
case VariableDeclaration():
await writeVariable(declaration);
default:
@ -652,6 +665,24 @@ class _Printer {
});
}
Future<void> writeTypeAliasDeclaration(TypeAliasDeclaration e) async {
if (!shouldWriteDetailsFor(e)) {
return;
}
sink.writelnWithIndent('typedef ${e.identifier.name}');
await sink.withIndent(() async {
await _writeMetadata(e);
await _writeTypeParameters(e.typeParameters);
await _writeNamedTypeAnnotation(
'aliasedType',
e.aliasedType,
);
});
}
Future<void> writeVariable(VariableDeclaration e) async {
sink.writelnWithIndent(e.identifier.name);

View file

@ -6690,6 +6690,44 @@ library
''');
}
test_macroDiagnostics_report_atTypeAnnotation_typeAlias_aliasedType() async {
newFile(
'$testPackageLibPath/diagnostic.dart',
_getMacroCode('diagnostic.dart'),
);
final library = await buildLibrary(r'''
import 'diagnostic.dart';
@ReportAtTypeAnnotation([
'aliasedType',
])
typedef A = List<int>;
''');
configuration
..withConstructors = false
..withMetadata = false;
checkElementText(library, r'''
library
imports
package:test/diagnostic.dart
definingUnit
typeAliases
A @81
aliasedType: List<int>
macroDiagnostics
MacroDiagnostic
message: MacroDiagnosticMessage
message: Reported message
target: TypeAnnotationMacroDiagnosticTarget
ElementTypeLocation
element: self::@typeAlias::A
AliasedTypeLocation
severity: warning
''');
}
test_macroDiagnostics_report_contextMessages() async {
newFile(
'$testPackageLibPath/diagnostic.dart',
@ -9002,6 +9040,17 @@ foo
''');
}
test_unit_typeAlias() async {
newFile('$testPackageLibPath/a.dart', r'''
typedef A = List<int>;
''');
await _assertIntrospectText('A', r'''
typedef A
aliasedType: List<int>
''');
}
test_unit_variable() async {
newFile('$testPackageLibPath/a.dart', r'''
final foo = 0;
@ -11416,6 +11465,16 @@ class A
''');
}
test_typedef_modern_namedType() async {
await _assertIntrospectText(r'''
@Introspect()
typedef X = List<int>;
''', r'''
typedef X
aliasedType: List<int>
''');
}
test_unit_function() async {
await _assertIntrospectText(r'''
@Introspect()

View file

@ -264,3 +264,22 @@ abstract interface class ExtensionTypeDefinitionMacro implements Macro {
FutureOr<void> buildDefinitionForExtensionType(
ExtensionTypeDeclaration extension, TypeDefinitionBuilder builder);
}
/// The interface for [Macro]s that can be applied to any type alias
/// declaration, and want to contribute new type declarations to the program.
abstract interface class TypeAliasTypesMacro implements Macro {
FutureOr<void> buildTypesForTypeAlias(
TypeAliasDeclaration declaration,
TypeBuilder builder,
);
}
/// The interface for [Macro]s that can be applied to any type alias
/// declaration, and want to contribute new non-type declarations to the
/// program.
abstract interface class TypeAliasDeclarationsMacro implements Macro {
FutureOr<void> buildDeclarationsForTypeAlias(
TypeAliasDeclaration declaration,
DeclarationBuilder builder,
);
}