[cfe] Support library macro applications

Change-Id: Ia2de239e56072e4fca22964b53dc8e7adcb415a2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/353264
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther 2024-02-22 09:10:38 +00:00 committed by Commit Queue
parent 42f7af2cb9
commit dc71c1ee4e
4 changed files with 241 additions and 202 deletions

View file

@ -138,7 +138,7 @@ class MacroIntrospection {
}
}
macro.LibraryImpl _libraryFor(LibraryBuilder builder) {
macro.LibraryImpl getLibrary(LibraryBuilder builder) {
return _libraries[builder] ??= () {
final Version version = builder.library.languageVersion;
return new macro.LibraryImpl(
@ -183,7 +183,7 @@ class MacroIntrospection {
final List<macro.NamedTypeAnnotationImpl> interfaces =
types.typeBuildersToAnnotations(
builder.libraryBuilder, builder.interfaceBuilders);
final macro.LibraryImpl library = _libraryFor(builder.libraryBuilder);
final macro.LibraryImpl library = getLibrary(builder.libraryBuilder);
macro.ParameterizedTypeDeclaration declaration = builder.isMixinDeclaration
? new macro.MixinDeclarationImpl(
@ -228,7 +228,7 @@ class MacroIntrospection {
macro.TypeAliasDeclaration _createTypeAliasDeclaration(
TypeAliasBuilder builder) {
final macro.LibraryImpl library = _libraryFor(builder.libraryBuilder);
final macro.LibraryImpl library = getLibrary(builder.libraryBuilder);
macro.TypeAliasDeclaration declaration = new macro.TypeAliasDeclarationImpl(
id: macro.RemoteInstance.uniqueId,
identifier: new TypeDeclarationBuilderIdentifier(
@ -255,7 +255,7 @@ class MacroIntrospection {
} else {
positionalParameters = [];
namedParameters = [];
final macro.LibraryImpl library = _libraryFor(builder.libraryBuilder);
final macro.LibraryImpl library = getLibrary(builder.libraryBuilder);
for (FormalParameterBuilder formal in formals) {
macro.TypeAnnotationImpl type =
types.computeTypeAnnotation(builder.libraryBuilder, formal.type);
@ -309,7 +309,7 @@ class MacroIntrospection {
memberBuilder: builder,
id: macro.RemoteInstance.uniqueId,
name: builder.name),
library: _libraryFor(builder.libraryBuilder),
library: getLibrary(builder.libraryBuilder),
// TODO: Provide metadata annotations.
metadata: const [],
definingType: definingClass.identifier as macro.IdentifierImpl,
@ -340,7 +340,7 @@ class MacroIntrospection {
memberBuilder: builder,
id: macro.RemoteInstance.uniqueId,
name: builder.name),
library: _libraryFor(builder.libraryBuilder),
library: getLibrary(builder.libraryBuilder),
// TODO: Provide metadata annotations.
metadata: const [],
definingType: definingClass.identifier as macro.IdentifierImpl,
@ -366,7 +366,7 @@ class MacroIntrospection {
if (builder.classBuilder != null) {
definingClass = getClassDeclaration(builder.classBuilder!);
}
final macro.LibraryImpl library = _libraryFor(builder.libraryBuilder);
final macro.LibraryImpl library = getLibrary(builder.libraryBuilder);
if (definingClass != null) {
// TODO(johnniwinther): Should static fields be field or variable
// declarations?
@ -424,7 +424,7 @@ class MacroIntrospection {
if (builder.classBuilder != null) {
definingClass = getClassDeclaration(builder.classBuilder!);
}
final macro.LibraryImpl library = _libraryFor(builder.libraryBuilder);
final macro.LibraryImpl library = getLibrary(builder.libraryBuilder);
if (definingClass != null) {
// TODO(johnniwinther): Should static fields be field or variable
// declarations?

View file

@ -101,61 +101,63 @@ class MacroApplicationDataForTesting {
Map<SourceLibraryBuilder, String> libraryTypesResult = {};
Map<SourceLibraryBuilder, String> libraryDefinitionResult = {};
Map<SourceClassBuilder, List<macro.MacroExecutionResult>> classTypesResults =
Map<SourceLibraryBuilder, MacroExecutionResultsForTesting> libraryResults =
{};
Map<SourceClassBuilder, List<macro.MacroExecutionResult>>
classDeclarationsResults = {};
Map<SourceClassBuilder, List<String>> classDeclarationsSources = {};
Map<SourceClassBuilder, List<macro.MacroExecutionResult>>
classDefinitionsResults = {};
Map<MemberBuilder, List<macro.MacroExecutionResult>> memberTypesResults = {};
Map<MemberBuilder, List<String>> memberTypesSources = {};
Map<MemberBuilder, List<macro.MacroExecutionResult>>
memberDeclarationsResults = {};
Map<MemberBuilder, List<String>> memberDeclarationsSources = {};
Map<MemberBuilder, List<macro.MacroExecutionResult>>
memberDefinitionsResults = {};
Map<SourceClassBuilder, MacroExecutionResultsForTesting> classResults = {};
Map<MemberBuilder, MacroExecutionResultsForTesting> memberResults = {};
List<ApplicationDataForTesting> typesApplicationOrder = [];
List<ApplicationDataForTesting> declarationsApplicationOrder = [];
List<ApplicationDataForTesting> definitionApplicationOrder = [];
MacroExecutionResultsForTesting _getResultsForTesting(Builder builder) {
MacroExecutionResultsForTesting resultsForTesting;
if (builder is SourceLibraryBuilder) {
resultsForTesting =
libraryResults[builder] ??= new MacroExecutionResultsForTesting();
} else if (builder is SourceClassBuilder) {
resultsForTesting =
classResults[builder] ??= new MacroExecutionResultsForTesting();
} else {
resultsForTesting = memberResults[builder as MemberBuilder] ??=
new MacroExecutionResultsForTesting();
}
return resultsForTesting;
}
void registerTypesResults(
Builder builder, List<macro.MacroExecutionResult> results) {
if (builder is SourceClassBuilder) {
(classTypesResults[builder] ??= []).addAll(results);
} else {
(memberTypesResults[builder as MemberBuilder] ??= []).addAll(results);
}
_getResultsForTesting(builder).typesResults.addAll(results);
}
void registerDeclarationsResult(
Builder builder, macro.MacroExecutionResult result, String source) {
if (builder is SourceClassBuilder) {
(classDeclarationsResults[builder] ??= []).add(result);
(classDeclarationsSources[builder] ??= []).add(source);
} else {
(memberDeclarationsResults[builder as MemberBuilder] ??= []).add(result);
(memberDeclarationsSources[builder] ??= []).add(source);
}
MacroExecutionResultsForTesting resultsForTesting =
_getResultsForTesting(builder);
resultsForTesting.declarationsResults.add(result);
resultsForTesting.declarationsSources.add(source);
}
void registerDeclarationsResults(
Builder builder, List<macro.MacroExecutionResult> results) {
MacroExecutionResultsForTesting resultsForTesting =
_getResultsForTesting(builder);
resultsForTesting.declarationsResults.addAll(results);
}
void registerDefinitionsResults(
Builder builder, List<macro.MacroExecutionResult> results) {
if (builder is SourceClassBuilder) {
(classDefinitionsResults[builder] ??= []).addAll(results);
} else {
(memberDefinitionsResults[builder as MemberBuilder] ??= [])
.addAll(results);
}
_getResultsForTesting(builder).definitionsResults.addAll(results);
}
}
class MacroExecutionResultsForTesting {
List<macro.MacroExecutionResult> typesResults = [];
List<macro.MacroExecutionResult> declarationsResults = [];
List<String> declarationsSources = [];
List<macro.MacroExecutionResult> definitionsResults = [];
}
class ApplicationDataForTesting {
final ApplicationData applicationData;
final MacroApplication macroApplication;
@ -182,6 +184,7 @@ class ApplicationDataForTesting {
}
class LibraryMacroApplicationData {
ApplicationData? libraryApplications;
Map<SourceClassBuilder, ClassMacroApplicationData> classData = {};
Map<MemberBuilder, ApplicationData> memberApplications = {};
}
@ -365,6 +368,18 @@ class MacroApplications {
// TODO(johnniwinther): Handle augmentation libraries.
LibraryMacroApplicationData libraryMacroApplicationData =
new LibraryMacroApplicationData();
List<MacroApplication>? libraryMacroApplications = prebuildAnnotations(
enclosingLibrary: libraryBuilder,
scope: libraryBuilder.scope,
fileUri: libraryBuilder.fileUri,
metadataBuilders: libraryBuilder.metadata);
if (libraryMacroApplications != null) {
libraryMacroApplicationData.libraryApplications =
new LibraryApplicationData(
_macroIntrospection, libraryBuilder, libraryMacroApplications);
}
Iterator<Builder> iterator = libraryBuilder.localMembersIterator;
while (iterator.moveNext()) {
Builder builder = iterator.current;
@ -531,6 +546,8 @@ class MacroApplications {
}
for (LibraryMacroApplicationData libraryData in _pendingLibraryData) {
await ensureMacroClassIds(
libraryData.libraryApplications?.macroApplications);
for (ClassMacroApplicationData classData
in libraryData.classData.values) {
await ensureMacroClassIds(
@ -551,7 +568,7 @@ class MacroApplications {
Future<List<macro.MacroExecutionResult>> _applyTypeMacros(
SourceLibraryBuilder originLibraryBuilder,
ApplicationData applicationData) async {
macro.Declaration declaration = applicationData.declaration;
macro.MacroTarget macroTarget = applicationData.macroTarget;
List<macro.MacroExecutionResult> results = [];
for (MacroApplication macroApplication
in applicationData.macroApplications) {
@ -562,7 +579,7 @@ class MacroApplications {
continue;
}
if (macroApplication.instanceIdentifier
.shouldExecute(_declarationKind(declaration), macro.Phase.types)) {
.shouldExecute(applicationData.declarationKind, macro.Phase.types)) {
if (retainDataForTesting) {
dataForTesting!.typesApplicationOrder.add(
new ApplicationDataForTesting(applicationData, macroApplication));
@ -570,7 +587,7 @@ class MacroApplications {
macro.MacroExecutionResult result =
await _macroExecutor.executeTypesPhase(
macroApplication.instanceIdentifier,
declaration,
macroTarget,
_macroIntrospection.typePhaseIntrospector);
result.reportDiagnostics(applicationData);
if (result.isNotEmpty) {
@ -599,6 +616,12 @@ class MacroApplications {
List<macro.MacroExecutionResult> executionResults = [];
SourceLibraryBuilder libraryBuilder = entry.key;
LibraryMacroApplicationData data = entry.value;
ApplicationData? libraryData = data.libraryApplications;
if (libraryData != null) {
executionResults
.addAll(await _applyTypeMacros(libraryBuilder.origin, libraryData));
}
for (ApplicationData applicationData in data.memberApplications.values) {
executionResults.addAll(
await _applyTypeMacros(libraryBuilder.origin, applicationData));
@ -667,7 +690,7 @@ class MacroApplications {
ApplicationData applicationData,
Future<void> Function(SourceLibraryBuilder) onAugmentationLibrary) async {
List<macro.MacroExecutionResult> results = [];
macro.Declaration declaration = applicationData.declaration;
macro.MacroTarget macroTarget = applicationData.macroTarget;
for (MacroApplication macroApplication
in applicationData.macroApplications) {
if (!macroApplication.appliedPhases.add(macro.Phase.declarations)) {
@ -677,7 +700,7 @@ class MacroApplications {
continue;
}
if (macroApplication.instanceIdentifier.shouldExecute(
_declarationKind(declaration), macro.Phase.declarations)) {
applicationData.declarationKind, macro.Phase.declarations)) {
if (retainDataForTesting) {
dataForTesting!.declarationsApplicationOrder.add(
new ApplicationDataForTesting(applicationData, macroApplication));
@ -685,7 +708,7 @@ class MacroApplications {
macro.MacroExecutionResult result =
await _macroExecutor.executeDeclarationsPhase(
macroApplication.instanceIdentifier,
declaration,
macroTarget,
_macroIntrospection.declarationPhaseIntrospector);
result.reportDiagnostics(applicationData);
if (result.isNotEmpty) {
@ -722,12 +745,7 @@ class MacroApplications {
}
if (retainDataForTesting) {
Builder builder = applicationData.builder;
if (builder is SourceClassBuilder) {
dataForTesting?.classDeclarationsResults[builder] = results;
} else {
dataForTesting?.memberDeclarationsResults[builder as MemberBuilder] =
results;
}
dataForTesting?.registerDeclarationsResults(builder, results);
}
}
@ -779,6 +797,13 @@ class MacroApplications {
in _libraryData.entries) {
SourceLibraryBuilder libraryBuilder = entry.key;
LibraryMacroApplicationData data = entry.value;
ApplicationData? libraryData = data.libraryApplications;
if (libraryData != null) {
await _applyDeclarationsMacros(
libraryBuilder.origin, libraryData, onAugmentationLibrary);
}
for (ApplicationData applicationData in data.memberApplications.values) {
await _applyDeclarationsMacros(
libraryBuilder.origin, applicationData, onAugmentationLibrary);
@ -790,7 +815,7 @@ class MacroApplications {
SourceLibraryBuilder originLibraryBuilder,
ApplicationData applicationData) async {
List<macro.MacroExecutionResult> results = [];
macro.Declaration declaration = applicationData.declaration;
macro.MacroTarget macroTarget = applicationData.macroTarget;
for (MacroApplication macroApplication
in applicationData.macroApplications) {
if (!macroApplication.appliedPhases.add(macro.Phase.definitions)) {
@ -800,7 +825,7 @@ class MacroApplications {
continue;
}
if (macroApplication.instanceIdentifier.shouldExecute(
_declarationKind(declaration), macro.Phase.definitions)) {
applicationData.declarationKind, macro.Phase.definitions)) {
if (retainDataForTesting) {
dataForTesting!.definitionApplicationOrder.add(
new ApplicationDataForTesting(applicationData, macroApplication));
@ -808,7 +833,7 @@ class MacroApplications {
macro.MacroExecutionResult result =
await _macroExecutor.executeDefinitionsPhase(
macroApplication.instanceIdentifier,
declaration,
macroTarget,
_macroIntrospection.definitionPhaseIntrospector);
result.reportDiagnostics(applicationData);
if (result.isNotEmpty) {
@ -837,6 +862,12 @@ class MacroApplications {
List<macro.MacroExecutionResult> executionResults = [];
SourceLibraryBuilder libraryBuilder = entry.key;
LibraryMacroApplicationData data = entry.value;
ApplicationData? libraryData = data.libraryApplications;
if (libraryData != null) {
executionResults.addAll(
await _applyDefinitionMacros(libraryBuilder.origin, libraryData));
}
for (ApplicationData applicationData in data.memberApplications.values) {
executionResults.addAll(await _applyDefinitionMacros(
libraryBuilder.origin, applicationData));
@ -990,7 +1021,7 @@ macro.DeclarationKind _declarationKind(macro.Declaration declaration) {
"Unexpected declaration ${declaration} (${declaration.runtimeType})");
}
/// Data needed to apply a list of macro applications to a class or member.
/// Data needed to apply a list of macro applications to a macro target.
abstract class ApplicationData {
final MacroIntrospection _macroIntrospection;
final SourceLibraryBuilder libraryBuilder;
@ -999,15 +1030,49 @@ abstract class ApplicationData {
ApplicationData(
this._macroIntrospection, this.libraryBuilder, this.macroApplications);
macro.Declaration get declaration;
macro.MacroTarget get macroTarget;
macro.DeclarationKind get declarationKind;
Builder get builder;
}
class ClassApplicationData extends ApplicationData {
final SourceClassBuilder _classBuilder;
class LibraryApplicationData extends ApplicationData {
macro.MacroTarget? _macroTarget;
macro.ParameterizedTypeDeclaration? _declaration;
LibraryApplicationData(
super.macroIntrospection, super.libraryBuilder, super.macroApplications);
@override
macro.DeclarationKind get declarationKind => macro.DeclarationKind.library;
@override
macro.MacroTarget get macroTarget {
return _macroTarget ??= _macroIntrospection.getLibrary(libraryBuilder);
}
@override
Builder get builder => libraryBuilder;
}
/// Data needed to apply a list of macro applications to a class or member.
abstract class DeclarationApplicationData extends ApplicationData {
macro.Declaration? _declaration;
DeclarationApplicationData(
super._macroIntrospection, super.libraryBuilder, super.macroApplications);
@override
macro.MacroTarget get macroTarget => declaration;
macro.Declaration get declaration;
@override
macro.DeclarationKind get declarationKind => _declarationKind(declaration);
}
class ClassApplicationData extends DeclarationApplicationData {
final SourceClassBuilder _classBuilder;
ClassApplicationData(super.macroIntrospection, super.libraryBuilder,
this._classBuilder, super.macroApplications);
@ -1022,11 +1087,9 @@ class ClassApplicationData extends ApplicationData {
Builder get builder => _classBuilder;
}
class MemberApplicationData extends ApplicationData {
class MemberApplicationData extends DeclarationApplicationData {
final MemberBuilder _memberBuilder;
macro.Declaration? _declaration;
MemberApplicationData(super.macroIntrospection, super.libraryBuilder,
this._memberBuilder, super.macroApplications);

View file

@ -192,6 +192,17 @@ class MacroDataComputer extends CfeDataComputer<String> {
sb.write('\n${source}');
}
}
for (MapEntry<SourceLibraryBuilder, MacroExecutionResultsForTesting> entry
in macroApplicationData.libraryResults.entries) {
if (entry.key.library == library) {
String resultsText = macroExecutionResultsToText(entry.value);
if (resultsText.isNotEmpty) {
sb.write('\nApplications:');
sb.write('\n$resultsText');
}
}
}
if (sb.isNotEmpty) {
Id id = new LibraryId(library.fileUri);
registry.registerValue(
@ -211,91 +222,19 @@ class MacroDataComputer extends CfeDataComputer<String> {
.loader
.dataForTesting!
.macroApplicationData;
StringBuffer sb = new StringBuffer();
StringBuffer typesSources = new StringBuffer();
List<DeclarationCode> mergedClassTypes = [];
for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
in macroApplicationData.classTypesResults.entries) {
for (MapEntry<SourceClassBuilder, MacroExecutionResultsForTesting> entry
in macroApplicationData.classResults.entries) {
if (entry.key.cls == cls) {
for (MacroExecutionResult result in entry.value) {
if (result.libraryAugmentations.isNotEmpty) {
if (result.libraryAugmentations.isNotEmpty) {
typesSources.write(
'\n${codeToString(result.libraryAugmentations.single)}');
}
for (var identifier in result.typeAugmentations.keys) {
if (identifier.name == entry.key.name) {
mergedClassTypes.addAll(result.typeAugmentations[identifier]!);
}
}
}
String resultsText =
macroExecutionResultsToText(entry.value, className: cls.name);
if (resultsText.isNotEmpty) {
Id id = new ClassId(cls.name);
registry.registerValue(
cls.fileUri, cls.fileOffset, id, '\n$resultsText', cls);
}
}
}
if (mergedClassTypes.isNotEmpty) {
typesSources.write('\naugment class ${cls.name} {');
for (var result in mergedClassTypes) {
typesSources.write('\n${codeToString(result)}');
}
typesSources.write('\n}');
}
if (typesSources.isNotEmpty) {
sb.write('types:');
sb.write(typesSources);
}
StringBuffer declarationsSources = new StringBuffer();
for (MapEntry<SourceClassBuilder, List<String>> entry
in macroApplicationData.classDeclarationsSources.entries) {
if (entry.key.cls == cls) {
for (String result in entry.value) {
if (result.isNotEmpty) {
declarationsSources.write('\n${result}');
}
}
}
}
if (declarationsSources.isNotEmpty) {
sb.write('declarations:');
sb.write(declarationsSources);
}
StringBuffer definitionsSources = new StringBuffer();
List<DeclarationCode> mergedClassDefinitions = [];
for (MapEntry<SourceClassBuilder, List<MacroExecutionResult>> entry
in macroApplicationData.classDefinitionsResults.entries) {
if (entry.key.cls == cls) {
for (MacroExecutionResult result in entry.value) {
if (result.libraryAugmentations.isNotEmpty) {
definitionsSources
.write('\n${codeToString(result.libraryAugmentations.single)}');
}
for (var identifier in result.typeAugmentations.keys) {
if (identifier.name == entry.key.name) {
mergedClassDefinitions
.addAll(result.typeAugmentations[identifier]!);
}
}
}
}
}
if (mergedClassDefinitions.isNotEmpty) {
definitionsSources.write('\naugment class ${cls.name} {');
for (var result in mergedClassDefinitions) {
definitionsSources.write('\n${codeToString(result)}');
}
definitionsSources.write('\n}');
}
if (definitionsSources.isNotEmpty) {
sb.write('definitions:');
sb.write(definitionsSources);
}
if (sb.isNotEmpty) {
Id id = new ClassId(cls.name);
registry.registerValue(cls.fileUri, cls.fileOffset, id, '\n$sb', cls);
}
}
@override
@ -310,69 +249,97 @@ class MacroDataComputer extends CfeDataComputer<String> {
.loader
.dataForTesting!
.macroApplicationData;
StringBuffer sb = StringBuffer();
StringBuffer typesSources = new StringBuffer();
for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry
in macroApplicationData.memberTypesResults.entries) {
for (MapEntry<MemberBuilder, MacroExecutionResultsForTesting> entry
in macroApplicationData.memberResults.entries) {
if (_isMember(entry.key, member)) {
for (MacroExecutionResult result in entry.value) {
if (result.libraryAugmentations.isNotEmpty) {
if (result.libraryAugmentations.isNotEmpty) {
typesSources.write(
'\n${codeToString(result.libraryAugmentations.single)}');
}
}
String resultsText = macroExecutionResultsToText(entry.value);
Id id = computeMemberId(member);
MemberBuilder memberBuilder =
lookupMemberBuilder(testResultData.compilerResult, member)!;
if (resultsText.isNotEmpty) {
registry.registerValue(memberBuilder.fileUri!,
memberBuilder.charOffset, id, '\n$resultsText', member);
}
}
}
if (typesSources.isNotEmpty) {
sb.write('types:');
sb.write(typesSources);
}
StringBuffer declarationsSources = new StringBuffer();
for (MapEntry<MemberBuilder, List<String>> entry
in macroApplicationData.memberDeclarationsSources.entries) {
if (_isMember(entry.key, member)) {
for (String result in entry.value) {
if (result.isNotEmpty) {
declarationsSources.write('\n${result}');
}
}
}
}
if (declarationsSources.isNotEmpty) {
sb.write('declarations:');
sb.write(declarationsSources);
}
StringBuffer definitionsSources = new StringBuffer();
for (MapEntry<MemberBuilder, List<MacroExecutionResult>> entry
in macroApplicationData.memberDefinitionsResults.entries) {
if (_isMember(entry.key, member)) {
for (MacroExecutionResult result in entry.value) {
if (result.libraryAugmentations.isNotEmpty) {
definitionsSources
.write('\n${codeToString(result.libraryAugmentations.single)}');
}
}
}
}
if (definitionsSources.isNotEmpty) {
sb.write('definitions:');
sb.write(definitionsSources);
}
if (sb.isNotEmpty) {
Id id = computeMemberId(member);
MemberBuilder memberBuilder =
lookupMemberBuilder(testResultData.compilerResult, member)!;
registry.registerValue(memberBuilder.fileUri!, memberBuilder.charOffset,
id, '\n$sb', member);
}
}
}
String macroExecutionResultsToText(MacroExecutionResultsForTesting results,
{String? className}) {
StringBuffer sb = new StringBuffer();
StringBuffer typesSources = new StringBuffer();
List<DeclarationCode> mergedClassTypes = [];
for (MacroExecutionResult result in results.typesResults) {
if (result.libraryAugmentations.isNotEmpty) {
if (result.libraryAugmentations.isNotEmpty) {
typesSources
.write('\n${codeToString(result.libraryAugmentations.single)}');
}
for (var identifier in result.typeAugmentations.keys) {
if (identifier.name == className) {
mergedClassTypes.addAll(result.typeAugmentations[identifier]!);
}
}
}
}
if (mergedClassTypes.isNotEmpty) {
typesSources.write('\naugment class ${className} {');
for (var result in mergedClassTypes) {
typesSources.write('\n${codeToString(result)}');
}
typesSources.write('\n}');
}
if (typesSources.isNotEmpty) {
sb.write('types:');
sb.write(typesSources);
}
StringBuffer declarationsSources = new StringBuffer();
for (String result in results.declarationsSources) {
if (result.isNotEmpty) {
declarationsSources.write('\n${result}');
}
}
if (declarationsSources.isNotEmpty) {
sb.write('declarations:');
sb.write(declarationsSources);
}
StringBuffer definitionsSources = new StringBuffer();
List<DeclarationCode> mergedClassDefinitions = [];
for (MacroExecutionResult result in results.definitionsResults) {
if (result.libraryAugmentations.isNotEmpty) {
definitionsSources
.write('\n${codeToString(result.libraryAugmentations.single)}');
}
for (var identifier in result.typeAugmentations.keys) {
if (identifier.name == className) {
mergedClassDefinitions.addAll(result.typeAugmentations[identifier]!);
}
}
}
if (mergedClassDefinitions.isNotEmpty) {
definitionsSources.write('\naugment class ${className} {');
for (var result in mergedClassDefinitions) {
definitionsSources.write('\n${codeToString(result)}');
}
definitionsSources.write('\n}');
}
if (definitionsSources.isNotEmpty) {
sb.write('definitions:');
sb.write(definitionsSources);
}
return sb.toString();
}
void _codeToString(StringBuffer sb, Code code) {
for (Object part in code.parts) {
if (part is Code) {

View file

@ -7,10 +7,13 @@
package:_fe_analyzer_shared/src/macros/api.dart|package:macro/macro.dart,
main.dart],
macroInstanceIds=[
package:macro/macro.dart/Macro1/(),
package:macro/macro.dart/Macro1/(),
package:macro/macro.dart/Macro1/(),
package:macro/macro.dart/Macro1/named(),
package:macro/macro.dart/Macro2/(),
package:macro/macro.dart/Macro2/(),
package:macro/macro.dart/Macro2/named(),
package:macro/macro.dart/Macro2/named(),
package:macro/macro.dart/Macro2/named(),
package:macro/macro.dart/Macro2/named(),
@ -18,11 +21,17 @@
package:macro/macro.dart/Macro3/(),
package:macro/macro.dart/Macro3/(),
package:macro/macro.dart/Macro3/named(),
package:macro/macro.dart/Macro3/named(),
package:macro/macro.dart/Macro3/named()],
macrosAreApplied,
macrosAreAvailable,
neededPrecompilations=[package:macro/macro.dart=Macro1(named/new)|Macro2(named/new)|Macro3(named/new)|Macro4(new)]
*/
@Macro2.named()
@prefix.Macro2()
@prefix.Macro3.named()
@Macro1()
library;
import 'package:macro/macro.dart';
import 'package:macro/macro.dart' as prefix;