Version 2.17.0-82.0.dev
Merge commit '9df38b50da5f6442f51c903182da7880abc45fca' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index 719b64d..9b9e14b 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -80,6 +80,9 @@
/// This is normally the member itself, if a setter, but for instance
/// lowered late fields this can be synthesized setters.
List<ClassMember> get localSetters;
+
+ /// The builder for the enclosing class, if any.
+ ClassBuilder? get classBuilder;
}
abstract class MemberBuilderImpl extends ModifierBuilderImpl
@@ -100,7 +103,7 @@
: this.fileUri = (fileUri ?? parent?.fileUri)!,
super(parent, charOffset);
- /// The builder for the enclosing class, if any.
+ @override
ClassBuilder? get classBuilder =>
parent is ClassBuilder ? parent as ClassBuilder : null;
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 818e97f..534c8bf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -423,7 +423,8 @@
loader.buildClassHierarchy(sourceClassBuilders, objectClassBuilder);
loader.checkSupertypes(sourceClassBuilders, enumClass);
if (macroApplications != null) {
- await macroApplications.applyDeclarationMacros(loader.hierarchyBuilder);
+ await macroApplications
+ .applyDeclarationsMacros(loader.hierarchyBuilder);
}
loader.buildClassHierarchyMembers(sourceClassBuilders);
loader.computeHierarchy();
diff --git a/pkg/front_end/lib/src/fasta/kernel/macro.dart b/pkg/front_end/lib/src/fasta/kernel/macro.dart
index 1cd915d..3ec39e6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/macro.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/macro.dart
@@ -8,11 +8,13 @@
as macro;
import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart'
as macro;
+import 'package:front_end/src/base/common.dart';
import 'package:kernel/ast.dart' show DartType, DynamicType;
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/src/types.dart';
import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+import '../builder/builder.dart';
import '../builder/class_builder.dart';
import '../builder/formal_parameter_builder.dart';
import '../builder/library_builder.dart';
@@ -21,6 +23,9 @@
import '../builder/type_builder.dart';
import '../identifiers.dart';
import '../source/source_class_builder.dart';
+import '../source/source_constructor_builder.dart';
+import '../source/source_factory_builder.dart';
+import '../source/source_field_builder.dart';
import '../source/source_library_builder.dart';
import '../source/source_procedure_builder.dart';
@@ -70,6 +75,12 @@
class MacroApplicationDataForTesting {
Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData = {};
+ Map<SourceClassBuilder, List<macro.MacroExecutionResult>> classTypesResults =
+ {};
+ Map<SourceClassBuilder, List<macro.MacroExecutionResult>>
+ classDeclarationsResults = {};
+ Map<SourceClassBuilder, List<macro.MacroExecutionResult>>
+ classDefinitionsResults = {};
Map<MemberBuilder, List<macro.MacroExecutionResult>> memberTypesResults = {};
Map<MemberBuilder, List<macro.MacroExecutionResult>>
memberDeclarationsResults = {};
@@ -145,6 +156,7 @@
return new MacroApplications(macroExecutor, libraryData, dataForTesting);
}
+ Map<SourceClassBuilder, macro.ClassDeclaration?> _classDeclarations = {};
Map<MemberBuilder, macro.Declaration?> _memberDeclarations = {};
// TODO(johnniwinther): Support all members.
@@ -153,35 +165,30 @@
_createMemberDeclaration(memberBuilder);
}
- macro.Declaration? _createMemberDeclaration(MemberBuilder memberBuilder) {
+ macro.ClassDeclaration _getClassDeclaration(SourceClassBuilder builder) {
+ return _classDeclarations[builder] ??= _createClassDeclaration(builder);
+ }
+
+ macro.Declaration _createMemberDeclaration(MemberBuilder memberBuilder) {
if (memberBuilder is SourceProcedureBuilder) {
- return createTopLevelFunctionDeclaration(memberBuilder);
+ return _createFunctionDeclaration(memberBuilder);
+ } else if (memberBuilder is SourceFieldBuilder) {
+ return _createVariableDeclaration(memberBuilder);
+ } else if (memberBuilder is SourceConstructorBuilder) {
+ return _createConstructorDeclaration(memberBuilder);
+ } else if (memberBuilder is SourceFactoryBuilder) {
+ return _createFactoryDeclaration(memberBuilder);
} else {
// TODO(johnniwinther): Throw when all members are supported.
- //throw new UnimplementedError('Unsupported member ${memberBuilder}');
- return null;
+ throw new UnimplementedError(
+ 'Unsupported member ${memberBuilder} (${memberBuilder.runtimeType})');
+ //return null;
}
}
- Future<List<macro.MacroExecutionResult>> _applyTypeMacros(
- macro.Declaration declaration,
- List<MacroApplication> macroApplications) async {
- List<macro.MacroExecutionResult> results = [];
- for (MacroApplication macroApplication in macroApplications) {
- if (macroApplication.instanceIdentifier.shouldExecute(
- // TODO(johnniwinther): Get the declaration kind from [declaration].
- macro.DeclarationKind.function,
- macro.Phase.types)) {
- macro.MacroExecutionResult result =
- await _macroExecutor.executeTypesPhase(
- macroApplication.instanceIdentifier, declaration);
- results.add(result);
- }
- }
- return results;
- }
-
- Future<void> applyTypeMacros() async {
+ Future<void> _applyMacros(
+ Future<void> Function(Builder, macro.Declaration, List<MacroApplication>)
+ applyMacros) async {
for (MapEntry<SourceLibraryBuilder,
LibraryMacroApplicationData> libraryEntry in libraryData.entries) {
LibraryMacroApplicationData libraryMacroApplicationData =
@@ -191,25 +198,67 @@
MemberBuilder memberBuilder = memberEntry.key;
macro.Declaration? declaration = _getMemberDeclaration(memberBuilder);
if (declaration != null) {
- List<macro.MacroExecutionResult> results =
- await _applyTypeMacros(declaration, memberEntry.value);
- dataForTesting?.memberTypesResults[memberBuilder] = results;
+ await applyMacros(memberBuilder, declaration, memberEntry.value);
+ }
+ }
+ for (MapEntry<SourceClassBuilder, ClassMacroApplicationData> classEntry
+ in libraryMacroApplicationData.classData.entries) {
+ SourceClassBuilder classBuilder = classEntry.key;
+ ClassMacroApplicationData classData = classEntry.value;
+ List<MacroApplication>? classApplications = classData.classApplications;
+ if (classApplications != null) {
+ macro.ClassDeclaration classDeclaration =
+ _getClassDeclaration(classBuilder);
+ await applyMacros(classBuilder, classDeclaration, classApplications);
+ }
+ for (MapEntry<MemberBuilder, List<MacroApplication>> memberEntry
+ in classData.memberApplications.entries) {
+ MemberBuilder memberBuilder = memberEntry.key;
+ macro.Declaration? declaration = _getMemberDeclaration(memberBuilder);
+ if (declaration != null) {
+ await applyMacros(memberBuilder, declaration, memberEntry.value);
+ }
}
}
}
}
- Future<List<macro.MacroExecutionResult>> _applyDeclarationMacros(
+ Future<List<macro.MacroExecutionResult>> _applyTypeMacros(
+ Builder builder,
macro.Declaration declaration,
- List<MacroApplication> macroApplications,
- macro.TypeResolver typeResolver,
- macro.ClassIntrospector classIntrospector) async {
+ List<MacroApplication> macroApplications) async {
+ List<macro.MacroExecutionResult> results = [];
+ for (MacroApplication macroApplication in macroApplications) {
+ if (macroApplication.instanceIdentifier
+ .shouldExecute(_declarationKind(declaration), macro.Phase.types)) {
+ macro.MacroExecutionResult result =
+ await _macroExecutor.executeTypesPhase(
+ macroApplication.instanceIdentifier, declaration);
+ results.add(result);
+ }
+ }
+ if (retainDataForTesting) {
+ if (builder is SourceClassBuilder) {
+ dataForTesting?.classTypesResults[builder] = results;
+ } else {
+ dataForTesting?.memberTypesResults[builder as MemberBuilder] = results;
+ }
+ }
+ return results;
+ }
+
+ Future<void> applyTypeMacros() async {
+ await _applyMacros(_applyTypeMacros);
+ }
+
+ Future<List<macro.MacroExecutionResult>> _applyDeclarationsMacros(
+ Builder builder,
+ macro.Declaration declaration,
+ List<MacroApplication> macroApplications) async {
List<macro.MacroExecutionResult> results = [];
for (MacroApplication macroApplication in macroApplications) {
if (macroApplication.instanceIdentifier.shouldExecute(
- // TODO(johnniwinther): Get the declaration kind from [declaration].
- macro.DeclarationKind.function,
- macro.Phase.declarations)) {
+ _declarationKind(declaration), macro.Phase.declarations)) {
macro.MacroExecutionResult result =
await _macroExecutor.executeDeclarationsPhase(
macroApplication.instanceIdentifier,
@@ -219,6 +268,14 @@
results.add(result);
}
}
+ if (retainDataForTesting) {
+ if (builder is SourceClassBuilder) {
+ dataForTesting?.classDeclarationsResults[builder] = results;
+ } else {
+ dataForTesting?.memberDeclarationsResults[builder as MemberBuilder] =
+ results;
+ }
+ }
return results;
}
@@ -226,40 +283,22 @@
late macro.TypeResolver typeResolver;
late macro.ClassIntrospector classIntrospector;
- Future<void> applyDeclarationMacros(ClassHierarchyBase classHierarchy) async {
+ Future<void> applyDeclarationsMacros(
+ ClassHierarchyBase classHierarchy) async {
types = new Types(classHierarchy);
typeResolver = new _TypeResolver(this);
classIntrospector = new _ClassIntrospector();
- for (MapEntry<SourceLibraryBuilder,
- LibraryMacroApplicationData> libraryEntry in libraryData.entries) {
- LibraryMacroApplicationData libraryMacroApplicationData =
- libraryEntry.value;
- for (MapEntry<MemberBuilder, List<MacroApplication>> memberEntry
- in libraryMacroApplicationData.memberApplications.entries) {
- MemberBuilder memberBuilder = memberEntry.key;
- macro.Declaration? declaration = _getMemberDeclaration(memberBuilder);
- if (declaration != null) {
- List<macro.MacroExecutionResult> results =
- await _applyDeclarationMacros(declaration, memberEntry.value,
- typeResolver, classIntrospector);
- dataForTesting?.memberDeclarationsResults[memberBuilder] = results;
- }
- }
- }
+ await _applyMacros(_applyDeclarationsMacros);
}
Future<List<macro.MacroExecutionResult>> _applyDefinitionMacros(
+ Builder builder,
macro.Declaration declaration,
- List<MacroApplication> macroApplications,
- macro.TypeResolver typeResolver,
- macro.ClassIntrospector classIntrospector,
- macro.TypeDeclarationResolver typeDeclarationResolver) async {
+ List<MacroApplication> macroApplications) async {
List<macro.MacroExecutionResult> results = [];
for (MacroApplication macroApplication in macroApplications) {
if (macroApplication.instanceIdentifier.shouldExecute(
- // TODO(johnniwinther): Get the declaration kind from [declaration].
- macro.DeclarationKind.function,
- macro.Phase.definitions)) {
+ _declarationKind(declaration), macro.Phase.definitions)) {
macro.MacroExecutionResult result =
await _macroExecutor.executeDefinitionsPhase(
macroApplication.instanceIdentifier,
@@ -270,28 +309,22 @@
results.add(result);
}
}
+ if (retainDataForTesting) {
+ if (builder is SourceClassBuilder) {
+ dataForTesting?.classDefinitionsResults[builder] = results;
+ } else {
+ dataForTesting?.memberDefinitionsResults[builder as MemberBuilder] =
+ results;
+ }
+ }
return results;
}
+ late macro.TypeDeclarationResolver typeDeclarationResolver;
+
Future<void> applyDefinitionMacros() async {
- macro.TypeDeclarationResolver typeDeclarationResolver =
- new _TypeDeclarationResolver();
- for (MapEntry<SourceLibraryBuilder,
- LibraryMacroApplicationData> libraryEntry in libraryData.entries) {
- LibraryMacroApplicationData libraryMacroApplicationData =
- libraryEntry.value;
- for (MapEntry<MemberBuilder, List<MacroApplication>> memberEntry
- in libraryMacroApplicationData.memberApplications.entries) {
- MemberBuilder memberBuilder = memberEntry.key;
- macro.Declaration? declaration = _getMemberDeclaration(memberBuilder);
- if (declaration != null) {
- List<macro.MacroExecutionResult> results =
- await _applyDefinitionMacros(declaration, memberEntry.value,
- typeResolver, classIntrospector, typeDeclarationResolver);
- dataForTesting?.memberDefinitionsResults[memberBuilder] = results;
- }
- }
- }
+ typeDeclarationResolver = new _TypeDeclarationResolver();
+ await _applyMacros(_applyDefinitionMacros);
}
void close() {
@@ -300,12 +333,27 @@
_typeAnnotationCache.clear();
}
- macro.FunctionDeclaration createTopLevelFunctionDeclaration(
- SourceProcedureBuilder builder) {
+ macro.ClassDeclaration _createClassDeclaration(SourceClassBuilder builder) {
+ return new macro.ClassDeclarationImpl(
+ id: macro.RemoteInstance.uniqueId,
+ identifier: new macro.IdentifierImpl(
+ id: macro.RemoteInstance.uniqueId, name: builder.name),
+ // TODO(johnniwinther): Support typeParameters
+ typeParameters: [],
+ // TODO(johnniwinther): Support interfaces
+ interfaces: [],
+ isAbstract: builder.isAbstract,
+ isExternal: builder.isExternal,
+ // TODO(johnniwinther): Support mixins
+ mixins: [],
+ // TODO(johnniwinther): Support superclass
+ superclass: null);
+ }
+
+ List<List<macro.ParameterDeclarationImpl>> _createParameters(
+ MemberBuilder builder, List<FormalParameterBuilder>? formals) {
List<macro.ParameterDeclarationImpl>? positionalParameters;
List<macro.ParameterDeclarationImpl>? namedParameters;
-
- List<FormalParameterBuilder>? formals = builder.formals;
if (formals == null) {
positionalParameters = namedParameters = const [];
} else {
@@ -336,21 +384,148 @@
}
}
}
+ return [positionalParameters, namedParameters];
+ }
- return new macro.FunctionDeclarationImpl(
- id: macro.RemoteInstance.uniqueId,
- identifier: new macro.IdentifierImpl(
- id: macro.RemoteInstance.uniqueId, name: builder.name),
- isAbstract: builder.isAbstract,
- isExternal: builder.isExternal,
- isGetter: builder.isGetter,
- isOperator: builder.isOperator,
- isSetter: builder.isSetter,
- positionalParameters: positionalParameters,
- namedParameters: namedParameters,
- returnType: computeTypeAnnotation(builder.library, builder.returnType),
- // TODO(johnniwinther): Support typeParameters
- typeParameters: const []);
+ macro.ConstructorDeclaration _createConstructorDeclaration(
+ SourceConstructorBuilder builder) {
+ List<FormalParameterBuilder>? formals = null;
+ // TODO(johnniwinther): Support formals for other constructors.
+ if (builder is DeclaredSourceConstructorBuilder) {
+ formals = builder.formals;
+ }
+ List<List<macro.ParameterDeclarationImpl>> parameters =
+ _createParameters(builder, formals);
+ macro.ClassDeclaration definingClass =
+ _getClassDeclaration(builder.classBuilder as SourceClassBuilder);
+ return new macro.ConstructorDeclarationImpl(
+ id: macro.RemoteInstance.uniqueId,
+ identifier: new macro.IdentifierImpl(
+ id: macro.RemoteInstance.uniqueId, name: builder.name),
+ definingClass: definingClass.identifier as macro.IdentifierImpl,
+ isFactory: builder.isFactory,
+ isAbstract: builder.isAbstract,
+ isExternal: builder.isExternal,
+ isGetter: builder.isGetter,
+ isOperator: builder.isOperator,
+ isSetter: builder.isSetter,
+ positionalParameters: parameters[0],
+ namedParameters: parameters[1],
+ // TODO(johnniwinther): Support constructor return type.
+ returnType: computeTypeAnnotation(builder.library, null),
+ // TODO(johnniwinther): Support typeParameters
+ typeParameters: const [],
+ );
+ }
+
+ macro.ConstructorDeclaration _createFactoryDeclaration(
+ SourceFactoryBuilder builder) {
+ List<List<macro.ParameterDeclarationImpl>> parameters =
+ _createParameters(builder, builder.formals);
+ macro.ClassDeclaration definingClass =
+ _getClassDeclaration(builder.classBuilder as SourceClassBuilder);
+
+ return new macro.ConstructorDeclarationImpl(
+ id: macro.RemoteInstance.uniqueId,
+ identifier: new macro.IdentifierImpl(
+ id: macro.RemoteInstance.uniqueId, name: builder.name),
+ definingClass: definingClass.identifier as macro.IdentifierImpl,
+ isFactory: builder.isFactory,
+ isAbstract: builder.isAbstract,
+ isExternal: builder.isExternal,
+ isGetter: builder.isGetter,
+ isOperator: builder.isOperator,
+ isSetter: builder.isSetter,
+ positionalParameters: parameters[0],
+ namedParameters: parameters[1],
+ // TODO(johnniwinther): Support constructor return type.
+ returnType: computeTypeAnnotation(builder.library, null),
+ // TODO(johnniwinther): Support typeParameters
+ typeParameters: const [],
+ );
+ }
+
+ macro.FunctionDeclaration _createFunctionDeclaration(
+ SourceProcedureBuilder builder) {
+ List<List<macro.ParameterDeclarationImpl>> parameters =
+ _createParameters(builder, builder.formals);
+
+ macro.ClassDeclaration? definingClass = null;
+ if (builder.classBuilder != null) {
+ definingClass =
+ _getClassDeclaration(builder.classBuilder as SourceClassBuilder);
+ }
+ if (definingClass != null) {
+ // TODO(johnniwinther): Should static fields be field or variable
+ // declarations?
+ return new macro.MethodDeclarationImpl(
+ id: macro.RemoteInstance.uniqueId,
+ identifier: new macro.IdentifierImpl(
+ id: macro.RemoteInstance.uniqueId, name: builder.name),
+ definingClass: definingClass.identifier as macro.IdentifierImpl,
+ isAbstract: builder.isAbstract,
+ isExternal: builder.isExternal,
+ isGetter: builder.isGetter,
+ isOperator: builder.isOperator,
+ isSetter: builder.isSetter,
+ positionalParameters: parameters[0],
+ namedParameters: parameters[1],
+ returnType:
+ computeTypeAnnotation(builder.library, builder.returnType),
+ // TODO(johnniwinther): Support typeParameters
+ typeParameters: const []);
+ } else {
+ return new macro.FunctionDeclarationImpl(
+ id: macro.RemoteInstance.uniqueId,
+ identifier: new macro.IdentifierImpl(
+ id: macro.RemoteInstance.uniqueId, name: builder.name),
+ isAbstract: builder.isAbstract,
+ isExternal: builder.isExternal,
+ isGetter: builder.isGetter,
+ isOperator: builder.isOperator,
+ isSetter: builder.isSetter,
+ positionalParameters: parameters[0],
+ namedParameters: parameters[1],
+ returnType:
+ computeTypeAnnotation(builder.library, builder.returnType),
+ // TODO(johnniwinther): Support typeParameters
+ typeParameters: const []);
+ }
+ }
+
+ macro.VariableDeclaration _createVariableDeclaration(
+ SourceFieldBuilder builder) {
+ macro.ClassDeclaration? definingClass = null;
+ if (builder.classBuilder != null) {
+ definingClass =
+ _getClassDeclaration(builder.classBuilder as SourceClassBuilder);
+ }
+ if (definingClass != null) {
+ // TODO(johnniwinther): Should static fields be field or variable
+ // declarations?
+ return new macro.FieldDeclarationImpl(
+ id: macro.RemoteInstance.uniqueId,
+ identifier: new macro.IdentifierImpl(
+ id: macro.RemoteInstance.uniqueId, name: builder.name),
+ definingClass: definingClass.identifier as macro.IdentifierImpl,
+ // TODO(johnniwinther): Support initializer.
+ initializer: null,
+ isExternal: builder.isExternal,
+ isFinal: builder.isFinal,
+ isLate: builder.isLate,
+ type: computeTypeAnnotation(builder.library, builder.type));
+ } else {
+ return new macro.VariableDeclarationImpl(
+ id: macro.RemoteInstance.uniqueId,
+ identifier: new macro.IdentifierImpl(
+ id: macro.RemoteInstance.uniqueId, name: builder.name),
+ // TODO(johnniwinther): Support initializer.
+ initializer: null,
+ isExternal: builder.isExternal,
+ isFinal: builder.isFinal,
+ isLate: builder.isLate,
+ type: computeTypeAnnotation(builder.library, builder.type));
+ }
}
Map<TypeBuilder?, _NamedTypeAnnotationImpl> _typeAnnotationCache = {};
@@ -535,3 +710,21 @@
throw new UnimplementedError('_TypeDeclarationResolver.declarationOf');
}
}
+
+macro.DeclarationKind _declarationKind(macro.Declaration declaration) {
+ if (declaration is macro.ConstructorDeclaration) {
+ return macro.DeclarationKind.constructor;
+ } else if (declaration is macro.MethodDeclaration) {
+ return macro.DeclarationKind.method;
+ } else if (declaration is macro.FunctionDeclaration) {
+ return macro.DeclarationKind.function;
+ } else if (declaration is macro.FieldDeclaration) {
+ return macro.DeclarationKind.field;
+ } else if (declaration is macro.VariableDeclaration) {
+ return macro.DeclarationKind.variable;
+ } else if (declaration is macro.ClassDeclaration) {
+ return macro.DeclarationKind.clazz;
+ }
+ throw new UnsupportedError(
+ "Unexpected declaration ${declaration} (${declaration.runtimeType})");
+}
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index 2ccd860..f1b940b 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -8,6 +8,7 @@
import 'package:kernel/class_hierarchy.dart';
import 'builder/builder.dart';
+import 'builder/class_builder.dart';
import 'builder/extension_builder.dart';
import 'builder/library_builder.dart';
import 'builder/member_builder.dart';
@@ -812,8 +813,13 @@
}
@override
+ ClassBuilder get classBuilder {
+ throw new UnsupportedError('AmbiguousMemberBuilder.classBuilder');
+ }
+
+ @override
LibraryBuilder get library {
- throw new UnsupportedError('AmbiguousMemberBuilder.parent=');
+ throw new UnsupportedError('AmbiguousMemberBuilder.library');
}
// TODO(johnniwinther): Remove this and create a [ProcedureBuilder] interface.
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 97db119..c46a77f 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -23,6 +23,7 @@
ScannerResult,
Token,
scan;
+import 'package:front_end/src/fasta/source/source_type_alias_builder.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart'
show ClassHierarchy, HandleAmbiguousSupertypes;
@@ -48,6 +49,7 @@
import '../builder/member_builder.dart';
import '../builder/modifier_builder.dart';
import '../builder/named_type_builder.dart';
+import '../builder/prefix_builder.dart';
import '../builder/procedure_builder.dart';
import '../builder/type_alias_builder.dart';
import '../builder/type_builder.dart';
@@ -86,6 +88,8 @@
import 'source_class_builder.dart' show SourceClassBuilder;
import 'source_constructor_builder.dart';
import 'source_enum_builder.dart';
+import 'source_extension_builder.dart';
+import 'source_factory_builder.dart';
import 'source_field_builder.dart';
import 'source_library_builder.dart'
show
@@ -1549,7 +1553,7 @@
scope: classBuilder.scope,
fileUri: classBuilder.fileUri,
metadataBuilders: classBuilder.metadata);
- builder.forEach((String name, Builder memberBuilder) {
+ classBuilder.forEach((String name, Builder memberBuilder) {
if (memberBuilder is SourceProcedureBuilder) {
List<MacroApplication>? macroApplications = prebuildAnnotations(
enclosingLibrary: libraryBuilder,
@@ -1570,6 +1574,9 @@
classMacroApplicationData.memberApplications[memberBuilder] =
macroApplications;
}
+ } else {
+ throw new UnsupportedError("Unexpected class member "
+ "$memberBuilder (${memberBuilder.runtimeType})");
}
});
classBuilder.forEachConstructor((String name, Builder memberBuilder) {
@@ -1583,6 +1590,19 @@
classMacroApplicationData.memberApplications[memberBuilder] =
macroApplications;
}
+ } else if (memberBuilder is SourceFactoryBuilder) {
+ List<MacroApplication>? macroApplications = prebuildAnnotations(
+ enclosingLibrary: libraryBuilder,
+ scope: classBuilder.scope,
+ fileUri: memberBuilder.fileUri,
+ metadataBuilders: memberBuilder.metadata);
+ if (macroApplications != null) {
+ classMacroApplicationData.memberApplications[memberBuilder] =
+ macroApplications;
+ }
+ } else {
+ throw new UnsupportedError("Unexpected constructor "
+ "$memberBuilder (${memberBuilder.runtimeType})");
}
});
@@ -1611,6 +1631,13 @@
libraryMacroApplicationData.memberApplications[builder] =
macroApplications;
}
+ } else if (builder is PrefixBuilder ||
+ builder is SourceExtensionBuilder ||
+ builder is SourceTypeAliasBuilder) {
+ // Macro applications are not supported.
+ } else {
+ throw new UnsupportedError("Unexpected library member "
+ "$builder (${builder.runtimeType})");
}
}
if (libraryMacroApplicationData.classData.isNotEmpty ||
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 7b57f38..23e4ee1 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
@@ -5,28 +5,32 @@
import 'dart:async';
import 'package:_fe_analyzer_shared/src/macros/api.dart';
-macro class FunctionDefinitionMacro1 implements FunctionDefinitionMacro {
+macro
+
+class FunctionDefinitionMacro1 implements FunctionDefinitionMacro {
const FunctionDefinitionMacro1();
- FutureOr<void> buildDefinitionForFunction(
- FunctionDeclaration function, FunctionDefinitionBuilder builder) {
- builder.augment(new FunctionBodyCode.fromString('''{
+ FutureOr<void> buildDefinitionForFunction(FunctionDeclaration function,
+ FunctionDefinitionBuilder builder) {
+ builder.augment(new FunctionBodyCode.fromString('''{
return 42;
}'''));
}
}
-macro class FunctionDefinitionMacro2 implements FunctionDefinitionMacro {
+macro
+
+class FunctionDefinitionMacro2 implements FunctionDefinitionMacro {
const FunctionDefinitionMacro2();
- FutureOr<void> buildDefinitionForFunction(
- FunctionDeclaration function, FunctionDefinitionBuilder builder) async {
+ FutureOr<void> buildDefinitionForFunction(FunctionDeclaration function,
+ FunctionDefinitionBuilder builder) async {
if (function.positionalParameters.isEmpty) {
return;
}
StaticType returnType = await builder.instantiateType(function.returnType);
StaticType parameterType =
- await builder.instantiateType(function.positionalParameters.first.type);
+ await builder.instantiateType(function.positionalParameters.first.type);
builder.augment(new FunctionBodyCode.fromString('''{
print('isExactly=${await returnType.isExactly(parameterType)}');
print('isSubtype=${await returnType.isSubtypeOf(parameterType)}');
@@ -35,38 +39,60 @@
}
-macro class FunctionTypesMacro1 implements FunctionTypesMacro {
+macro
+
+class FunctionTypesMacro1 implements FunctionTypesMacro {
const FunctionTypesMacro1();
- FutureOr<void> buildTypesForFunction(
- FunctionDeclaration function, TypeBuilder builder) {
- var name = '${function.identifier.name}GeneratedClass';
+ FutureOr<void> buildTypesForFunction(FunctionDeclaration function,
+ TypeBuilder builder) {
+ var name = '${function.identifier.name}GeneratedClass';
builder.declareType(name, new DeclarationCode.fromString('class $name {}'));
}
}
-macro class FunctionDeclarationsMacro1 implements FunctionDeclarationsMacro {
+macro
+
+class FunctionDeclarationsMacro1 implements FunctionDeclarationsMacro {
const FunctionDeclarationsMacro1();
- FutureOr<void> buildDeclarationsForFunction(
- FunctionDeclaration function, DeclarationBuilder builder) {
+ FutureOr<void> buildDeclarationsForFunction(FunctionDeclaration function,
+ DeclarationBuilder builder) {
+ StringBuffer sb = new StringBuffer();
+ if (function.isAbstract) {
+ sb.write('a');
+ }
+ if (function.isExternal) {
+ sb.write('e');
+ }
+ if (function.isGetter) {
+ sb.write('g');
+ }
+ if (function.isOperator) {
+ sb.write('o');
+ }
+ if (function.isSetter) {
+ sb.write('s');
+ }
builder.declareInLibrary(new DeclarationCode.fromString('''
-void ${function.identifier.name}GeneratedMethod() {}
+void ${function.identifier.name}GeneratedMethod_${sb}() {}
'''));
}
}
-macro class FunctionDeclarationsMacro2 implements FunctionDeclarationsMacro {
+macro
+
+class FunctionDeclarationsMacro2 implements FunctionDeclarationsMacro {
const FunctionDeclarationsMacro2();
- FutureOr<void> buildDeclarationsForFunction(
- FunctionDeclaration function, DeclarationBuilder builder) async {
+ FutureOr<void> buildDeclarationsForFunction(FunctionDeclaration function,
+ DeclarationBuilder builder) async {
if (function.positionalParameters.isEmpty) {
return;
}
StaticType returnType = await builder.instantiateType(function.returnType);
StaticType parameterType =
- await builder.instantiateType(function.positionalParameters.first.type);
+ await builder.instantiateType(function.positionalParameters.first.type);
bool isExactly = await returnType.isExactly(parameterType);
bool isSubtype = await returnType.isSubtypeOf(parameterType);
String tag = '${isExactly ? 'e' : ''}${isSubtype ? 's' : ''}';
@@ -75,3 +101,133 @@
'''));
}
}
+
+macro
+
+class MethodDeclarationsMacro1 implements MethodDeclarationsMacro {
+ const MethodDeclarationsMacro1();
+
+ FutureOr<void> buildDeclarationsForMethod(MethodDeclaration method,
+ ClassMemberDeclarationBuilder builder) {
+ StringBuffer sb = new StringBuffer();
+ if (method.isAbstract) {
+ sb.write('a');
+ }
+ if (method.isExternal) {
+ sb.write('e');
+ }
+ if (method.isGetter) {
+ sb.write('g');
+ }
+ if (method.isOperator) {
+ sb.write('o');
+ }
+ if (method.isSetter) {
+ sb.write('s');
+ }
+ builder.declareInLibrary(new DeclarationCode.fromString('''
+void ${method.definingClass.name}_${method.identifier.name}GeneratedMethod_${sb}() {}
+'''));
+ }
+}
+
+macro
+
+class VariableDeclarationsMacro1 implements VariableDeclarationsMacro {
+ const VariableDeclarationsMacro1();
+
+ FutureOr<void> buildDeclarationsForVariable(VariableDeclaration variable,
+ DeclarationBuilder builder) {
+ StringBuffer sb = new StringBuffer();
+ if (variable.isExternal) {
+ sb.write('e');
+ }
+ if (variable.isFinal) {
+ sb.write('f');
+ }
+ if (variable.isLate) {
+ sb.write('l');
+ }
+ builder.declareInLibrary(new DeclarationCode.fromString('''
+void ${variable.identifier.name}GeneratedMethod_${sb}() {}
+'''));
+ }
+}
+
+macro
+
+class FieldDeclarationsMacro1 implements FieldDeclarationsMacro {
+ const FieldDeclarationsMacro1();
+
+ FutureOr<void> buildDeclarationsForField(FieldDeclaration field,
+ ClassMemberDeclarationBuilder builder) {
+ StringBuffer sb = new StringBuffer();
+ if (field.isExternal) {
+ sb.write('e');
+ }
+ if (field.isFinal) {
+ sb.write('f');
+ }
+ if (field.isLate) {
+ sb.write('l');
+ }
+ builder.declareInLibrary(new DeclarationCode.fromString('''
+void ${field.definingClass.name}_${field.identifier.name}GeneratedMethod_${sb}() {}
+'''));
+ }
+}
+
+macro
+
+class ClassDeclarationsMacro1 implements ClassDeclarationsMacro {
+ const ClassDeclarationsMacro1();
+
+ FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
+ ClassMemberDeclarationBuilder builder) {
+ StringBuffer sb = new StringBuffer();
+ if (clazz.isAbstract) {
+ sb.write('a');
+ }
+ if (clazz.isExternal) {
+ sb.write('e');
+ }
+ builder.declareInLibrary(new DeclarationCode.fromString('''
+void ${clazz.identifier.name}GeneratedMethod_${sb}() {}
+'''));
+ }
+}
+
+macro
+
+class ConstructorDeclarationsMacro1
+ implements ConstructorDeclarationsMacro {
+ const ConstructorDeclarationsMacro1();
+
+ FutureOr<void> buildDeclarationsForConstructor(
+ ConstructorDeclaration constructor,
+ ClassMemberDeclarationBuilder builder) {
+ StringBuffer sb = new StringBuffer();
+ if (constructor.isAbstract) {
+ sb.write('a');
+ }
+ if (constructor.isExternal) {
+ sb.write('e');
+ }
+ if (constructor.isGetter) {
+ sb.write('g');
+ }
+ if (constructor.isOperator) {
+ sb.write('o');
+ }
+ if (constructor.isSetter) {
+ sb.write('s');
+ }
+ if (constructor.isFactory) {
+ sb.write('f');
+ }
+ builder.declareInClass(new DeclarationCode.fromString('''
+void ${constructor.definingClass.name}_${constructor.identifier
+ .name}GeneratedMethod_${sb}() {}
+'''));
+ }
+}
diff --git a/pkg/front_end/test/macro_application/data/tests/declarations.dart b/pkg/front_end/test/macro_application/data/tests/declarations.dart
index a992685..cf13538 100644
--- a/pkg/front_end/test/macro_application/data/tests/declarations.dart
+++ b/pkg/front_end/test/macro_application/data/tests/declarations.dart
@@ -5,13 +5,139 @@
import 'package:macro/macro.dart';
/*member: topLevelFunction1:
-void topLevelFunction1GeneratedMethod() {}
+void topLevelFunction1GeneratedMethod_() {}
*/
@FunctionDeclarationsMacro1()
void topLevelFunction1() {}
-@FunctionDeclarationsMacro1()
/*member: topLevelFunction2:
-void topLevelFunction2GeneratedMethod() {}
+void topLevelFunction2GeneratedMethod_e() {}
*/
-void topLevelFunction2() {}
+@FunctionDeclarationsMacro1()
+external void topLevelFunction2();
+
+/*member: topLevelField1:
+void topLevelField1GeneratedMethod_() {}
+*/
+@VariableDeclarationsMacro1()
+int? topLevelField1;
+
+/*member: topLevelField2:
+void topLevelField2GeneratedMethod_e() {}
+*/
+@VariableDeclarationsMacro1()
+external int? topLevelField2;
+
+/*member: topLevelField3:
+void topLevelField3GeneratedMethod_f() {}
+*/
+@VariableDeclarationsMacro1()
+final int? topLevelField3 = null;
+
+/*member: topLevelField4:
+void topLevelField4GeneratedMethod_l() {}
+*/
+@VariableDeclarationsMacro1()
+late int? topLevelField4;
+
+/*member: topLevelGetter1:
+void topLevelGetter1GeneratedMethod_g() {}
+*/
+@FunctionDeclarationsMacro1()
+int? get topLevelGetter1 => null;
+
+/*member: topLevelSetter1=:
+void topLevelSetter1GeneratedMethod_s() {}
+*/
+@FunctionDeclarationsMacro1()
+void set topLevelSetter1(int? value) {}
+
+/*class: Class1:
+void Class1GeneratedMethod_() {}
+*/
+@ClassDeclarationsMacro1()
+class Class1 {
+ /*member: Class1.:
+augment class Class1 {
+void Class1_GeneratedMethod_() {}
+
+}*/
+ @ConstructorDeclarationsMacro1()
+ Class1();
+
+ /*member: Class1.redirect:
+augment class Class1 {
+void Class1_redirectGeneratedMethod_f() {}
+
+}*/
+ @ConstructorDeclarationsMacro1()
+ factory Class1.redirect() = Class1;
+
+ /*member: Class1.fact:
+augment class Class1 {
+void Class1_factGeneratedMethod_f() {}
+
+}*/
+ @ConstructorDeclarationsMacro1()
+ factory Class1.fact() => new Class1();
+
+ /*member: Class1.instanceMethod1:
+void Class1_instanceMethod1GeneratedMethod_() {}
+*/
+ @MethodDeclarationsMacro1()
+ void instanceMethod1() {}
+
+ /*member: Class1.instanceGetter1:
+void Class1_instanceGetter1GeneratedMethod_g() {}
+*/
+ @MethodDeclarationsMacro1()
+ int? get instanceGetter1 => null;
+
+ /*member: Class1.instanceSetter1=:
+void Class1_instanceSetter1GeneratedMethod_s() {}
+*/
+ @MethodDeclarationsMacro1()
+ void set instanceSetter1(int? value) {}
+
+ /*member: Class1.[]:
+void Class1_[]GeneratedMethod_o() {}
+*/
+ @MethodDeclarationsMacro1()
+ int operator [](int i) => i;
+
+ /*member: Class1.instanceField1:
+void Class1_instanceField1GeneratedMethod_() {}
+*/
+ @FieldDeclarationsMacro1()
+ int? instanceField1;
+
+ /*member: Class1.instanceField2:
+void Class1_instanceField2GeneratedMethod_f() {}
+*/
+ @FieldDeclarationsMacro1()
+ final int? instanceField2 = null;
+
+ /*member: Class1.instanceField3:
+void Class1_instanceField3GeneratedMethod_fl() {}
+*/
+ @FieldDeclarationsMacro1()
+ late final int? instanceField3 = null;
+}
+
+/*class: Class2:
+void Class2GeneratedMethod_a() {}
+*/
+@ClassDeclarationsMacro1()
+abstract class Class2 {
+ /*member: Class2.instanceMethod1:
+void Class2_instanceMethod1GeneratedMethod_a() {}
+*/
+ @MethodDeclarationsMacro1()
+ void instanceMethod1();
+
+ /*member: Class2.instanceField1:
+void Class2_instanceField1GeneratedMethod_() {}
+*/
+ @FieldDeclarationsMacro1()
+ abstract int? instanceField1;
+}
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 45ae3a5..42cbb6a 100644
--- a/pkg/front_end/test/macro_application/macro_application_test.dart
+++ b/pkg/front_end/test/macro_application/macro_application_test.dart
@@ -9,14 +9,17 @@
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
import 'package:_fe_analyzer_shared/src/macros/isolated_executor/isolated_executor.dart'
as isolatedExecutor;
-import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
+import 'package:_fe_analyzer_shared/src/testing/id.dart'
+ show ActualData, ClassId, Id;
import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart';
import 'package:front_end/src/api_prototype/kernel_generator.dart';
+import 'package:front_end/src/fasta/builder/field_builder.dart';
import 'package:front_end/src/fasta/builder/member_builder.dart';
import 'package:front_end/src/fasta/kernel/macro.dart';
import 'package:front_end/src/fasta/kernel/utils.dart';
+import 'package:front_end/src/fasta/source/source_class_builder.dart';
import 'package:front_end/src/testing/compiler_common.dart';
import 'package:front_end/src/testing/id_extractor.dart';
import 'package:front_end/src/testing/id_testing_helper.dart';
@@ -32,6 +35,11 @@
'FunctionTypesMacro1': [''],
'FunctionDeclarationsMacro1': [''],
'FunctionDeclarationsMacro2': [''],
+ 'MethodDeclarationsMacro1': [''],
+ 'VariableDeclarationsMacro1': [''],
+ 'FieldDeclarationsMacro1': [''],
+ 'ClassDeclarationsMacro1': [''],
+ 'ConstructorDeclarationsMacro1': [''],
}
};
@@ -95,6 +103,19 @@
}
}
+bool _isMember(MemberBuilder memberBuilder, Member member) {
+ if (memberBuilder is FieldBuilder) {
+ // Only show annotations for the field or getter.
+ return memberBuilder.readTarget == member;
+ } else if (member is Procedure && member.isSetter) {
+ return memberBuilder.writeTarget == member;
+ } else if (member is Procedure && member.isGetter) {
+ return memberBuilder.readTarget == member;
+ } else {
+ return memberBuilder.invokeTarget == member;
+ }
+}
+
class MacroDataComputer extends DataComputer<String> {
const MacroDataComputer();
@@ -102,6 +123,50 @@
DataInterpreter<String> get dataValidator => const StringDataInterpreter();
@override
+ void computeClassData(TestResultData testResultData, Class cls,
+ Map<Id, ActualData<String>> actualMap,
+ {bool? verbose}) {
+ CfeDataRegistry<String> registry =
+ new CfeDataRegistry(testResultData.compilerResult, actualMap);
+ MacroApplicationDataForTesting macroApplicationData = testResultData
+ .compilerResult
+ .kernelTargetForTesting!
+ .loader
+ .dataForTesting!
+ .macroApplicationData;
+ StringBuffer sb = new StringBuffer();
+ for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
+ in macroApplicationData.classTypesResults.entries) {
+ if (entry.key.cls == cls) {
+ for (MacroExecutionResult result in entry.value) {
+ sb.write('\n${codeToString(result.augmentations.first)}');
+ }
+ }
+ }
+ for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
+ in macroApplicationData.classDeclarationsResults.entries) {
+ if (entry.key.cls == cls) {
+ for (MacroExecutionResult result in entry.value) {
+ sb.write('\n${codeToString(result.augmentations.first)}');
+ }
+ }
+ }
+ for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
+ in macroApplicationData.classDefinitionsResults.entries) {
+ if (entry.key.cls == cls) {
+ for (MacroExecutionResult result in entry.value) {
+ sb.write('\n${codeToString(result.augmentations.first)}');
+ }
+ }
+ }
+ if (sb.isNotEmpty) {
+ Id id = new ClassId(cls.name);
+ registry.registerValue(
+ cls.fileUri, cls.fileOffset, id, sb.toString(), cls);
+ }
+ }
+
+ @override
void computeMemberData(TestResultData testResultData, Member member,
Map<Id, ActualData<String>> actualMap,
{bool? verbose}) {
@@ -116,7 +181,7 @@
StringBuffer sb = new StringBuffer();
for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry
in macroApplicationData.memberTypesResults.entries) {
- if (entry.key.member == member) {
+ if (_isMember(entry.key, member)) {
for (MacroExecutionResult result in entry.value) {
sb.write('\n${codeToString(result.augmentations.first)}');
}
@@ -124,7 +189,7 @@
}
for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry
in macroApplicationData.memberDeclarationsResults.entries) {
- if (entry.key.member == member) {
+ if (_isMember(entry.key, member)) {
for (MacroExecutionResult result in entry.value) {
sb.write('\n${codeToString(result.augmentations.first)}');
}
@@ -132,7 +197,7 @@
}
for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry
in macroApplicationData.memberDefinitionsResults.entries) {
- if (entry.key.member == member) {
+ if (_isMember(entry.key, member)) {
for (MacroExecutionResult result in entry.value) {
sb.write('\n${codeToString(result.augmentations.first)}');
}
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 3300b99..b71a7ff 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -269,6 +269,7 @@
filters
fisk
five
+fl
floor
fluctuate
foo'bar'baz
diff --git a/tools/VERSION b/tools/VERSION
index ff3bbc2..18e7a2b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 81
+PRERELEASE 82
PRERELEASE_PATCH 0
\ No newline at end of file