Skip to content

Commit c864e17

Browse files
davidmorganvkorencik
authored andcommitted
Migrate to element2 APIs (google#1504)
* Prepare to publish 6.10.0-dev.
1 parent 6de08be commit c864e17

19 files changed

+267
-236
lines changed

json_serializable/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
## 6.9.6-wip
1+
## 6.10.0-dev
22

3+
- Switch to analyzer element2 model and `build: ^3.0.0-dev`.
34
- Move `package:collection` to a dev dependency.
45
- Use new `null-aware element` feature in generated code.
56
- Require Dart 3.8

json_serializable/lib/src/decode_helper.dart

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'package:analyzer/dart/element/element.dart';
5+
import 'package:analyzer/dart/element/element2.dart';
66
import 'package:analyzer/dart/element/nullability_suffix.dart';
77
import 'package:build/build.dart';
88
import 'package:source_gen/source_gen.dart';
@@ -23,7 +23,7 @@ class CreateFactoryResult {
2323

2424
mixin DecodeHelper implements HelperCore {
2525
CreateFactoryResult createFactory(
26-
Map<String, FieldElement> accessibleFields,
26+
Map<String, FieldElement2> accessibleFields,
2727
Map<String, String> unavailableReasons,
2828
) {
2929
assert(config.createFactory);
@@ -37,14 +37,14 @@ mixin DecodeHelper implements HelperCore {
3737
);
3838

3939
if (config.genericArgumentFactories) {
40-
for (var arg in element.typeParameters) {
40+
for (var arg in element.typeParameters2) {
4141
final helperName = fromJsonForType(
4242
arg.instantiate(nullabilitySuffix: NullabilitySuffix.none),
4343
);
4444

45-
buffer.write(', ${arg.name} Function(Object? json) $helperName');
45+
buffer.write(', ${arg.name3} Function(Object? json) $helperName');
4646
}
47-
if (element.typeParameters.isNotEmpty) {
47+
if (element.typeParameters2.isNotEmpty) {
4848
buffer.write(',');
4949
}
5050
}
@@ -55,7 +55,7 @@ mixin DecodeHelper implements HelperCore {
5555

5656
String deserializeFun(
5757
String paramOrFieldName, {
58-
ParameterElement? ctorParam,
58+
FormalParameterElement? ctorParam,
5959
}) => _deserializeForField(
6060
accessibleFields[paramOrFieldName]!,
6161
ctorParam: ctorParam,
@@ -66,21 +66,28 @@ mixin DecodeHelper implements HelperCore {
6666
config.constructor,
6767
accessibleFields.keys,
6868
accessibleFields.values
69-
.where((fe) => element.lookUpSetter(fe.name, element.library) != null)
70-
.map((fe) => fe.name)
69+
.where(
70+
(fe) =>
71+
element.lookUpSetter2(
72+
name: fe.name3!,
73+
library: element.library2,
74+
) !=
75+
null,
76+
)
77+
.map((fe) => fe.name3!)
7178
.toList(),
7279
unavailableReasons,
7380
deserializeFun,
7481
);
7582

7683
final checks = _checkKeys(
7784
accessibleFields.values.where(
78-
(fe) => data.usedCtorParamsAndFields.contains(fe.name),
85+
(fe) => data.usedCtorParamsAndFields.contains(fe.name3),
7986
),
8087
).toList();
8188

8289
if (config.checked) {
83-
final classLiteral = escapeDartString(element.name);
90+
final classLiteral = escapeDartString(element.name3!);
8491

8592
final sectionBuffer = StringBuffer()
8693
..write('''
@@ -163,10 +170,11 @@ mixin DecodeHelper implements HelperCore {
163170
return CreateFactoryResult(buffer.toString(), data.usedCtorParamsAndFields);
164171
}
165172

166-
Iterable<String> _checkKeys(Iterable<FieldElement> accessibleFields) sync* {
173+
Iterable<String> _checkKeys(Iterable<FieldElement2> accessibleFields) sync* {
167174
final args = <String>[];
168175

169-
String constantList(Iterable<FieldElement> things) => 'const ${jsonLiteralAsDart(things.map(nameAccess).toList())}';
176+
String constantList(Iterable<FieldElement2> things) =>
177+
'const ${jsonLiteralAsDart(things.map<String>(nameAccess).toList())}';
170178

171179
if (config.disallowUnrecognizedKeys) {
172180
final allowKeysLiteral = constantList(accessibleFields);
@@ -198,8 +206,8 @@ mixin DecodeHelper implements HelperCore {
198206
/// If [checkedProperty] is `true`, we're using this function to write to a
199207
/// setter.
200208
String _deserializeForField(
201-
FieldElement field, {
202-
ParameterElement? ctorParam,
209+
FieldElement2 field, {
210+
FormalParameterElement? ctorParam,
203211
bool checkedProperty = false,
204212
}) {
205213
final jsonKeyName = safeNameAccess(field);
@@ -241,7 +249,7 @@ mixin DecodeHelper implements HelperCore {
241249
if (defaultValue != null) {
242250
if (jsonKey.disallowNullValue && jsonKey.required) {
243251
log.warning(
244-
'The `defaultValue` on field `${field.name}` will have no '
252+
'The `defaultValue` on field `${field.name3}` will have no '
245253
'effect because both `disallowNullValue` and `required` are set to '
246254
'`true`.',
247255
);
@@ -262,30 +270,30 @@ mixin DecodeHelper implements HelperCore {
262270
/// [writableFields] are also populated, but only if they have not already
263271
/// been defined by a constructor parameter with the same name.
264272
_ConstructorData _writeConstructorInvocation(
265-
ClassElement classElement,
273+
ClassElement2 classElement,
266274
String constructorName,
267275
Iterable<String> availableConstructorParameters,
268276
Iterable<String> writableFields,
269277
Map<String, String> unavailableReasons,
270-
String Function(String paramOrFieldName, {ParameterElement ctorParam})
278+
String Function(String paramOrFieldName, {FormalParameterElement ctorParam})
271279
deserializeForField,
272280
) {
273-
final className = classElement.name;
281+
final className = classElement.name3;
274282

275283
final ctor = constructorByName(classElement, constructorName);
276284

277285
final usedCtorParamsAndFields = <String>{};
278-
final constructorArguments = <ParameterElement>[];
279-
final namedConstructorArguments = <ParameterElement>[];
286+
final constructorArguments = <FormalParameterElement>[];
287+
final namedConstructorArguments = <FormalParameterElement>[];
280288

281-
for (final arg in ctor.parameters) {
282-
if (!availableConstructorParameters.contains(arg.name)) {
289+
for (final arg in ctor.formalParameters) {
290+
if (!availableConstructorParameters.contains(arg.name3)) {
283291
if (arg.isRequired) {
284292
var msg =
285293
'Cannot populate the required constructor '
286-
'argument: ${arg.name}.';
294+
'argument: ${arg.name3}.';
287295

288-
final additionalInfo = unavailableReasons[arg.name];
296+
final additionalInfo = unavailableReasons[arg.name3];
289297

290298
if (additionalInfo != null) {
291299
msg = '$msg $additionalInfo';
@@ -303,7 +311,7 @@ _ConstructorData _writeConstructorInvocation(
303311
} else {
304312
constructorArguments.add(arg);
305313
}
306-
usedCtorParamsAndFields.add(arg.name);
314+
usedCtorParamsAndFields.add(arg.name3!);
307315
}
308316

309317
// fields that aren't already set by the constructor and that aren't final
@@ -322,7 +330,7 @@ _ConstructorData _writeConstructorInvocation(
322330
..writeAll(
323331
constructorArguments.map((paramElement) {
324332
final content = deserializeForField(
325-
paramElement.name,
333+
paramElement.name3!,
326334
ctorParam: paramElement,
327335
);
328336
return ' $content,\n';
@@ -331,10 +339,10 @@ _ConstructorData _writeConstructorInvocation(
331339
..writeAll(
332340
namedConstructorArguments.map((paramElement) {
333341
final value = deserializeForField(
334-
paramElement.name,
342+
paramElement.name3!,
335343
ctorParam: paramElement,
336344
);
337-
return ' ${paramElement.name}: $value,\n';
345+
return ' ${paramElement.name3!}: $value,\n';
338346
}),
339347
)
340348
..write(')');

json_serializable/lib/src/encoder_helper.dart

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
import 'package:analyzer/dart/element/element.dart';
5+
import 'package:analyzer/dart/element/element2.dart';
66
import 'package:analyzer/dart/element/nullability_suffix.dart';
77
import 'package:source_helper/source_helper.dart';
88

@@ -13,18 +13,21 @@ import 'type_helpers/json_converter_helper.dart';
1313
import 'unsupported_type_error.dart';
1414

1515
mixin EncodeHelper implements HelperCore {
16-
String _fieldAccess(FieldElement field) => '$_toJsonParamName.${field.name}';
16+
String _fieldAccess(FieldElement2 field) =>
17+
'$_toJsonParamName.${field.name3!}';
1718

18-
String createPerFieldToJson(Set<FieldElement> accessibleFieldSet) {
19+
String createPerFieldToJson(Set<FieldElement2> accessibleFieldSet) {
1920
final buffer = StringBuffer()
2021
..writeln('// ignore: unused_element')
21-
..writeln('abstract class _\$${element.name.nonPrivate}PerFieldToJson {');
22+
..writeln(
23+
'abstract class _\$${element.name3!.nonPrivate}PerFieldToJson {',
24+
);
2225

2326
for (final field in accessibleFieldSet) {
2427
buffer
2528
..writeln(' // ignore: unused_element')
2629
..write(
27-
'static Object? ${field.name}'
30+
'static Object? ${field.name3!}'
2831
'${genericClassArgumentsImpl(withConstraints: true)}'
2932
'(${field.type} $_toJsonParamName',
3033
);
@@ -43,16 +46,16 @@ mixin EncodeHelper implements HelperCore {
4346

4447
/// Generates an object containing metadatas related to the encoding,
4548
/// destined to be used by other code-generators.
46-
String createFieldMap(Set<FieldElement> accessibleFieldSet) {
49+
String createFieldMap(Set<FieldElement2> accessibleFieldSet) {
4750
assert(config.createFieldMap);
4851

4952
final buffer = StringBuffer(
50-
'const _\$${element.name.nonPrivate}FieldMap = <String, String> {',
53+
'const _\$${element.name3!.nonPrivate}FieldMap = <String, String> {',
5154
);
5255

5356
for (final field in accessibleFieldSet) {
5457
buffer.writeln(
55-
'${escapeDartString(field.name)}: '
58+
'${escapeDartString(field.name3!)}: '
5659
'${escapeDartString(nameAccess(field))},',
5760
);
5861
}
@@ -64,17 +67,17 @@ mixin EncodeHelper implements HelperCore {
6467

6568
/// Generates an object containing metadatas related to the encoding,
6669
/// destined to be used by other code-generators.
67-
String createJsonKeys(Set<FieldElement> accessibleFieldSet) {
70+
String createJsonKeys(Set<FieldElement2> accessibleFieldSet) {
6871
assert(config.createJsonKeys);
6972

7073
final buffer = StringBuffer(
71-
'abstract final class _\$${element.name.nonPrivate}JsonKeys {',
74+
'abstract final class _\$${element.name3!.nonPrivate}JsonKeys {',
7275
);
7376
// ..write('static const _\$${element.name.nonPrivate}JsonKeys();');
7477

7578
for (final field in accessibleFieldSet) {
7679
buffer.writeln(
77-
'static const String ${field.name} = '
80+
'static const String ${field.name3} = '
7881
'${escapeDartString(nameAccess(field))};',
7982
);
8083
}
@@ -84,7 +87,7 @@ mixin EncodeHelper implements HelperCore {
8487
return buffer.toString();
8588
}
8689

87-
Iterable<String> createToJson(Set<FieldElement> accessibleFields) sync* {
90+
Iterable<String> createToJson(Set<FieldElement2> accessibleFields) sync* {
8891
assert(config.createToJson);
8992

9093
final buffer = StringBuffer();
@@ -120,20 +123,20 @@ mixin EncodeHelper implements HelperCore {
120123
}
121124

122125
void _writeGenericArgumentFactories(StringBuffer buffer) {
123-
for (var arg in element.typeParameters) {
126+
for (var arg in element.typeParameters2) {
124127
final helperName = toJsonForType(
125128
arg.instantiate(nullabilitySuffix: NullabilitySuffix.none),
126129
);
127-
buffer.write(',Object? Function(${arg.name} value) $helperName');
130+
buffer.write(',Object? Function(${arg.name3} value) $helperName');
128131
}
129-
if (element.typeParameters.isNotEmpty) {
132+
if (element.typeParameters2.isNotEmpty) {
130133
buffer.write(',');
131134
}
132135
}
133136

134137
static const _toJsonParamName = 'instance';
135138

136-
String _serializeField(FieldElement field, String accessExpression) {
139+
String _serializeField(FieldElement2 field, String accessExpression) {
137140
try {
138141
return getHelperContext(
139142
field,
@@ -146,7 +149,7 @@ mixin EncodeHelper implements HelperCore {
146149

147150
/// Returns `true` if the field can be written to JSON 'naively' – meaning
148151
/// we can avoid checking for `null`.
149-
bool _canWriteJsonWithoutNullCheck(FieldElement field) {
152+
bool _canWriteJsonWithoutNullCheck(FieldElement2 field) {
150153
final jsonKey = jsonKeyFor(field);
151154

152155
if (jsonKey.includeIfNull) {

json_serializable/lib/src/enum_utils.dart

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analyzer/dart/constant/value.dart';
6-
import 'package:analyzer/dart/element/element.dart';
6+
import 'package:analyzer/dart/element/element2.dart';
77
import 'package:analyzer/dart/element/type.dart';
88
import 'package:json_annotation/json_annotation.dart';
99
import 'package:source_gen/source_gen.dart';
@@ -45,15 +45,15 @@ String? enumValueMapFromType(
4545
final items = enumMap.entries
4646
.map(
4747
(e) =>
48-
' ${targetType.element!.name}.${e.key.name}: '
48+
' ${targetType.element!.name}.${e.key.name3}: '
4949
'${jsonLiteralAsDart(e.value)},',
5050
)
5151
.join();
5252

5353
return 'const ${constMapName(targetType)} = {\n$items\n};';
5454
}
5555

56-
Map<FieldElement, Object?>? _enumMap(
56+
Map<FieldElement2, Object?>? _enumMap(
5757
DartType targetType, {
5858
bool nullWithNoAnnotation = false,
5959
}) {
@@ -79,7 +79,7 @@ Map<FieldElement, Object?>? _enumMap(
7979
}
8080

8181
Object? _generateEntry({
82-
required FieldElement field,
82+
required FieldElement2 field,
8383
required JsonEnum jsonEnum,
8484
required DartType targetType,
8585
}) {
@@ -92,12 +92,12 @@ Object? _generateEntry({
9292
if (valueField != null) {
9393
// TODO: fieldRename is pointless here!!! At least log a warning!
9494

95-
final fieldElementType = field.type.element as EnumElement;
95+
final fieldElementType = field.type.element3 as EnumElement2;
9696

97-
final e = fieldElementType.getField(valueField);
97+
final e = fieldElementType.getField2(valueField);
9898

9999
if (e == null && valueField == 'index') {
100-
return fieldElementType.fields
100+
return fieldElementType.fields2
101101
.where((element) => element.isEnumConstant)
102102
.toList(growable: false)
103103
.indexOf(field);
@@ -108,7 +108,7 @@ Object? _generateEntry({
108108
'`JsonEnum.valueField` was set to "$valueField", but '
109109
'that is not a valid, instance field on '
110110
'`${typeToCode(targetType)}`.',
111-
element: targetType.element,
111+
element: targetType.element3,
112112
);
113113
}
114114

@@ -120,11 +120,11 @@ Object? _generateEntry({
120120
throw InvalidGenerationSourceError(
121121
'`JsonEnum.valueField` was set to "$valueField", but '
122122
'that field does not have a type of String, int, or null.',
123-
element: targetType.element,
123+
element: targetType.element3,
124124
);
125125
}
126126
} else {
127-
return encodedFieldName(jsonEnum.fieldRename, field.name);
127+
return encodedFieldName(jsonEnum.fieldRename, field.name3!);
128128
}
129129
} else {
130130
final reader = ConstantReader(annotation);
@@ -136,7 +136,7 @@ Object? _generateEntry({
136136
} else {
137137
final targetTypeCode = typeToCode(targetType);
138138
throw InvalidGenerationSourceError(
139-
'The `JsonValue` annotation on `$targetTypeCode.${field.name}` does '
139+
'The `JsonValue` annotation on `$targetTypeCode.${field.name3}` does '
140140
'not have a value of type String, int, or null.',
141141
element: field,
142142
);

0 commit comments

Comments
 (0)