[cfe] Apply phase 2 macro results
Results of Phase 2 macros are now applied. The macro application code has been refactored to support that Phase 1 can apply all macro applications within a library in bulk, but Phase 2 can apply each macro application in sequence. The later is to prepare for making added member visible to subsequent macro applications within Phase 2. This functionality has not been completed yet. Change-Id: Idaf2702e21bde75aedb1509d88e02f270196af5e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/233380 Reviewed-by: Jens Johansen <jensj@google.com> Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
Commit Bot
parent
0a275f6e97
commit
931fd976c6
@@ -7010,6 +7010,34 @@ const MessageCode messageLoadLibraryTakesNoArguments = const MessageCode(
|
||||
analyzerCodes: <String>["LOAD_LIBRARY_TAKES_NO_ARGUMENTS"],
|
||||
problemMessage: r"""'loadLibrary' takes no arguments.""");
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Template<
|
||||
Message Function(
|
||||
String
|
||||
name)> templateMacroClassNotDeclaredMacro = const Template<
|
||||
Message Function(String name)>(
|
||||
problemMessageTemplate:
|
||||
r"""Non-abstract class '#name' implements 'Macro' but isn't declared as a macro class.""",
|
||||
correctionMessageTemplate: r"""Try adding the 'macro' class modifier.""",
|
||||
withArguments: _withArgumentsMacroClassNotDeclaredMacro);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Message Function(String name)> codeMacroClassNotDeclaredMacro =
|
||||
const Code<Message Function(String name)>(
|
||||
"MacroClassNotDeclaredMacro",
|
||||
);
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
Message _withArgumentsMacroClassNotDeclaredMacro(String name) {
|
||||
if (name.isEmpty) throw 'No name provided';
|
||||
name = demangleMixinApplicationName(name);
|
||||
return new Message(codeMacroClassNotDeclaredMacro,
|
||||
problemMessage:
|
||||
"""Non-abstract class '${name}' implements 'Macro' but isn't declared as a macro class.""",
|
||||
correctionMessage: """Try adding the 'macro' class modifier.""",
|
||||
arguments: {'name': name});
|
||||
}
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
|
||||
const Code<Null> codeMainNotFunctionDeclaration =
|
||||
messageMainNotFunctionDeclaration;
|
||||
|
||||
@@ -1749,6 +1749,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
||||
loader: lastGoodKernelTarget.loader,
|
||||
nameOrigin: libraryBuilder,
|
||||
isUnsupported: libraryBuilder.isUnsupported,
|
||||
isAugmentation: false,
|
||||
);
|
||||
libraryBuilder.scope.forEachLocalMember((name, member) {
|
||||
debugLibrary.scope.addLocalMember(name, member, setter: false);
|
||||
@@ -1803,6 +1804,7 @@ class IncrementalCompiler implements IncrementalKernelGenerator {
|
||||
scope: debugLibrary.scope.createNestedScope("expression"),
|
||||
nameOrigin: libraryBuilder,
|
||||
isUnsupported: libraryBuilder.isUnsupported,
|
||||
isAugmentation: false,
|
||||
);
|
||||
|
||||
HybridFileSystem hfs =
|
||||
|
||||
@@ -427,12 +427,25 @@ class KernelTarget extends TargetImplementation {
|
||||
Future<void> _buildForPhase1(
|
||||
Iterable<SourceLibraryBuilder> augmentationLibraries) async {
|
||||
await loader.buildOutlines();
|
||||
// Normally patch libraries are applied in [SourceLoader.resolveParts].
|
||||
// For augmentation libraries we instead apply them directly here.
|
||||
for (SourceLibraryBuilder augmentationLibrary in augmentationLibraries) {
|
||||
augmentationLibrary.applyPatches();
|
||||
}
|
||||
loader.computeLibraryScopes(augmentationLibraries);
|
||||
// TODO(johnniwinther): Support computation of macro applications in
|
||||
// augmentation libraries?
|
||||
loader.resolveTypes(augmentationLibraries);
|
||||
}
|
||||
|
||||
/// Builds [augmentationLibrary] to the state expected after applying phase
|
||||
/// 2 macros.
|
||||
void _buildForPhase2(SourceLibraryBuilder augmentationLibrary) {
|
||||
augmentationLibrary.finishTypeVariables(objectClassBuilder, dynamicType);
|
||||
augmentationLibrary.build(loader.coreLibrary, modifyTarget: false);
|
||||
augmentationLibrary.resolveConstructors();
|
||||
}
|
||||
|
||||
Future<BuildResult> buildOutlines({CanonicalName? nameRoot}) async {
|
||||
if (loader.first == null) return new BuildResult();
|
||||
return withCrashReporting<BuildResult>(() async {
|
||||
@@ -483,7 +496,8 @@ class KernelTarget extends TargetImplementation {
|
||||
loader.checkSemantics(objectClassBuilder);
|
||||
|
||||
benchmarker?.enterPhase(BenchmarkPhases.outline_finishTypeVariables);
|
||||
loader.finishTypeVariables(objectClassBuilder, dynamicType);
|
||||
loader.finishTypeVariables(
|
||||
loader.sourceLibraryBuilders, objectClassBuilder, dynamicType);
|
||||
|
||||
benchmarker
|
||||
?.enterPhase(BenchmarkPhases.outline_createTypeInferenceEngine);
|
||||
@@ -500,7 +514,7 @@ class KernelTarget extends TargetImplementation {
|
||||
installSyntheticConstructors(sourceClassBuilders);
|
||||
|
||||
benchmarker?.enterPhase(BenchmarkPhases.outline_resolveConstructors);
|
||||
loader.resolveConstructors();
|
||||
loader.resolveConstructors(loader.sourceLibraryBuilders);
|
||||
|
||||
benchmarker?.enterPhase(BenchmarkPhases.outline_link);
|
||||
component =
|
||||
@@ -517,8 +531,11 @@ class KernelTarget extends TargetImplementation {
|
||||
|
||||
if (macroApplications != null) {
|
||||
benchmarker?.enterPhase(BenchmarkPhases.outline_applyDeclarationMacros);
|
||||
await macroApplications
|
||||
.applyDeclarationsMacros(loader.hierarchyBuilder);
|
||||
await macroApplications.applyDeclarationsMacros(loader.hierarchyBuilder,
|
||||
(SourceLibraryBuilder augmentationLibrary) async {
|
||||
await _buildForPhase1([augmentationLibrary]);
|
||||
_buildForPhase2(augmentationLibrary);
|
||||
});
|
||||
}
|
||||
|
||||
benchmarker
|
||||
|
||||
@@ -116,6 +116,7 @@ class MacroApplications {
|
||||
final macro.MacroExecutor _macroExecutor;
|
||||
final Map<SourceLibraryBuilder, LibraryMacroApplicationData> libraryData;
|
||||
final MacroApplicationDataForTesting? dataForTesting;
|
||||
List<_ApplicationData>? _applicationDataCache;
|
||||
|
||||
MacroApplications(
|
||||
this._macroExecutor, this.libraryData, this.dataForTesting) {
|
||||
@@ -272,60 +273,57 @@ class MacroApplications {
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<SourceLibraryBuilder, List<macro.MacroExecutionResult>>>
|
||||
_applyMacros(
|
||||
Future<List<macro.MacroExecutionResult>> Function(
|
||||
Builder, macro.Declaration, List<MacroApplication>)
|
||||
applyMacros) async {
|
||||
Map<SourceLibraryBuilder, List<macro.MacroExecutionResult>> libraryResults =
|
||||
{};
|
||||
for (MapEntry<SourceLibraryBuilder,
|
||||
LibraryMacroApplicationData> libraryEntry in libraryData.entries) {
|
||||
SourceLibraryBuilder libraryBuilder = libraryEntry.key;
|
||||
List<macro.MacroExecutionResult> results = [];
|
||||
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) {
|
||||
results.addAll(
|
||||
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);
|
||||
results.addAll(await applyMacros(
|
||||
classBuilder, classDeclaration, classApplications));
|
||||
}
|
||||
Iterable<_ApplicationData> get _applicationData {
|
||||
if (_applicationDataCache == null) {
|
||||
List<_ApplicationData> data = _applicationDataCache = [];
|
||||
for (MapEntry<SourceLibraryBuilder,
|
||||
LibraryMacroApplicationData> libraryEntry in libraryData.entries) {
|
||||
SourceLibraryBuilder libraryBuilder = libraryEntry.key;
|
||||
LibraryMacroApplicationData libraryMacroApplicationData =
|
||||
libraryEntry.value;
|
||||
for (MapEntry<MemberBuilder, List<MacroApplication>> memberEntry
|
||||
in classData.memberApplications.entries) {
|
||||
in libraryMacroApplicationData.memberApplications.entries) {
|
||||
MemberBuilder memberBuilder = memberEntry.key;
|
||||
macro.Declaration? declaration = _getMemberDeclaration(memberBuilder);
|
||||
if (declaration != null) {
|
||||
results.addAll(await applyMacros(
|
||||
memberBuilder, declaration, memberEntry.value));
|
||||
data.add(new _ApplicationData(
|
||||
libraryBuilder, 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);
|
||||
data.add(new _ApplicationData(libraryBuilder, 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) {
|
||||
data.add(new _ApplicationData(libraryBuilder, memberBuilder,
|
||||
declaration, memberEntry.value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
libraryResults[libraryBuilder] = results;
|
||||
}
|
||||
return libraryResults;
|
||||
return _applicationDataCache!;
|
||||
}
|
||||
|
||||
Future<List<macro.MacroExecutionResult>> _applyTypeMacros(
|
||||
Builder builder,
|
||||
macro.Declaration declaration,
|
||||
List<MacroApplication> macroApplications) async {
|
||||
_ApplicationData applicationData) async {
|
||||
macro.Declaration declaration = applicationData.declaration;
|
||||
List<macro.MacroExecutionResult> results = [];
|
||||
for (MacroApplication macroApplication in macroApplications) {
|
||||
for (MacroApplication macroApplication
|
||||
in applicationData.macroApplications) {
|
||||
if (macroApplication.instanceIdentifier
|
||||
.shouldExecute(_declarationKind(declaration), macro.Phase.types)) {
|
||||
macro.MacroExecutionResult result =
|
||||
@@ -336,6 +334,7 @@ class MacroApplications {
|
||||
}
|
||||
|
||||
if (retainDataForTesting) {
|
||||
Builder builder = applicationData.builder;
|
||||
if (builder is SourceClassBuilder) {
|
||||
dataForTesting?.classTypesResults[builder] = results;
|
||||
} else {
|
||||
@@ -347,8 +346,13 @@ class MacroApplications {
|
||||
|
||||
Future<List<SourceLibraryBuilder>> applyTypeMacros() async {
|
||||
List<SourceLibraryBuilder> augmentationLibraries = [];
|
||||
Map<SourceLibraryBuilder, List<macro.MacroExecutionResult>> results =
|
||||
await _applyMacros(_applyTypeMacros);
|
||||
Map<SourceLibraryBuilder, List<macro.MacroExecutionResult>> results = {};
|
||||
for (_ApplicationData macroApplication in _applicationData) {
|
||||
List<macro.MacroExecutionResult> executionResults =
|
||||
await _applyTypeMacros(macroApplication);
|
||||
(results[macroApplication.libraryBuilder] ??= [])
|
||||
.addAll(executionResults);
|
||||
}
|
||||
for (MapEntry<SourceLibraryBuilder, List<macro.MacroExecutionResult>> entry
|
||||
in results.entries) {
|
||||
SourceLibraryBuilder sourceLibraryBuilder = entry.key;
|
||||
@@ -363,12 +367,12 @@ class MacroApplications {
|
||||
return augmentationLibraries;
|
||||
}
|
||||
|
||||
Future<List<macro.MacroExecutionResult>> _applyDeclarationsMacros(
|
||||
Builder builder,
|
||||
macro.Declaration declaration,
|
||||
List<MacroApplication> macroApplications) async {
|
||||
Future<void> _applyDeclarationsMacros(_ApplicationData applicationData,
|
||||
Future<void> Function(SourceLibraryBuilder) onAugmentationLibrary) async {
|
||||
List<macro.MacroExecutionResult> results = [];
|
||||
for (MacroApplication macroApplication in macroApplications) {
|
||||
macro.Declaration declaration = applicationData.declaration;
|
||||
for (MacroApplication macroApplication
|
||||
in applicationData.macroApplications) {
|
||||
if (macroApplication.instanceIdentifier.shouldExecute(
|
||||
_declarationKind(declaration), macro.Phase.declarations)) {
|
||||
macro.MacroExecutionResult result =
|
||||
@@ -377,10 +381,19 @@ class MacroApplications {
|
||||
declaration,
|
||||
typeResolver,
|
||||
classIntrospector);
|
||||
results.add(result);
|
||||
String source = _macroExecutor
|
||||
.buildAugmentationLibrary([result], _resolveIdentifier);
|
||||
SourceLibraryBuilder augmentationLibrary = await applicationData
|
||||
.libraryBuilder
|
||||
.createAugmentationLibrary(source);
|
||||
await onAugmentationLibrary(augmentationLibrary);
|
||||
if (retainDataForTesting) {
|
||||
results.add(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (retainDataForTesting) {
|
||||
Builder builder = applicationData.builder;
|
||||
if (builder is SourceClassBuilder) {
|
||||
dataForTesting?.classDeclarationsResults[builder] = results;
|
||||
} else {
|
||||
@@ -388,27 +401,28 @@ class MacroApplications {
|
||||
results;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
late Types types;
|
||||
late macro.TypeResolver typeResolver;
|
||||
late macro.ClassIntrospector classIntrospector;
|
||||
|
||||
Future<void> applyDeclarationsMacros(
|
||||
ClassHierarchyBase classHierarchy) async {
|
||||
Future<void> applyDeclarationsMacros(ClassHierarchyBase classHierarchy,
|
||||
Future<void> Function(SourceLibraryBuilder) onAugmentationLibrary) async {
|
||||
types = new Types(classHierarchy);
|
||||
typeResolver = new _TypeResolver(this);
|
||||
classIntrospector = new _ClassIntrospector(this);
|
||||
await _applyMacros(_applyDeclarationsMacros);
|
||||
for (_ApplicationData macroApplication in _applicationData) {
|
||||
await _applyDeclarationsMacros(macroApplication, onAugmentationLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<macro.MacroExecutionResult>> _applyDefinitionMacros(
|
||||
Builder builder,
|
||||
macro.Declaration declaration,
|
||||
List<MacroApplication> macroApplications) async {
|
||||
_ApplicationData applicationData) async {
|
||||
List<macro.MacroExecutionResult> results = [];
|
||||
for (MacroApplication macroApplication in macroApplications) {
|
||||
macro.Declaration declaration = applicationData.declaration;
|
||||
for (MacroApplication macroApplication
|
||||
in applicationData.macroApplications) {
|
||||
if (macroApplication.instanceIdentifier.shouldExecute(
|
||||
_declarationKind(declaration), macro.Phase.definitions)) {
|
||||
macro.MacroExecutionResult result =
|
||||
@@ -422,6 +436,7 @@ class MacroApplications {
|
||||
}
|
||||
}
|
||||
if (retainDataForTesting) {
|
||||
Builder builder = applicationData.builder;
|
||||
if (builder is SourceClassBuilder) {
|
||||
dataForTesting?.classDefinitionsResults[builder] = results;
|
||||
} else {
|
||||
@@ -436,13 +451,16 @@ class MacroApplications {
|
||||
|
||||
Future<void> applyDefinitionMacros() async {
|
||||
typeDeclarationResolver = new _TypeDeclarationResolver();
|
||||
await _applyMacros(_applyDefinitionMacros);
|
||||
for (_ApplicationData macroApplication in _applicationData) {
|
||||
await _applyDefinitionMacros(macroApplication);
|
||||
}
|
||||
}
|
||||
|
||||
void close() {
|
||||
_macroExecutor.close();
|
||||
_staticTypeCache.clear();
|
||||
_typeAnnotationCache.clear();
|
||||
_applicationDataCache?.clear();
|
||||
}
|
||||
|
||||
macro.ClassDeclaration _createClassDeclaration(SourceClassBuilder builder) {
|
||||
@@ -951,3 +969,14 @@ macro.DeclarationKind _declarationKind(macro.Declaration declaration) {
|
||||
throw new UnsupportedError(
|
||||
"Unexpected declaration ${declaration} (${declaration.runtimeType})");
|
||||
}
|
||||
|
||||
/// Data needed to apply a list of macro applications to a class or member.
|
||||
class _ApplicationData {
|
||||
final SourceLibraryBuilder libraryBuilder;
|
||||
final Builder builder;
|
||||
final macro.Declaration declaration;
|
||||
final List<MacroApplication> macroApplications;
|
||||
|
||||
_ApplicationData(this.libraryBuilder, this.builder, this.declaration,
|
||||
this.macroApplications);
|
||||
}
|
||||
|
||||
@@ -618,8 +618,11 @@ class SourceClassBuilder extends ClassBuilderImpl
|
||||
}
|
||||
}
|
||||
|
||||
void checkSupertypes(CoreTypes coreTypes,
|
||||
ClassHierarchyBuilder hierarchyBuilder, Class enumClass) {
|
||||
void checkSupertypes(
|
||||
CoreTypes coreTypes,
|
||||
ClassHierarchyBuilder hierarchyBuilder,
|
||||
Class enumClass,
|
||||
Class? macroClass) {
|
||||
// This method determines whether the class (that's being built) its super
|
||||
// class appears both in 'extends' and 'implements' clauses and whether any
|
||||
// interface appears multiple times in the 'implements' clause.
|
||||
@@ -679,6 +682,27 @@ class SourceClassBuilder extends ClassBuilderImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
if (macroClass != null && !cls.isMacro && !cls.isAbstract) {
|
||||
// TODO(johnniwinther): Merge this check with the loop above.
|
||||
bool isMacroFound = false;
|
||||
List<Supertype> interfaces =
|
||||
hierarchyBuilder.getNodeFromClass(cls).superclasses;
|
||||
for (int i = 0; !isMacroFound && i < interfaces.length; i++) {
|
||||
if (interfaces[i].classNode == macroClass) {
|
||||
isMacroFound = true;
|
||||
}
|
||||
}
|
||||
interfaces = hierarchyBuilder.getNodeFromClass(cls).interfaces;
|
||||
for (int i = 0; !isMacroFound && i < interfaces.length; i++) {
|
||||
if (interfaces[i].classNode == macroClass) {
|
||||
isMacroFound = true;
|
||||
}
|
||||
}
|
||||
if (isMacroFound) {
|
||||
addProblem(templateMacroClassNotDeclaredMacro.withArguments(name),
|
||||
charOffset, noLength);
|
||||
}
|
||||
}
|
||||
|
||||
void fail(NamedTypeBuilder target, Message message,
|
||||
TypeAliasBuilder? aliasBuilder) {
|
||||
|
||||
@@ -243,6 +243,9 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
||||
|
||||
List<SourceLibraryBuilder>? _patchLibraries;
|
||||
|
||||
/// `true` if this is an augmentation library.
|
||||
final bool isAugmentation;
|
||||
|
||||
SourceLibraryBuilder.internal(
|
||||
SourceLoader loader,
|
||||
Uri fileUri,
|
||||
@@ -253,8 +256,9 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
||||
Library library,
|
||||
LibraryBuilder? nameOrigin,
|
||||
Library? referencesFrom,
|
||||
bool? referenceIsPartOwner,
|
||||
bool isUnsupported)
|
||||
{bool? referenceIsPartOwner,
|
||||
required bool isUnsupported,
|
||||
required bool isAugmentation})
|
||||
: this.fromScopes(
|
||||
loader,
|
||||
fileUri,
|
||||
@@ -266,7 +270,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
||||
library,
|
||||
nameOrigin,
|
||||
referencesFrom,
|
||||
isUnsupported);
|
||||
isUnsupported: isUnsupported,
|
||||
isAugmentation: isAugmentation);
|
||||
|
||||
SourceLibraryBuilder.fromScopes(
|
||||
this.loader,
|
||||
@@ -279,7 +284,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
||||
this.library,
|
||||
this._nameOrigin,
|
||||
this.referencesFrom,
|
||||
this.isUnsupported)
|
||||
{required this.isUnsupported,
|
||||
required this.isAugmentation})
|
||||
: _languageVersion = packageLanguageVersion,
|
||||
currentTypeParameterScopeBuilder = _libraryTypeParameterScopeBuilder,
|
||||
referencesFromIndexed =
|
||||
@@ -469,7 +475,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
||||
LibraryBuilder? nameOrigin,
|
||||
Library? referencesFrom,
|
||||
bool? referenceIsPartOwner,
|
||||
required bool isUnsupported})
|
||||
required bool isUnsupported,
|
||||
required bool isAugmentation})
|
||||
: this.internal(
|
||||
loader,
|
||||
fileUri,
|
||||
@@ -487,8 +494,9 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
||||
..setLanguageVersion(packageLanguageVersion.version)),
|
||||
nameOrigin,
|
||||
referencesFrom,
|
||||
referenceIsPartOwner,
|
||||
isUnsupported);
|
||||
referenceIsPartOwner: referenceIsPartOwner,
|
||||
isUnsupported: isUnsupported,
|
||||
isAugmentation: isAugmentation);
|
||||
|
||||
@override
|
||||
bool get isPart => partOfName != null || partOfUri != null;
|
||||
@@ -520,7 +528,8 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
||||
loader: loader,
|
||||
isUnsupported: false,
|
||||
target: library,
|
||||
origin: this);
|
||||
origin: this,
|
||||
isAugmentation: true);
|
||||
addPatchLibrary(augmentationLibrary);
|
||||
loader.registerUnparsedLibrarySource(augmentationLibrary, source);
|
||||
return augmentationLibrary;
|
||||
@@ -3896,9 +3905,11 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
|
||||
Builder member = patchDeclarations.current;
|
||||
// We need to inject all non-patch members into the origin library. This
|
||||
// should only apply to private members.
|
||||
// For augmentation libraries, all members are injected into the origin
|
||||
// library, regardless of privacy.
|
||||
if (member.isPatch) {
|
||||
// Ignore patches.
|
||||
} else if (name.startsWith("_")) {
|
||||
} else if (name.startsWith("_") || isAugmentation) {
|
||||
origin.injectMemberFromPatch(name, member);
|
||||
} else {
|
||||
origin.exportMemberFromPatch(name, member);
|
||||
|
||||
@@ -328,7 +328,8 @@ class SourceLoader extends Loader {
|
||||
referenceIsPartOwner: referenceIsPartOwner,
|
||||
isUnsupported: origin?.library.isUnsupported ??
|
||||
importUri.isScheme('dart') &&
|
||||
!target.uriTranslator.isLibrarySupported(importUri.path));
|
||||
!target.uriTranslator.isLibrarySupported(importUri.path),
|
||||
isAugmentation: false);
|
||||
}
|
||||
|
||||
/// Return `"true"` if the [dottedName] is a 'dart.library.*' qualifier for a
|
||||
@@ -1689,9 +1690,9 @@ severity: $severity
|
||||
ticker.logMs("Finished forwarders for $count procedures");
|
||||
}
|
||||
|
||||
void resolveConstructors() {
|
||||
void resolveConstructors(List<SourceLibraryBuilder> libraryBuilders) {
|
||||
int count = 0;
|
||||
for (SourceLibraryBuilder library in sourceLibraryBuilders) {
|
||||
for (SourceLibraryBuilder library in libraryBuilders) {
|
||||
count += library.resolveConstructors();
|
||||
}
|
||||
ticker.logMs("Resolved $count constructors");
|
||||
@@ -1705,9 +1706,10 @@ severity: $severity
|
||||
}
|
||||
}
|
||||
|
||||
void finishTypeVariables(ClassBuilder object, TypeBuilder dynamicType) {
|
||||
void finishTypeVariables(Iterable<SourceLibraryBuilder> libraryBuilders,
|
||||
ClassBuilder object, TypeBuilder dynamicType) {
|
||||
int count = 0;
|
||||
for (SourceLibraryBuilder library in sourceLibraryBuilders) {
|
||||
for (SourceLibraryBuilder library in libraryBuilders) {
|
||||
count += library.finishTypeVariables(object, dynamicType);
|
||||
}
|
||||
ticker.logMs("Resolved $count type-variable bounds");
|
||||
@@ -2065,7 +2067,8 @@ severity: $severity
|
||||
List<SourceClassBuilder> sourceClasses, Class enumClass) {
|
||||
for (SourceClassBuilder builder in sourceClasses) {
|
||||
if (builder.library.loader == this && !builder.isPatch) {
|
||||
builder.checkSupertypes(coreTypes, hierarchyBuilder, enumClass);
|
||||
builder.checkSupertypes(
|
||||
coreTypes, hierarchyBuilder, enumClass, _macroClassBuilder?.cls);
|
||||
}
|
||||
}
|
||||
ticker.logMs("Checked supertypes");
|
||||
|
||||
@@ -578,6 +578,8 @@ LibraryDirectiveNotFirst/script2: Fail
|
||||
LibraryDirectiveNotFirst/script3: Fail
|
||||
ListLiteralTooManyTypeArguments/example: Fail
|
||||
LoadLibraryTakesNoArguments/example: Fail
|
||||
MacroClassNotDeclaredMacro/analyzerCode: Fail
|
||||
MacroClassNotDeclaredMacro/example: Fail
|
||||
MainNotFunctionDeclaration/analyzerCode: Fail
|
||||
MainNotFunctionDeclarationExported/analyzerCode: Fail
|
||||
MainNotFunctionDeclarationExported/part_wrapped_script: Fail
|
||||
|
||||
@@ -5479,3 +5479,7 @@ EnumContainsValuesDeclaration:
|
||||
|
||||
EnumImplementerContainsValuesDeclaration:
|
||||
problemMessage: "'#name' has 'Enum' as a superinterface and can't contain non-static member with name 'values'."
|
||||
|
||||
MacroClassNotDeclaredMacro:
|
||||
problemMessage: "Non-abstract class '#name' implements 'Macro' but isn't declared as a macro class."
|
||||
correctionMessage: "Try adding the 'macro' class modifier."
|
||||
|
||||
@@ -95,7 +95,8 @@ Future<void> main() async {
|
||||
new NoneTarget(new TargetFlags())),
|
||||
uriTranslator)
|
||||
.loader,
|
||||
isUnsupported: false);
|
||||
isUnsupported: false,
|
||||
isAugmentation: false);
|
||||
libraryBuilder.markLanguageVersionFinal();
|
||||
LoadLibraryBuilder loadLibraryBuilder =
|
||||
new LoadLibraryBuilder(libraryBuilder, dummyLibraryDependency, -1);
|
||||
|
||||
@@ -51,7 +51,8 @@ class FunctionTypesMacro1 implements FunctionTypesMacro {
|
||||
name, new DeclarationCode.fromParts(['''
|
||||
class $name {
|
||||
external ''', function.returnType.code, ''' method();
|
||||
}''']));
|
||||
}'''
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,8 +130,14 @@ class MethodDeclarationsMacro1 implements MethodDeclarationsMacro {
|
||||
if (method.isSetter) {
|
||||
sb.write('s');
|
||||
}
|
||||
String name;
|
||||
if (method.isOperator) {
|
||||
name = 'operator';
|
||||
} else {
|
||||
name = method.identifier.name;
|
||||
}
|
||||
builder.declareInLibrary(new DeclarationCode.fromString('''
|
||||
void ${method.definingClass.name}_${method.identifier.name}GeneratedMethod_${sb}() {}
|
||||
void ${method.definingClass.name}_${name}GeneratedMethod_${sb}() {}
|
||||
'''));
|
||||
}
|
||||
}
|
||||
@@ -288,3 +295,31 @@ void ${constructor.definingClass.name}_${constructor.identifier
|
||||
'''));
|
||||
}
|
||||
}
|
||||
|
||||
macro
|
||||
|
||||
class ToStringMacro implements ClassDeclarationsMacro {
|
||||
const ToStringMacro();
|
||||
|
||||
FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
|
||||
ClassMemberDeclarationBuilder builder) async {
|
||||
Iterable<MethodDeclaration> methods = await builder.methodsOf(clazz);
|
||||
if (!methods.any((m) => m.identifier.name == 'toString')) {
|
||||
Iterable<FieldDeclaration> fields = await builder.fieldsOf(clazz);
|
||||
List<Object> parts = ['''
|
||||
toString() {
|
||||
return "${clazz.identifier.name}('''];
|
||||
String comma = '';
|
||||
for (FieldDeclaration field in fields) {
|
||||
parts.add(comma);
|
||||
parts.add('${field.identifier.name}=\${');
|
||||
parts.add(field.identifier.name);
|
||||
parts.add('}');
|
||||
comma = ',';
|
||||
}
|
||||
parts.add(''')";
|
||||
}''');
|
||||
builder.declareInClass(new DeclarationCode.fromParts(parts));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ void Class1_instanceSetter1GeneratedMethod_s() {}
|
||||
void set instanceSetter1(int? value) {}
|
||||
|
||||
/*member: Class1.[]:
|
||||
void Class1_[]GeneratedMethod_o() {}
|
||||
void Class1_operatorGeneratedMethod_o() {}
|
||||
*/
|
||||
@MethodDeclarationsMacro1()
|
||||
int operator [](int i) => i;
|
||||
|
||||
@@ -19,6 +19,9 @@ class Class1 extends core::Object {
|
||||
constructor •() → self::Class1
|
||||
: super core::Object::•()
|
||||
;
|
||||
method /* from org-dartlang-augmentation:/a/b/c/main.dart-18 */ Class1_GeneratedMethod_() → void {}
|
||||
method /* from org-dartlang-augmentation:/a/b/c/main.dart-19 */ Class1_redirectGeneratedMethod_f() → void {}
|
||||
method /* from org-dartlang-augmentation:/a/b/c/main.dart-20 */ Class1_factGeneratedMethod_f() → void {}
|
||||
@#C5
|
||||
static factory redirect() → self::Class1
|
||||
return new self::Class1::•();
|
||||
@@ -68,6 +71,35 @@ static get topLevelGetter1() → core::int?
|
||||
return null;
|
||||
@#C8
|
||||
static set topLevelSetter1(core::int? value) → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-1 */ topLevelFunction1GeneratedMethod_() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-2 */ topLevelFunction2GeneratedMethod_e() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-3 */ topLevelField1GeneratedMethod_() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-4 */ topLevelField2GeneratedMethod_e() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-5 */ topLevelField3GeneratedMethod_f() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-6 */ topLevelField4GeneratedMethod_l() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-7 */ topLevelGetter1GeneratedMethod_g() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-8 */ topLevelSetter1GeneratedMethod_s() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-9 */ Class1GeneratedMethod_() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-10 */ Class1Introspection() → void {
|
||||
core::print("constructors=''");
|
||||
core::print("fields='instanceField1','instanceField2','instanceField3'");
|
||||
core::print("methods='instanceMethod1','instanceGetter1','[]','instanceSetter1'");
|
||||
}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-11 */ Class1_instanceMethod1GeneratedMethod_() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-12 */ Class1_instanceGetter1GeneratedMethod_g() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-13 */ Class1_operatorGeneratedMethod_o() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-14 */ Class1_instanceField1GeneratedMethod_() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-15 */ Class1_instanceField2GeneratedMethod_f() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-16 */ Class1_instanceField3GeneratedMethod_fl() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-17 */ Class1_instanceSetter1GeneratedMethod_s() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-21 */ Class2GeneratedMethod_a() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-22 */ Class2Introspection() → void {
|
||||
core::print("constructors=");
|
||||
core::print("fields='instanceField1'");
|
||||
core::print("methods='instanceMethod1'");
|
||||
}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-23 */ Class2_instanceMethod1GeneratedMethod_a() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-24 */ Class2_instanceField1GeneratedMethod_() → void {}
|
||||
|
||||
constants {
|
||||
#C1 = mac::ClassDeclarationsMacro1 {}
|
||||
|
||||
@@ -52,6 +52,10 @@ external static method topLevelFunction3(self::C1 a) → self::C2;
|
||||
@#C1
|
||||
@#C2
|
||||
external static method topLevelFunction4(self::D1 a) → self::D2;
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-1 */ topLevelFunction1GeneratedMethod_es() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-2 */ topLevelFunction2GeneratedMethod_s() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-3 */ topLevelFunction3GeneratedMethod_() → void {}
|
||||
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-4 */ topLevelFunction4GeneratedMethod_() → void {}
|
||||
|
||||
constants {
|
||||
#C1 = mac::FunctionDeclarationsMacro2 {}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
// 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.
|
||||
|
||||
/*library:
|
||||
|
||||
|
||||
*/
|
||||
|
||||
import 'package:macro/macro.dart';
|
||||
|
||||
@ToStringMacro()
|
||||
/*class: A:
|
||||
augment class A {
|
||||
toString() {
|
||||
return "A(a=${a},b=${b})";
|
||||
}
|
||||
}*/
|
||||
class A {
|
||||
var a;
|
||||
var b;
|
||||
}
|
||||
|
||||
@ToStringMacro()
|
||||
/*class: B:
|
||||
augment class B {
|
||||
toString() {
|
||||
return "B(c=${c},d=${d},e=${e})";
|
||||
}
|
||||
}*/
|
||||
class B {
|
||||
var c, d;
|
||||
var e;
|
||||
}
|
||||
|
||||
@ToStringMacro()
|
||||
class C {
|
||||
var f;
|
||||
|
||||
@override
|
||||
String toString() => 'C()';
|
||||
}
|
||||
|
||||
class D {
|
||||
var g;
|
||||
var h;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
library /*isNonNullableByDefault*/;
|
||||
import self as self;
|
||||
import "package:macro/macro.dart" as mac;
|
||||
import "dart:core" as core;
|
||||
|
||||
import "package:macro/macro.dart";
|
||||
|
||||
@#C1
|
||||
class A extends core::Object {
|
||||
field dynamic a = null;
|
||||
field dynamic b = null;
|
||||
synthetic constructor •() → self::A
|
||||
: super core::Object::•()
|
||||
;
|
||||
method /* from org-dartlang-augmentation:/a/b/c/main.dart-1 */ toString() → dynamic {
|
||||
return "A(a=${this.{self::A::a}{dynamic}},b=${this.{self::A::b}{dynamic}})";
|
||||
}
|
||||
}
|
||||
@#C1
|
||||
class B extends core::Object {
|
||||
field dynamic c = null;
|
||||
field dynamic d = null;
|
||||
field dynamic e = null;
|
||||
synthetic constructor •() → self::B
|
||||
: super core::Object::•()
|
||||
;
|
||||
method /* from org-dartlang-augmentation:/a/b/c/main.dart-2 */ toString() → dynamic {
|
||||
return "B(c=${this.{self::B::c}{dynamic}},d=${this.{self::B::d}{dynamic}},e=${this.{self::B::e}{dynamic}})";
|
||||
}
|
||||
}
|
||||
@#C1
|
||||
class C extends core::Object {
|
||||
field dynamic f = null;
|
||||
synthetic constructor •() → self::C
|
||||
: super core::Object::•()
|
||||
;
|
||||
@#C2
|
||||
method toString() → core::String
|
||||
return "C()";
|
||||
}
|
||||
class D extends core::Object {
|
||||
field dynamic g = null;
|
||||
field dynamic h = null;
|
||||
synthetic constructor •() → self::D
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
|
||||
constants {
|
||||
#C1 = mac::ToStringMacro {}
|
||||
#C2 = core::_Override {}
|
||||
}
|
||||
@@ -184,7 +184,9 @@ class MacroDataComputer extends DataComputer<String> {
|
||||
in macroApplicationData.classTypesResults.entries) {
|
||||
if (entry.key.cls == cls) {
|
||||
for (MacroExecutionResult result in entry.value) {
|
||||
sb.write('\n${codeToString(result.augmentations.first)}');
|
||||
if (result.augmentations.isNotEmpty) {
|
||||
sb.write('\n${codeToString(result.augmentations.first)}');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,7 +194,9 @@ class MacroDataComputer extends DataComputer<String> {
|
||||
in macroApplicationData.classDeclarationsResults.entries) {
|
||||
if (entry.key.cls == cls) {
|
||||
for (MacroExecutionResult result in entry.value) {
|
||||
sb.write('\n${codeToString(result.augmentations.first)}');
|
||||
if (result.augmentations.isNotEmpty) {
|
||||
sb.write('\n${codeToString(result.augmentations.first)}');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -200,7 +204,9 @@ class MacroDataComputer extends DataComputer<String> {
|
||||
in macroApplicationData.classDefinitionsResults.entries) {
|
||||
if (entry.key.cls == cls) {
|
||||
for (MacroExecutionResult result in entry.value) {
|
||||
sb.write('\n${codeToString(result.augmentations.first)}');
|
||||
if (result.augmentations.isNotEmpty) {
|
||||
sb.write('\n${codeToString(result.augmentations.first)}');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,20 +38,20 @@ macro class ImplementsAlias implements Alias {}
|
||||
|
||||
macro class MixinAlias with Alias {}
|
||||
|
||||
class ExtendsNoKeyword extends Macro {}
|
||||
class /*error: error=MacroClassNotDeclaredMacro*/ExtendsNoKeyword extends Macro {}
|
||||
|
||||
class ImplementsNoKeyword implements Macro {}
|
||||
class /*error: error=MacroClassNotDeclaredMacro*/ImplementsNoKeyword implements Macro {}
|
||||
|
||||
class MixinNoKeyword with Macro {}
|
||||
class /*error: error=MacroClassNotDeclaredMacro*/MixinNoKeyword with Macro {}
|
||||
|
||||
class ExtendsAliasNoKeyword extends Alias {}
|
||||
class /*error: error=MacroClassNotDeclaredMacro*/ExtendsAliasNoKeyword extends Alias {}
|
||||
|
||||
class ImplementsAliasNoKeyword implements Alias {}
|
||||
class /*error: error=MacroClassNotDeclaredMacro*/ImplementsAliasNoKeyword implements Alias {}
|
||||
|
||||
class MixinAliasNoKeyword with Alias {}
|
||||
class /*error: error=MacroClassNotDeclaredMacro*/MixinAliasNoKeyword with Alias {}
|
||||
|
||||
class NamedMixin1NoKeyword = Macro with _Mixin;
|
||||
class /*error: error=MacroClassNotDeclaredMacro*/NamedMixin1NoKeyword = Macro with _Mixin;
|
||||
|
||||
class NamedMixin2NoKeyword = Object with Macro;
|
||||
class /*error: error=MacroClassNotDeclaredMacro*/NamedMixin2NoKeyword = Object with Macro;
|
||||
|
||||
void main() {}
|
||||
|
||||
@@ -17,6 +17,7 @@ import 'package:front_end/src/fasta/builder/library_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/testing/id_testing_helper.dart';
|
||||
import 'package:front_end/src/testing/id_testing_utils.dart';
|
||||
import 'package:kernel/ast.dart' hide Arguments;
|
||||
|
||||
Future<void> main(List<String> args) async {
|
||||
@@ -77,6 +78,17 @@ class MacroDataComputer extends DataComputer<Features> {
|
||||
.computeForLibrary(library);
|
||||
}
|
||||
|
||||
@override
|
||||
bool get supportsErrors => true;
|
||||
|
||||
@override
|
||||
Features? computeErrorData(
|
||||
TestResultData testResultData, Id id, List<FormattedMessage> errors) {
|
||||
Features features = new Features();
|
||||
features[Tags.error] = errorsToText(errors, useCodes: true);
|
||||
return features;
|
||||
}
|
||||
|
||||
@override
|
||||
DataInterpreter<Features> get dataValidator =>
|
||||
const FeaturesDataInterpreter();
|
||||
@@ -91,6 +103,7 @@ class Tags {
|
||||
static const String appliedMacros = 'appliedMacros';
|
||||
static const String macroClassIds = 'macroClassIds';
|
||||
static const String macroInstanceIds = 'macroInstanceIds';
|
||||
static const String error = 'error';
|
||||
}
|
||||
|
||||
String constructorNameToString(String constructorName) {
|
||||
|
||||
@@ -45,6 +45,7 @@ js_util
|
||||
libraries.json
|
||||
list.filled
|
||||
loadlibrary
|
||||
macro
|
||||
migrate
|
||||
name.#name
|
||||
name.stack
|
||||
|
||||
@@ -834,6 +834,7 @@ class DocTestIncrementalCompiler extends IncrementalCompiler {
|
||||
scope: libraryBuilder.scope.createNestedScope("dartdoctest"),
|
||||
nameOrigin: libraryBuilder,
|
||||
isUnsupported: false,
|
||||
isAugmentation: false,
|
||||
);
|
||||
|
||||
if (libraryBuilder is DillLibraryBuilder) {
|
||||
|
||||
Reference in New Issue
Block a user