[cfe] Apply declarations macro using class-relations

Declarations macros on classes are now run using topological
order of the classes. This lets declarations macros see the
result of declarations macros applied to superclasses.

Change-Id: Ic843408edc86fdedea2b5e15596ec67b5b54ef52
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244620
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
Johnni Winther
2022-05-17 09:32:26 +00:00
committed by Commit Bot
parent 787f83acab
commit 6ef2b237e0
8 changed files with 280 additions and 64 deletions
@@ -459,8 +459,8 @@ class KernelTarget extends TargetImplementation {
}
benchmarker?.enterPhase(BenchmarkPhases.outline_checkSemantics);
List<SourceClassBuilder>? sourceClassBuilders =
loader.checkSemantics(objectClassBuilder);
List<SourceClassBuilder>? sortedSourceClassBuilders =
loader.checkClassCycles(objectClassBuilder);
benchmarker?.enterPhase(BenchmarkPhases.outline_finishTypeVariables);
loader.finishTypeVariables(
@@ -484,15 +484,16 @@ class KernelTarget extends TargetImplementation {
computeCoreTypes();
benchmarker?.enterPhase(BenchmarkPhases.outline_buildClassHierarchy);
loader.buildClassHierarchy(sourceClassBuilders, objectClassBuilder);
loader.buildClassHierarchy(sortedSourceClassBuilders, objectClassBuilder);
benchmarker?.enterPhase(BenchmarkPhases.outline_checkSupertypes);
loader.checkSupertypes(
sourceClassBuilders, enumClass, underscoreEnumClass);
sortedSourceClassBuilders, enumClass, underscoreEnumClass);
if (macroApplications != null) {
benchmarker?.enterPhase(BenchmarkPhases.outline_applyDeclarationMacros);
await macroApplications.applyDeclarationsMacros(loader.hierarchyBuilder,
await macroApplications.applyDeclarationsMacros(
loader.hierarchyBuilder, sortedSourceClassBuilders,
(SourceLibraryBuilder augmentationLibrary) async {
List<SourceLibraryBuilder> augmentationLibraries = [
augmentationLibrary
@@ -508,14 +509,14 @@ class KernelTarget extends TargetImplementation {
benchmarker
?.enterPhase(BenchmarkPhases.outline_installSyntheticConstructors);
installSyntheticConstructors(sourceClassBuilders);
installSyntheticConstructors(sortedSourceClassBuilders);
benchmarker?.enterPhase(BenchmarkPhases.outline_resolveConstructors);
loader.resolveConstructors(loader.sourceLibraryBuilders);
benchmarker
?.enterPhase(BenchmarkPhases.outline_buildClassHierarchyMembers);
loader.buildClassHierarchyMembers(sourceClassBuilders);
loader.buildClassHierarchyMembers(sortedSourceClassBuilders);
benchmarker?.enterPhase(BenchmarkPhases.outline_computeHierarchy);
loader.computeHierarchy();
@@ -527,20 +528,20 @@ class KernelTarget extends TargetImplementation {
loader.installTypedefTearOffs();
benchmarker?.enterPhase(BenchmarkPhases.outline_performTopLevelInference);
loader.performTopLevelInference(sourceClassBuilders);
loader.performTopLevelInference(sortedSourceClassBuilders);
benchmarker?.enterPhase(BenchmarkPhases.outline_checkOverrides);
loader.checkOverrides(sourceClassBuilders);
loader.checkOverrides(sortedSourceClassBuilders);
benchmarker?.enterPhase(BenchmarkPhases.outline_checkAbstractMembers);
loader.checkAbstractMembers(sourceClassBuilders);
loader.checkAbstractMembers(sortedSourceClassBuilders);
benchmarker
?.enterPhase(BenchmarkPhases.outline_addNoSuchMethodForwarders);
loader.addNoSuchMethodForwarders(sourceClassBuilders);
loader.addNoSuchMethodForwarders(sortedSourceClassBuilders);
benchmarker?.enterPhase(BenchmarkPhases.outline_checkMixins);
loader.checkMixins(sourceClassBuilders);
loader.checkMixins(sortedSourceClassBuilders);
benchmarker?.enterPhase(BenchmarkPhases.outline_buildOutlineExpressions);
// TODO(johnniwinther): Add an interface for registering delayed actions.
@@ -554,7 +555,7 @@ class KernelTarget extends TargetImplementation {
benchmarker
?.enterPhase(BenchmarkPhases.outline_checkRedirectingFactories);
loader.checkRedirectingFactories(sourceClassBuilders);
loader.checkRedirectingFactories(sortedSourceClassBuilders);
benchmarker
?.enterPhase(BenchmarkPhases.outline_finishSynthesizedParameters);
@@ -574,7 +575,7 @@ class KernelTarget extends TargetImplementation {
// of time, meaning that all source library builders will be kept alive
// (for whatever amount of time) even though we convert them to dill
// library builders. To avoid it we null it out here.
sourceClassBuilders = null;
sortedSourceClassBuilders = null;
return new BuildResult(
component: component, macroApplications: macroApplications);
@@ -454,31 +454,40 @@ class MacroApplications {
late macro.TypeResolver typeResolver;
late macro.ClassIntrospector classIntrospector;
Future<void> applyDeclarationsMacros(ClassHierarchyBuilder classHierarchy,
Future<void> applyDeclarationsMacros(
ClassHierarchyBuilder classHierarchy,
List<SourceClassBuilder> sortedSourceClassBuilders,
Future<void> Function(SourceLibraryBuilder) onAugmentationLibrary) async {
types = new Types(classHierarchy);
typeResolver = new _TypeResolver(this);
classIntrospector = new _ClassIntrospector(this, classHierarchy);
// Apply macros to classes first, in class hierarchy order.
for (SourceClassBuilder classBuilder in sortedSourceClassBuilders) {
LibraryMacroApplicationData? libraryApplicationData =
libraryData[classBuilder.libraryBuilder];
if (libraryApplicationData == null) continue;
ClassMacroApplicationData? classApplicationData =
libraryApplicationData.classData[classBuilder];
if (classApplicationData == null) continue;
for (ApplicationData applicationData
in classApplicationData.memberApplications.values) {
await _applyDeclarationsMacros(applicationData, onAugmentationLibrary);
}
if (classApplicationData.classApplications != null) {
await _applyDeclarationsMacros(
classApplicationData.classApplications!, onAugmentationLibrary);
}
}
// Apply macros to library members second.
for (MapEntry<SourceLibraryBuilder, LibraryMacroApplicationData> entry
in libraryData.entries) {
LibraryMacroApplicationData data = entry.value;
for (ApplicationData applicationData in data.memberApplications.values) {
await _applyDeclarationsMacros(applicationData, onAugmentationLibrary);
}
for (MapEntry<ClassBuilder, ClassMacroApplicationData> entry
in data.classData.entries) {
ClassMacroApplicationData classApplicationData = entry.value;
for (ApplicationData applicationData
in classApplicationData.memberApplications.values) {
await _applyDeclarationsMacros(
applicationData, onAugmentationLibrary);
}
if (classApplicationData.classApplications != null) {
await _applyDeclarationsMacros(
classApplicationData.classApplications!, onAugmentationLibrary);
}
}
}
}
@@ -2005,7 +2005,11 @@ severity: $severity
}
}
List<SourceClassBuilder> checkSemantics(ClassBuilder objectClass) {
/// Checks that there are no cycles in the class hierarchy, and if so break
/// these cycles by removing supertypes.
///
/// Returns a list of all source classes in topological order.
List<SourceClassBuilder> checkClassCycles(ClassBuilder objectClass) {
checkObjectClassHierarchy(objectClass);
return handleHierarchyCycles(objectClass);
}
@@ -340,9 +340,25 @@ class SequenceMacro
ClassMemberDeclarationBuilder builder) async {
}
Future<void> _findAllMethods(ClassMemberDeclarationBuilder builder,
ClassDeclaration cls, List<MethodDeclaration> methods) async {
ClassDeclaration? superclass = await builder.superclassOf(cls);
if (superclass != null) {
await _findAllMethods(builder, superclass, methods);
}
for (ClassDeclaration mixin in await builder.mixinsOf(cls)) {
await _findAllMethods(builder, mixin, methods);
}
for (ClassDeclaration interface in await builder.interfacesOf(cls)) {
await _findAllMethods(builder, interface, methods);
}
methods.addAll(await builder.methodsOf(cls));
}
FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz,
ClassMemberDeclarationBuilder builder) async {
Iterable<MethodDeclaration> methods = await builder.methodsOf(clazz);
List<MethodDeclaration> methods = [];
await _findAllMethods(builder, clazz, methods);
int index = 0;
String suffix = '';
while (methods.any((m) => m.identifier.name == 'method$suffix')) {
@@ -4,14 +4,6 @@
/*library:
Declarations Order:
topLevelFunction1:FunctionDeclarationsMacro1.new()
topLevelFunction2:FunctionDeclarationsMacro1.new()
topLevelField1:VariableDeclarationsMacro1.new()
topLevelField2:VariableDeclarationsMacro1.new()
topLevelField3:VariableDeclarationsMacro1.new()
topLevelField4:VariableDeclarationsMacro1.new()
topLevelGetter1:FunctionDeclarationsMacro1.new()
topLevelSetter1:FunctionDeclarationsMacro1.new()
Class1.instanceMethod1:MethodDeclarationsMacro1.new()
Class1.instanceGetter1:MethodDeclarationsMacro1.new()
Class1.[]:MethodDeclarationsMacro1.new()
@@ -27,7 +19,15 @@ Declarations Order:
Class2.instanceMethod1:MethodDeclarationsMacro1.new()
Class2.instanceField1:FieldDeclarationsMacro1.new()
Class2:ClassDeclarationsMacro2.new()
Class2:ClassDeclarationsMacro1.new()*/
Class2:ClassDeclarationsMacro1.new()
topLevelFunction1:FunctionDeclarationsMacro1.new()
topLevelFunction2:FunctionDeclarationsMacro1.new()
topLevelField1:VariableDeclarationsMacro1.new()
topLevelField2:VariableDeclarationsMacro1.new()
topLevelField3:VariableDeclarationsMacro1.new()
topLevelField4:VariableDeclarationsMacro1.new()
topLevelGetter1:FunctionDeclarationsMacro1.new()
topLevelSetter1:FunctionDeclarationsMacro1.new()*/
import 'package:macro/macro.dart';
@@ -19,9 +19,9 @@ class Class1 extends core::Object {
constructor •() → self::Class1
: super core::Object::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-15 */ Class1_GeneratedMethod_() → void {}
method /* from org-dartlang-augmentation:/a/b/c/main.dart-16 */ Class1_redirectGeneratedMethod_f() → void {}
method /* from org-dartlang-augmentation:/a/b/c/main.dart-17 */ Class1_factGeneratedMethod_f() → void {}
method /* from org-dartlang-augmentation:/a/b/c/main.dart-7 */ Class1_GeneratedMethod_() → void {}
method /* from org-dartlang-augmentation:/a/b/c/main.dart-8 */ Class1_redirectGeneratedMethod_f() → void {}
method /* from org-dartlang-augmentation:/a/b/c/main.dart-9 */ Class1_factGeneratedMethod_f() → void {}
@#C5
static factory redirect() → self::Class1
return new self::Class1::•();
@@ -71,35 +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-0 */ topLevelFunction1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-1 */ topLevelFunction2GeneratedMethod_e() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-2 */ topLevelField1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-3 */ topLevelField2GeneratedMethod_e() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-4 */ topLevelField3GeneratedMethod_f() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-5 */ topLevelField4GeneratedMethod_l() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-6 */ topLevelGetter1GeneratedMethod_g() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-7 */ topLevelSetter1GeneratedMethod_s() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-8 */ Class1_instanceMethod1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-9 */ Class1_instanceGetter1GeneratedMethod_g() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-10 */ Class1_operatorGeneratedMethod_o() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-11 */ Class1_instanceField1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-12 */ Class1_instanceField2GeneratedMethod_f() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-13 */ Class1_instanceField3GeneratedMethod_fl() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-14 */ Class1_instanceSetter1GeneratedMethod_s() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-18 */ Class1Introspection() → void {
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-0 */ Class1_instanceMethod1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-1 */ Class1_instanceGetter1GeneratedMethod_g() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-2 */ Class1_operatorGeneratedMethod_o() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-3 */ Class1_instanceField1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-4 */ Class1_instanceField2GeneratedMethod_f() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-5 */ Class1_instanceField3GeneratedMethod_fl() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-6 */ Class1_instanceSetter1GeneratedMethod_s() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-10 */ Class1Introspection() → void {
core::print("constructors='','redirect','fact'");
core::print("fields='instanceField1','instanceField2','instanceField3'");
core::print("methods='instanceMethod1','instanceGetter1','[]','Class1_GeneratedMethod_','Class1_redirectGeneratedMethod_f','Class1_factGeneratedMethod_f','instanceSetter1','Class1_GeneratedMethod_','Class1_redirectGeneratedMethod_f','Class1_factGeneratedMethod_f'");
}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-19 */ Class1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-20 */ Class2_instanceMethod1GeneratedMethod_a() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-21 */ Class2_instanceField1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-22 */ Class2Introspection() → void {
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-11 */ Class1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-12 */ Class2_instanceMethod1GeneratedMethod_a() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-13 */ Class2_instanceField1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-14 */ 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 */ Class2GeneratedMethod_a() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-15 */ Class2GeneratedMethod_a() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-16 */ topLevelFunction1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-17 */ topLevelFunction2GeneratedMethod_e() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-18 */ topLevelField1GeneratedMethod_() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-19 */ topLevelField2GeneratedMethod_e() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-20 */ topLevelField3GeneratedMethod_f() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-21 */ topLevelField4GeneratedMethod_l() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-22 */ topLevelGetter1GeneratedMethod_g() → void {}
static method /* from org-dartlang-augmentation:/a/b/c/main.dart-23 */ topLevelSetter1GeneratedMethod_s() → void {}
constants {
#C1 = mac::ClassDeclarationsMacro1 {}
@@ -14,7 +14,18 @@ Declarations Order:
Class4.method2:SequenceMacro.new(4)
Class4:SequenceMacro.new(2)
Class4:SequenceMacro.new(1)
Class4:SequenceMacro.new(0)*/
Class4:SequenceMacro.new(0)
Class5a:SequenceMacro.new(0)
Class5b:SequenceMacro.new(0)
Class5c:SequenceMacro.new(0)
Class6c:SequenceMacro.new(0)
Class6a:SequenceMacro.new(0)
Class6b:SequenceMacro.new(0)
Class6d:SequenceMacro.new(0)
Class7a:SequenceMacro.new(0)
Class7b:SequenceMacro.new(0)
Class7c:SequenceMacro.new(0)
Class7d:SequenceMacro.new(0)*/
import 'package:macro/macro.dart';
@@ -60,3 +71,80 @@ class Class4 {
@SequenceMacro(5)
method2() {}
}
/*class: Class5c:
augment class Class5c {
method2() {}
}*/
@SequenceMacro(0)
class Class5c extends Class5b {}
/*class: Class5b:
augment class Class5b {
method1() {}
}*/
@SequenceMacro(0)
class Class5b extends Class5a {}
/*class: Class5a:
augment class Class5a {
method() {}
}*/
@SequenceMacro(0)
class Class5a {}
/*class: Class6d:
augment class Class6d {
method2() {}
}*/
@SequenceMacro(0)
abstract class Class6d implements Class6c, Class6b {}
/*class: Class6c:
augment class Class6c {
method() {}
}*/
@SequenceMacro(0)
class Class6c {}
/*class: Class6b:
augment class Class6b {
method1() {}
}*/
@SequenceMacro(0)
abstract class Class6b implements Class6a {}
/*class: Class6a:
augment class Class6a {
method() {}
}*/
@SequenceMacro(0)
class Class6a {}
/*class: Class7d:
augment class Class7d {
method2() {}
}*/
@SequenceMacro(0)
class Class7d with Class7b, Class7c {}
/*class: Class7c:
augment class Class7c {
method() {}
}*/
@SequenceMacro(0)
class Class7c {}
/*class: Class7b:
augment class Class7b {
method1() {}
}*/
@SequenceMacro(0)
class Class7b with Class7a {}
/*class: Class7a:
augment class Class7a {
method() {}
}*/
@SequenceMacro(0)
class Class7a {}
@@ -46,6 +46,104 @@ class Class4 extends core::Object {
@#C12
method method2() → dynamic {}
}
@#C2
class Class5c extends self::Class5b {
synthetic constructor •() → self::Class5c
: super self::Class5b::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-9 */ method2() → dynamic {}
}
@#C2
class Class5b extends self::Class5a {
synthetic constructor •() → self::Class5b
: super self::Class5a::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-8 */ method1() → dynamic {}
}
@#C2
class Class5a extends core::Object {
synthetic constructor •() → self::Class5a
: super core::Object::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-7 */ method() → dynamic {}
}
@#C2
class Class6d extends core::Object implements self::Class6c, self::Class6b {
synthetic constructor •() → self::Class6d
: super core::Object::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-13 */ method2() → dynamic {}
}
@#C2
class Class6c extends core::Object {
synthetic constructor •() → self::Class6c
: super core::Object::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-10 */ method() → dynamic {}
}
@#C2
class Class6b extends core::Object implements self::Class6a {
synthetic constructor •() → self::Class6b
: super core::Object::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-12 */ method1() → dynamic {}
}
@#C2
class Class6a extends core::Object {
synthetic constructor •() → self::Class6a
: super core::Object::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-11 */ method() → dynamic {}
}
abstract class _Class7d&Object&Class7b = core::Object with self::Class7b /*isAnonymousMixin,hasConstConstructor*/ {
const synthetic constructor •() → self::_Class7d&Object&Class7b
: super core::Object::•()
;
mixin-super-stub method method1() → dynamic
return super.{self::Class7b::method1}();
}
abstract class _Class7d&Object&Class7b&Class7c = self::_Class7d&Object&Class7b with self::Class7c /*isAnonymousMixin,hasConstConstructor*/ {
const synthetic constructor •() → self::_Class7d&Object&Class7b&Class7c
: super self::_Class7d&Object&Class7b::•()
;
mixin-super-stub method method() → dynamic
return super.{self::Class7c::method}();
}
@#C2
class Class7d extends self::_Class7d&Object&Class7b&Class7c {
synthetic constructor •() → self::Class7d
: super self::_Class7d&Object&Class7b&Class7c::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-17 */ method2() → dynamic {}
}
@#C2
class Class7c extends core::Object {
synthetic constructor •() → self::Class7c
: super core::Object::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-16 */ method() → dynamic {}
}
abstract class _Class7b&Object&Class7a = core::Object with self::Class7a /*isAnonymousMixin,hasConstConstructor*/ {
const synthetic constructor •() → self::_Class7b&Object&Class7a
: super core::Object::•()
;
mixin-super-stub method method() → dynamic
return super.{self::Class7a::method}();
}
@#C2
class Class7b extends self::_Class7b&Object&Class7a {
synthetic constructor •() → self::Class7b
: super self::_Class7b&Object&Class7a::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-15 */ method1() → dynamic {}
}
@#C2
class Class7a extends core::Object {
synthetic constructor •() → self::Class7a
: super core::Object::•()
;
method /* from org-dartlang-augmentation:/a/b/c/main.dart-14 */ method() → dynamic {}
}
constants {
#C1 = 0