[cfe] Support extension types in macro introspection
Change-Id: I946ba3461ca2ff897cf4c1071b3aa356bf835535
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368102
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
index 8aede22..dcb9ebb 100644
--- a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
+++ b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
@@ -20,4 +20,3 @@
- test/inference/inferred_type_arguments/data/**
- test/inference/inferred_variable_types/data/**
- test/inheritance/data/**
- - test/macros/api/**
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart b/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart
index 1508116..79600f2 100644
--- a/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_data.dart
@@ -47,13 +47,25 @@
class Class4 extends Class1 with Mixin1 {}
@ClassMacro()
-class Class5 extends Class2
+abstract class Class5 extends Class2
with Mixin1, Mixin2
implements Interface1, Interface2 {}
+@MixinMacro()
mixin Mixin1 {}
-mixin Mixin2 {}
+@MixinMacro()
+mixin Mixin2 {
+ var instanceField;
+ static var staticField;
+ get instanceGetter => 42;
+ set instanceSetter(int value) {}
+ static get staticGetter => 42;
+ static set staticSetter(int value) {}
+ instanceMethod() {}
+ abstractMethod();
+ static staticMethod() {}
+}
@ClassMacro()
abstract class Interface1 {}
@@ -66,3 +78,17 @@
@FunctionMacro()
external Class2 topLevelFunction2(Class1 a, [Class2? b]);
+
+@ExtensionTypeMacro()
+extension type ExtensionType1(int i) {
+ ExtensionType1.constructor(this.i);
+ factory ExtensionType1.fact(int i) => ExtensionType1(i);
+ factory ExtensionType1.redirect(int i) = ExtensionType1.constructor;
+ static var staticField;
+ get instanceGetter => 42;
+ set instanceSetter(int value) {}
+ static get staticGetter => 42;
+ static set staticSetter(int value) {}
+ instanceMethod() {}
+ static staticMethod() {}
+}
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart b/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
index 209ea7d..0acf91c 100644
--- a/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_expectations.dart
@@ -41,12 +41,62 @@
'Class5': ClassData(
superclass: 'Class2',
superSuperclass: 'Object',
+ isAbstract: true,
mixins: ['Mixin1', 'Mixin2'],
interfaces: ['Interface1', 'Interface2']),
'Interface1': ClassData(isAbstract: true),
'Interface2': ClassData(isAbstract: true),
};
+const Map<String, MixinData> expectedMixinData = {
+ 'Mixin1': MixinData(),
+ 'Mixin2': MixinData(
+ // TODO(johnniwinther): Should we require a specific order?
+ fieldsOf: [
+ 'instanceField',
+ 'staticField',
+ ],
+ // TODO(johnniwinther): Should we require a specific order?
+ methodsOf: [
+ 'instanceGetter',
+ 'staticGetter',
+ 'instanceMethod',
+ 'abstractMethod',
+ 'staticMethod',
+ 'instanceSetter',
+ 'staticSetter',
+ ],
+ ),
+};
+
+const Map<String, ExtensionTypeData> expectedExtensionTypeData = {
+ 'ExtensionType1': ExtensionTypeData(
+ representationType: NamedTypeData(name: 'int'),
+ // TODO(johnniwinther): Should we require a specific order?
+ fieldsOf: [
+ 'i',
+ 'staticField',
+ ],
+ // TODO(johnniwinther): Should we require a specific order?
+ methodsOf: [
+ 'instanceGetter',
+ 'staticGetter',
+ 'instanceMethod',
+ 'staticMethod',
+ 'instanceSetter',
+ 'staticSetter',
+ ],
+ // TODO(johnniwinther): Should we require a specific order?
+ constructorsOf: [
+ // TODO(johnniwinther): Should we normalize no-name constructor names?
+ '',
+ 'constructor',
+ 'fact',
+ 'redirect',
+ ],
+ ),
+};
+
const Map<String, FunctionData> expectedFunctionData = {
'topLevelFunction1': FunctionData(
returnType: NamedTypeData(name: 'void'),
@@ -187,7 +237,105 @@
'$name.constructorsOf[$i]');
}
}
- // TODO(johnniwinther): Test more properties when there are supported.
+ // TODO(johnniwinther): Test more properties when they are supported.
+ } else {
+ throw 'Unexpected class declaration "${name}"';
+ }
+}
+
+Future<void> checkMixinDeclaration(MixinDeclaration declaration,
+ {DeclarationPhaseIntrospector? introspector}) async {
+ String name = declaration.identifier.name;
+ MixinData? expected = expectedMixinData[name];
+ if (expected != null) {
+ expect(expected.hasBase, declaration.hasBase, '$name.hasBase');
+ if (introspector != null) {
+ List<TypeDeclaration> superClassConstraints = [
+ for (NamedTypeAnnotation superclassConstraint
+ in declaration.superclassConstraints)
+ await introspector.typeDeclarationOf(superclassConstraint.identifier),
+ ];
+ expect(expected.superclassConstraints.length,
+ superClassConstraints.length, '$name.superClassConstraints.length');
+ for (int i = 0; i < superClassConstraints.length; i++) {
+ expect(
+ expected.superclassConstraints[i],
+ superClassConstraints[i].identifier.name,
+ '$name.superClassConstraints[$i]');
+ }
+
+ List<TypeDeclaration> interfaces = [
+ for (NamedTypeAnnotation interface in declaration.interfaces)
+ await introspector.typeDeclarationOf(interface.identifier),
+ ];
+ expect(expected.interfaces.length, interfaces.length,
+ '$name.interfaces.length');
+ for (int i = 0; i < interfaces.length; i++) {
+ expect(expected.interfaces[i], interfaces[i].identifier.name,
+ '$name.interfaces[$i]');
+ }
+ }
+ if (introspector != null) {
+ List<FieldDeclaration> fieldsOf =
+ await introspector.fieldsOf(declaration);
+ expect(
+ expected.fieldsOf.length, fieldsOf.length, '$name.fieldsOf.length');
+ for (int i = 0; i < fieldsOf.length; i++) {
+ expect(expected.fieldsOf[i], fieldsOf[i].identifier.name,
+ '$name.fieldsOf[$i]');
+ }
+
+ List<MethodDeclaration> methodsOf =
+ await introspector.methodsOf(declaration);
+ expect(expected.methodsOf.length, methodsOf.length,
+ '$name.methodsOf.length');
+ for (int i = 0; i < methodsOf.length; i++) {
+ expect(expected.methodsOf[i], methodsOf[i].identifier.name,
+ '$name.methodsOf[$i]');
+ }
+ }
+ // TODO(johnniwinther): Test more properties when they are supported.
+ } else {
+ throw 'Unexpected mixin declaration "${name}"';
+ }
+}
+
+Future<void> checkExtensionTypeDeclaration(ExtensionTypeDeclaration declaration,
+ {DeclarationPhaseIntrospector? introspector}) async {
+ String name = declaration.identifier.name;
+ ExtensionTypeData? expected = expectedExtensionTypeData[name];
+ if (expected != null) {
+ checkTypeAnnotation(expected.representationType,
+ declaration.representationType, '$name.representationType');
+ if (introspector != null) {
+ List<FieldDeclaration> fieldsOf =
+ await introspector.fieldsOf(declaration);
+ expect(
+ expected.fieldsOf.length, fieldsOf.length, '$name.fieldsOf.length');
+ for (int i = 0; i < fieldsOf.length; i++) {
+ expect(expected.fieldsOf[i], fieldsOf[i].identifier.name,
+ '$name.fieldsOf[$i]');
+ }
+
+ List<MethodDeclaration> methodsOf =
+ await introspector.methodsOf(declaration);
+ expect(expected.methodsOf.length, methodsOf.length,
+ '$name.methodsOf.length');
+ for (int i = 0; i < methodsOf.length; i++) {
+ expect(expected.methodsOf[i], methodsOf[i].identifier.name,
+ '$name.methodsOf[$i]');
+ }
+
+ List<ConstructorDeclaration> constructorsOf =
+ await introspector.constructorsOf(declaration);
+ expect(expected.constructorsOf.length, constructorsOf.length,
+ '$name.constructorsOf.length');
+ for (int i = 0; i < constructorsOf.length; i++) {
+ expect(expected.constructorsOf[i], constructorsOf[i].identifier.name,
+ '$name.constructorsOf[$i]');
+ }
+ }
+ // TODO(johnniwinther): Test more properties when they are supported.
} else {
throw 'Unexpected class declaration "${name}"';
}
@@ -232,9 +380,11 @@
Future<void> check(Uri uri, String name, {bool expectThrows = false}) async {
if (expectThrows) {
await throws(() async {
+ // ignore: deprecated_member_use
await introspector.resolveIdentifier(uri, name);
}, '$name from $uri');
} else {
+ // ignore: deprecated_member_use
Identifier result = await introspector.resolveIdentifier(uri, name);
expect(name, result.name, '$name from $uri');
}
@@ -265,7 +415,8 @@
await introspector.typeDeclarationOf(identifier);
}, '$name from $identifier',
expectedError: (e) => e is! MacroImplementationException
- ? 'Expected MacroImplementationException, got ${e.runtimeType}: $e'
+ ? 'Expected MacroImplementationException, got ${e.runtimeType}: '
+ '$e'
: null);
} else {
TypeDeclaration result = await introspector.typeDeclarationOf(identifier);
@@ -302,6 +453,34 @@
this.constructorsOf = const []});
}
+class MixinData {
+ final bool hasBase;
+ final List<String> interfaces;
+ final List<String> superclassConstraints;
+ final List<String> fieldsOf;
+ final List<String> methodsOf;
+
+ const MixinData(
+ {this.hasBase = false,
+ this.interfaces = const [],
+ this.superclassConstraints = const [],
+ this.fieldsOf = const [],
+ this.methodsOf = const []});
+}
+
+class ExtensionTypeData {
+ final TypeData representationType;
+ final List<String> fieldsOf;
+ final List<String> methodsOf;
+ final List<String> constructorsOf;
+
+ const ExtensionTypeData(
+ {required this.representationType,
+ this.fieldsOf = const [],
+ this.methodsOf = const [],
+ this.constructorsOf = const []});
+}
+
class FunctionData {
final bool isAbstract;
final bool isExternal;
@@ -333,8 +512,7 @@
final String? name;
final List<TypeData>? typeArguments;
- const NamedTypeData({bool isNullable = false, this.name, this.typeArguments})
- : super(isNullable: isNullable);
+ const NamedTypeData({super.isNullable, this.name, this.typeArguments});
}
class ParameterData {
diff --git a/pkg/_fe_analyzer_shared/test/macros/api/api_test_macro.dart b/pkg/_fe_analyzer_shared/test/macros/api/api_test_macro.dart
index fa20e54..c05a9f0 100644
--- a/pkg/_fe_analyzer_shared/test/macros/api/api_test_macro.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/api/api_test_macro.dart
@@ -2,29 +2,32 @@
// 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.
+// ignore_for_file: experiment_not_enabled
+
import 'dart:async';
import 'package:macros/macros.dart';
import 'api_test_expectations.dart';
-macro
-
-class ClassMacro
+macro class ClassMacro
implements ClassTypesMacro, ClassDeclarationsMacro, ClassDefinitionMacro {
const ClassMacro();
+ @override
FutureOr<void> buildTypesForClass(ClassDeclaration clazz,
TypeBuilder builder) async {
await checkClassDeclaration(clazz);
}
- FutureOr<void> buildDeclarationsForClass(
- ClassDeclaration clazz, MemberDeclarationBuilder builder) async {
+ @override
+ FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
+ MemberDeclarationBuilder builder) async {
await checkClassDeclaration(
- clazz, introspector: builder);
+ clazz, introspector: builder);
}
- FutureOr<void> buildDefinitionForClass(
- ClassDeclaration clazz, TypeDefinitionBuilder builder) async {
+ @override
+ FutureOr<void> buildDefinitionForClass(ClassDeclaration clazz,
+ TypeDefinitionBuilder builder) async {
await checkClassDeclaration(clazz, introspector: builder);
await checkIdentifierResolver(builder);
await checkTypeDeclarationResolver(builder,
@@ -32,27 +35,88 @@
}
}
-macro
+macro class MixinMacro
+ implements MixinTypesMacro, MixinDeclarationsMacro, MixinDefinitionMacro {
+ const MixinMacro();
-class FunctionMacro
+ @override
+ FutureOr<void> buildTypesForMixin(MixinDeclaration mixin,
+ MixinTypeBuilder builder) async {
+ await checkMixinDeclaration(mixin);
+ }
+
+ @override
+ FutureOr<void> buildDeclarationsForMixin(MixinDeclaration mixin,
+ MemberDeclarationBuilder builder) async {
+ await checkMixinDeclaration(
+ mixin, introspector: builder);
+ }
+
+ @override
+ FutureOr<void> buildDefinitionForMixin(MixinDeclaration mixin,
+ TypeDefinitionBuilder builder) async {
+ await checkMixinDeclaration(mixin, introspector: builder);
+ await checkIdentifierResolver(builder);
+ await checkTypeDeclarationResolver(builder,
+ {mixin.identifier: mixin.identifier.name});
+ }
+}
+
+macro class ExtensionTypeMacro
+ implements
+ ExtensionTypeTypesMacro,
+ ExtensionTypeDeclarationsMacro,
+ ExtensionTypeDefinitionMacro {
+ const ExtensionTypeMacro();
+
+ @override
+ FutureOr<void> buildTypesForExtensionType(
+ ExtensionTypeDeclaration extensionType,
+ TypeBuilder builder) async {
+ await checkExtensionTypeDeclaration(extensionType);
+ }
+
+ @override
+ FutureOr<void> buildDeclarationsForExtensionType(
+ ExtensionTypeDeclaration extensionType,
+ MemberDeclarationBuilder builder) async {
+ await checkExtensionTypeDeclaration(
+ extensionType, introspector: builder);
+ }
+
+ @override
+ FutureOr<void> buildDefinitionForExtensionType(
+ ExtensionTypeDeclaration extensionType,
+ TypeDefinitionBuilder builder) async {
+ await checkExtensionTypeDeclaration(extensionType, introspector: builder);
+ await checkIdentifierResolver(builder);
+ await checkTypeDeclarationResolver(builder,
+ {extensionType.identifier: extensionType.identifier.name});
+ }
+}
+
+macro class FunctionMacro
implements
FunctionTypesMacro,
FunctionDeclarationsMacro,
FunctionDefinitionMacro {
const FunctionMacro();
+ @override
FutureOr<void> buildTypesForFunction(FunctionDeclaration function,
TypeBuilder builder) async {
checkFunctionDeclaration(function);
await checkIdentifierResolver(builder);
}
+ @override
FutureOr<void> buildDeclarationsForFunction(FunctionDeclaration function,
DeclarationBuilder builder) async {
checkFunctionDeclaration(function);
await checkIdentifierResolver(builder);
}
+ @override
FutureOr<void> buildDefinitionForFunction(FunctionDeclaration function,
FunctionDefinitionBuilder builder) async {
checkFunctionDeclaration(function);
diff --git a/pkg/front_end/lib/src/fasta/builder/augmentation_iterator.dart b/pkg/front_end/lib/src/fasta/builder/augmentation_iterator.dart
new file mode 100644
index 0000000..2389b44
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/builder/augmentation_iterator.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+/// Iterator for iterating through an origin and all its augmentations.
+class AugmentationIterator<T> implements Iterator<T> {
+ final T _origin;
+ final List<T>? _augmentations;
+ Iterator<T>? _augmentationsIterator;
+ T? _current;
+
+ AugmentationIterator(this._origin, this._augmentations);
+
+ @override
+ T get current =>
+ _augmentationsIterator?.current ??
+ _current ??
+ (throw new StateError('No element'));
+
+ @override
+ bool moveNext() {
+ if (_augmentationsIterator == null) {
+ if (_current == null) {
+ _current = _origin;
+ return true;
+ }
+ _augmentationsIterator =
+ _augmentations?.iterator ?? const Iterable<Never>.empty().iterator;
+ }
+ return _augmentationsIterator!.moveNext();
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index a36d3fd..a3a7529 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -382,13 +382,17 @@
loader.resolveConstructors(augmentationLibraries);
}
- Future<void> _applyMacroPhase2(MacroApplications macroApplications,
- List<SourceClassBuilder> sortedSourceClassBuilders) async {
+ Future<void> _applyMacroPhase2(
+ MacroApplications macroApplications,
+ List<SourceClassBuilder> sortedSourceClassBuilders,
+ List<SourceExtensionTypeDeclarationBuilder>
+ sortedSourceExtensionTypeBuilders) async {
benchmarker?.enterPhase(BenchmarkPhases.outline_applyDeclarationMacros);
macroApplications.enterDeclarationsMacroPhase(loader.hierarchyBuilder);
Future<void> applyDeclarationMacros() async {
- await macroApplications.applyDeclarationsMacros(sortedSourceClassBuilders,
+ await macroApplications.applyDeclarationsMacros(
+ sortedSourceClassBuilders, sortedSourceExtensionTypeBuilders,
(SourceLibraryBuilder augmentationLibrary) async {
List<SourceLibraryBuilder> augmentationLibraries = [
augmentationLibrary
@@ -503,7 +507,8 @@
underscoreEnumClass);
if (macroApplications != null) {
- await _applyMacroPhase2(macroApplications, sortedSourceClassBuilders);
+ await _applyMacroPhase2(macroApplications, sortedSourceClassBuilders,
+ sortedSourceExtensionTypeBuilders);
}
benchmarker
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro/identifiers.dart b/pkg/front_end/lib/src/fasta/kernel/macro/identifiers.dart
index 169b4e5..e63aaca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro/identifiers.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro/identifiers.dart
@@ -40,14 +40,14 @@
uri = typeDeclarationBuilder.libraryBuilder.origin.importUri;
case TypeAliasBuilder():
uri = typeDeclarationBuilder.libraryBuilder.origin.importUri;
+ case ExtensionTypeDeclarationBuilder():
+ uri = typeDeclarationBuilder.libraryBuilder.origin.importUri;
case NominalVariableBuilder():
// TODO(johnniwinther): Handle this case.
case StructuralVariableBuilder():
// TODO(johnniwinther): Handle this case.
case ExtensionBuilder():
// TODO(johnniwinther): Handle this case.
- case ExtensionTypeDeclarationBuilder():
- // TODO(johnniwinther): Handle this case.
case InvalidTypeDeclarationBuilder():
case BuiltinTypeDeclarationBuilder():
if (name == 'dynamic') {
@@ -72,13 +72,15 @@
switch (typeDeclarationBuilder) {
case ClassBuilder():
return macroIntrospection.getClassDeclaration(typeDeclarationBuilder);
+ case ExtensionTypeDeclarationBuilder():
+ return macroIntrospection
+ .getExtensionTypeDeclaration(typeDeclarationBuilder);
case TypeAliasBuilder():
return macroIntrospection
.getTypeAliasDeclaration(typeDeclarationBuilder);
case NominalVariableBuilder():
case StructuralVariableBuilder():
case ExtensionBuilder():
- case ExtensionTypeDeclarationBuilder():
case InvalidTypeDeclarationBuilder():
case BuiltinTypeDeclarationBuilder():
// TODO(johnniwinther): How should we handle this case?
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro/introspectors.dart b/pkg/front_end/lib/src/fasta/kernel/macro/introspectors.dart
index 1808b2e..ec50958 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro/introspectors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro/introspectors.dart
@@ -36,6 +36,10 @@
Map<ClassBuilder, macro.ParameterizedTypeDeclaration> _classDeclarations = {};
Map<macro.ParameterizedTypeDeclaration, ClassBuilder> _classBuilders = {};
+ Map<ExtensionTypeDeclarationBuilder, macro.ParameterizedTypeDeclaration>
+ _extensionTypeDeclarations = {};
+ Map<macro.ExtensionTypeDeclaration, ExtensionTypeDeclarationBuilder>
+ _extensionTypeBuilders = {};
Map<NominalVariableBuilder, macro.TypeParameterDeclarationImpl>
_typeParameters = {};
Map<TypeAliasBuilder, macro.TypeAliasDeclaration> _typeAliasDeclarations = {};
@@ -65,6 +69,8 @@
_libraries.clear();
_classDeclarations.clear();
_classBuilders.clear();
+ _extensionTypeDeclarations.clear();
+ _extensionTypeBuilders.clear();
_memberDeclarations.clear();
_typeAliasDeclarations.clear();
_declarationOffsets.clear();
@@ -89,6 +95,14 @@
return _classDeclarations[builder] ??= _createClassDeclaration(builder);
}
+ /// Returns the [macro.ParameterizedTypeDeclaration] corresponding to
+ /// [builder].
+ macro.ParameterizedTypeDeclaration getExtensionTypeDeclaration(
+ ExtensionTypeDeclarationBuilder builder) {
+ return _extensionTypeDeclarations[builder] ??=
+ _createExtensionTypeDeclaration(builder);
+ }
+
/// Returns the [macro.TypeAliasDeclaration] corresponding to [builder].
macro.TypeAliasDeclaration getTypeAliasDeclaration(TypeAliasBuilder builder) {
return _typeAliasDeclarations[builder] ??=
@@ -101,6 +115,13 @@
return _classBuilders[declaration]!;
}
+ /// Returns the [ExtensionTypeDeclarationBuilder] corresponding to
+ /// [declaration].
+ ExtensionTypeDeclarationBuilder _getExtensionTypeDeclarationBuilder(
+ macro.ExtensionTypeDeclaration declaration) {
+ return _extensionTypeBuilders[declaration]!;
+ }
+
/// Creates the [macro.Declaration] corresponding to [memberBuilder].
macro.Declaration _createMemberDeclaration(MemberBuilder memberBuilder) {
if (memberBuilder is SourceProcedureBuilder) {
@@ -266,6 +287,31 @@
return declaration;
}
+ macro.ExtensionTypeDeclaration _createExtensionTypeDeclaration(
+ ExtensionTypeDeclarationBuilder builder) {
+ final macro.LibraryImpl library = getLibrary(builder.libraryBuilder);
+ List<macro.TypeParameterDeclarationImpl> typeParameters =
+ _nominalVariableBuildersToDeclarations(
+ builder.libraryBuilder, builder.typeParameters);
+ macro.ExtensionTypeDeclarationImpl declaration =
+ new macro.ExtensionTypeDeclarationImpl(
+ id: macro.RemoteInstance.uniqueId,
+ identifier: new TypeDeclarationBuilderIdentifier(
+ typeDeclarationBuilder: builder,
+ libraryBuilder: builder.libraryBuilder,
+ id: macro.RemoteInstance.uniqueId,
+ name: builder.name),
+ library: library,
+ // TODO: Provide metadata annotations.
+ metadata: const [],
+ typeParameters: typeParameters,
+ representationType: types.getTypeAnnotation(
+ builder.libraryBuilder, builder.declaredRepresentationTypeBuilder),
+ );
+ _extensionTypeBuilders[declaration] = builder;
+ return declaration;
+ }
+
/// Creates the [macro.TypeAliasDeclaration] corresponding to [builder].
macro.TypeAliasDeclaration _createTypeAliasDeclaration(
TypeAliasBuilder builder) {
@@ -360,8 +406,15 @@
List<macro.FormalParameterDeclarationImpl> positionalParameters,
List<macro.FormalParameterDeclarationImpl> namedParameters
) = _createParameters(builder.libraryBuilder, formals);
- macro.ParameterizedTypeDeclaration definingClass =
- getClassDeclaration(builder.classBuilder!);
+ macro.ParameterizedTypeDeclaration definingTypeDeclaration;
+ Builder? parent = builder.parent;
+ if (parent is ClassBuilder) {
+ definingTypeDeclaration = getClassDeclaration(parent);
+ } else if (parent is ExtensionTypeDeclarationBuilder) {
+ definingTypeDeclaration = getExtensionTypeDeclaration(parent);
+ } else {
+ throw new UnsupportedError("Unexpected parent of constructor: $parent");
+ }
macro.ConstructorDeclaration declaration =
new macro.ConstructorDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
@@ -372,7 +425,7 @@
library: getLibrary(builder.libraryBuilder),
// TODO: Provide metadata annotations.
metadata: const [],
- definingType: definingClass.identifier as macro.IdentifierImpl,
+ definingType: definingTypeDeclaration.identifier as macro.IdentifierImpl,
isFactory: builder.isFactory,
// TODO(johnniwinther): Real implementation of hasBody.
hasBody: true,
@@ -398,10 +451,15 @@
List<macro.FormalParameterDeclarationImpl> positionalParameters,
List<macro.FormalParameterDeclarationImpl> namedParameters
) = _createParameters(builder.libraryBuilder, builder.formals);
- macro.ParameterizedTypeDeclaration definingClass =
- // TODO(johnniwinther): Support extension type factories.
- getClassDeclaration(builder.classBuilder!);
-
+ macro.ParameterizedTypeDeclaration definingTypeDeclaration;
+ Builder? parent = builder.parent;
+ if (parent is ClassBuilder) {
+ definingTypeDeclaration = getClassDeclaration(parent);
+ } else if (parent is ExtensionTypeDeclarationBuilder) {
+ definingTypeDeclaration = getExtensionTypeDeclaration(parent);
+ } else {
+ throw new UnsupportedError("Unexpected parent of constructor: $parent");
+ }
macro.ConstructorDeclaration declaration =
new macro.ConstructorDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
@@ -412,7 +470,7 @@
library: getLibrary(builder.libraryBuilder),
// TODO: Provide metadata annotations.
metadata: const [],
- definingType: definingClass.identifier as macro.IdentifierImpl,
+ definingType: definingTypeDeclaration.identifier as macro.IdentifierImpl,
isFactory: builder.isFactory,
// TODO(johnniwinther): Real implementation of hasBody.
hasBody: true,
@@ -437,13 +495,16 @@
List<macro.FormalParameterDeclarationImpl> namedParameters
) = _createParameters(builder.libraryBuilder, builder.formals);
- macro.ParameterizedTypeDeclaration? definingClass = null;
- if (builder.classBuilder != null) {
- definingClass = getClassDeclaration(builder.classBuilder!);
+ macro.ParameterizedTypeDeclaration? definingTypeDeclaration = null;
+ Builder? parent = builder.parent;
+ if (parent is ClassBuilder) {
+ definingTypeDeclaration = getClassDeclaration(parent);
+ } else if (parent is ExtensionTypeDeclarationBuilder) {
+ definingTypeDeclaration = getExtensionTypeDeclaration(parent);
}
final macro.LibraryImpl library = getLibrary(builder.libraryBuilder);
macro.FunctionDeclaration declaration;
- if (definingClass != null) {
+ if (definingTypeDeclaration != null) {
// TODO(johnniwinther): Should static fields be field or variable
// declarations?
declaration = new macro.MethodDeclarationImpl(
@@ -455,7 +516,8 @@
library: library,
// TODO(johnniwinther): Provide metadata annotations.
metadata: const [],
- definingType: definingClass.identifier as macro.IdentifierImpl,
+ definingType:
+ definingTypeDeclaration.identifier as macro.IdentifierImpl,
// TODO(johnniwinther): Real implementation of hasBody.
hasBody: true,
hasExternal: builder.isExternal,
@@ -500,13 +562,16 @@
/// Creates the [macro.VariableDeclaration] corresponding to [builder].
macro.VariableDeclaration _createVariableDeclaration(
SourceFieldBuilder builder) {
- macro.ParameterizedTypeDeclaration? definingClass = null;
- if (builder.classBuilder != null) {
- definingClass = getClassDeclaration(builder.classBuilder!);
+ macro.ParameterizedTypeDeclaration? definingTypeDeclaration = null;
+ Builder? parent = builder.parent;
+ if (parent is ClassBuilder) {
+ definingTypeDeclaration = getClassDeclaration(parent);
+ } else if (parent is ExtensionTypeDeclarationBuilder) {
+ definingTypeDeclaration = getExtensionTypeDeclaration(parent);
}
final macro.LibraryImpl library = getLibrary(builder.libraryBuilder);
macro.VariableDeclaration declaration;
- if (definingClass != null) {
+ if (definingTypeDeclaration != null) {
// TODO(johnniwinther): Should static fields be field or variable
// declarations?
declaration = new macro.FieldDeclarationImpl(
@@ -518,7 +583,8 @@
library: library,
// TODO: Provide metadata annotations.
metadata: const [],
- definingType: definingClass.identifier as macro.IdentifierImpl,
+ definingType:
+ definingTypeDeclaration.identifier as macro.IdentifierImpl,
hasAbstract: builder.isAbstract,
hasConst: builder.isConst,
hasExternal: builder.isExternal,
@@ -666,23 +732,40 @@
@override
Future<List<macro.ConstructorDeclaration>> constructorsOf(
macro.TypeDeclaration type) {
- if (type is! macro.ClassDeclaration) {
- throw new UnsupportedError('Only introspection on classes is supported');
- }
- ClassBuilder classBuilder = _introspection
- ._getClassBuilder(type as macro.ParameterizedTypeDeclaration);
+ // TODO(johnniwinther): Create all member declarations together so that
+ // can assert that all are handled.
List<macro.ConstructorDeclaration> result = [];
- Iterator<MemberBuilder> iterator = classBuilder.fullConstructorIterator();
- while (iterator.moveNext()) {
- MemberBuilder memberBuilder = iterator.current;
- if (memberBuilder is DeclaredSourceConstructorBuilder) {
- // TODO(johnniwinther): Should we support synthesized constructors?
- result.add(_introspection.getMemberDeclaration(memberBuilder)
- as macro.ConstructorDeclaration);
- } else if (memberBuilder is SourceFactoryBuilder) {
- result.add(_introspection.getMemberDeclaration(memberBuilder)
- as macro.ConstructorDeclaration);
+ if (type is macro.ClassDeclaration) {
+ ClassBuilder classBuilder = _introspection._getClassBuilder(type);
+ Iterator<MemberBuilder> iterator = classBuilder.fullConstructorIterator();
+ while (iterator.moveNext()) {
+ MemberBuilder memberBuilder = iterator.current;
+ if (memberBuilder is DeclaredSourceConstructorBuilder) {
+ // TODO(johnniwinther): Should we support synthesized constructors?
+ result.add(_introspection.getMemberDeclaration(memberBuilder)
+ as macro.ConstructorDeclaration);
+ } else if (memberBuilder is SourceFactoryBuilder) {
+ result.add(_introspection.getMemberDeclaration(memberBuilder)
+ as macro.ConstructorDeclaration);
+ }
}
+ } else if (type is macro.ExtensionTypeDeclaration) {
+ ExtensionTypeDeclarationBuilder extensionTypeDeclarationBuilder =
+ _introspection._getExtensionTypeDeclarationBuilder(type);
+ Iterator<MemberBuilder> iterator =
+ extensionTypeDeclarationBuilder.fullConstructorIterator();
+ while (iterator.moveNext()) {
+ MemberBuilder memberBuilder = iterator.current;
+ if (memberBuilder is SourceExtensionTypeConstructorBuilder) {
+ result.add(_introspection.getMemberDeclaration(memberBuilder)
+ as macro.ConstructorDeclaration);
+ } else if (memberBuilder is SourceFactoryBuilder) {
+ result.add(_introspection.getMemberDeclaration(memberBuilder)
+ as macro.ConstructorDeclaration);
+ }
+ }
+ } else {
+ throw new UnsupportedError('Only introspection on classes is supported');
}
return new Future.value(result);
}
@@ -696,35 +779,57 @@
@override
Future<List<macro.FieldDeclaration>> fieldsOf(macro.TypeDeclaration type) {
- if (type is! macro.ClassDeclaration) {
- throw new UnsupportedError('Only introspection on classes is supported');
- }
- ClassBuilder classBuilder = _introspection._getClassBuilder(type);
List<macro.FieldDeclaration> result = [];
- Iterator<SourceFieldBuilder> iterator =
- classBuilder.fullMemberIterator<SourceFieldBuilder>();
- while (iterator.moveNext()) {
- result.add(_introspection.getMemberDeclaration(iterator.current)
- as macro.FieldDeclaration);
+ if (type is macro.ClassDeclaration || type is macro.MixinDeclaration) {
+ ClassBuilder classBuilder = _introspection
+ ._getClassBuilder(type as macro.ParameterizedTypeDeclaration);
+ Iterator<SourceFieldBuilder> iterator =
+ classBuilder.fullMemberIterator<SourceFieldBuilder>();
+ while (iterator.moveNext()) {
+ result.add(_introspection.getMemberDeclaration(iterator.current)
+ as macro.FieldDeclaration);
+ }
+ } else if (type is macro.ExtensionTypeDeclaration) {
+ ExtensionTypeDeclarationBuilder extensionTypeDeclarationBuilder =
+ _introspection._getExtensionTypeDeclarationBuilder(type);
+ Iterator<SourceFieldBuilder> iterator = extensionTypeDeclarationBuilder
+ .fullMemberIterator<SourceFieldBuilder>();
+ while (iterator.moveNext()) {
+ result.add(_introspection.getMemberDeclaration(iterator.current)
+ as macro.FieldDeclaration);
+ }
+ } else {
+ throw new UnsupportedError('Only introspection on classes is supported');
}
return new Future.value(result);
}
@override
Future<List<macro.MethodDeclaration>> methodsOf(macro.TypeDeclaration type) {
- if (type is! macro.ClassDeclaration && type is! macro.MixinDeclaration) {
+ List<macro.MethodDeclaration> result = [];
+ if (type is macro.ClassDeclaration || type is macro.MixinDeclaration) {
+ ClassBuilder classBuilder = _introspection
+ ._getClassBuilder(type as macro.ParameterizedTypeDeclaration);
+ Iterator<SourceProcedureBuilder> iterator =
+ classBuilder.fullMemberIterator<SourceProcedureBuilder>();
+ while (iterator.moveNext()) {
+ result.add(_introspection.getMemberDeclaration(iterator.current)
+ as macro.MethodDeclaration);
+ }
+ } else if (type is macro.ExtensionTypeDeclaration) {
+ ExtensionTypeDeclarationBuilder extensionTypeDeclarationBuilder =
+ _introspection._getExtensionTypeDeclarationBuilder(type);
+ Iterator<SourceProcedureBuilder> iterator =
+ extensionTypeDeclarationBuilder
+ .fullMemberIterator<SourceProcedureBuilder>();
+ while (iterator.moveNext()) {
+ result.add(_introspection.getMemberDeclaration(iterator.current)
+ as macro.MethodDeclaration);
+ }
+ } else {
throw new UnsupportedError(
'Only introspection on classes and mixins is supported');
}
- ClassBuilder classBuilder = _introspection
- ._getClassBuilder(type as macro.ParameterizedTypeDeclaration);
- List<macro.MethodDeclaration> result = [];
- Iterator<SourceProcedureBuilder> iterator =
- classBuilder.fullMemberIterator<SourceProcedureBuilder>();
- while (iterator.moveNext()) {
- result.add(_introspection.getMemberDeclaration(iterator.current)
- as macro.MethodDeclaration);
- }
return new Future.value(result);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
index f501416..af4eb5a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro/macro.dart
@@ -123,6 +123,8 @@
Map<SourceLibraryBuilder, MacroExecutionResultsForTesting> libraryResults =
{};
Map<SourceClassBuilder, MacroExecutionResultsForTesting> classResults = {};
+ Map<SourceExtensionTypeDeclarationBuilder, MacroExecutionResultsForTesting>
+ extensionTypeResults = {};
Map<MemberBuilder, MacroExecutionResultsForTesting> memberResults = {};
List<ApplicationDataForTesting> typesApplicationOrder = [];
@@ -137,6 +139,9 @@
} else if (builder is SourceClassBuilder) {
resultsForTesting =
classResults[builder] ??= new MacroExecutionResultsForTesting();
+ } else if (builder is SourceExtensionTypeDeclarationBuilder) {
+ resultsForTesting = extensionTypeResults[builder] ??=
+ new MacroExecutionResultsForTesting();
} else {
resultsForTesting = memberResults[builder as MemberBuilder] ??=
new MacroExecutionResultsForTesting();
@@ -196,6 +201,8 @@
class LibraryMacroApplicationData {
ApplicationData? libraryApplications;
Map<SourceClassBuilder, ClassMacroApplicationData> classData = {};
+ Map<SourceExtensionTypeDeclarationBuilder, ExtensionTypeMacroApplicationData>
+ extensionTypeData = {};
Map<MemberBuilder, ApplicationData> memberApplications = {};
}
@@ -204,6 +211,11 @@
Map<MemberBuilder, ApplicationData> memberApplications = {};
}
+class ExtensionTypeMacroApplicationData {
+ ApplicationData? extensionTypeApplications;
+ Map<MemberBuilder, ApplicationData> memberApplications = {};
+}
+
/// Macro classes that need to be precompiled.
class NeededPrecompilations {
/// Map from library uris to macro class names and the names of constructor
@@ -290,6 +302,8 @@
}
Map<Class, List<ClassMacroApplicationData>> classData = {};
+ Map<ExtensionTypeDeclaration, List<ExtensionTypeMacroApplicationData>>
+ extensionTypeData = {};
Map<Annotatable, List<ApplicationData>> libraryMemberData = {};
List<LibraryMacroApplicationData>? libraryMacroApplicationDataList =
libraryData[libraryBuilder.library];
@@ -300,6 +314,12 @@
in libraryMacroApplicationData.classData.entries) {
(classData[entry.key.cls] ??= []).add(entry.value);
}
+ for (MapEntry<SourceExtensionTypeDeclarationBuilder,
+ ExtensionTypeMacroApplicationData> entry
+ in libraryMacroApplicationData.extensionTypeData.entries) {
+ (extensionTypeData[entry.key.extensionTypeDeclaration] ??= [])
+ .add(entry.value);
+ }
for (MapEntry<MemberBuilder, ApplicationData> entry
in libraryMacroApplicationData.memberApplications.entries) {
for (Annotatable annotatable in entry.key.annotatables) {
@@ -341,6 +361,38 @@
}
checkMembers(cls.members, classMemberData);
}
+ for (ExtensionTypeDeclaration cls in library.extensionTypeDeclarations) {
+ List<ExtensionTypeMacroApplicationData>? classMacroApplications =
+ extensionTypeData[cls];
+ List<ApplicationData> applicationDataList = [];
+ if (classMacroApplications != null) {
+ for (ExtensionTypeMacroApplicationData classMacroApplicationData
+ in classMacroApplications) {
+ ApplicationData? classApplications =
+ classMacroApplicationData.extensionTypeApplications;
+ if (classApplications != null) {
+ applicationDataList.add(classApplications);
+ }
+ }
+ }
+ checkAnnotations(cls.annotations, applicationDataList,
+ fileUri: cls.fileUri);
+
+ Map<Annotatable, List<ApplicationData>> classMemberData = {};
+ if (classMacroApplications != null) {
+ for (ExtensionTypeMacroApplicationData classMacroApplicationData
+ in classMacroApplications) {
+ for (MapEntry<MemberBuilder, ApplicationData> entry
+ in classMacroApplicationData.memberApplications.entries) {
+ for (Annotatable annotatable in entry.key.annotatables) {
+ (classMemberData[annotatable] ??= []).add(entry.value);
+ }
+ }
+ }
+ }
+ // TODO(johnniwinther): Check member applications.
+ //checkMembers(cls.members, classMemberData);
+ }
}
}
@@ -398,27 +450,26 @@
while (iterator.moveNext()) {
Builder builder = iterator.current;
if (builder is SourceClassBuilder) {
- SourceClassBuilder classBuilder = builder;
ClassMacroApplicationData classMacroApplicationData =
new ClassMacroApplicationData();
List<MacroApplication>? classMacroApplications = prebuildAnnotations(
enclosingLibrary: libraryBuilder,
- scope: classBuilder.scope,
- fileUri: classBuilder.fileUri,
- metadataBuilders: classBuilder.metadata,
+ scope: builder.scope,
+ fileUri: builder.fileUri,
+ metadataBuilders: builder.metadata,
currentMacroDeclarations: currentMacroDeclarations);
if (classMacroApplications != null) {
classMacroApplicationData.classApplications =
new ClassApplicationData(_macroIntrospection, libraryBuilder,
- classBuilder, classMacroApplications);
+ builder, classMacroApplications);
}
- Iterator<Builder> memberIterator = classBuilder.localMemberIterator();
+ Iterator<Builder> memberIterator = builder.localMemberIterator();
while (memberIterator.moveNext()) {
Builder memberBuilder = memberIterator.current;
if (memberBuilder is SourceProcedureBuilder) {
List<MacroApplication>? macroApplications = prebuildAnnotations(
enclosingLibrary: libraryBuilder,
- scope: classBuilder.scope,
+ scope: builder.scope,
fileUri: memberBuilder.fileUri,
metadataBuilders: memberBuilder.metadata,
currentMacroDeclarations: currentMacroDeclarations);
@@ -430,7 +481,7 @@
} else if (memberBuilder is SourceFieldBuilder) {
List<MacroApplication>? macroApplications = prebuildAnnotations(
enclosingLibrary: libraryBuilder,
- scope: classBuilder.scope,
+ scope: builder.scope,
fileUri: memberBuilder.fileUri,
metadataBuilders: memberBuilder.metadata,
currentMacroDeclarations: currentMacroDeclarations);
@@ -445,13 +496,13 @@
}
}
Iterator<MemberBuilder> constructorIterator =
- classBuilder.localConstructorIterator();
+ builder.localConstructorIterator();
while (constructorIterator.moveNext()) {
MemberBuilder memberBuilder = constructorIterator.current;
if (memberBuilder is DeclaredSourceConstructorBuilder) {
List<MacroApplication>? macroApplications = prebuildAnnotations(
enclosingLibrary: libraryBuilder,
- scope: classBuilder.scope,
+ scope: builder.scope,
fileUri: memberBuilder.fileUri,
metadataBuilders: memberBuilder.metadata,
currentMacroDeclarations: currentMacroDeclarations);
@@ -463,7 +514,7 @@
} else if (memberBuilder is SourceFactoryBuilder) {
List<MacroApplication>? macroApplications = prebuildAnnotations(
enclosingLibrary: libraryBuilder,
- scope: classBuilder.scope,
+ scope: builder.scope,
fileUri: memberBuilder.fileUri,
metadataBuilders: memberBuilder.metadata,
currentMacroDeclarations: currentMacroDeclarations);
@@ -507,8 +558,97 @@
new MemberApplicationData(_macroIntrospection, libraryBuilder,
builder, macroApplications);
}
+ } else if (builder is SourceExtensionTypeDeclarationBuilder) {
+ ExtensionTypeMacroApplicationData extensionTypeMacroApplicationData =
+ new ExtensionTypeMacroApplicationData();
+ List<MacroApplication>? classMacroApplications = prebuildAnnotations(
+ enclosingLibrary: libraryBuilder,
+ scope: builder.scope,
+ fileUri: builder.fileUri,
+ metadataBuilders: builder.metadata,
+ currentMacroDeclarations: currentMacroDeclarations);
+ if (classMacroApplications != null) {
+ extensionTypeMacroApplicationData.extensionTypeApplications =
+ new ExtensionTypeApplicationData(_macroIntrospection,
+ libraryBuilder, builder, classMacroApplications);
+ }
+ Iterator<Builder> memberIterator = builder.localMemberIterator();
+ while (memberIterator.moveNext()) {
+ Builder memberBuilder = memberIterator.current;
+ if (memberBuilder is SourceProcedureBuilder) {
+ List<MacroApplication>? macroApplications = prebuildAnnotations(
+ enclosingLibrary: libraryBuilder,
+ scope: builder.scope,
+ fileUri: memberBuilder.fileUri,
+ metadataBuilders: memberBuilder.metadata,
+ currentMacroDeclarations: currentMacroDeclarations);
+ if (macroApplications != null) {
+ extensionTypeMacroApplicationData
+ .memberApplications[memberBuilder] =
+ new MemberApplicationData(_macroIntrospection, libraryBuilder,
+ memberBuilder, macroApplications);
+ }
+ } else if (memberBuilder is SourceFieldBuilder) {
+ List<MacroApplication>? macroApplications = prebuildAnnotations(
+ enclosingLibrary: libraryBuilder,
+ scope: builder.scope,
+ fileUri: memberBuilder.fileUri,
+ metadataBuilders: memberBuilder.metadata,
+ currentMacroDeclarations: currentMacroDeclarations);
+ if (macroApplications != null) {
+ extensionTypeMacroApplicationData
+ .memberApplications[memberBuilder] =
+ new MemberApplicationData(_macroIntrospection, libraryBuilder,
+ memberBuilder, macroApplications);
+ }
+ } else {
+ throw new UnsupportedError("Unexpected class member "
+ "$memberBuilder (${memberBuilder.runtimeType})");
+ }
+ }
+ Iterator<MemberBuilder> constructorIterator =
+ builder.localConstructorIterator();
+ while (constructorIterator.moveNext()) {
+ MemberBuilder memberBuilder = constructorIterator.current;
+ if (memberBuilder is SourceExtensionTypeConstructorBuilder) {
+ List<MacroApplication>? macroApplications = prebuildAnnotations(
+ enclosingLibrary: libraryBuilder,
+ scope: builder.scope,
+ fileUri: memberBuilder.fileUri,
+ metadataBuilders: memberBuilder.metadata,
+ currentMacroDeclarations: currentMacroDeclarations);
+ if (macroApplications != null) {
+ extensionTypeMacroApplicationData
+ .memberApplications[memberBuilder] =
+ new MemberApplicationData(_macroIntrospection, libraryBuilder,
+ memberBuilder, macroApplications);
+ }
+ } else if (memberBuilder is SourceFactoryBuilder) {
+ List<MacroApplication>? macroApplications = prebuildAnnotations(
+ enclosingLibrary: libraryBuilder,
+ scope: builder.scope,
+ fileUri: memberBuilder.fileUri,
+ metadataBuilders: memberBuilder.metadata,
+ currentMacroDeclarations: currentMacroDeclarations);
+ if (macroApplications != null) {
+ extensionTypeMacroApplicationData
+ .memberApplications[memberBuilder] =
+ new MemberApplicationData(_macroIntrospection, libraryBuilder,
+ memberBuilder, macroApplications);
+ }
+ } else {
+ throw new UnsupportedError("Unexpected constructor "
+ "$memberBuilder (${memberBuilder.runtimeType})");
+ }
+ }
+
+ if (extensionTypeMacroApplicationData.extensionTypeApplications !=
+ null ||
+ extensionTypeMacroApplicationData.memberApplications.isNotEmpty) {
+ libraryMacroApplicationData.extensionTypeData[builder] =
+ extensionTypeMacroApplicationData;
+ }
} else if (builder is SourceExtensionBuilder ||
- builder is SourceExtensionTypeDeclarationBuilder ||
builder is SourceTypeAliasBuilder) {
// TODO(johnniwinther): Support macro applications.
} else if (builder is PrefixBuilder) {
@@ -520,6 +660,7 @@
}
if (libraryMacroApplications != null ||
libraryMacroApplicationData.classData.isNotEmpty ||
+ libraryMacroApplicationData.extensionTypeData.isNotEmpty ||
libraryMacroApplicationData.memberApplications.isNotEmpty) {
_libraryData[libraryBuilder] = libraryMacroApplicationData;
dataForTesting?.libraryData[libraryBuilder] = libraryMacroApplicationData;
@@ -624,6 +765,14 @@
await ensureMacroClassIds(applicationData);
}
}
+ for (ExtensionTypeMacroApplicationData extensionTypeData
+ in libraryData.extensionTypeData.values) {
+ await ensureMacroClassIds(extensionTypeData.extensionTypeApplications);
+ for (ApplicationData applicationData
+ in extensionTypeData.memberApplications.values) {
+ await ensureMacroClassIds(applicationData);
+ }
+ }
for (ApplicationData applicationData
in libraryData.memberApplications.values) {
await ensureMacroClassIds(applicationData);
@@ -688,9 +837,8 @@
executionResults.addAll(
await _applyTypeMacros(libraryBuilder.origin, applicationData));
}
- for (MapEntry<ClassBuilder, ClassMacroApplicationData> entry
- in data.classData.entries) {
- ClassMacroApplicationData classApplicationData = entry.value;
+ for (ClassMacroApplicationData classApplicationData
+ in data.classData.values) {
for (ApplicationData applicationData
in classApplicationData.memberApplications.values) {
executionResults.addAll(
@@ -701,6 +849,18 @@
libraryBuilder.origin, classApplicationData.classApplications!));
}
}
+ for (ExtensionTypeMacroApplicationData extensionTypeApplicationData
+ in data.extensionTypeData.values) {
+ for (ApplicationData applicationData
+ in extensionTypeApplicationData.memberApplications.values) {
+ executionResults.addAll(
+ await _applyTypeMacros(libraryBuilder.origin, applicationData));
+ }
+ if (extensionTypeApplicationData.extensionTypeApplications != null) {
+ executionResults.addAll(await _applyTypeMacros(libraryBuilder.origin,
+ extensionTypeApplicationData.extensionTypeApplications!));
+ }
+ }
if (executionResults.isNotEmpty) {
Map<macro.OmittedTypeAnnotation, String> omittedTypes = {};
List<macro.Span> spans = [];
@@ -813,6 +973,8 @@
Future<void> applyDeclarationsMacros(
List<SourceClassBuilder> sortedSourceClassBuilders,
+ List<SourceExtensionTypeDeclarationBuilder>
+ sortedSourceExtensionTypeBuilders,
Future<void> Function(SourceLibraryBuilder) onAugmentationLibrary) async {
// TODO(johnniwinther): Maintain a pending list instead of running through
// all annotations to find the once have to be applied now.
@@ -838,19 +1000,52 @@
// Apply macros to classes first, in class hierarchy order.
for (SourceClassBuilder classBuilder in sortedSourceClassBuilders) {
- await applyClassMacros(classBuilder);
- // TODO(johnniwinther): Avoid accessing augmentations from the outside.
- List<SourceClassBuilder>? augmentationClassBuilders =
- classBuilder.augmentationsForTesting;
- if (augmentationClassBuilders != null) {
- for (SourceClassBuilder augmentationClassBuilder
- in augmentationClassBuilders) {
- await applyClassMacros(augmentationClassBuilder);
- }
+ Iterator<SourceClassBuilder> declarationIterator =
+ classBuilder.declarationIterator;
+ while (declarationIterator.moveNext()) {
+ await applyClassMacros(declarationIterator.current);
}
}
- // Apply macros to library members second.
+ // TODO(johnniwinther): Maintain a pending list instead of running through
+ // all annotations to find the once have to be applied now.
+ Future<void> applyExtensionTypeMacros(
+ SourceExtensionTypeDeclarationBuilder
+ extensionTypeDeclarationBuilder) async {
+ SourceLibraryBuilder libraryBuilder =
+ extensionTypeDeclarationBuilder.libraryBuilder;
+ LibraryMacroApplicationData? libraryApplicationData =
+ _libraryData[libraryBuilder];
+ if (libraryApplicationData == null) return;
+
+ ExtensionTypeMacroApplicationData? extensionTypeApplicationData =
+ libraryApplicationData
+ .extensionTypeData[extensionTypeDeclarationBuilder];
+ if (extensionTypeApplicationData == null) return;
+ for (ApplicationData applicationData
+ in extensionTypeApplicationData.memberApplications.values) {
+ await _applyDeclarationsMacros(
+ libraryBuilder.origin, applicationData, onAugmentationLibrary);
+ }
+ if (extensionTypeApplicationData.extensionTypeApplications != null) {
+ await _applyDeclarationsMacros(
+ libraryBuilder.origin,
+ extensionTypeApplicationData.extensionTypeApplications!,
+ onAugmentationLibrary);
+ }
+ }
+
+ // Apply macros to extension types second, in class hierarchy order.
+ for (SourceExtensionTypeDeclarationBuilder extensionTypeDeclarationBuilder
+ in sortedSourceExtensionTypeBuilders) {
+ Iterator<SourceExtensionTypeDeclarationBuilder> declarationIterator =
+ extensionTypeDeclarationBuilder.declarationIterator;
+ while (declarationIterator.moveNext()) {
+ await applyExtensionTypeMacros(declarationIterator.current);
+ }
+ }
+
+ // Apply macros to library members third.
for (MapEntry<SourceLibraryBuilder, LibraryMacroApplicationData> entry
in _libraryData.entries) {
SourceLibraryBuilder libraryBuilder = entry.key;
@@ -925,9 +1120,8 @@
executionResults.addAll(await _applyDefinitionMacros(
libraryBuilder.origin, applicationData));
}
- for (MapEntry<ClassBuilder, ClassMacroApplicationData> entry
- in data.classData.entries) {
- ClassMacroApplicationData classApplicationData = entry.value;
+ for (ClassMacroApplicationData classApplicationData
+ in data.classData.values) {
for (ApplicationData applicationData
in classApplicationData.memberApplications.values) {
executionResults.addAll(await _applyDefinitionMacros(
@@ -938,6 +1132,19 @@
libraryBuilder.origin, classApplicationData.classApplications!));
}
}
+ for (ExtensionTypeMacroApplicationData extensionTypeApplicationData
+ in data.extensionTypeData.values) {
+ for (ApplicationData applicationData
+ in extensionTypeApplicationData.memberApplications.values) {
+ executionResults.addAll(await _applyDefinitionMacros(
+ libraryBuilder.origin, applicationData));
+ }
+ if (extensionTypeApplicationData.extensionTypeApplications != null) {
+ executionResults.addAll(await _applyDefinitionMacros(
+ libraryBuilder.origin,
+ extensionTypeApplicationData.extensionTypeApplications!));
+ }
+ }
if (executionResults.isNotEmpty) {
List<macro.Span> spans = [];
String result = _macroExecutor.buildAugmentationLibrary(
@@ -1072,6 +1279,8 @@
return macro.DeclarationKind.enumType;
} else if (declaration is macro.MixinDeclaration) {
return macro.DeclarationKind.mixinType;
+ } else if (declaration is macro.ExtensionTypeDeclaration) {
+ return macro.DeclarationKind.extensionType;
}
throw new UnsupportedError(
"Unexpected declaration ${declaration} (${declaration.runtimeType})");
@@ -1151,6 +1360,25 @@
String get textForTesting => _classBuilder.name;
}
+class ExtensionTypeApplicationData extends DeclarationApplicationData {
+ final SourceExtensionTypeDeclarationBuilder _extensionTypeDeclarationBuilder;
+
+ ExtensionTypeApplicationData(super.macroIntrospection, super.libraryBuilder,
+ this._extensionTypeDeclarationBuilder, super.macroApplications);
+
+ @override
+ macro.Declaration get declaration {
+ return _declaration ??= _macroIntrospection
+ .getExtensionTypeDeclaration(_extensionTypeDeclarationBuilder);
+ }
+
+ @override
+ Builder get builder => _extensionTypeDeclarationBuilder;
+
+ @override
+ String get textForTesting => _extensionTypeDeclarationBuilder.name;
+}
+
class MemberApplicationData extends DeclarationApplicationData {
final MemberBuilder _memberBuilder;
diff --git a/pkg/front_end/lib/src/fasta/source/class_declaration.dart b/pkg/front_end/lib/src/fasta/source/class_declaration.dart
index 42ba5f6..cfd979a 100644
--- a/pkg/front_end/lib/src/fasta/source/class_declaration.dart
+++ b/pkg/front_end/lib/src/fasta/source/class_declaration.dart
@@ -31,6 +31,60 @@
bool get isMixinDeclaration;
int resolveConstructors(SourceLibraryBuilder library);
+
+ /// [Iterator] for all members declared directly in this class, including
+ /// augmenting members.
+ ///
+ /// Duplicates are _not_ included.
+ ///
+ /// For instance:
+ ///
+ /// class Class {
+ /// // Declared, so it is included for this class but not for the
+ /// // augmentation class below.
+ /// method() {}
+ /// // Declared, so it is included for this class but not for the
+ /// // augmentation class below.
+ /// method2() {}
+ /// method2() {} // Duplicate, so it is *not* included.
+ /// }
+ ///
+ /// augment class Class {
+ /// // Augmenting, so it is included for this augmentation class but
+ /// // not for the origin class above.
+ /// augment method() {}
+ /// // Declared, so it is included for this augmentation class but not
+ /// // for the origin class above.
+ /// extra() {}
+ /// }
+ ///
+ Iterator<T> localMemberIterator<T extends Builder>();
+
+ /// [Iterator] for all constructors declared directly in this class, including
+ /// augmenting constructors.
+ ///
+ /// For instance:
+ ///
+ /// class Class {
+ /// // Declared, so it is included for this class but not for the
+ /// // augmentation class below.
+ /// Class();
+ /// // Declared, so it is included for this class but not for the
+ /// // augmentation class below.
+ /// Class.named();
+ /// Class.named(); // Duplicate, so it is *not* included.
+ /// }
+ ///
+ /// augment class Class {
+ /// // Augmenting, so it is included for this augmentation class but
+ /// // not for the origin class above.
+ /// augment Class();
+ /// // Declared, so it is included for this augmentation class but not
+ /// // for the origin class above.
+ /// Class.extra();
+ /// }
+ ///
+ Iterator<T> localConstructorIterator<T extends MemberBuilder>();
}
mixin ClassDeclarationMixin implements ClassDeclaration {
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 757c927..c5f967d 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -21,6 +21,7 @@
updateBoundNullabilities;
import 'package:kernel/type_environment.dart';
+import '../builder/augmentation_iterator.dart';
import '../builder/builder.dart';
import '../builder/constructor_reference_builder.dart';
import '../builder/declaration_builders.dart';
@@ -370,60 +371,12 @@
.forEach(build);
}
- /// [Iterator] for all members declared directly in this class, including
- /// augmenting members.
- ///
- /// Duplicates are _not_ included.
- ///
- /// For instance:
- ///
- /// class Class {
- /// // Declared, so it is included for this class but not for the
- /// // augmentation class below.
- /// method() {}
- /// // Declared, so it is included for this class but not for the
- /// // augmentation class below.
- /// method2() {}
- /// method2() {} // Duplicate, so it is *not* included.
- /// }
- ///
- /// augment class Class {
- /// // Augmenting, so it is included for this augmentation class but
- /// // not for the origin class above.
- /// augment method() {}
- /// // Declared, so it is included for this augmentation class but not
- /// // for the origin class above.
- /// extra() {}
- /// }
- ///
+ @override
Iterator<T> localMemberIterator<T extends Builder>() =>
new ClassDeclarationMemberIterator<SourceClassBuilder, T>.local(this,
includeDuplicates: false);
- /// [Iterator] for all constructors declared directly in this class, including
- /// augmenting constructors.
- ///
- /// For instance:
- ///
- /// class Class {
- /// // Declared, so it is included for this class but not for the
- /// // augmentation class below.
- /// Class();
- /// // Declared, so it is included for this class but not for the
- /// // augmentation class below.
- /// Class.named();
- /// Class.named(); // Duplicate, so it is *not* included.
- /// }
- ///
- /// augment class Class {
- /// // Augmenting, so it is included for this augmentation class but
- /// // not for the origin class above.
- /// augment Class();
- /// // Declared, so it is included for this augmentation class but not
- /// // for the origin class above.
- /// Class.extra();
- /// }
- ///
+ @override
Iterator<T> localConstructorIterator<T extends MemberBuilder>() =>
new ClassDeclarationConstructorIterator<SourceClassBuilder, T>.local(this,
includeDuplicates: false);
@@ -1954,6 +1907,12 @@
}
}
}
+
+ /// Returns an iterator the origin class and all augmentations in application
+ /// order.
+ Iterator<SourceClassBuilder> get declarationIterator =>
+ new AugmentationIterator<SourceClassBuilder>(
+ origin, origin._augmentations);
}
/// Returns `true` if override problems should be overlooked.
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
index fd547e6..627311b 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_type_declaration_builder.dart
@@ -9,6 +9,7 @@
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
+import '../builder/augmentation_iterator.dart';
import '../builder/builder.dart';
import '../builder/constructor_reference_builder.dart';
import '../builder/declaration_builders.dart';
@@ -779,6 +780,25 @@
}
return result;
}
+
+ @override
+ Iterator<T> localMemberIterator<T extends Builder>() =>
+ new ClassDeclarationMemberIterator<SourceExtensionTypeDeclarationBuilder,
+ T>.local(this, includeDuplicates: false);
+
+ @override
+ Iterator<T> localConstructorIterator<T extends MemberBuilder>() =>
+ new ClassDeclarationConstructorIterator<
+ SourceExtensionTypeDeclarationBuilder,
+ T>.local(this, includeDuplicates: false);
+
+ /// Returns an iterator the origin extension type declaration and all
+ /// augmentations in application order.
+ Iterator<SourceExtensionTypeDeclarationBuilder> get declarationIterator =>
+ new AugmentationIterator<SourceExtensionTypeDeclarationBuilder>(
+ // TODO(johnniwinther): Support augmentations.
+ origin,
+ null);
}
class _SourceExtensionTypeDeclarationBuilderAugmentationAccess
diff --git a/pkg/front_end/test/coverage_suite.dart b/pkg/front_end/test/coverage_suite.dart
index fc4038a..f36da0c 100644
--- a/pkg/front_end/test/coverage_suite.dart
+++ b/pkg/front_end/test/coverage_suite.dart
@@ -229,7 +229,7 @@
"package:front_end/src/fasta/source/source_extension_builder.dart":
61.261261261261254,
"package:front_end/src/fasta/source/source_extension_type_declaration_builder.dart":
- 85.34136546184739,
+ 84.0,
"package:front_end/src/fasta/source/source_factory_builder.dart":
92.22222222222223,
"package:front_end/src/fasta/source/source_field_builder.dart":
diff --git a/pkg/front_end/test/macros/application/data/tests/targets.dart b/pkg/front_end/test/macros/application/data/tests/targets.dart
index f5efb5b..af8dedd 100644
--- a/pkg/front_end/test/macros/application/data/tests/targets.dart
+++ b/pkg/front_end/test/macros/application/data/tests/targets.dart
@@ -22,6 +22,7 @@
Enum.a:VariableTypesMacro.new()
Enum:ClassTypesMacro.new()
Mixin:MixinTypesMacro.new()
+ ExtensionType:ExtensionTypeTypesMacro.new()
Declarations Order:
Class.field:FieldDeclarationsMacro.new()
Class.field:VariableDeclarationsMacro.new()
@@ -34,6 +35,7 @@
Enum.a:VariableDeclarationsMacro.new()
Enum:ClassDeclarationsMacro.new()
Mixin:MixinDeclarationsMacro.new()
+ ExtensionType:ExtensionTypeDeclarationsMacro.new()
org-dartlang-test:///a/b/c/main.dart:LibraryDeclarationsMacro.new()
function:FunctionDeclarationsMacro.new()
variable:VariableDeclarationsMacro.new()
@@ -50,7 +52,8 @@
Enum.a:FieldDefinitionMacro.new()
Enum.a:VariableDefinitionMacro.new()
Enum:ClassDefinitionMacro.new()
- Mixin:MixinDefinitionMacro.new()*/
+ Mixin:MixinDefinitionMacro.new()
+ ExtensionType:ExtensionTypeDefinitionMacro.new()*/
@LibraryTypesMacro() // Ok
@LibraryDeclarationsMacro() // Ok
diff --git a/pkg/front_end/test/macros/application/data/tests/targets.dart.expect b/pkg/front_end/test/macros/application/data/tests/targets.dart.expect
index 9b5e1e9..f708358 100644
--- a/pkg/front_end/test/macros/application/data/tests/targets.dart.expect
+++ b/pkg/front_end/test/macros/application/data/tests/targets.dart.expect
@@ -1166,6 +1166,154 @@
// @LibraryTypesMacro() // Error
// ^
//
+// org-dartlang-test:///a/b/c/main.dart:507:2: Error: The macro can only be applied to fields, functions, methods or variables.
+// @VariableAndFunctionTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:506:2: Error: The macro can only be applied to fields or methods.
+// @FieldAndMethodTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:505:2: Error: The macro can only be applied to typedefs.
+// @TypeAliasDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:504:2: Error: The macro can only be applied to typedefs.
+// @TypeAliasTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:500:2: Error: The macro can only be applied to extensions.
+// @ExtensionDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:499:2: Error: The macro can only be applied to extensions.
+// @ExtensionDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:498:2: Error: The macro can only be applied to extensions.
+// @ExtensionTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:497:2: Error: The macro can only be applied to mixin declarations.
+// @MixinDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:496:2: Error: The macro can only be applied to mixin declarations.
+// @MixinDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:495:2: Error: The macro can only be applied to mixin declarations.
+// @MixinTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:494:2: Error: The macro can only be applied to constructors.
+// @ConstructorDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:493:2: Error: The macro can only be applied to constructors.
+// @ConstructorDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:492:2: Error: The macro can only be applied to constructors.
+// @ConstructorTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:491:2: Error: The macro can only be applied to methods.
+// @MethodDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:490:2: Error: The macro can only be applied to methods.
+// @MethodDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:489:2: Error: The macro can only be applied to methods.
+// @MethodTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:488:2: Error: The macro can only be applied to fields.
+// @FieldDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:487:2: Error: The macro can only be applied to fields.
+// @FieldDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:486:2: Error: The macro can only be applied to fields.
+// @FieldTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:485:2: Error: The macro can only be applied to enum values.
+// @EnumValueDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:484:2: Error: The macro can only be applied to enum values.
+// @EnumValueDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:483:2: Error: The macro can only be applied to enum values.
+// @EnumValueTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:482:2: Error: The macro can only be applied to enums.
+// @EnumDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:481:2: Error: The macro can only be applied to enums.
+// @EnumDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:480:2: Error: The macro can only be applied to enums.
+// @EnumTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:479:2: Error: The macro can only be applied to classes.
+// @ClassDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:478:2: Error: The macro can only be applied to classes.
+// @ClassDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:477:2: Error: The macro can only be applied to classes.
+// @ClassTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:476:2: Error: The macro can only be applied to fields or variables.
+// @VariableDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:475:2: Error: The macro can only be applied to fields or variables.
+// @VariableDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:474:2: Error: The macro can only be applied to fields or variables.
+// @VariableTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:473:2: Error: The macro can only be applied to functions or methods.
+// @FunctionDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:472:2: Error: The macro can only be applied to functions or methods.
+// @FunctionDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:471:2: Error: The macro can only be applied to functions or methods.
+// @FunctionTypesMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:470:2: Error: The macro can only be applied to libraries.
+// @LibraryDefinitionMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:469:2: Error: The macro can only be applied to libraries.
+// @LibraryDeclarationsMacro() // Error
+// ^
+//
+// org-dartlang-test:///a/b/c/main.dart:468:2: Error: The macro can only be applied to libraries.
+// @LibraryTypesMacro() // Error
+// ^
+//
// org-dartlang-test:///a/b/c/main.dart:256:2: Error: The macro can only be applied to fields or methods.
// @FieldAndMethodTypesMacro() // Error
// ^
diff --git a/pkg/front_end/test/macros/macro_api_test.dart b/pkg/front_end/test/macros/macro_api_test.dart
index a1dc02e..b1d756b8 100644
--- a/pkg/front_end/test/macros/macro_api_test.dart
+++ b/pkg/front_end/test/macros/macro_api_test.dart
@@ -4,6 +4,7 @@
import 'dart:io' show Platform;
+import 'package:front_end/src/api_prototype/terminal_color_support.dart';
import 'package:macros/src/executor/multi_executor.dart';
import 'package:expect/expect.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart';
@@ -24,7 +25,9 @@
'../../../_fe_analyzer_shared/test/macros/api/package_config.json');
options.macroExecutor ??= new MultiMacroExecutor();
options.macroSerializer = macroSerializer;
-
+ options.onDiagnostic = (DiagnosticMessage message) {
+ printDiagnosticMessage(message, print);
+ };
InternalCompilerResult result = await kernelForProgramInternal(
Platform.script.resolve(
'../../../_fe_analyzer_shared/test/macros/api/api_test_data.dart'),