Macro. More ordering for declarations phase.
Change-Id: I01e528a0f077367929e9e631992644b198165d6b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/333581
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/library_builder.dart b/pkg/analyzer/lib/src/summary2/library_builder.dart
index 010ab14..4f78ea1 100644
--- a/pkg/analyzer/lib/src/summary2/library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/library_builder.dart
@@ -350,66 +350,71 @@
_declaredReferences[name] = reference;
}
- Future<void> executeMacroDeclarationsPhase({
+ /// Completes with `true` if a macro application was run in this library.
+ ///
+ /// Completes with `false` if there are no macro applications to run, either
+ /// because we ran all, or those that we have not run yet have dependencies
+ /// of interfaces declared in other libraries that, and we have not run yet
+ /// declarations phase macro applications for them.
+ Future<bool> executeMacroDeclarationsPhase({
required OperationPerformanceImpl performance,
}) async {
final macroApplier = linker.macroApplier;
if (macroApplier == null) {
- return;
+ return false;
}
- while (true) {
- final results = await macroApplier.executeDeclarationsPhase(
- typeSystem: element.typeSystem,
- );
+ final results = await macroApplier.executeDeclarationsPhase(
+ library: element,
+ );
- // No more applications to execute.
- if (results == null) {
- break;
- }
-
- // No results from the application.
- if (results.isEmpty) {
- continue;
- }
-
- _macroResults.add(results);
-
- final augmentationCode = macroApplier.buildAugmentationLibraryCode(
- results,
- );
- if (augmentationCode == null) {
- continue;
- }
-
- final importState = kind.addMacroAugmentation(
- augmentationCode,
- addLibraryAugmentDirective: true,
- partialIndex: _macroResults.length,
- );
-
- final augmentation = _addMacroAugmentation(importState);
-
- final macroLinkingUnit = units.last;
- ElementBuilder(
- libraryBuilder: this,
- container: macroLinkingUnit.container,
- unitReference: macroLinkingUnit.reference,
- unitElement: macroLinkingUnit.element,
- ).buildDeclarationElements(macroLinkingUnit.node);
-
- final nodesToBuildType = NodesToBuildType();
- final resolver =
- ReferenceResolver(linker, nodesToBuildType, augmentation);
- macroLinkingUnit.node.accept(resolver);
- TypesBuilder(linker).build(nodesToBuildType);
-
- // Append applications from the partial augmentation.
- await macroApplier.add(
- container: augmentation,
- unit: macroLinkingUnit.node,
- );
+ // No more applications to execute.
+ if (results == null) {
+ return false;
}
+
+ // No results from the application.
+ if (results.isEmpty) {
+ return true;
+ }
+
+ _macroResults.add(results);
+
+ final augmentationCode = macroApplier.buildAugmentationLibraryCode(
+ results,
+ );
+ if (augmentationCode == null) {
+ return true;
+ }
+
+ final importState = kind.addMacroAugmentation(
+ augmentationCode,
+ addLibraryAugmentDirective: true,
+ partialIndex: _macroResults.length,
+ );
+
+ final augmentation = _addMacroAugmentation(importState);
+
+ final macroLinkingUnit = units.last;
+ ElementBuilder(
+ libraryBuilder: this,
+ container: macroLinkingUnit.container,
+ unitReference: macroLinkingUnit.reference,
+ unitElement: macroLinkingUnit.element,
+ ).buildDeclarationElements(macroLinkingUnit.node);
+
+ final nodesToBuildType = NodesToBuildType();
+ final resolver = ReferenceResolver(linker, nodesToBuildType, augmentation);
+ macroLinkingUnit.node.accept(resolver);
+ TypesBuilder(linker).build(nodesToBuildType);
+
+ // Append applications from the partial augmentation.
+ await macroApplier.add(
+ libraryElement: element,
+ container: augmentation,
+ unit: macroLinkingUnit.node,
+ );
+ return true;
}
Future<void> executeMacroTypesPhase({
@@ -460,6 +465,7 @@
// Append applications from the partial augmentation.
await macroApplier.add(
+ libraryElement: element,
container: augmentation,
unit: macroLinkingUnit.node,
);
@@ -470,6 +476,7 @@
Future<void> fillMacroApplier(LibraryMacroApplier macroApplier) async {
for (final linkingUnit in units) {
await macroApplier.add(
+ libraryElement: element,
container: element,
unit: linkingUnit.node,
);
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 61edb9d..ed5fe4c 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -305,10 +305,16 @@
Future<void> _executeMacroDeclarationsPhase({
required OperationPerformanceImpl performance,
}) async {
- for (final library in builders.values) {
- await library.executeMacroDeclarationsPhase(
- performance: performance,
- );
+ while (true) {
+ var hasProgress = false;
+ for (final library in builders.values) {
+ hasProgress |= await library.executeMacroDeclarationsPhase(
+ performance: performance,
+ );
+ }
+ if (!hasProgress) {
+ break;
+ }
}
}
diff --git a/pkg/analyzer/lib/src/summary2/macro_application.dart b/pkg/analyzer/lib/src/summary2/macro_application.dart
index f3434af..c2cd358 100644
--- a/pkg/analyzer/lib/src/summary2/macro_application.dart
+++ b/pkg/analyzer/lib/src/summary2/macro_application.dart
@@ -8,6 +8,7 @@
import 'package:_fe_analyzer_shared/src/macros/executor/protocol.dart' as macro;
import 'package:analyzer/dart/ast/ast.dart' as ast;
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart' as ast;
@@ -18,6 +19,7 @@
import 'package:analyzer/src/summary2/macro_application_error.dart';
import 'package:analyzer/src/summary2/macro_declarations.dart';
import 'package:analyzer/src/utilities/extensions/object.dart';
+import 'package:collection/collection.dart';
/// The full list of [macro.ArgumentKind]s for this dart type (includes the type
/// itself as well as type arguments, in source order with
@@ -71,8 +73,25 @@
final MultiMacroExecutor macroExecutor;
final bool Function(Uri) isLibraryBeingLinked;
final DeclarationBuilder declarationBuilder;
+
+ /// The reversed queue of macro applications to apply.
+ ///
+ /// We add classes before methods, and methods in the reverse order,
+ /// classes in the reverse order, annotations in the direct order.
+ ///
+ /// We iterate from the end looking for the next application to apply.
+ /// This way we ensure two ordering rules:
+ /// 1. inner before outer
+ /// 2. right to left
+ /// 3. source order
final List<_MacroApplication> _applications = [];
+ /// The map from [InstanceElement] to the applications associated with it.
+ /// This includes applications on the class itself, and on the methods of
+ /// the class.
+ final Map<InstanceElement, List<_MacroApplication>> _interfaceApplications =
+ {};
+
late final macro.TypePhaseIntrospector _typesPhaseIntrospector =
_TypePhaseIntrospector(elementFactory, declarationBuilder);
@@ -84,6 +103,7 @@
});
Future<void> add({
+ required LibraryElementImpl libraryElement,
required LibraryOrAugmentationElementImpl container,
required ast.CompilationUnit unit,
}) async {
@@ -92,23 +112,31 @@
case ast.ClassDeclaration():
final element = declaration.declaredElement;
element as ClassElementImpl;
+ final declarationElement = element.augmented?.declaration ?? element;
+ declarationElement as ClassElementImpl;
await _addClassLike(
+ libraryElement: libraryElement,
container: container,
- targetElement: element.declarationElement,
+ targetElement: declarationElement,
classNode: declaration,
classDeclarationKind: macro.DeclarationKind.classType,
classAnnotations: declaration.metadata,
+ declarationsPhaseInterface: declarationElement,
members: declaration.members,
);
case ast.MixinDeclaration():
final element = declaration.declaredElement;
element as MixinElementImpl;
+ final declarationElement = element.augmented?.declaration ?? element;
+ declarationElement as MixinElementImpl;
await _addClassLike(
+ libraryElement: libraryElement,
container: container,
- targetElement: element.declarationElement,
+ targetElement: declarationElement,
classNode: declaration,
classDeclarationKind: macro.DeclarationKind.mixinType,
classAnnotations: declaration.metadata,
+ declarationsPhaseInterface: declarationElement,
members: declaration.members,
);
}
@@ -134,9 +162,11 @@
}
Future<List<macro.MacroExecutionResult>?> executeDeclarationsPhase({
- required TypeSystemImpl typeSystem,
+ required LibraryElementImpl library,
}) async {
- final application = _nextForDeclarationsPhase();
+ final application = _nextForDeclarationsPhase(
+ library: library,
+ );
if (application == null) {
return null;
}
@@ -150,7 +180,7 @@
final introspector = _DeclarationPhaseIntrospector(
elementFactory,
declarationBuilder,
- typeSystem,
+ library.typeSystem,
);
final result = await macroExecutor.executeDeclarationsPhase(
@@ -204,7 +234,9 @@
}
Future<void> _addAnnotations({
+ required LibraryElementImpl libraryElement,
required LibraryOrAugmentationElementImpl container,
+ required InstanceElement? declarationsPhaseElement,
required ast.Declaration targetNode,
required macro.DeclarationKind targetDeclarationKind,
required List<ast.Annotation> annotations,
@@ -251,39 +283,54 @@
return instance.shouldExecute(targetDeclarationKind, phase);
}).toSet();
- _applications.add(
- _MacroApplication(
- targetNode: targetNode,
- targetElement: targetElement,
- targetDeclarationKind: targetDeclarationKind,
- instance: instance,
- phasesToExecute: phasesToExecute,
- ),
+ final application = _MacroApplication(
+ libraryElement: libraryElement,
+ declarationsPhaseElement: declarationsPhaseElement,
+ targetNode: targetNode,
+ targetElement: targetElement,
+ targetDeclarationKind: targetDeclarationKind,
+ annotationNode: annotation,
+ instance: instance,
+ phasesToExecute: phasesToExecute,
);
+
+ _applications.add(application);
+
+ // Record mapping for declarations phase dependencies.
+ if (declarationsPhaseElement != null) {
+ (_interfaceApplications[declarationsPhaseElement] ??= [])
+ .add(application);
+ }
}
}
Future<void> _addClassLike({
+ required LibraryElementImpl libraryElement,
required LibraryOrAugmentationElementImpl container,
required MacroTargetElement targetElement,
required ast.Declaration classNode,
required macro.DeclarationKind classDeclarationKind,
required List<ast.Annotation> classAnnotations,
+ required InterfaceElement? declarationsPhaseInterface,
required List<ast.ClassMember> members,
}) async {
await _addAnnotations(
+ libraryElement: libraryElement,
container: container,
targetNode: classNode,
targetDeclarationKind: classDeclarationKind,
+ declarationsPhaseElement: declarationsPhaseInterface,
annotations: classAnnotations,
);
for (final member in members.reversed) {
await _addAnnotations(
+ libraryElement: libraryElement,
container: container,
targetNode: member,
// TODO(scheglov) incomplete
targetDeclarationKind: macro.DeclarationKind.method,
+ declarationsPhaseElement: declarationsPhaseInterface,
annotations: member.metadata,
);
}
@@ -304,6 +351,28 @@
}
}
+ bool _hasInterfaceDependenciesSatisfied(_MacroApplication application) {
+ final dependencyElements = _interfaceDependencies(
+ application.declarationsPhaseElement,
+ );
+ if (dependencyElements == null) {
+ return true;
+ }
+
+ for (final dependencyElement in dependencyElements) {
+ final applications = _interfaceApplications[dependencyElement];
+ if (applications != null) {
+ for (final dependencyApplication in applications) {
+ if (dependencyApplication.hasDeclarationsPhase) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
/// If [annotation] references a macro, invokes the right callback.
_AnnotationMacro? _importedMacro({
required LibraryOrAugmentationElementImpl container,
@@ -385,13 +454,58 @@
throw UnimplementedError();
}
- /// TODO(scheglov) Should use dependencies.
- _MacroApplication? _nextForDeclarationsPhase() {
- for (final application in _applications.reversed) {
- if (application.phasesToExecute.remove(macro.Phase.declarations)) {
- return application;
- }
+ Set<InstanceElement>? _interfaceDependencies(InstanceElement? element) {
+ // TODO(scheglov) other elements
+ switch (element) {
+ case ExtensionElement():
+ // TODO(scheglov) implement
+ throw UnimplementedError();
+ case MixinElement():
+ final augmented = element.augmented;
+ switch (augmented) {
+ case null:
+ return const {};
+ default:
+ return [
+ ...augmented.superclassConstraints.map((e) => e.element),
+ ...augmented.interfaces.map((e) => e.element),
+ ].whereNotNull().toSet();
+ }
+ case InterfaceElement():
+ final augmented = element.augmented;
+ switch (augmented) {
+ case null:
+ return const {};
+ default:
+ return [
+ element.supertype?.element,
+ ...augmented.mixins.map((e) => e.element),
+ ...augmented.interfaces.map((e) => e.element),
+ ].whereNotNull().toSet();
+ }
+ default:
+ return null;
}
+ }
+
+ _MacroApplication? _nextForDeclarationsPhase({
+ required LibraryElementImpl library,
+ }) {
+ for (final application in _applications.reversed) {
+ if (!application.hasDeclarationsPhase) {
+ continue;
+ }
+ if (application.libraryElement != library) {
+ continue;
+ }
+ if (!_hasInterfaceDependenciesSatisfied(application)) {
+ continue;
+ }
+ // The application has no dependencies to run.
+ application.removeDeclarationsPhase();
+ return application;
+ }
+
return null;
}
@@ -610,14 +724,22 @@
.map(declarationBuilder.fromElement.fieldElement)
.toList();
}
+ // TODO(scheglov) implement
throw UnsupportedError('Only introspection on classes is supported');
}
@override
Future<List<macro.MethodDeclaration>> methodsOf(
- covariant macro.IntrospectableType clazz) {
- // TODO: implement methodsOf
- throw UnimplementedError();
+ covariant macro.IntrospectableType type) async {
+ switch (type) {
+ case IntrospectableClassDeclarationImpl():
+ return type.element.augmented!.methods
+ .where((e) => !e.isSynthetic)
+ .map(declarationBuilder.fromElement.methodElement)
+ .toList();
+ }
+ // TODO(scheglov) implement
+ throw UnsupportedError('Only introspection on classes is supported');
}
@override
@@ -675,19 +797,33 @@
}
class _MacroApplication {
+ final LibraryElementImpl libraryElement;
+ final InstanceElement? declarationsPhaseElement;
final ast.AstNode targetNode;
final MacroTargetElement targetElement;
final macro.DeclarationKind targetDeclarationKind;
+ final ast.Annotation annotationNode;
final macro.MacroInstanceIdentifier instance;
final Set<macro.Phase> phasesToExecute;
_MacroApplication({
+ required this.libraryElement,
+ required this.declarationsPhaseElement,
required this.targetNode,
required this.targetElement,
required this.targetDeclarationKind,
+ required this.annotationNode,
required this.instance,
required this.phasesToExecute,
});
+
+ bool get hasDeclarationsPhase {
+ return phasesToExecute.contains(macro.Phase.declarations);
+ }
+
+ void removeDeclarationsPhase() {
+ phasesToExecute.remove(macro.Phase.declarations);
+ }
}
class _StaticTypeImpl implements macro.StaticType {
@@ -736,14 +872,3 @@
mixinAugmentations.isNotEmpty ||
typeAugmentations.isNotEmpty;
}
-
-extension<T extends InstanceElementImpl> on T {
- T get declarationElement {
- switch (augmented) {
- case T(:final T declaration):
- return declaration;
- default:
- return this;
- }
- }
-}
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index b453b2d..6de638c 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -55,6 +55,7 @@
bool withPropertyLinking = false;
bool withRedirectedConstructors = false;
bool withReferences = false;
+ bool withReturnType = true;
bool withSyntheticDartCoreImport = false;
ElementTextConfiguration({
@@ -539,7 +540,7 @@
_writeCodeRange(e);
_writeTypeParameterElements(e.typeParameters);
_writeParameterElements(e.parameters);
- _writeType('returnType', e.returnType);
+ _writeReturnType(e.returnType);
_writeAugmentationTarget(e);
_writeAugmentation(e);
});
@@ -710,10 +711,12 @@
_writeElements('exports', e.libraryExports, _writeExportElement);
- _sink.writelnWithIndent('definingUnit');
- _sink.withIndent(() {
- _writeUnitElement(e.definingCompilationUnit);
- });
+ if (configuration.filter(e.definingCompilationUnit)) {
+ _sink.writelnWithIndent('definingUnit');
+ _sink.withIndent(() {
+ _writeUnitElement(e.definingCompilationUnit);
+ });
+ }
if (e is LibraryElementImpl) {
_writeLibraryAugmentations(e);
@@ -760,7 +763,7 @@
_writeTypeParameterElements(e.typeParameters);
_writeParameterElements(e.parameters);
- _writeType('returnType', e.returnType);
+ _writeReturnType(e.returnType);
_writeNonSyntheticElement(e);
if (e.isAugmentation) {
@@ -967,7 +970,7 @@
expect(e.typeParameters, isEmpty);
_writeParameterElements(e.parameters);
- _writeType('returnType', e.returnType);
+ _writeReturnType(e.returnType);
_writeNonSyntheticElement(e);
writeLinking();
_writeAugmentationTarget(e);
@@ -1058,6 +1061,12 @@
}
}
+ void _writeReturnType(DartType type) {
+ if (configuration.withReturnType) {
+ _writeType('returnType', type);
+ }
+ }
+
void _writeShouldUseTypeForInitializerInference(
PropertyInducingElementImpl e,
) {
@@ -1129,7 +1138,7 @@
_sink.withIndent(() {
_writeTypeParameterElements(aliasedElement.typeParameters);
_writeParameterElements(aliasedElement.parameters);
- _writeType('returnType', aliasedElement.returnType);
+ _writeReturnType(aliasedElement.returnType);
});
}
});
diff --git a/pkg/analyzer/test/src/summary/elements_base.dart b/pkg/analyzer/test/src/summary/elements_base.dart
index 9162cc0..b7d95fc 100644
--- a/pkg/analyzer/test/src/summary/elements_base.dart
+++ b/pkg/analyzer/test/src/summary/elements_base.dart
@@ -32,18 +32,14 @@
final uriStr = 'package:test/test.dart';
final libraryResult = await analysisSession.getLibraryByUri(uriStr);
- libraryResult as LibraryElementResult;
if (keepLinkingLibraries) {
- return libraryResult.element as LibraryElementImpl;
+ return libraryResult.element;
} else {
analysisContext.changeFile(file.path);
await analysisContext.applyPendingFileChanges();
// Ask again, should be read from bytes.
- final analysisSession = analysisContext.currentSession;
- final libraryResult = await analysisSession.getLibraryByUri(uriStr);
- libraryResult as LibraryElementResult;
- return libraryResult.element as LibraryElementImpl;
+ return testContextLibrary(uriStr);
}
}
@@ -59,4 +55,17 @@
}
expect(actual, expected);
}
+
+ Future<LibraryElementImpl> testContextLibrary(String uriStr) async {
+ final analysisContext = contextFor(testFile);
+ final analysisSession = analysisContext.currentSession;
+ final libraryResult = await analysisSession.getLibraryByUri(uriStr);
+ return libraryResult.element;
+ }
+}
+
+extension on SomeLibraryElementResult {
+ LibraryElementImpl get element {
+ return (this as LibraryElementResult).element as LibraryElementImpl;
+ }
}
diff --git a/pkg/analyzer/test/src/summary/macro/order.dart b/pkg/analyzer/test/src/summary/macro/order.dart
index 971a597..34ed6f7 100644
--- a/pkg/analyzer/test/src/summary/macro/order.dart
+++ b/pkg/analyzer/test/src/summary/macro/order.dart
@@ -4,7 +4,8 @@
import 'package:_fe_analyzer_shared/src/macros/api.dart';
-/*macro*/ class AddClass implements ClassTypesMacro, MethodTypesMacro {
+/*macro*/ class AddClass
+ implements ClassTypesMacro, MethodTypesMacro, MixinTypesMacro {
final String name;
const AddClass(this.name);
@@ -19,6 +20,11 @@
_add(builder);
}
+ @override
+ buildTypesForMixin(method, builder) {
+ _add(builder);
+ }
+
void _add(TypeBuilder builder) {
final code = 'class $name {}';
builder.declareType(name, DeclarationCode.fromString(code));
@@ -26,7 +32,10 @@
}
/*macro*/ class AddFunction
- implements ClassDeclarationsMacro, MethodDeclarationsMacro {
+ implements
+ ClassDeclarationsMacro,
+ MethodDeclarationsMacro,
+ MixinDeclarationsMacro {
final String name;
const AddFunction(this.name);
@@ -41,9 +50,42 @@
_add(builder);
}
+ @override
+ buildDeclarationsForMixin(method, builder) {
+ _add(builder);
+ }
+
void _add(DeclarationBuilder builder) {
final code = 'void $name() {}';
final declaration = DeclarationCode.fromString(code);
builder.declareInLibrary(declaration);
}
}
+
+/*macro*/ class AddHierarchyMethod implements ClassDeclarationsMacro {
+ final String name;
+
+ const AddHierarchyMethod(this.name);
+
+ @override
+ buildDeclarationsForClass(clazz, builder) async {
+ // builder.typeDeclarationOf(identifier);
+ final methods = (await Future.wait(
+ clazz.interfaces.map(
+ (interface) async {
+ final type = await builder.typeDeclarationOf(interface.identifier);
+ type as IntrospectableType;
+ return await builder.methodsOf(type);
+ },
+ ),
+ ))
+ .expand((element) => element)
+ .toList();
+ final methodsStr = methods.map((e) => e.identifier.name).join('_');
+
+ final compoundName = methodsStr.isEmpty ? name : '${methodsStr}_$name';
+ final code = ' void $compoundName() {}';
+ final declaration = DeclarationCode.fromString(code);
+ builder.declareInType(declaration);
+ }
+}
diff --git a/pkg/analyzer/test/src/summary/macro_test.dart b/pkg/analyzer/test/src/summary/macro_test.dart
index 934f9ff..47b4e06 100644
--- a/pkg/analyzer/test/src/summary/macro_test.dart
+++ b/pkg/analyzer/test/src/summary/macro_test.dart
@@ -23,6 +23,7 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/node_text_expectations.dart';
+import 'element_text.dart';
import 'elements_base.dart';
import 'macros_environment.dart';
@@ -45,12 +46,16 @@
defineReflectiveTests(MacroDeclarationsTest_fromBytes);
defineReflectiveTests(MacroElementsTest_keepLinking);
defineReflectiveTests(MacroElementsTest_fromBytes);
- defineReflectiveTests(MacroApplicationOrderTest_keepLinking);
+ defineReflectiveTests(MacroApplicationOrderTest);
defineReflectiveTests(UpdateNodeTextExpectations);
});
}
-abstract class MacroApplicationOrderTest extends MacroElementsBaseTest {
+@reflectiveTest
+class MacroApplicationOrderTest extends MacroElementsBaseTest {
+ @override
+ bool get keepLinkingLibraries => true;
+
String get _orderCode {
var code = MacrosEnvironment.instance.packageAnalyzerFolder
.getChildAssumingFile('test/src/summary/macro/order.dart')
@@ -58,34 +63,799 @@
return code.replaceAll('/*macro*/', 'macro');
}
- test_phases_class_types_declarations() async {
- newFile('$testPackageLibPath/a.dart', _orderCode);
+ test_declarations_class_interfaces_backward() async {
+ _newOrderMacrosFile();
var library = await buildLibrary(r'''
-import 'a.dart';
+import 'order.dart';
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f11')
+@AddFunction('f12')
+class X1 implements X2, X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f32() {}
+void f31() {}
+void f22() {}
+void f21() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_class_interfaces_forward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f11')
+@AddFunction('f12')
+class X1 implements X2, X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f22() {}
+void f21() {}
+void f32() {}
+void f31() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_class_interfaces_forward2() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f11')
+@AddFunction('f12')
+class X1 implements X3, X4 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 implements X3, X4 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+
+@AddFunction('f41')
+@AddFunction('f42')
+class X4 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f32() {}
+void f31() {}
+void f42() {}
+void f41() {}
+void f12() {}
+void f11() {}
+void f22() {}
+void f21() {}
+---
+''');
+ }
+
+ test_declarations_class_interfaces_forward3() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f11')
+@AddFunction('f12')
+class X1 implements X2, X4 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 implements X3 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+
+@AddFunction('f41')
+@AddFunction('f42')
+class X4 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f32() {}
+void f31() {}
+void f22() {}
+void f21() {}
+void f42() {}
+void f41() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_class_mixins_backward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f31')
+@AddFunction('f32')
+mixin X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+mixin X2 {}
+
+@AddFunction('f11')
+@AddFunction('f12')
+class X1 with X2, X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f32() {}
+void f31() {}
+void f22() {}
+void f21() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_class_mixins_forward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f11')
+@AddFunction('f12')
+class X1 with X2, X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+mixin X2 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+mixin X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f22() {}
+void f21() {}
+void f32() {}
+void f31() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_class_superclass_backward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f3')
+class X3 extends X2 {
+ @AddFunction('f31')
+ void foo() {}
+
+ @AddFunction('f32')
+ void bar() {}
+}
+
+@AddFunction('f2')
+class X2 extends X1 {
+ @AddFunction('f21')
+ void foo() {}
+
+ @AddFunction('f22')
+ void bar() {}
+}
+
+@AddFunction('f1')
+class X1 {
+ @AddFunction('f11')
+ void foo() {}
+
+ @AddFunction('f12')
+ void bar() {}
+}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f11() {}
+void f12() {}
+void f1() {}
+void f21() {}
+void f22() {}
+void f2() {}
+void f31() {}
+void f32() {}
+void f3() {}
+---
+''');
+ }
+
+ test_declarations_class_superclass_forward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f1')
+class X1 {
+ @AddFunction('f11')
+ void foo() {}
+
+ @AddFunction('f12')
+ void bar() {}
+}
+
+@AddFunction('f2')
+class X2 extends X1 {
+ @AddFunction('f21')
+ void foo() {}
+
+ @AddFunction('f22')
+ void bar() {}
+}
+
+@AddFunction('f3')
+class X3 extends X2 {
+ @AddFunction('f31')
+ void foo() {}
+
+ @AddFunction('f32')
+ void bar() {}
+}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f11() {}
+void f12() {}
+void f1() {}
+void f21() {}
+void f22() {}
+void f2() {}
+void f31() {}
+void f32() {}
+void f3() {}
+---
+''');
+ }
+
+ test_declarations_class_superClass_mixins_interfaces_backward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f41')
+@AddFunction('f42')
+class X4 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+mixin X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f11')
+@AddFunction('f12')
+class X1 extends X2 with X3 implements X4 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f42() {}
+void f41() {}
+void f32() {}
+void f31() {}
+void f22() {}
+void f21() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_class_superClass_mixins_interfaces_forward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f11')
+@AddFunction('f12')
+class X1 extends X2 with X3 implements X4 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+mixin X3 {}
+
+@AddFunction('f41')
+@AddFunction('f42')
+class X4 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f22() {}
+void f21() {}
+void f32() {}
+void f31() {}
+void f42() {}
+void f41() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_libraryCycle_class_interfaces() async {
+ useEmptyByteStore();
+ _newOrderMacrosFile();
+
+ newFile('$testPackageLibPath/x2.dart', r'''
+import 'test.dart';
+import 'order.dart';
+
+@AddHierarchyMethod('f211')
+@AddHierarchyMethod('f212')
+class X21 {}
+
+@AddHierarchyMethod('f221')
+@AddHierarchyMethod('f222')
+class X22 {}
+''');
+
+ final testLibrary = await buildLibrary(r'''
+import 'order.dart';
+import 'x2.dart';
+
+@AddHierarchyMethod('f11')
+@AddHierarchyMethod('f12')
+class X1 implements X22 {}
+''');
+
+ // When we process `X1`, we see macro generated methods of `X22`.
+ // This shows that we processed `X22` before `X1`.
+ configuration.forOrder();
+ checkElementText(testLibrary, r'''
+library
+ imports
+ package:test/order.dart
+ package:test/x2.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+augment class X1 {
+ void f222_f221_f12() {}
+ void f222_f221_f11() {}
+}
+---
+''');
+
+ // There are no dependencies between `X21` and `X22`, so they are
+ // processed in the source order.
+ // We see `f212` before `f211`, this shows that we process annotations
+ // from right to left.
+ final x2Library = await testContextLibrary('package:test/x2.dart');
+ checkElementText(x2Library, r'''
+library
+ imports
+ package:test/test.dart
+ package:test/order.dart
+ augmentationImports
+ package:test/x2.macro.dart
+ macroGeneratedCode
+---
+library augment 'x2.dart';
+
+augment class X21 {
+ void f212() {}
+ void f211() {}
+}
+augment class X22 {
+ void f222() {}
+ void f221() {}
+}
+---
+''');
+ }
+
+ test_declarations_mixin_interfaces_backward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f11')
+@AddFunction('f12')
+mixin X1 implements X2, X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f32() {}
+void f31() {}
+void f22() {}
+void f21() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_mixin_interfaces_forward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f11')
+@AddFunction('f12')
+mixin X1 implements X2, X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f22() {}
+void f21() {}
+void f32() {}
+void f31() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_mixin_superclassConstraints_backward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f11')
+@AddFunction('f12')
+mixin X1 on X2, X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f32() {}
+void f31() {}
+void f22() {}
+void f21() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_mixin_superclassConstraints_forward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f11')
+@AddFunction('f12')
+mixin X1 on X2, X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f22() {}
+void f21() {}
+void f32() {}
+void f31() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_mixin_superclassConstraints_interfaces_backward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f11')
+@AddFunction('f12')
+mixin X1 on X2 implements X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f32() {}
+void f31() {}
+void f22() {}
+void f21() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_declarations_mixin_superclassConstraints_interfaces_forward() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddFunction('f11')
+@AddFunction('f12')
+mixin X1 on X2 implements X3 {}
+
+@AddFunction('f21')
+@AddFunction('f22')
+class X2 {}
+
+@AddFunction('f31')
+@AddFunction('f32')
+class X3 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+void f22() {}
+void f21() {}
+void f32() {}
+void f31() {}
+void f12() {}
+void f11() {}
+---
+''');
+ }
+
+ test_phases_class_types_declarations() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
@AddClass('A1')
@AddFunction('f1')
class X {}
''');
- configuration
- ..withConstructors = false
- ..withMetadata = false
- ..withReferences = true;
+ configuration.forOrder();
checkElementText(library, r'''
library
- reference: self
imports
- package:test/a.dart
- definingUnit
- reference: self
- classes
- class X @59
- reference: self::@class::X
+ package:test/order.dart
augmentationImports
package:test/test.macro.dart
- reference: self::@augmentation::package:test/test.macro.dart
macroGeneratedCode
---
library augment 'test.dart';
@@ -93,23 +863,14 @@
class A1 {}
void f1() {}
---
- definingUnit
- reference: self::@augmentation::package:test/test.macro.dart
- classes
- class A1 @36
- reference: self::@augmentation::package:test/test.macro.dart::@class::A1
- functions
- f1 @47
- reference: self::@augmentation::package:test/test.macro.dart::@function::f1
- returnType: void
''');
}
test_types_class_method_rightToLeft() async {
- newFile('$testPackageLibPath/a.dart', _orderCode);
+ _newOrderMacrosFile();
var library = await buildLibrary(r'''
-import 'a.dart';
+import 'order.dart';
class X {
@AddClass('A1')
@@ -118,27 +879,13 @@
}
''');
- configuration
- ..withConstructors = false
- ..withMetadata = false
- ..withReferences = true;
+ configuration.forOrder();
checkElementText(library, r'''
library
- reference: self
imports
- package:test/a.dart
- definingUnit
- reference: self
- classes
- class X @24
- reference: self::@class::X
- methods
- foo @71
- reference: self::@class::X::@method::foo
- returnType: void
+ package:test/order.dart
augmentationImports
package:test/test.macro.dart
- reference: self::@augmentation::package:test/test.macro.dart
macroGeneratedCode
---
library augment 'test.dart';
@@ -146,21 +893,14 @@
class A2 {}
class A1 {}
---
- definingUnit
- reference: self::@augmentation::package:test/test.macro.dart
- classes
- class A2 @36
- reference: self::@augmentation::package:test/test.macro.dart::@class::A2
- class A1 @48
- reference: self::@augmentation::package:test/test.macro.dart::@class::A1
''');
}
test_types_class_method_sourceOrder() async {
- newFile('$testPackageLibPath/a.dart', _orderCode);
+ _newOrderMacrosFile();
var library = await buildLibrary(r'''
-import 'a.dart';
+import 'order.dart';
class X {
@AddClass('A1')
@@ -171,30 +911,13 @@
}
''');
- configuration
- ..withConstructors = false
- ..withMetadata = false
- ..withReferences = true;
+ configuration.forOrder();
checkElementText(library, r'''
library
- reference: self
imports
- package:test/a.dart
- definingUnit
- reference: self
- classes
- class X @24
- reference: self::@class::X
- methods
- foo @53
- reference: self::@class::X::@method::foo
- returnType: void
- bar @88
- reference: self::@class::X::@method::bar
- returnType: void
+ package:test/order.dart
augmentationImports
package:test/test.macro.dart
- reference: self::@augmentation::package:test/test.macro.dart
macroGeneratedCode
---
library augment 'test.dart';
@@ -202,44 +925,27 @@
class A1 {}
class A2 {}
---
- definingUnit
- reference: self::@augmentation::package:test/test.macro.dart
- classes
- class A1 @36
- reference: self::@augmentation::package:test/test.macro.dart::@class::A1
- class A2 @48
- reference: self::@augmentation::package:test/test.macro.dart::@class::A2
''');
}
test_types_class_rightToLeft() async {
- newFile('$testPackageLibPath/a.dart', _orderCode);
+ _newOrderMacrosFile();
var library = await buildLibrary(r'''
-import 'a.dart';
+import 'order.dart';
@AddClass('A1')
@AddClass('A2')
class X {}
''');
- configuration
- ..withConstructors = false
- ..withMetadata = false
- ..withReferences = true;
+ configuration.forOrder();
checkElementText(library, r'''
library
- reference: self
imports
- package:test/a.dart
- definingUnit
- reference: self
- classes
- class X @56
- reference: self::@class::X
+ package:test/order.dart
augmentationImports
package:test/test.macro.dart
- reference: self::@augmentation::package:test/test.macro.dart
macroGeneratedCode
---
library augment 'test.dart';
@@ -247,48 +953,29 @@
class A2 {}
class A1 {}
---
- definingUnit
- reference: self::@augmentation::package:test/test.macro.dart
- classes
- class A2 @36
- reference: self::@augmentation::package:test/test.macro.dart::@class::A2
- class A1 @48
- reference: self::@augmentation::package:test/test.macro.dart::@class::A1
''');
}
test_types_class_sourceOrder() async {
- newFile('$testPackageLibPath/a.dart', _orderCode);
+ _newOrderMacrosFile();
var library = await buildLibrary(r'''
-import 'a.dart';
+import 'order.dart';
@AddClass('A1')
-class X {}
+class X1 {}
@AddClass('A2')
-class Y {}
+class X2 {}
''');
- configuration
- ..withConstructors = false
- ..withMetadata = false
- ..withReferences = true;
+ configuration.forOrder();
checkElementText(library, r'''
library
- reference: self
imports
- package:test/a.dart
- definingUnit
- reference: self
- classes
- class X @40
- reference: self::@class::X
- class Y @68
- reference: self::@class::Y
+ package:test/order.dart
augmentationImports
package:test/test.macro.dart
- reference: self::@augmentation::package:test/test.macro.dart
macroGeneratedCode
---
library augment 'test.dart';
@@ -296,21 +983,14 @@
class A1 {}
class A2 {}
---
- definingUnit
- reference: self::@augmentation::package:test/test.macro.dart
- classes
- class A1 @36
- reference: self::@augmentation::package:test/test.macro.dart::@class::A1
- class A2 @48
- reference: self::@augmentation::package:test/test.macro.dart::@class::A2
''');
}
test_types_innerBeforeOuter_class_method() async {
- newFile('$testPackageLibPath/a.dart', _orderCode);
+ _newOrderMacrosFile();
var library = await buildLibrary(r'''
-import 'a.dart';
+import 'order.dart';
@AddClass('A1')
class X {
@@ -319,27 +999,13 @@
}
''');
- configuration
- ..withConstructors = false
- ..withMetadata = false
- ..withReferences = true;
+ configuration.forOrder();
checkElementText(library, r'''
library
- reference: self
imports
- package:test/a.dart
- definingUnit
- reference: self
- classes
- class X @40
- reference: self::@class::X
- methods
- foo @69
- reference: self::@class::X::@method::foo
- returnType: void
+ package:test/order.dart
augmentationImports
package:test/test.macro.dart
- reference: self::@augmentation::package:test/test.macro.dart
macroGeneratedCode
---
library augment 'test.dart';
@@ -347,21 +1013,162 @@
class A2 {}
class A1 {}
---
- definingUnit
- reference: self::@augmentation::package:test/test.macro.dart
- classes
- class A2 @36
- reference: self::@augmentation::package:test/test.macro.dart::@class::A2
- class A1 @48
- reference: self::@augmentation::package:test/test.macro.dart::@class::A1
''');
}
-}
-@reflectiveTest
-class MacroApplicationOrderTest_keepLinking extends MacroApplicationOrderTest {
- @override
- bool get keepLinkingLibraries => true;
+ test_types_innerBeforeOuter_mixin_method() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddClass('A1')
+mixin X {
+ @AddClass('A2')
+ void foo() {}
+}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+class A2 {}
+class A1 {}
+---
+''');
+ }
+
+ test_types_mixin_method_rightToLeft() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+mixin X {
+ @AddClass('A1')
+ @AddClass('A2')
+ void foo() {}
+}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+class A2 {}
+class A1 {}
+---
+''');
+ }
+
+ test_types_mixin_method_sourceOrder() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+mixin X {
+ @AddClass('A1')
+ void foo() {}
+
+ @AddClass('A2')
+ void bar() {}
+}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+class A1 {}
+class A2 {}
+---
+''');
+ }
+
+ test_types_mixin_rightToLeft() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddClass('A1')
+@AddClass('A2')
+mixin X {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+class A2 {}
+class A1 {}
+---
+''');
+ }
+
+ test_types_mixin_sourceOrder() async {
+ _newOrderMacrosFile();
+
+ var library = await buildLibrary(r'''
+import 'order.dart';
+
+@AddClass('A1')
+mixin X1 {}
+
+@AddClass('A2')
+mixin X2 {}
+''');
+
+ configuration.forOrder();
+ checkElementText(library, r'''
+library
+ imports
+ package:test/order.dart
+ augmentationImports
+ package:test/test.macro.dart
+ macroGeneratedCode
+---
+library augment 'test.dart';
+
+class A1 {}
+class A2 {}
+---
+''');
+ }
+
+ void _newOrderMacrosFile() {
+ newFile('$testPackageLibPath/order.dart', _orderCode);
+ }
}
@reflectiveTest
@@ -3256,3 +4063,18 @@
return file;
}
}
+
+extension on ElementTextConfiguration {
+ void forOrder() {
+ filter = (element) {
+ if (element is CompilationUnitElement) {
+ return false;
+ // return element.source.uri != Uri.parse('package:test/test.dart');
+ }
+ return true;
+ };
+ withConstructors = false;
+ withMetadata = false;
+ withReturnType = false;
+ }
+}