Skip to content

Commit ad0e804

Browse files
committed
add benchmark for checks extension
1 parent b77ed81 commit ad0e804

File tree

7 files changed

+268
-6
lines changed

7 files changed

+268
-6
lines changed

working/macros/example/benchmark/simple.dart

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import 'package:_fe_analyzer_shared/src/macros/executor/process_executor.dart'
2828
import 'package:_fe_analyzer_shared/src/macros/executor/multi_executor.dart'
2929
as multiExecutor;
3030

31+
import 'src/checks_extensions.dart' as checks_extensions;
3132
import 'src/data_class.dart' as data_class;
3233
import 'src/functional_widget.dart' as functional_widget;
3334
import 'src/injectable.dart' as injectable;
@@ -52,7 +53,13 @@ final argParser = ArgParser()
5253
help: 'The communication channel to use when running as a separate'
5354
' process.')
5455
..addOption('macro',
55-
allowed: ['DataClass', 'Injectable', 'FunctionalWidget'], mandatory: true)
56+
allowed: [
57+
'ChecksExtensions',
58+
'DataClass',
59+
'Injectable',
60+
'FunctionalWidget'
61+
],
62+
mandatory: true)
5663
..addFlag('help', negatable: false, hide: true);
5764

5865
// Run this script to print out the generated augmentation library for an example class.
@@ -102,6 +109,7 @@ Macro: $macro
102109

103110
// You must run from the `macros` directory, paths are relative to that.
104111
var macroFile = switch (macro) {
112+
'ChecksExtensions' => File('lib/checks_extensions.dart'),
105113
'DataClass' => File('lib/data_class.dart'),
106114
'Injectable' => File('lib/injectable.dart'),
107115
'FunctionalWidget' => File('lib/functional_widget.dart'),
@@ -114,13 +122,19 @@ Macro: $macro
114122
var tmpDir = Directory.systemTemp.createTempSync('macro_benchmark');
115123
try {
116124
var macroUri = switch (macro) {
125+
'ChecksExtensions' =>
126+
Uri.parse('package:macro_proposal/checks_extensions.dart'),
117127
'DataClass' => Uri.parse('package:macro_proposal/data_class.dart'),
118128
'Injectable' => Uri.parse('package:macro_proposal/injectable.dart'),
119129
'FunctionalWidget' =>
120130
Uri.parse('package:macro_proposal/functional_widget.dart'),
121131
_ => throw UnsupportedError('Unrecognized macro $macro'),
122132
};
123133
var macroConstructors = switch (macro) {
134+
'ChecksExtensions' => {
135+
'ChecksExtension': [''],
136+
'ChecksExtensions': [''],
137+
},
124138
'DataClass' => {
125139
'DataClass': ['']
126140
},
@@ -171,6 +185,7 @@ Macro: $macro
171185

172186
_log('Running benchmark');
173187
await switch (macro) {
188+
'ChecksExtensions' => checks_extensions.runBenchmarks(executor, macroUri),
174189
'DataClass' => data_class.runBenchmarks(executor, macroUri),
175190
'Injectable' => injectable.runBenchmarks(executor, macroUri),
176191
'FunctionalWidget' => functional_widget.runBenchmarks(executor, macroUri),
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
import 'package:_fe_analyzer_shared/src/macros/api.dart';
2+
import 'package:_fe_analyzer_shared/src/macros/executor/introspection_impls.dart';
3+
import 'package:_fe_analyzer_shared/src/macros/executor/remote_instance.dart';
4+
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
5+
import 'package:benchmark_harness/benchmark_harness.dart';
6+
7+
import 'shared.dart';
8+
9+
Future<void> runBenchmarks(MacroExecutor executor, Uri macroUri) async {
10+
final introspector = SimpleDefinitionPhaseIntrospector(declarations: {
11+
myClass.identifier: myClass,
12+
objectClass.identifier: objectClass,
13+
myExtension.identifier: myExtension,
14+
}, identifiers: {
15+
Uri.parse('dart:core'): {
16+
'bool': boolIdentifier,
17+
'int': intIdentifier,
18+
'Object': objectIdentifier,
19+
'String': stringIdentifier,
20+
},
21+
Uri.parse('package:checks/checks.dart'): {
22+
'Subject': subjectIdentifier,
23+
},
24+
Uri.parse('package:macro_proposal/checks_extensions.dart'): {
25+
'ChecksExtension': checksExtensionIdentifier,
26+
},
27+
}, constructors: {}, enumValues: {}, fields: {
28+
myClass: myClassFields
29+
}, methods: {});
30+
final identifierDeclarations = {
31+
...introspector.declarations,
32+
for (final constructors in introspector.constructors.values)
33+
for (final constructor in constructors)
34+
constructor.identifier: constructor,
35+
for (final methods in introspector.methods.values)
36+
for (final method in methods) method.identifier: method,
37+
for (final fields in introspector.fields.values)
38+
for (final field in fields) field.identifier: field,
39+
};
40+
final checksExtensionsInstantiateBenchmark =
41+
ChecksExtensionsInstantiateBenchmark(executor, macroUri);
42+
await checksExtensionsInstantiateBenchmark.report();
43+
final checksExtensionsInstanceId =
44+
checksExtensionsInstantiateBenchmark.instanceIdentifier;
45+
final typesBenchmark = ChecksExtensionsTypesPhaseBenchmark(
46+
executor, macroUri, checksExtensionsInstanceId, introspector);
47+
await typesBenchmark.report();
48+
BuildAugmentationLibraryBenchmark.reportAndPrint(
49+
executor,
50+
[if (typesBenchmark.result != null) typesBenchmark.result!],
51+
identifierDeclarations);
52+
53+
final checksExtensionInstantiateBenchmark =
54+
ChecksExtensionInstantiateBenchmark(executor, macroUri);
55+
await checksExtensionInstantiateBenchmark.report();
56+
final checksExtensionInstanceId =
57+
checksExtensionInstantiateBenchmark.instanceIdentifier;
58+
final declarationsBenchmark = ChecksExtensionDeclarationsPhaseBenchmark(
59+
executor, macroUri, checksExtensionInstanceId, introspector);
60+
await declarationsBenchmark.report();
61+
BuildAugmentationLibraryBenchmark.reportAndPrint(
62+
executor,
63+
[if (declarationsBenchmark.result != null) declarationsBenchmark.result!],
64+
identifierDeclarations);
65+
}
66+
67+
class ChecksExtensionsInstantiateBenchmark extends AsyncBenchmarkBase {
68+
final MacroExecutor executor;
69+
final Uri macroUri;
70+
late MacroInstanceIdentifier instanceIdentifier;
71+
72+
ChecksExtensionsInstantiateBenchmark(this.executor, this.macroUri)
73+
: super('ChecksExtensionsInstantiate');
74+
75+
Future<void> run() async {
76+
instanceIdentifier = await executor.instantiateMacro(
77+
macroUri,
78+
'ChecksExtensions',
79+
'',
80+
Arguments([
81+
ListArgument([TypeAnnotationArgument(myClassType)],
82+
[ArgumentKind.typeAnnotation])
83+
], {}));
84+
}
85+
}
86+
87+
class ChecksExtensionsTypesPhaseBenchmark extends AsyncBenchmarkBase {
88+
final MacroExecutor executor;
89+
final Uri macroUri;
90+
final MacroInstanceIdentifier instanceIdentifier;
91+
final TypePhaseIntrospector introspector;
92+
MacroExecutionResult? result;
93+
94+
ChecksExtensionsTypesPhaseBenchmark(
95+
this.executor, this.macroUri, this.instanceIdentifier, this.introspector)
96+
: super('ChecksExtensionsTypesPhase');
97+
98+
Future<void> run() async {
99+
if (instanceIdentifier.shouldExecute(
100+
DeclarationKind.library, Phase.types)) {
101+
result = await executor.executeTypesPhase(
102+
instanceIdentifier, fooLibrary, introspector);
103+
}
104+
}
105+
}
106+
107+
class ChecksExtensionInstantiateBenchmark extends AsyncBenchmarkBase {
108+
final MacroExecutor executor;
109+
final Uri macroUri;
110+
late MacroInstanceIdentifier instanceIdentifier;
111+
112+
ChecksExtensionInstantiateBenchmark(this.executor, this.macroUri)
113+
: super('ChecksExtensionsInstantiate');
114+
115+
Future<void> run() async {
116+
instanceIdentifier = await executor.instantiateMacro(
117+
macroUri, 'ChecksExtension', '', Arguments([], {}));
118+
}
119+
}
120+
121+
class ChecksExtensionDeclarationsPhaseBenchmark extends AsyncBenchmarkBase {
122+
final MacroExecutor executor;
123+
final Uri macroUri;
124+
final MacroInstanceIdentifier instanceIdentifier;
125+
final DeclarationPhaseIntrospector introspector;
126+
127+
MacroExecutionResult? result;
128+
129+
ChecksExtensionDeclarationsPhaseBenchmark(
130+
this.executor, this.macroUri, this.instanceIdentifier, this.introspector)
131+
: super('ChecksExtensionDeclarationsPhase');
132+
133+
Future<void> run() async {
134+
result = null;
135+
if (instanceIdentifier.shouldExecute(
136+
DeclarationKind.extension, Phase.declarations)) {
137+
result = await executor.executeDeclarationsPhase(
138+
instanceIdentifier, myExtension, introspector);
139+
}
140+
}
141+
}
142+
143+
final myClassIdentifier =
144+
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'MyClass');
145+
final myClassType = NamedTypeAnnotationImpl(
146+
id: RemoteInstance.uniqueId,
147+
isNullable: false,
148+
identifier: myClassIdentifier,
149+
typeArguments: const []);
150+
final myClass = IntrospectableClassDeclarationImpl(
151+
id: RemoteInstance.uniqueId,
152+
identifier: myClassIdentifier,
153+
library: fooLibrary,
154+
metadata: [],
155+
interfaces: [],
156+
hasAbstract: false,
157+
hasBase: false,
158+
hasExternal: false,
159+
hasFinal: false,
160+
hasInterface: false,
161+
hasMixin: false,
162+
hasSealed: false,
163+
mixins: [],
164+
superclass: NamedTypeAnnotationImpl(
165+
id: RemoteInstance.uniqueId,
166+
isNullable: false,
167+
identifier: objectIdentifier,
168+
typeArguments: [],
169+
),
170+
typeParameters: []);
171+
172+
final myClassFields = [
173+
FieldDeclarationImpl(
174+
definingType: myClassIdentifier,
175+
id: RemoteInstance.uniqueId,
176+
identifier: IdentifierImpl(id: RemoteInstance.uniqueId, name: 'myString'),
177+
library: fooLibrary,
178+
metadata: [],
179+
hasExternal: false,
180+
hasFinal: true,
181+
hasLate: false,
182+
isStatic: false,
183+
type: stringType),
184+
FieldDeclarationImpl(
185+
definingType: myClassIdentifier,
186+
id: RemoteInstance.uniqueId,
187+
identifier: IdentifierImpl(id: RemoteInstance.uniqueId, name: 'myBool'),
188+
library: fooLibrary,
189+
metadata: [],
190+
hasExternal: false,
191+
hasFinal: true,
192+
hasLate: false,
193+
isStatic: false,
194+
type: boolType),
195+
];
196+
197+
final myExtension = IntrospectableExtensionDeclarationImpl(
198+
id: RemoteInstance.uniqueId,
199+
identifier:
200+
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'MyClassChecks'),
201+
library: fooLibrary,
202+
metadata: const [],
203+
typeParameters: const [],
204+
onType: NamedTypeAnnotationImpl(
205+
id: RemoteInstance.uniqueId,
206+
isNullable: false,
207+
identifier: subjectIdentifier,
208+
typeArguments: [myClassType]));
209+
210+
final subjectIdentifier =
211+
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'Subject');
212+
final checksExtensionIdentifier =
213+
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'ChecksExtension');

working/macros/example/benchmark/src/data_class.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ final myClassMethods = [
194194
library: fooLibrary,
195195
metadata: [],
196196
hasAbstract: false,
197+
hasBody: true,
197198
hasExternal: false,
198199
isGetter: false,
199200
isOperator: true,
@@ -225,6 +226,7 @@ final myClassMethods = [
225226
library: fooLibrary,
226227
metadata: [],
227228
hasAbstract: false,
229+
hasBody: true,
228230
hasExternal: false,
229231
isOperator: false,
230232
isGetter: true,
@@ -242,6 +244,7 @@ final myClassMethods = [
242244
library: fooLibrary,
243245
metadata: [],
244246
hasAbstract: false,
247+
hasBody: true,
245248
hasExternal: false,
246249
isGetter: false,
247250
isOperator: false,

working/macros/example/benchmark/src/functional_widget.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ final myFunction = FunctionDeclarationImpl(
8585
library: fooLibrary,
8686
metadata: [],
8787
hasAbstract: false,
88+
hasBody: true,
8889
hasExternal: false,
8990
isGetter: false,
9091
isOperator: false,

0 commit comments

Comments
 (0)