[cfe] Support TypeResolver and StaticType in macro implementation
This adds initial support for TypeResolver.resolve and
StaticType.isExactly and StaticType.isSubtypeOf.
Change-Id: Iaa147a6fc3c8c9eee8940aa9bcf4a01b51819ddc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/228860
Reviewed-by: Jake Macdonald <jakemac@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index 514fcd9..4d2f6a1 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -2,21 +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.
-/// Generates a Dart program for a given macro, which can be compiled and then
-/// passed as a precompiled kernel file to `MacroExecutor.loadMacro`.
+/// Generates a Dart program for a given set of macros, which can be compiled
+/// and then passed as a precompiled kernel file to `MacroExecutor.loadMacro`.
+///
+/// The [macroDeclarations] is a map from library URIs to macro classes for the
+/// macros supported. The macro classes are provided as a map from macro class
+/// names to the names of the macro class constructors.
String bootstrapMacroIsolate(
- String macroImport, String macroName, List<String> constructorNames) {
- StringBuffer constructorEntries = new StringBuffer(
- "MacroClassIdentifierImpl(Uri.parse('$macroImport'), '$macroName'): {");
- for (String constructor in constructorNames) {
- constructorEntries.writeln("'$constructor': "
- "$macroName.${constructor.isEmpty ? 'new' : constructor},");
- }
- constructorEntries.writeln('},');
- return template
- .replaceFirst(_importMarker, 'import \'$macroImport\';')
- .replaceFirst(
- _macroConstructorEntriesMarker, constructorEntries.toString());
+ Map<String, Map<String, List<String>>> macroDeclarations) {
+ StringBuffer imports = new StringBuffer();
+ StringBuffer constructorEntries = new StringBuffer();
+ macroDeclarations
+ .forEach((String macroImport, Map<String, List<String>> macroClasses) {
+ imports.writeln('import \'$macroImport\';');
+ macroClasses.forEach((String macroName, List<String> constructorNames) {
+ constructorEntries
+ .writeln("MacroClassIdentifierImpl(Uri.parse('$macroImport'), "
+ "'$macroName'): {");
+ for (String constructor in constructorNames) {
+ constructorEntries.writeln("'$constructor': "
+ "$macroName.${constructor.isEmpty ? 'new' : constructor},");
+ }
+ constructorEntries.writeln('},');
+ });
+ });
+ return template.replaceFirst(_importMarker, imports.toString()).replaceFirst(
+ _macroConstructorEntriesMarker, constructorEntries.toString());
}
const String _importMarker = '{{IMPORT}}';
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
index 849c662..57f0ec8 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
@@ -182,7 +182,7 @@
IsExactlyTypeRequest request =
new IsExactlyTypeRequest.deserialize(deserializer, zoneId);
StaticType leftType = request.leftType.instance as StaticType;
- StaticType rightType = request.leftType.instance as StaticType;
+ StaticType rightType = request.rightType.instance as StaticType;
SerializableResponse response = new SerializableResponse(
response:
new BooleanValue(await leftType.isExactly(rightType)),
@@ -197,7 +197,7 @@
IsSubtypeOfRequest request =
new IsSubtypeOfRequest.deserialize(deserializer, zoneId);
StaticType leftType = request.leftType.instance as StaticType;
- StaticType rightType = request.leftType.instance as StaticType;
+ StaticType rightType = request.rightType.instance as StaticType;
SerializableResponse response = new SerializableResponse(
response:
new BooleanValue(await leftType.isSubtypeOf(rightType)),
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
index a7f5491..7c242a4 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
@@ -44,8 +44,11 @@
var macroUri = simpleMacroFile.absolute.uri;
var macroName = 'SimpleMacro';
- var bootstrapContent =
- bootstrapMacroIsolate(macroUri.toString(), macroName, ['', 'named']);
+ var bootstrapContent = bootstrapMacroIsolate({
+ macroUri.toString(): {
+ macroName: ['', 'named']
+ }
+ });
var bootstrapFile = File(tmpDir.uri.resolve('main.dart').toFilePath())
..writeAsStringSync(bootstrapContent);
var kernelOutputFile =
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
index 035d96f..84ddb7a 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/simple_macro.dart
@@ -36,13 +36,13 @@
}
var classType =
await builder.resolve(method.definingClass) as NamedStaticType;
- if (!(await staticReturnType.isExactly(classType))) {
+ if (await staticReturnType.isExactly(classType)) {
throw StateError(
'The return type should not be exactly equal to the class type');
}
- if (!(await staticReturnType.isSubtypeOf(classType))) {
+ if (await staticReturnType.isSubtypeOf(classType)) {
throw StateError(
- 'The return type should be a subtype of the class type!');
+ 'The return type should not be a subtype of the class type!');
}
// Test the type declaration resolver
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 76ab9eb8..2a1e8b7 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -361,7 +361,7 @@
verify: c.options.verify);
componentWithDill = buildResult.component;
}
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
hierarchy ??= currentKernelTarget.loader.hierarchy;
if (currentKernelTarget.classHierarchyChanges != null) {
hierarchy.applyTreeChanges(
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 814b523..86144de 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -284,6 +284,7 @@
}
Version? _currentSdkVersion;
+
Version get currentSdkVersion {
if (_currentSdkVersion == null) {
_parseCurrentSdkVersion();
@@ -464,7 +465,8 @@
loader.finishNoSuchMethodForwarders();
List<SourceClassBuilder> sourceClasses = loader.collectSourceClasses();
if (macroApplications != null) {
- await macroApplications.applyDefinitionMacros();
+ await macroApplications.applyDefinitionMacros(
+ loader.coreTypes, loader.hierarchy);
}
loader.finishNativeMethods();
loader.finishPatchMethods();
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro.dart
index 6d95bbf..3c8f11a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro.dart
@@ -5,9 +5,15 @@
import 'package:_fe_analyzer_shared/src/macros/api.dart' hide TypeBuilder;
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
+import 'package:kernel/ast.dart' show DartType, DynamicType;
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/type_environment.dart';
import '../builder/class_builder.dart';
import '../builder/formal_parameter_builder.dart';
+import '../builder/library_builder.dart';
import '../builder/member_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/type_builder.dart';
@@ -46,12 +52,39 @@
}
}
+class MacroApplication {
+ final ClassBuilder classBuilder;
+ final String constructorName;
+
+ // TODO(johnniwinther): Add support for arguments.
+
+ MacroApplication(this.classBuilder, this.constructorName);
+
+ late MacroInstanceIdentifier instanceIdentifier;
+}
+
+class MacroApplicationDataForTesting {
+ Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData = {};
+ Map<MemberBuilder, List<MacroExecutionResult>> memberDefinitionsResults = {};
+}
+
+class LibraryMacroApplicationData {
+ Map<SourceClassBuilder, ClassMacroApplicationData> classData = {};
+ Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
+}
+
+class ClassMacroApplicationData {
+ List<MacroApplication>? classApplications;
+ Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
+}
+
class MacroApplications {
- final MacroExecutor macroExecutor;
+ final MacroExecutor _macroExecutor;
final Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData;
final MacroApplicationDataForTesting? dataForTesting;
- MacroApplications(this.macroExecutor, this.libraryData, this.dataForTesting) {
+ MacroApplications(
+ this._macroExecutor, this.libraryData, this.dataForTesting) {
dataForTesting?.libraryData.addAll(libraryData);
}
@@ -124,7 +157,7 @@
Future<void> _applyTypeMacros(
Declaration declaration, List<MacroApplication> macroApplications) async {
for (MacroApplication macroApplication in macroApplications) {
- await macroExecutor.executeTypesPhase(
+ await _macroExecutor.executeTypesPhase(
macroApplication.instanceIdentifier, declaration);
}
}
@@ -151,7 +184,7 @@
TypeResolver typeResolver,
ClassIntrospector classIntrospector) async {
for (MacroApplication macroApplication in macroApplications) {
- await macroExecutor.executeDeclarationsPhase(
+ await _macroExecutor.executeDeclarationsPhase(
macroApplication.instanceIdentifier,
declaration,
typeResolver,
@@ -160,7 +193,7 @@
}
Future<void> applyDeclarationMacros() async {
- TypeResolver typeResolver = new _TypeResolver();
+ TypeResolver typeResolver = new _TypeResolver(this);
ClassIntrospector classIntrospector = new _ClassIntrospector();
for (MapEntry<SourceLibraryBuilder,
LibraryMacroApplicationData> libraryEntry in libraryData.entries) {
@@ -186,19 +219,24 @@
TypeDeclarationResolver typeDeclarationResolver) async {
List<MacroExecutionResult> results = [];
for (MacroApplication macroApplication in macroApplications) {
- MacroExecutionResult result = await macroExecutor.executeDefinitionsPhase(
- macroApplication.instanceIdentifier,
- declaration,
- typeResolver,
- classIntrospector,
- typeDeclarationResolver);
+ MacroExecutionResult result =
+ await _macroExecutor.executeDefinitionsPhase(
+ macroApplication.instanceIdentifier,
+ declaration,
+ typeResolver,
+ classIntrospector,
+ typeDeclarationResolver);
results.add(result);
}
return results;
}
- Future<void> applyDefinitionMacros() async {
- TypeResolver typeResolver = new _TypeResolver();
+ late TypeEnvironment typeEnvironment;
+
+ Future<void> applyDefinitionMacros(
+ CoreTypes coreTypes, ClassHierarchy classHierarchy) async {
+ typeEnvironment = new TypeEnvironment(coreTypes, classHierarchy);
+ TypeResolver typeResolver = new _TypeResolver(this);
ClassIntrospector classIntrospector = new _ClassIntrospector();
TypeDeclarationResolver typeDeclarationResolver =
new _TypeDeclarationResolver();
@@ -222,126 +260,179 @@
}
}
}
-}
-class MacroApplication {
- final ClassBuilder classBuilder;
- final String constructorName;
- // TODO(johnniwinther): Add support for arguments.
-
- MacroApplication(this.classBuilder, this.constructorName);
-
- late MacroInstanceIdentifier instanceIdentifier;
-}
-
-class MacroApplicationDataForTesting {
- Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData = {};
- Map<MemberBuilder, List<MacroExecutionResult>> memberDefinitionsResults = {};
-}
-
-class LibraryMacroApplicationData {
- Map<SourceClassBuilder, ClassMacroApplicationData> classData = {};
- Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
-}
-
-class ClassMacroApplicationData {
- List<MacroApplication>? classApplications;
- Map<MemberBuilder, List<MacroApplication>> memberApplications = {};
-}
-
-FunctionDeclaration createTopLevelFunctionDeclaration(
- SourceProcedureBuilder builder) {
- List<ParameterDeclarationImpl>? positionalParameters;
- List<ParameterDeclarationImpl>? namedParameters;
-
- List<FormalParameterBuilder>? formals = builder.formals;
- if (formals == null) {
- positionalParameters = namedParameters = const [];
- } else {
- positionalParameters = [];
- namedParameters = [];
- for (FormalParameterBuilder formal in formals) {
- TypeAnnotationImpl type = computeTypeAnnotation(formal.type);
- // TODO(johnniwinther): Support default values.
- if (formal.isNamed) {
- namedParameters.add(new ParameterDeclarationImpl(
- id: _removeInstanceId++,
- name: formal.name,
- isRequired: formal.isNamedRequired,
- isNamed: true,
- type: type,
- defaultValue: null));
- } else {
- positionalParameters.add(new ParameterDeclarationImpl(
- id: _removeInstanceId++,
- name: formal.name,
- isRequired: formal.isRequired,
- isNamed: false,
- type: type,
- defaultValue: null));
- }
- }
+ void close() {
+ _macroExecutor.close();
+ _staticTypeCache.clear();
+ _typeAnnotationCache.clear();
}
- return new FunctionDeclarationImpl(
- id: _removeInstanceId++,
- name: builder.name,
- isAbstract: builder.isAbstract,
- isExternal: builder.isExternal,
- isGetter: builder.isGetter,
- isSetter: builder.isSetter,
- positionalParameters: positionalParameters,
- namedParameters: namedParameters,
- returnType: computeTypeAnnotation(builder.returnType),
- // TODO(johnniwinther): Support typeParameters
- typeParameters: const []);
+ FunctionDeclaration createTopLevelFunctionDeclaration(
+ SourceProcedureBuilder builder) {
+ List<ParameterDeclarationImpl>? positionalParameters;
+ List<ParameterDeclarationImpl>? namedParameters;
+
+ List<FormalParameterBuilder>? formals = builder.formals;
+ if (formals == null) {
+ positionalParameters = namedParameters = const [];
+ } else {
+ positionalParameters = [];
+ namedParameters = [];
+ for (FormalParameterBuilder formal in formals) {
+ TypeAnnotationImpl type =
+ computeTypeAnnotation(builder.library, formal.type);
+ // TODO(johnniwinther): Support default values.
+ if (formal.isNamed) {
+ namedParameters.add(new ParameterDeclarationImpl(
+ id: RemoteInstance.uniqueId,
+ name: formal.name,
+ isRequired: formal.isNamedRequired,
+ isNamed: true,
+ type: type,
+ defaultValue: null));
+ } else {
+ positionalParameters.add(new ParameterDeclarationImpl(
+ id: RemoteInstance.uniqueId,
+ name: formal.name,
+ isRequired: formal.isRequired,
+ isNamed: false,
+ type: type,
+ defaultValue: null));
+ }
+ }
+ }
+
+ return new FunctionDeclarationImpl(
+ id: RemoteInstance.uniqueId,
+ name: builder.name,
+ isAbstract: builder.isAbstract,
+ isExternal: builder.isExternal,
+ isGetter: builder.isGetter,
+ isSetter: builder.isSetter,
+ positionalParameters: positionalParameters,
+ namedParameters: namedParameters,
+ returnType: computeTypeAnnotation(builder.library, builder.returnType),
+ // TODO(johnniwinther): Support typeParameters
+ typeParameters: const []);
+ }
+
+ Map<TypeBuilder?, _NamedTypeAnnotationImpl> _typeAnnotationCache = {};
+
+ List<TypeAnnotationImpl> computeTypeAnnotations(
+ LibraryBuilder library, List<TypeBuilder>? typeBuilders) {
+ if (typeBuilders == null) return const [];
+ return new List.generate(typeBuilders.length,
+ (int index) => computeTypeAnnotation(library, typeBuilders[index]));
+ }
+
+ _NamedTypeAnnotationImpl _computeTypeAnnotation(
+ LibraryBuilder libraryBuilder, TypeBuilder? typeBuilder) {
+ if (typeBuilder != null) {
+ if (typeBuilder is NamedTypeBuilder) {
+ Object name = typeBuilder.name;
+ List<TypeAnnotationImpl> typeArguments =
+ computeTypeAnnotations(libraryBuilder, typeBuilder.arguments);
+ bool isNullable = typeBuilder.nullabilityBuilder.isNullable;
+ if (name is String) {
+ return new _NamedTypeAnnotationImpl(
+ typeBuilder: typeBuilder,
+ libraryBuilder: libraryBuilder,
+ id: RemoteInstance.uniqueId,
+ name: name,
+ typeArguments: typeArguments,
+ isNullable: isNullable);
+ } else if (name is QualifiedName) {
+ assert(name.qualifier is String);
+ return new _NamedTypeAnnotationImpl(
+ typeBuilder: typeBuilder,
+ libraryBuilder: libraryBuilder,
+ id: RemoteInstance.uniqueId,
+ name: '${name.qualifier}.${name.name}',
+ typeArguments: typeArguments,
+ isNullable: isNullable);
+ }
+ }
+ }
+ return new _NamedTypeAnnotationImpl(
+ typeBuilder: typeBuilder,
+ libraryBuilder: libraryBuilder,
+ id: RemoteInstance.uniqueId,
+ name: 'dynamic',
+ isNullable: false,
+ typeArguments: const []);
+ }
+
+ TypeAnnotationImpl computeTypeAnnotation(
+ LibraryBuilder libraryBuilder, TypeBuilder? typeBuilder) {
+ return _typeAnnotationCache[typeBuilder] ??=
+ _computeTypeAnnotation(libraryBuilder, typeBuilder);
+ }
+
+ StaticType resolveTypeAnnotation(_NamedTypeAnnotationImpl typeAnnotation) {
+ TypeBuilder? typeBuilder = typeAnnotation.typeBuilder;
+ LibraryBuilder libraryBuilder = typeAnnotation.libraryBuilder;
+ DartType dartType;
+ if (typeBuilder != null) {
+ dartType = typeBuilder.build(libraryBuilder);
+ } else {
+ dartType = const DynamicType();
+ }
+ return createStaticType(dartType);
+ }
+
+ Map<DartType, _StaticTypeImpl> _staticTypeCache = {};
+
+ StaticType createStaticType(DartType dartType) {
+ return _staticTypeCache[dartType] ??= new _StaticTypeImpl(this, dartType);
+ }
}
-// TODO(johnniwinther): Cache remote instances when needed.
-int _removeInstanceId = 0;
+class _NamedTypeAnnotationImpl extends NamedTypeAnnotationImpl {
+ final TypeBuilder? typeBuilder;
+ final LibraryBuilder libraryBuilder;
-List<TypeAnnotationImpl> computeTypeAnnotations(
- List<TypeBuilder>? typeBuilders) {
- if (typeBuilders == null) return const [];
- return new List.generate(typeBuilders.length,
- (int index) => computeTypeAnnotation(typeBuilders[index]));
-}
-
-TypeAnnotationImpl computeTypeAnnotation(TypeBuilder? typeBuilder) {
- if (typeBuilder != null) {
- if (typeBuilder is NamedTypeBuilder) {
- Object name = typeBuilder.name;
- List<TypeAnnotationImpl> typeArguments =
- computeTypeAnnotations(typeBuilder.arguments);
- bool isNullable = typeBuilder.nullabilityBuilder.isNullable;
- if (name is String) {
- return new NamedTypeAnnotationImpl(
- id: _removeInstanceId++,
+ _NamedTypeAnnotationImpl({
+ required this.typeBuilder,
+ required this.libraryBuilder,
+ required int id,
+ required bool isNullable,
+ required String name,
+ required List<TypeAnnotationImpl> typeArguments,
+ }) : super(
+ id: id,
+ isNullable: isNullable,
name: name,
- typeArguments: typeArguments,
- isNullable: isNullable);
- } else if (name is QualifiedName) {
- assert(name.qualifier is String);
- return new NamedTypeAnnotationImpl(
- id: _removeInstanceId++,
- name: '${name.qualifier}.${name.name}',
- typeArguments: typeArguments,
- isNullable: isNullable);
- }
- }
+ typeArguments: typeArguments);
+}
+
+class _StaticTypeImpl extends StaticType {
+ final MacroApplications macroApplications;
+ final DartType type;
+
+ _StaticTypeImpl(this.macroApplications, this.type);
+
+ @override
+ Future<bool> isExactly(covariant _StaticTypeImpl other) {
+ return new Future.value(type == other.type);
}
- return new NamedTypeAnnotationImpl(
- id: _removeInstanceId++,
- name: 'dynamic',
- isNullable: false,
- typeArguments: const []);
+
+ @override
+ Future<bool> isSubtypeOf(covariant _StaticTypeImpl other) {
+ return new Future.value(macroApplications.typeEnvironment
+ .isSubtypeOf(type, other.type, SubtypeCheckMode.withNullabilities));
+ }
}
class _TypeResolver implements TypeResolver {
+ final MacroApplications macroApplications;
+
+ _TypeResolver(this.macroApplications);
+
@override
- Future<StaticType> resolve(TypeAnnotation typeAnnotation) {
- // TODO: implement resolve
- throw new UnimplementedError('_TypeResolver.resolve');
+ Future<StaticType> resolve(
+ covariant _NamedTypeAnnotationImpl typeAnnotation) {
+ return new Future.value(
+ macroApplications.resolveTypeAnnotation(typeAnnotation));
}
}
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 0deb368..2470a1a 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -172,7 +172,7 @@
}
// TODO(johnniwinther): Should we reuse the macro executor on subsequent
// compilations where possible?
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
return new InternalCompilerResult(
summary: summary,
diff --git a/pkg/front_end/test/explicit_creation_git_test.dart b/pkg/front_end/test/explicit_creation_git_test.dart
index 0f00042..3200635 100644
--- a/pkg/front_end/test/explicit_creation_git_test.dart
+++ b/pkg/front_end/test/explicit_creation_git_test.dart
@@ -104,7 +104,7 @@
BuildResult buildResult = await kernelTarget.buildOutlines();
buildResult = await kernelTarget.buildComponent(
macroApplications: buildResult.macroApplications);
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
});
print("Done in ${stopwatch.elapsedMilliseconds} ms. "
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index d4e1b8c..02231dd 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -1856,7 +1856,7 @@
: context.verify);
p = buildResult.component!;
}
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
// To avoid possible crash in mixin transformation in the transformation
// of the user of this linked dependency we have to transform this too.
@@ -1928,7 +1928,7 @@
if (updateComments) {
await instrumentation.fixSource(description.uri, false);
} else {
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
return new Result<ComponentResult>(
new ComponentResult(description, p, userLibraries,
compilationSetup, sourceTarget),
@@ -1939,7 +1939,7 @@
}
}
}
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
return pass(new ComponentResult(
description, p, userLibraries, compilationSetup, sourceTarget));
});
diff --git a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
index a5469f1..b686cc0 100644
--- a/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
+++ b/pkg/front_end/test/macro_application/data/pkgs/macro/lib/macro.dart
@@ -15,3 +15,21 @@
}'''));
}
}
+
+macro class FunctionDefinitionMacro2 implements FunctionDefinitionMacro {
+ const FunctionDefinitionMacro2();
+
+ FutureOr<void> buildDefinitionForFunction(
+ FunctionDeclaration function, FunctionDefinitionBuilder builder) async {
+ if (function.positionalParameters.isEmpty) {
+ return;
+ }
+ StaticType returnType = await builder.resolve(function.returnType);
+ StaticType parameterType =
+ await builder.resolve(function.positionalParameters.first.type);
+ builder.augment(new FunctionBodyCode.fromString('''{
+ print('isExactly=${await returnType.isExactly(parameterType)}');
+ print('isSubtype=${await returnType.isSubtypeOf(parameterType)}');
+}'''));
+ }
+}
diff --git a/pkg/front_end/test/macro_application/data/tests/parameters.dart b/pkg/front_end/test/macro_application/data/tests/parameters.dart
index 41fcf36..bb606bb 100644
--- a/pkg/front_end/test/macro_application/data/tests/parameters.dart
+++ b/pkg/front_end/test/macro_application/data/tests/parameters.dart
@@ -4,30 +4,30 @@
import 'package:macro/macro.dart';
-@FunctionDefinitionMacro1()
/*member: topLevelFunction1:
augment void topLevelFunction1(int a, ) {
return 42;
}*/
+@FunctionDefinitionMacro1()
external void topLevelFunction1(int a);
-@FunctionDefinitionMacro1()
/*member: topLevelFunction2:
augment void topLevelFunction2(int a, int b, ) {
return 42;
}*/
+@FunctionDefinitionMacro1()
external void topLevelFunction2(int a, int b);
-@FunctionDefinitionMacro1()
/*member: topLevelFunction3:
augment void topLevelFunction3(int a, [int? b, ]) {
return 42;
}*/
+@FunctionDefinitionMacro1()
external void topLevelFunction3(int a, [int? b]);
-@FunctionDefinitionMacro1()
/*member: topLevelFunction4:
augment void topLevelFunction4(int a, {int? b, int? c, }) {
return 42;
}*/
+@FunctionDefinitionMacro1()
external void topLevelFunction4(int a, {int? b, int? c});
diff --git a/pkg/front_end/test/macro_application/data/tests/subtypes.dart b/pkg/front_end/test/macro_application/data/tests/subtypes.dart
new file mode 100644
index 0000000..245908a
--- /dev/null
+++ b/pkg/front_end/test/macro_application/data/tests/subtypes.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2022, 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.
+
+import 'package:macro/macro.dart';
+
+class A {}
+
+class B1 {}
+
+class B2 extends B1 {}
+
+class C1 extends C2 {}
+
+class C2 {}
+
+class D1 {}
+
+class D2 {}
+
+/*member: topLevelFunction1:
+augment A topLevelFunction1(A a, ) {
+ print('isExactly=true');
+ print('isSubtype=true');
+}*/
+@FunctionDefinitionMacro2()
+external A topLevelFunction1(A a);
+
+/*member: topLevelFunction2:
+augment B2 topLevelFunction2(B1 a, ) {
+ print('isExactly=false');
+ print('isSubtype=true');
+}*/
+@FunctionDefinitionMacro2()
+external B2 topLevelFunction2(B1 a);
+
+/*member: topLevelFunction3:
+augment C2 topLevelFunction3(C1 a, ) {
+ print('isExactly=false');
+ print('isSubtype=false');
+}*/
+@FunctionDefinitionMacro2()
+external C2 topLevelFunction3(C1 a);
+
+/*member: topLevelFunction4:
+augment D2 topLevelFunction4(D1 a, ) {
+ print('isExactly=false');
+ print('isSubtype=false');
+}*/
+@FunctionDefinitionMacro2()
+external D2 topLevelFunction4(D1 a);
diff --git a/pkg/front_end/test/macro_application/macro_application_test.dart b/pkg/front_end/test/macro_application/macro_application_test.dart
index db171e8..d24b4ae 100644
--- a/pkg/front_end/test/macro_application/macro_application_test.dart
+++ b/pkg/front_end/test/macro_application/macro_application_test.dart
@@ -25,6 +25,13 @@
import 'package:kernel/target/targets.dart';
import 'package:vm/target/vm.dart';
+const Map<String, Map<String, List<String>>> macroDeclarations = {
+ 'package:macro/macro.dart': {
+ 'FunctionDefinitionMacro1': [''],
+ 'FunctionDefinitionMacro2': [''],
+ }
+};
+
Future<Uri> compileMacros(Directory directory) async {
CompilerOptions options = new CompilerOptions();
options.target = new VmTarget(new TargetFlags());
@@ -32,10 +39,9 @@
options.environmentDefines = {};
options.packagesFileUri = Platform.script.resolve('data/package_config.json');
- CompilerResult? compilerResult = await compileScript({
- 'main.dart': bootstrapMacroIsolate(
- 'package:macro/macro.dart', 'FunctionDefinitionMacro1', [''])
- }, options: options, requireMain: false);
+ CompilerResult? compilerResult = await compileScript(
+ {'main.dart': bootstrapMacroIsolate(macroDeclarations)},
+ options: options, requireMain: false);
Uri uri = directory.absolute.uri.resolve('macros.dill');
await writeComponentToFile(compilerResult!.component!, uri);
return uri;
@@ -48,11 +54,14 @@
await Directory.systemTemp.createTemp('macro_application');
Uri macrosUri = await compileMacros(tempDirectory);
- Map<MacroClass, Uri> precompiledMacroUris = {
- new MacroClass(
- Uri.parse('package:macro/macro.dart'), 'FunctionDefinitionMacro1'):
- macrosUri
- };
+ Map<MacroClass, Uri> precompiledMacroUris = {};
+ macroDeclarations
+ .forEach((String macroUri, Map<String, List<String>> macroClasses) {
+ macroClasses.forEach((String macroClass, List<String> constructorNames) {
+ precompiledMacroUris[new MacroClass(Uri.parse(macroUri), macroClass)] =
+ macrosUri;
+ });
+ });
Directory dataDir =
new Directory.fromUri(Platform.script.resolve('data/tests'));
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index f99d05f..24fad8f 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -309,7 +309,7 @@
output: output,
omitPlatform: omitPlatform,
supportAdditionalDills: supportAdditionalDills);
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
return kernelTarget;
}
@@ -384,7 +384,7 @@
buildResult = await kernelTarget.buildComponent(
macroApplications: buildResult.macroApplications,
verify: c.options.verify);
- buildResult.macroApplications?.macroExecutor.close();
+ buildResult.macroApplications?.close();
Component component = buildResult.component!;
if (c.options.debugDump) {
printComponentText(component,