Skip to content

Commit e410078

Browse files
authored
Updates to the JsonSerialization macro example. (#3550)
* Updates to the JsonSerialization macro example. - Add support for a `toJson` method. - Directly apply separate FromJson/ToJson macros in the declaration phase, instead of scanning the class for methods.
1 parent 21261cb commit e410078

File tree

3 files changed

+220
-59
lines changed

3 files changed

+220
-59
lines changed

working/macros/example/benchmark/simple.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,18 @@ Macro: $macro
118118
}
119119
var tmpDir = Directory.systemTemp.createTempSync('macro_benchmark');
120120
try {
121+
var jsonSerializableUri =
122+
Uri.parse('package:macro_proposal/json_serializable.dart');
121123
var macroUri = switch (macro) {
122124
'ChecksExtensions' =>
123125
Uri.parse('package:macro_proposal/checks_extensions.dart'),
124126
'DataClass' => Uri.parse('package:macro_proposal/data_class.dart'),
125127
'Injectable' => Uri.parse('package:macro_proposal/injectable.dart'),
126128
'FunctionalWidget' =>
127129
Uri.parse('package:macro_proposal/functional_widget.dart'),
128-
'JsonSerializable' =>
129-
Uri.parse('package:macro_proposal/json_serializable.dart'),
130+
'JsonSerializable' => jsonSerializableUri,
131+
'FromJson' => jsonSerializableUri,
132+
'ToJson' => jsonSerializableUri,
130133
_ => throw UnsupportedError('Unrecognized macro $macro'),
131134
};
132135
var macroConstructors = switch (macro) {
@@ -147,6 +150,8 @@ Macro: $macro
147150
},
148151
'JsonSerializable' => {
149152
'JsonSerializable': [''],
153+
'FromJson': [''],
154+
'ToJson': [''],
150155
},
151156
_ => throw UnsupportedError('Unrecognized macro $macro'),
152157
};

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

Lines changed: 92 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,11 @@ Future<void> runBenchmarks(MacroExecutor executor, Uri macroUri) async {
2222
'String': stringIdentifier,
2323
'Map': mapIdentifier,
2424
'Object': objectIdentifier,
25-
}
25+
},
26+
jsonSerializableUri: {
27+
'FromJson': fromJsonMacroIdentifier,
28+
'ToJson': toJsonMacroIdentifier,
29+
},
2630
}, constructors: {}, enumValues: {}, fields: {
2731
myClass: myClassFields
2832
}, methods: {});
@@ -37,107 +41,129 @@ Future<void> runBenchmarks(MacroExecutor executor, Uri macroUri) async {
3741
for (final field in fields) field.identifier: field,
3842
};
3943
final instantiateBenchmark =
40-
JsonSerializableInstantiateBenchmark(executor, macroUri);
44+
InstantiateBenchmark(executor, macroUri, 'JsonSerializable');
4145
await instantiateBenchmark.report();
4246
final instanceId = instantiateBenchmark.instanceIdentifier;
43-
final typesBenchmark = JsonSerializableTypesPhaseBenchmark(
44-
executor, macroUri, instanceId, introspector);
45-
await typesBenchmark.report();
46-
BuildAugmentationLibraryBenchmark.reportAndPrint(
47-
executor,
48-
[if (typesBenchmark.result != null) typesBenchmark.result!],
49-
identifierDeclarations);
5047
final declarationsBenchmark = JsonSerializableDeclarationsPhaseBenchmark(
5148
executor, macroUri, instanceId, introspector);
5249
await declarationsBenchmark.report();
5350
BuildAugmentationLibraryBenchmark.reportAndPrint(
5451
executor,
5552
[if (declarationsBenchmark.result != null) declarationsBenchmark.result!],
5653
identifierDeclarations);
54+
5755
introspector.constructors[myClass] = myClassConstructors;
58-
final definitionsBenchmark = JsonSerializableDefinitionPhaseBenchmark(
59-
executor, macroUri, instanceId, introspector);
60-
await definitionsBenchmark.report();
56+
introspector.methods[myClass] = myClassMethods;
57+
58+
final fromJsonInstantiateBenchmark =
59+
InstantiateBenchmark(executor, macroUri, 'FromJson');
60+
await fromJsonInstantiateBenchmark.report();
61+
final fromJsonDefinitionsBenchmark = FromJsonDefinitionPhaseBenchmark(
62+
executor,
63+
macroUri,
64+
fromJsonInstantiateBenchmark.instanceIdentifier,
65+
introspector);
66+
await fromJsonDefinitionsBenchmark.report();
6167
BuildAugmentationLibraryBenchmark.reportAndPrint(
6268
executor,
63-
[if (definitionsBenchmark.result != null) definitionsBenchmark.result!],
69+
[
70+
if (fromJsonDefinitionsBenchmark.result != null)
71+
fromJsonDefinitionsBenchmark.result!
72+
],
73+
identifierDeclarations);
74+
75+
final toJsonInstantiateBenchmark =
76+
InstantiateBenchmark(executor, macroUri, 'ToJson');
77+
await toJsonInstantiateBenchmark.report();
78+
final toJsonDefinitionsBenchmark = ToJsonDefinitionPhaseBenchmark(executor,
79+
macroUri, toJsonInstantiateBenchmark.instanceIdentifier, introspector);
80+
await toJsonDefinitionsBenchmark.report();
81+
BuildAugmentationLibraryBenchmark.reportAndPrint(
82+
executor,
83+
[
84+
if (toJsonDefinitionsBenchmark.result != null)
85+
toJsonDefinitionsBenchmark.result!
86+
],
6487
identifierDeclarations);
6588
}
6689

67-
class JsonSerializableInstantiateBenchmark extends AsyncBenchmarkBase {
90+
class InstantiateBenchmark extends AsyncBenchmarkBase {
6891
final MacroExecutor executor;
6992
final Uri macroUri;
7093
late MacroInstanceIdentifier instanceIdentifier;
94+
final String macroName;
7195

72-
JsonSerializableInstantiateBenchmark(this.executor, this.macroUri)
73-
: super('JsonSerializableInstantiate');
96+
InstantiateBenchmark(this.executor, this.macroUri, this.macroName)
97+
: super('${macroName}Instantiate');
7498

7599
Future<void> run() async {
76100
instanceIdentifier = await executor.instantiateMacro(
77-
macroUri, 'JsonSerializable', '', Arguments([], {}));
101+
macroUri, macroName, '', Arguments([], {}));
78102
}
79103
}
80104

81-
class JsonSerializableTypesPhaseBenchmark extends AsyncBenchmarkBase {
105+
class JsonSerializableDeclarationsPhaseBenchmark extends AsyncBenchmarkBase {
82106
final MacroExecutor executor;
83107
final Uri macroUri;
84108
final MacroInstanceIdentifier instanceIdentifier;
85-
final TypePhaseIntrospector introspector;
109+
final DeclarationPhaseIntrospector introspector;
110+
86111
MacroExecutionResult? result;
87112

88-
JsonSerializableTypesPhaseBenchmark(
113+
JsonSerializableDeclarationsPhaseBenchmark(
89114
this.executor, this.macroUri, this.instanceIdentifier, this.introspector)
90-
: super('JsonSerializableTypesPhase');
115+
: super('JsonSerializableDeclarationsPhase');
91116

92117
Future<void> run() async {
118+
result = null;
93119
if (instanceIdentifier.shouldExecute(
94-
DeclarationKind.classType, Phase.types)) {
95-
result = await executor.executeTypesPhase(
120+
DeclarationKind.classType, Phase.declarations)) {
121+
result = await executor.executeDeclarationsPhase(
96122
instanceIdentifier, myClass, introspector);
97123
}
98124
}
99125
}
100126

101-
class JsonSerializableDeclarationsPhaseBenchmark extends AsyncBenchmarkBase {
127+
class FromJsonDefinitionPhaseBenchmark extends AsyncBenchmarkBase {
102128
final MacroExecutor executor;
103129
final Uri macroUri;
104130
final MacroInstanceIdentifier instanceIdentifier;
105-
final DeclarationPhaseIntrospector introspector;
131+
final DefinitionPhaseIntrospector introspector;
106132

107133
MacroExecutionResult? result;
108134

109-
JsonSerializableDeclarationsPhaseBenchmark(
135+
FromJsonDefinitionPhaseBenchmark(
110136
this.executor, this.macroUri, this.instanceIdentifier, this.introspector)
111-
: super('JsonSerializableDeclarationsPhase');
137+
: super('FromJsonDefinitionPhase');
112138

113139
Future<void> run() async {
114140
result = null;
115141
if (instanceIdentifier.shouldExecute(
116-
DeclarationKind.classType, Phase.declarations)) {
117-
result = await executor.executeDeclarationsPhase(
118-
instanceIdentifier, myClass, introspector);
142+
DeclarationKind.constructor, Phase.definitions)) {
143+
result = await executor.executeDefinitionsPhase(
144+
instanceIdentifier, myClassConstructors.single, introspector);
119145
}
120146
}
121147
}
122148

123-
class JsonSerializableDefinitionPhaseBenchmark extends AsyncBenchmarkBase {
149+
class ToJsonDefinitionPhaseBenchmark extends AsyncBenchmarkBase {
124150
final MacroExecutor executor;
125151
final Uri macroUri;
126152
final MacroInstanceIdentifier instanceIdentifier;
127153
final DefinitionPhaseIntrospector introspector;
128154

129155
MacroExecutionResult? result;
130156

131-
JsonSerializableDefinitionPhaseBenchmark(
157+
ToJsonDefinitionPhaseBenchmark(
132158
this.executor, this.macroUri, this.instanceIdentifier, this.introspector)
133-
: super('JsonSerializableDefinitionPhase');
159+
: super('ToJsonDefinitionPhase');
134160

135161
Future<void> run() async {
136162
result = null;
137163
if (instanceIdentifier.shouldExecute(
138-
DeclarationKind.classType, Phase.definitions)) {
164+
DeclarationKind.method, Phase.definitions)) {
139165
result = await executor.executeDefinitionsPhase(
140-
instanceIdentifier, myClass, introspector);
166+
instanceIdentifier, myClassMethods.single, introspector);
141167
}
142168
}
143169
}
@@ -222,3 +248,34 @@ final myClassConstructors = [
222248
definingType: myClass.identifier,
223249
isFactory: true),
224250
];
251+
252+
final myClassMethods = [
253+
MethodDeclarationImpl(
254+
id: RemoteInstance.uniqueId,
255+
identifier: IdentifierImpl(id: RemoteInstance.uniqueId, name: 'toJson'),
256+
isGetter: false,
257+
isOperator: false,
258+
isSetter: false,
259+
isStatic: false,
260+
library: fooLibrary,
261+
metadata: [],
262+
hasBody: false,
263+
hasExternal: false,
264+
namedParameters: [],
265+
positionalParameters: [],
266+
returnType: NamedTypeAnnotationImpl(
267+
id: RemoteInstance.uniqueId,
268+
isNullable: false,
269+
identifier: mapIdentifier,
270+
typeArguments: [stringType, dynamicType]),
271+
typeParameters: [],
272+
definingType: myClass.identifier),
273+
];
274+
275+
final jsonSerializableUri =
276+
Uri.parse('package:macro_proposal/json_serializable.dart');
277+
278+
final fromJsonMacroIdentifier =
279+
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'FromJson');
280+
final toJsonMacroIdentifier =
281+
IdentifierImpl(id: RemoteInstance.uniqueId, name: 'ToJson');

0 commit comments

Comments
 (0)