Skip to content

Commit 6515e99

Browse files
committed
update data class example and run script with the latest apis
1 parent 089daf9 commit 6515e99

File tree

2 files changed

+75
-24
lines changed

2 files changed

+75
-24
lines changed

working/macros/example/data_class.dart

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,17 @@
55
// There is no public API exposed yet, the in progress api lives here.
66
import 'package:_fe_analyzer_shared/src/macros/api.dart';
77

8-
// TODO: support loading macros by const instance reference.
9-
const dataClass = DataClass();
10-
118
/*macro*/ class DataClass
129
implements ClassDeclarationsMacro, ClassDefinitionMacro {
1310
const DataClass();
1411

1512
@override
1613
Future<void> buildDeclarationsForClass(
1714
ClassDeclaration clazz, ClassMemberDeclarationBuilder context) async {
18-
await autoConstructor.buildDeclarationsForClass(clazz, context);
19-
await copyWith.buildDeclarationsForClass(clazz, context);
15+
await Future.wait([
16+
autoConstructor.buildDeclarationsForClass(clazz, context),
17+
copyWith.buildDeclarationsForClass(clazz, context),
18+
]);
2019
hashCode.buildDeclarationsForClass(clazz, context);
2120
equality.buildDeclarationsForClass(clazz, context);
2221
toString.buildDeclarationsForClass(clazz, context);
@@ -25,9 +24,11 @@ const dataClass = DataClass();
2524
@override
2625
Future<void> buildDefinitionForClass(
2726
ClassDeclaration clazz, ClassDefinitionBuilder builder) async {
28-
await hashCode.buildDefinitionForClass(clazz, builder);
29-
await equality.buildDefinitionForClass(clazz, builder);
30-
await toString.buildDefinitionForClass(clazz, builder);
27+
await Future.wait([
28+
hashCode.buildDefinitionForClass(clazz, builder),
29+
equality.buildDefinitionForClass(clazz, builder),
30+
toString.buildDefinitionForClass(clazz, builder),
31+
]);
3132
}
3233
}
3334

@@ -45,12 +46,13 @@ const autoConstructor = _AutoConstructor();
4546
'Cannot generate an unnamed constructor because one already exists');
4647
}
4748

49+
// Don't use the identifier here because it should just be the raw name.
4850
var parts = <Object>[clazz.identifier.name, '({'];
4951
// Add all the fields of `declaration` as named parameters.
5052
var fields = await builder.fieldsOf(clazz);
5153
for (var field in fields) {
5254
var requiredKeyword = field.type.isNullable ? '' : 'required ';
53-
parts.addAll(['\n${requiredKeyword}this.', field.identifier.name, ',']);
55+
parts.addAll(['\n${requiredKeyword}', field.identifier, ',']);
5456
}
5557

5658
// Add all super constructor parameters as named parameters.
@@ -129,8 +131,10 @@ const copyWith = _CopyWith();
129131
];
130132
var args = [
131133
for (var field in allFields)
132-
'${field.identifier.name}: ${field.identifier.name} '
133-
'?? this.${field.identifier.name}',
134+
Code.fromParts([
135+
'${field.identifier.name}: ${field.identifier.name} ?? ',
136+
field.identifier,
137+
]),
134138
];
135139
builder.declareInClass(DeclarationCode.fromParts([
136140
clazz.identifier,
@@ -167,7 +171,7 @@ external int get hashCode;'''));
167171
methods.firstWhere((m) => m.identifier.name == 'hashCode').identifier);
168172
var hashCodeExprs = [
169173
await for (var field in clazz.allFields(builder))
170-
ExpressionCode.fromString('${field.identifier.name}.hashCode')
174+
ExpressionCode.fromParts([field.identifier, '.hashCode']),
171175
].joinAsCode(' ^ ');
172176
hashCodeBuilder.augment(FunctionBodyCode.fromParts([
173177
' => ',
@@ -199,8 +203,12 @@ external bool operator==(Object other);'''));
199203
methods.firstWhere((m) => m.identifier.name == '==').identifier);
200204
var equalityExprs = [
201205
await for (var field in clazz.allFields(builder))
202-
ExpressionCode.fromString(
203-
'this.${field.identifier.name} == other.${field.identifier.name}'),
206+
ExpressionCode.fromParts([
207+
field.identifier,
208+
' == other.',
209+
// Shouldn't be prefixed with `this.` due to having a receiver.
210+
field.identifier,
211+
]),
204212
].joinAsCode(' && ');
205213
equalsBuilder.augment(FunctionBodyCode.fromParts([
206214
' => other is ',
@@ -236,14 +244,17 @@ external String toString();''',
236244
methods.firstWhere((m) => m.identifier.name == 'toString').identifier);
237245
var fieldExprs = [
238246
await for (var field in clazz.allFields(builder))
239-
Code.fromString(
240-
' ${field.identifier.name}: \${${field.identifier.name}}'),
247+
Code.fromParts([
248+
' ${field.identifier.name}: \${',
249+
field.identifier,
250+
'}',
251+
]),
241252
].joinAsCode('\n');
242253

243254
toStringBuilder.augment(FunctionBodyCode.fromParts([
244-
' => """\${${clazz.identifier.name}} { ',
255+
' => """\${${clazz.identifier.name}} {\n',
245256
...fieldExprs,
246-
'}""";',
257+
'\n}""";',
247258
]));
248259
}
249260
}

working/macros/example/run.dart

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import 'package:_fe_analyzer_shared/src/macros/bootstrap.dart';
2222
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
2323
import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
2424
import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
25+
import 'package:_fe_analyzer_shared/src/macros/executor_shared/serialization.dart';
2526
import 'package:_fe_analyzer_shared/src/macros/isolated_executor/isolated_executor.dart'
2627
as isolatedExecutor;
2728

@@ -30,6 +31,9 @@ void _log(String message) {
3031
print('${_watch.elapsed}: $message');
3132
}
3233

34+
var clientSerializationMode = SerializationMode.jsonClient;
35+
var serverSerializationMode = SerializationMode.jsonServer;
36+
3337
// Run this script to print out the generated augmentation library for an example class.
3438
void main() async {
3539
_log('Preparing to run macros.');
@@ -39,7 +43,7 @@ void main() async {
3943
print('This script must be ran from the `macros` directory.');
4044
exit(1);
4145
}
42-
var executor = await isolatedExecutor.start();
46+
var executor = await isolatedExecutor.start(serverSerializationMode);
4347
var tmpDir = Directory.systemTemp.createTempSync('data_class_macro_example');
4448
try {
4549
var macroUri = thisFile.absolute.uri;
@@ -49,7 +53,7 @@ void main() async {
4953
macroUri.toString(): {
5054
macroName: [''],
5155
}
52-
});
56+
}, clientSerializationMode);
5357

5458
var bootstrapFile = File(tmpDir.uri.resolve('main.dart').toFilePath())
5559
..writeAsStringSync(bootstrapContent);
@@ -73,12 +77,16 @@ void main() async {
7377
_log('Loading DataClass macro');
7478
var clazzId = await executor.loadMacro(macroUri, macroName,
7579
precompiledKernelUri: kernelOutputFile.uri);
80+
_log('Instantiating macro');
7681
var instanceId =
7782
await executor.instantiateMacro(clazzId, '', Arguments([], {}));
7883

7984
_log('Running DataClass macro 100 times...');
8085
var results = <MacroExecutionResult>[];
81-
for (var i = 1; i < 101; i++) {
86+
var macroExecutionStart = _watch.elapsed;
87+
late Duration firstRunEnd;
88+
late Duration first11RunsEnd;
89+
for (var i = 1; i <= 111; i++) {
8290
var _shouldLog = i == 1 || i == 10 || i == 100;
8391
if (_shouldLog) _log('Running DataClass macro for the ${i}th time');
8492
if (instanceId.shouldExecute(DeclarationKind.clazz, Phase.types)) {
@@ -103,17 +111,34 @@ void main() async {
103111
if (i == 1) results.add(result);
104112
}
105113
if (_shouldLog) _log('Done running DataClass macro for the ${i}th time.');
114+
115+
if (i == 1) {
116+
firstRunEnd = _watch.elapsed;
117+
} else if (i == 11) {
118+
first11RunsEnd = _watch.elapsed;
119+
}
106120
}
121+
var first111RunsEnd = _watch.elapsed;
107122

108123
_log('Building augmentation library');
109124
var library = executor.buildAugmentationLibrary(results, (identifier) {
110125
if (identifier == boolIdentifier ||
111126
identifier == objectIdentifier ||
112127
identifier == stringIdentifier ||
113128
identifier == intIdentifier) {
114-
return Uri(scheme: 'dart', path: 'core');
129+
return ResolvedIdentifier(
130+
kind: IdentifierKind.topLevelMember,
131+
name: identifier.name,
132+
staticScope: null,
133+
uri: null);
115134
} else {
116-
return File('example/data_class.dart').absolute.uri;
135+
return ResolvedIdentifier(
136+
kind: identifier.name == 'MyClass'
137+
? IdentifierKind.topLevelMember
138+
: IdentifierKind.instanceMember,
139+
name: identifier.name,
140+
staticScope: null,
141+
uri: Platform.script.resolve('data_class.dart'));
117142
}
118143
});
119144
executor.close();
@@ -125,6 +150,11 @@ void main() async {
125150
.replaceAll('/*augment*/', 'augment');
126151

127152
_log('Macro augmentation library:\n\n$formatted');
153+
_log('Time for the first run: ${macroExecutionStart - firstRunEnd}');
154+
_log('Average time for the next 10 runs: '
155+
'${(first11RunsEnd - firstRunEnd).dividedBy(10)}');
156+
_log('Average time for the next 100 runs: '
157+
'${(first111RunsEnd - first11RunsEnd).dividedBy(100)}');
128158
} finally {
129159
tmpDir.deleteSync(recursive: true);
130160
}
@@ -136,7 +166,7 @@ final intIdentifier = IdentifierImpl(id: RemoteInstance.uniqueId, name: 'int');
136166
final objectIdentifier =
137167
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'Object');
138168
final stringIdentifier =
139-
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'bool');
169+
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'String');
140170

141171
final boolType = NamedTypeAnnotationImpl(
142172
id: RemoteInstance.uniqueId,
@@ -189,6 +219,7 @@ final myClassFields = [
189219
isExternal: false,
190220
isFinal: true,
191221
isLate: false,
222+
isStatic: false,
192223
type: stringType),
193224
FieldDeclarationImpl(
194225
definingClass: myClassIdentifier,
@@ -197,6 +228,7 @@ final myClassFields = [
197228
isExternal: false,
198229
isFinal: true,
199230
isLate: false,
231+
isStatic: false,
200232
type: boolType),
201233
];
202234

@@ -210,6 +242,7 @@ final myClassMethods = [
210242
isGetter: false,
211243
isOperator: true,
212244
isSetter: false,
245+
isStatic: false,
213246
namedParameters: [],
214247
positionalParameters: [
215248
ParameterDeclarationImpl(
@@ -236,6 +269,7 @@ final myClassMethods = [
236269
isOperator: false,
237270
isGetter: true,
238271
isSetter: false,
272+
isStatic: false,
239273
namedParameters: [],
240274
positionalParameters: [],
241275
returnType: intType,
@@ -250,6 +284,7 @@ final myClassMethods = [
250284
isGetter: false,
251285
isOperator: false,
252286
isSetter: false,
287+
isStatic: false,
253288
namedParameters: [],
254289
positionalParameters: [],
255290
returnType: stringType,
@@ -289,3 +324,8 @@ class FakeTypeDeclarationResolver extends Fake
289324
implements TypeDeclarationResolver {}
290325

291326
class FakeTypeResolver extends Fake implements TypeResolver {}
327+
328+
extension _ on Duration {
329+
Duration dividedBy(int amount) =>
330+
Duration(microseconds: (this.inMicroseconds / amount).round());
331+
}

0 commit comments

Comments
 (0)