From 737c932dd67d0be7593025b0d153a4802959a754 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Wed, 25 Jun 2025 11:55:11 +0200 Subject: [PATCH 1/4] Migrate to element2 APIs. --- json_serializable/CHANGELOG.md | 1 + json_serializable/lib/src/decode_helper.dart | 65 ++++++++++--------- json_serializable/lib/src/encoder_helper.dart | 37 ++++++----- json_serializable/lib/src/enum_utils.dart | 22 +++---- json_serializable/lib/src/field_helpers.dart | 63 ++++++++---------- .../lib/src/generator_helper.dart | 27 ++++---- json_serializable/lib/src/helper_core.dart | 30 ++++----- .../lib/src/json_enum_generator.dart | 6 +- json_serializable/lib/src/json_key_utils.dart | 24 +++---- .../lib/src/json_literal_generator.dart | 6 +- .../lib/src/json_serializable_generator.dart | 6 +- json_serializable/lib/src/type_helper.dart | 6 +- .../lib/src/type_helper_ctx.dart | 29 +++++---- .../type_helpers/json_converter_helper.dart | 42 ++++++------ .../lib/src/type_helpers/json_helper.dart | 47 ++++++++------ json_serializable/lib/src/utils.dart | 64 +++++++++--------- json_serializable/pubspec.yaml | 14 +++- .../src/_json_serializable_test_input.dart | 4 +- .../test/src/json_converter_test_input.dart | 4 +- 19 files changed, 263 insertions(+), 234 deletions(-) diff --git a/json_serializable/CHANGELOG.md b/json_serializable/CHANGELOG.md index 43ab453da..b807ab6eb 100644 --- a/json_serializable/CHANGELOG.md +++ b/json_serializable/CHANGELOG.md @@ -1,5 +1,6 @@ ## 6.9.6-wip +- Switch to analyzer element2 model and `build: ^3.0.0-dev`. - Move `package:collection` to a dev dependency. - Use new `null-aware element` feature in generated code. - Require Dart 3.8 diff --git a/json_serializable/lib/src/decode_helper.dart b/json_serializable/lib/src/decode_helper.dart index 633935e7d..2668b4243 100644 --- a/json_serializable/lib/src/decode_helper.dart +++ b/json_serializable/lib/src/decode_helper.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; @@ -23,7 +23,7 @@ class CreateFactoryResult { mixin DecodeHelper implements HelperCore { CreateFactoryResult createFactory( - Map accessibleFields, + Map accessibleFields, Map unavailableReasons, ) { assert(config.createFactory); @@ -37,14 +37,14 @@ mixin DecodeHelper implements HelperCore { ); if (config.genericArgumentFactories) { - for (var arg in element.typeParameters) { + for (var arg in element.typeParameters2) { final helperName = fromJsonForType( arg.instantiate(nullabilitySuffix: NullabilitySuffix.none), ); - buffer.write(', ${arg.name} Function(Object? json) $helperName'); + buffer.write(', ${arg.name3} Function(Object? json) $helperName'); } - if (element.typeParameters.isNotEmpty) { + if (element.typeParameters2.isNotEmpty) { buffer.write(','); } } @@ -55,7 +55,7 @@ mixin DecodeHelper implements HelperCore { String deserializeFun( String paramOrFieldName, { - ParameterElement? ctorParam, + FormalParameterElement? ctorParam, }) => _deserializeForField( accessibleFields[paramOrFieldName]!, ctorParam: ctorParam, @@ -66,8 +66,15 @@ mixin DecodeHelper implements HelperCore { config.constructor, accessibleFields.keys, accessibleFields.values - .where((fe) => element.lookUpSetter(fe.name, element.library) != null) - .map((fe) => fe.name) + .where( + (fe) => + element.lookUpSetter2( + name: fe.name3!, + library: element.library2, + ) != + null, + ) + .map((fe) => fe.name3!) .toList(), unavailableReasons, deserializeFun, @@ -75,12 +82,12 @@ mixin DecodeHelper implements HelperCore { final checks = _checkKeys( accessibleFields.values.where( - (fe) => data.usedCtorParamsAndFields.contains(fe.name), + (fe) => data.usedCtorParamsAndFields.contains(fe.name3), ), ).toList(); if (config.checked) { - final classLiteral = escapeDartString(element.name); + final classLiteral = escapeDartString(element.name3!); final sectionBuffer = StringBuffer() ..write(''' @@ -163,11 +170,11 @@ mixin DecodeHelper implements HelperCore { return CreateFactoryResult(buffer.toString(), data.usedCtorParamsAndFields); } - Iterable _checkKeys(Iterable accessibleFields) sync* { + Iterable _checkKeys(Iterable accessibleFields) sync* { final args = []; - String constantList(Iterable things) => - 'const ${jsonLiteralAsDart(things.map(nameAccess).toList())}'; + String constantList(Iterable things) => + 'const ${jsonLiteralAsDart(things.map(nameAccess).toList())}'; if (config.disallowUnrecognizedKeys) { final allowKeysLiteral = constantList(accessibleFields); @@ -201,8 +208,8 @@ mixin DecodeHelper implements HelperCore { /// If [checkedProperty] is `true`, we're using this function to write to a /// setter. String _deserializeForField( - FieldElement field, { - ParameterElement? ctorParam, + FieldElement2 field, { + FormalParameterElement? ctorParam, bool checkedProperty = false, }) { final jsonKeyName = safeNameAccess(field); @@ -246,7 +253,7 @@ mixin DecodeHelper implements HelperCore { if (defaultValue != null) { if (jsonKey.disallowNullValue && jsonKey.required) { log.warning( - 'The `defaultValue` on field `${field.name}` will have no ' + 'The `defaultValue` on field `${field.name3}` will have no ' 'effect because both `disallowNullValue` and `required` are set to ' '`true`.', ); @@ -267,30 +274,30 @@ mixin DecodeHelper implements HelperCore { /// [writableFields] are also populated, but only if they have not already /// been defined by a constructor parameter with the same name. _ConstructorData _writeConstructorInvocation( - ClassElement classElement, + ClassElement2 classElement, String constructorName, Iterable availableConstructorParameters, Iterable writableFields, Map unavailableReasons, - String Function(String paramOrFieldName, {ParameterElement ctorParam}) + String Function(String paramOrFieldName, {FormalParameterElement ctorParam}) deserializeForField, ) { - final className = classElement.name; + final className = classElement.name3; final ctor = constructorByName(classElement, constructorName); final usedCtorParamsAndFields = {}; - final constructorArguments = []; - final namedConstructorArguments = []; + final constructorArguments = []; + final namedConstructorArguments = []; - for (final arg in ctor.parameters) { - if (!availableConstructorParameters.contains(arg.name)) { + for (final arg in ctor.formalParameters) { + if (!availableConstructorParameters.contains(arg.name3)) { if (arg.isRequired) { var msg = 'Cannot populate the required constructor ' - 'argument: ${arg.name}.'; + 'argument: ${arg.name3}.'; - final additionalInfo = unavailableReasons[arg.name]; + final additionalInfo = unavailableReasons[arg.name3]; if (additionalInfo != null) { msg = '$msg $additionalInfo'; @@ -308,7 +315,7 @@ _ConstructorData _writeConstructorInvocation( } else { constructorArguments.add(arg); } - usedCtorParamsAndFields.add(arg.name); + usedCtorParamsAndFields.add(arg.name3!); } // fields that aren't already set by the constructor and that aren't final @@ -327,7 +334,7 @@ _ConstructorData _writeConstructorInvocation( ..writeAll( constructorArguments.map((paramElement) { final content = deserializeForField( - paramElement.name, + paramElement.name3!, ctorParam: paramElement, ); return ' $content,\n'; @@ -336,10 +343,10 @@ _ConstructorData _writeConstructorInvocation( ..writeAll( namedConstructorArguments.map((paramElement) { final value = deserializeForField( - paramElement.name, + paramElement.name3!, ctorParam: paramElement, ); - return ' ${paramElement.name}: $value,\n'; + return ' ${paramElement.name3!}: $value,\n'; }), ) ..write(')'); diff --git a/json_serializable/lib/src/encoder_helper.dart b/json_serializable/lib/src/encoder_helper.dart index 7effcd05e..6536cddda 100644 --- a/json_serializable/lib/src/encoder_helper.dart +++ b/json_serializable/lib/src/encoder_helper.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:source_helper/source_helper.dart'; @@ -13,18 +13,21 @@ import 'type_helpers/json_converter_helper.dart'; import 'unsupported_type_error.dart'; mixin EncodeHelper implements HelperCore { - String _fieldAccess(FieldElement field) => '$_toJsonParamName.${field.name}'; + String _fieldAccess(FieldElement2 field) => + '$_toJsonParamName.${field.name3!}'; - String createPerFieldToJson(Set accessibleFieldSet) { + String createPerFieldToJson(Set accessibleFieldSet) { final buffer = StringBuffer() ..writeln('// ignore: unused_element') - ..writeln('abstract class _\$${element.name.nonPrivate}PerFieldToJson {'); + ..writeln( + 'abstract class _\$${element.name3!.nonPrivate}PerFieldToJson {', + ); for (final field in accessibleFieldSet) { buffer ..writeln(' // ignore: unused_element') ..write( - 'static Object? ${field.name}' + 'static Object? ${field.name3!}' '${genericClassArgumentsImpl(withConstraints: true)}' '(${field.type} $_toJsonParamName', ); @@ -43,16 +46,16 @@ mixin EncodeHelper implements HelperCore { /// Generates an object containing metadatas related to the encoding, /// destined to be used by other code-generators. - String createFieldMap(Set accessibleFieldSet) { + String createFieldMap(Set accessibleFieldSet) { assert(config.createFieldMap); final buffer = StringBuffer( - 'const _\$${element.name.nonPrivate}FieldMap = {', + 'const _\$${element.name3!.nonPrivate}FieldMap = {', ); for (final field in accessibleFieldSet) { buffer.writeln( - '${escapeDartString(field.name)}: ' + '${escapeDartString(field.name3!)}: ' '${escapeDartString(nameAccess(field))},', ); } @@ -64,17 +67,17 @@ mixin EncodeHelper implements HelperCore { /// Generates an object containing metadatas related to the encoding, /// destined to be used by other code-generators. - String createJsonKeys(Set accessibleFieldSet) { + String createJsonKeys(Set accessibleFieldSet) { assert(config.createJsonKeys); final buffer = StringBuffer( - 'abstract final class _\$${element.name.nonPrivate}JsonKeys {', + 'abstract final class _\$${element.name3!.nonPrivate}JsonKeys {', ); // ..write('static const _\$${element.name.nonPrivate}JsonKeys();'); for (final field in accessibleFieldSet) { buffer.writeln( - 'static const String ${field.name} = ' + 'static const String ${field.name3} = ' '${escapeDartString(nameAccess(field))};', ); } @@ -84,7 +87,7 @@ mixin EncodeHelper implements HelperCore { return buffer.toString(); } - Iterable createToJson(Set accessibleFields) sync* { + Iterable createToJson(Set accessibleFields) sync* { assert(config.createToJson); final buffer = StringBuffer(); @@ -120,20 +123,20 @@ mixin EncodeHelper implements HelperCore { } void _writeGenericArgumentFactories(StringBuffer buffer) { - for (var arg in element.typeParameters) { + for (var arg in element.typeParameters2) { final helperName = toJsonForType( arg.instantiate(nullabilitySuffix: NullabilitySuffix.none), ); - buffer.write(',Object? Function(${arg.name} value) $helperName'); + buffer.write(',Object? Function(${arg.name3} value) $helperName'); } - if (element.typeParameters.isNotEmpty) { + if (element.typeParameters2.isNotEmpty) { buffer.write(','); } } static const _toJsonParamName = 'instance'; - String _serializeField(FieldElement field, String accessExpression) { + String _serializeField(FieldElement2 field, String accessExpression) { try { return getHelperContext( field, @@ -146,7 +149,7 @@ mixin EncodeHelper implements HelperCore { /// Returns `true` if the field can be written to JSON 'naively' – meaning /// we can avoid checking for `null`. - bool _canWriteJsonWithoutNullCheck(FieldElement field) { + bool _canWriteJsonWithoutNullCheck(FieldElement2 field) { final jsonKey = jsonKeyFor(field); if (jsonKey.includeIfNull) { diff --git a/json_serializable/lib/src/enum_utils.dart b/json_serializable/lib/src/enum_utils.dart index 00f0cbc0f..c5d5d1b54 100644 --- a/json_serializable/lib/src/enum_utils.dart +++ b/json_serializable/lib/src/enum_utils.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/constant/value.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:source_gen/source_gen.dart'; @@ -45,7 +45,7 @@ String? enumValueMapFromType( final items = enumMap.entries .map( (e) => - ' ${targetType.element!.name}.${e.key.name}: ' + ' ${targetType.element!.name}.${e.key.name3}: ' '${jsonLiteralAsDart(e.value)},', ) .join(); @@ -53,7 +53,7 @@ String? enumValueMapFromType( return 'const ${constMapName(targetType)} = {\n$items\n};'; } -Map? _enumMap( +Map? _enumMap( DartType targetType, { bool nullWithNoAnnotation = false, }) { @@ -79,7 +79,7 @@ Map? _enumMap( } Object? _generateEntry({ - required FieldElement field, + required FieldElement2 field, required JsonEnum jsonEnum, required DartType targetType, }) { @@ -92,12 +92,12 @@ Object? _generateEntry({ if (valueField != null) { // TODO: fieldRename is pointless here!!! At least log a warning! - final fieldElementType = field.type.element as EnumElement; + final fieldElementType = field.type.element3 as EnumElement2; - final e = fieldElementType.getField(valueField); + final e = fieldElementType.getField2(valueField); if (e == null && valueField == 'index') { - return fieldElementType.fields + return fieldElementType.fields2 .where((element) => element.isEnumConstant) .toList(growable: false) .indexOf(field); @@ -108,7 +108,7 @@ Object? _generateEntry({ '`JsonEnum.valueField` was set to "$valueField", but ' 'that is not a valid, instance field on ' '`${typeToCode(targetType)}`.', - element: targetType.element, + element: targetType.element3, ); } @@ -120,11 +120,11 @@ Object? _generateEntry({ throw InvalidGenerationSourceError( '`JsonEnum.valueField` was set to "$valueField", but ' 'that field does not have a type of String, int, or null.', - element: targetType.element, + element: targetType.element3, ); } } else { - return encodedFieldName(jsonEnum.fieldRename, field.name); + return encodedFieldName(jsonEnum.fieldRename, field.name3!); } } else { final reader = ConstantReader(annotation); @@ -136,7 +136,7 @@ Object? _generateEntry({ } else { final targetTypeCode = typeToCode(targetType); throw InvalidGenerationSourceError( - 'The `JsonValue` annotation on `$targetTypeCode.${field.name}` does ' + 'The `JsonValue` annotation on `$targetTypeCode.${field.name3}` does ' 'not have a value of type String, int, or null.', element: field, ); diff --git a/json_serializable/lib/src/field_helpers.dart b/json_serializable/lib/src/field_helpers.dart index bc9d6133f..4539c7e53 100644 --- a/json_serializable/lib/src/field_helpers.dart +++ b/json_serializable/lib/src/field_helpers.dart @@ -2,9 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; -import 'package:analyzer/src/dart/element/element.dart' // ignore: implementation_imports - show InterfaceElementImpl; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/src/dart/element/inheritance_manager3.dart' // ignore: implementation_imports show InheritanceManager3; import 'package:source_gen/source_gen.dart'; @@ -12,15 +10,15 @@ import 'package:source_gen/source_gen.dart'; import 'utils.dart'; class _FieldSet implements Comparable<_FieldSet> { - final FieldElement field; - final FieldElement sortField; + final FieldElement2 field; + final FieldElement2 sortField; _FieldSet._(this.field, this.sortField) - : assert(field.name == sortField.name); + : assert(field.name3 == sortField.name3); - factory _FieldSet(FieldElement? classField, FieldElement? superField) { + factory _FieldSet(FieldElement2? classField, FieldElement2? superField) { // At least one of these will != null, perhaps both. - final fields = [classField, superField].whereType().toList(); + final fields = [classField, superField].whereType().toList(); // Prefer the class field over the inherited field when sorting. final sortField = fields.first; @@ -38,69 +36,60 @@ class _FieldSet implements Comparable<_FieldSet> { @override int compareTo(_FieldSet other) => _sortByLocation(sortField, other.sortField); - static int _sortByLocation(FieldElement a, FieldElement b) { - final checkerA = TypeChecker.fromStatic( - (a.enclosingElement3 as InterfaceElement).thisType, - ); + static int _sortByLocation(FieldElement2 a, FieldElement2 b) { + final checkerA = TypeChecker.fromStatic(a.enclosingElement2.thisType); - if (!checkerA.isExactly(b.enclosingElement3)) { + if (!checkerA.isExactly(b.enclosingElement2)) { // in this case, you want to prioritize the enclosingElement that is more // "super". - if (checkerA.isAssignableFrom(b.enclosingElement3)) { + if (checkerA.isAssignableFrom(b.enclosingElement2)) { return -1; } - final checkerB = TypeChecker.fromStatic( - (b.enclosingElement3 as InterfaceElement).thisType, - ); + final checkerB = TypeChecker.fromStatic(b.enclosingElement2.thisType); - if (checkerB.isAssignableFrom(a.enclosingElement3)) { + if (checkerB.isAssignableFrom(a.enclosingElement2)) { return 1; } } /// Returns the offset of given field/property in its source file – with a /// preference for the getter if it's defined. - int offsetFor(FieldElement e) { + int offsetFor(FieldElement2 e) { if (e.isSynthetic) { - return (e.getter ?? e.setter)!.nameOffset; + return (e.getter2 ?? e.setter2)!.firstFragment.nameOffset2!; } - return e.nameOffset; + return e.firstFragment.nameOffset2!; } return offsetFor(a).compareTo(offsetFor(b)); } } -/// Returns a [List] of all instance [FieldElement] items for [element] and +/// Returns a [List] of all instance [FieldElement2] items for [element] and /// super classes, sorted first by their location in the inheritance hierarchy /// (super first) and then by their location in the source file. -List createSortedFieldSet(ClassElement element) { +List createSortedFieldSet(ClassElement2 element) { // Get all of the fields that need to be assigned // TODO: support overriding the field set with an annotation option final elementInstanceFields = Map.fromEntries( - element.fields.where((e) => !e.isStatic).map((e) => MapEntry(e.name, e)), + element.fields2.where((e) => !e.isStatic).map((e) => MapEntry(e.name3, e)), ); - final inheritedFields = {}; + final inheritedFields = {}; final manager = InheritanceManager3(); - for (final v - in manager - .getInheritedConcreteMap2(element as InterfaceElementImpl) - .values) { - assert(v is! FieldElement); - if (_dartCoreObjectChecker.isExactly(v.enclosingElement3)) { + for (final v in manager.getInheritedConcreteMap(element).values) { + assert(v is! FieldElement2); + if (_dartCoreObjectChecker.isExactly(v.enclosingElement2!)) { continue; } - if (v is PropertyAccessorElement && - (v as PropertyAccessorElement).isGetter) { - assert((v as PropertyAccessorElement).variable2 is FieldElement); - final variable = (v as PropertyAccessorElement).variable2 as FieldElement; - assert(!inheritedFields.containsKey(variable.name)); - inheritedFields[variable.name] = variable; + if (v is GetterElement) { + final variable = v.variable3 as FieldElement2; + assert(!inheritedFields.containsKey(variable.name3)); + inheritedFields[variable.name3!] = variable; } } diff --git a/json_serializable/lib/src/generator_helper.dart b/json_serializable/lib/src/generator_helper.dart index ef1bf16e0..ff5577472 100644 --- a/json_serializable/lib/src/generator_helper.dart +++ b/json_serializable/lib/src/generator_helper.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:build/build.dart'; import 'package:source_gen/source_gen.dart'; @@ -20,7 +20,7 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper { GeneratorHelper( this._generator, - ClassElement element, + ClassElement2 element, ConstantReader annotation, ) : super( element, @@ -38,7 +38,7 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper { Iterable generate() sync* { assert(_addedMembers.isEmpty); - if (config.genericArgumentFactories && element.typeParameters.isEmpty) { + if (config.genericArgumentFactories && element.typeParameters2.isEmpty) { log.warning( 'The class `${element.displayName}` is annotated ' 'with `JsonSerializable` field `genericArgumentFactories: true`. ' @@ -55,23 +55,24 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper { // these fields. final unavailableReasons = {}; - final accessibleFields = sortedFields.fold>( - {}, + final accessibleFields = sortedFields.fold>( + {}, (map, field) { final jsonKey = jsonKeyFor(field); if (!field.isPublic && !jsonKey.explicitYesFromJson) { - unavailableReasons[field.name] = 'It is assigned to a private field.'; - } else if (field.getter == null) { - assert(field.setter != null); - unavailableReasons[field.name] = + unavailableReasons[field.name3!] = + 'It is assigned to a private field.'; + } else if (field.getter2 == null) { + assert(field.setter2 != null); + unavailableReasons[field.name3!] = 'Setter-only properties are not supported.'; - log.warning('Setters are ignored: ${element.name}.${field.name}'); + log.warning('Setters are ignored: ${element.name3!}.${field.name3!}'); } else if (jsonKey.explicitNoFromJson) { - unavailableReasons[field.name] = + unavailableReasons[field.name3!] = 'It is assigned to a field not meant to be used in fromJson.'; } else { - assert(!map.containsKey(field.name)); - map[field.name] = field; + assert(!map.containsKey(field.name3)); + map[field.name3!] = field; } return map; diff --git a/json_serializable/lib/src/helper_core.dart b/json_serializable/lib/src/helper_core.dart index 6e9e731ab..b30bc36e0 100644 --- a/json_serializable/lib/src/helper_core.dart +++ b/json_serializable/lib/src/helper_core.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:meta/meta.dart'; import 'package:source_gen/source_gen.dart'; @@ -17,7 +17,7 @@ import 'unsupported_type_error.dart'; import 'utils.dart'; abstract class HelperCore { - final ClassElement element; + final ClassElement2 element; final ClassConfig config; HelperCore(this.element, this.config); @@ -28,17 +28,17 @@ abstract class HelperCore { @protected String get targetClassReference => - '${element.name}${genericClassArgumentsImpl(withConstraints: false)}'; + '${element.name3}${genericClassArgumentsImpl(withConstraints: false)}'; @protected - String nameAccess(FieldElement field) => jsonKeyFor(field).name; + String nameAccess(FieldElement2 field) => jsonKeyFor(field).name; @protected - String safeNameAccess(FieldElement field) => + String safeNameAccess(FieldElement2 field) => escapeDartString(nameAccess(field)); @protected - String get prefix => '_\$${element.name.nonPrivate}'; + String get prefix => '_\$${element.name3!.nonPrivate}'; /// Returns a [String] representing the type arguments that exist on /// [element]. @@ -49,19 +49,19 @@ abstract class HelperCore { genericClassArguments(element, withConstraints); @protected - KeyConfig jsonKeyFor(FieldElement field) => jsonKeyForField(field, config); + KeyConfig jsonKeyFor(FieldElement2 field) => jsonKeyForField(field, config); @protected - TypeHelperCtx getHelperContext(FieldElement field) => + TypeHelperCtx getHelperContext(FieldElement2 field) => typeHelperContext(this, field); } InvalidGenerationSourceError createInvalidGenerationError( String targetMember, - FieldElement field, + FieldElement2 field, UnsupportedTypeError error, ) { - var message = 'Could not generate `$targetMember` code for `${field.name}`'; + var message = 'Could not generate `$targetMember` code for `${field.name3!}`'; String? todo; if (error.type is TypeParameterType) { @@ -114,17 +114,17 @@ $converterOrKeyInstructions'''; /// ``` /// "" /// ``` -String genericClassArguments(ClassElement element, bool? withConstraints) { - if (withConstraints == null || element.typeParameters.isEmpty) { +String genericClassArguments(ClassElement2 element, bool? withConstraints) { + if (withConstraints == null || element.typeParameters2.isEmpty) { return ''; } - final values = element.typeParameters + final values = element.typeParameters2 .map((t) { if (withConstraints && t.bound != null) { final boundCode = typeToCode(t.bound!); - return '${t.name} extends $boundCode'; + return '${t.name3!} extends $boundCode'; } else { - return t.name; + return t.name3!; } }) .join(', '); diff --git a/json_serializable/lib/src/json_enum_generator.dart b/json_serializable/lib/src/json_enum_generator.dart index 17fe4bd8b..2c6fb3530 100644 --- a/json_serializable/lib/src/json_enum_generator.dart +++ b/json_serializable/lib/src/json_enum_generator.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:build/build.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:source_gen/source_gen.dart'; @@ -14,11 +14,11 @@ class JsonEnumGenerator extends GeneratorForAnnotation { @override List generateForAnnotatedElement( - Element element, + Element2 element, ConstantReader annotation, BuildStep buildStep, ) { - if (element is! EnumElement) { + if (element is! EnumElement2) { throw InvalidGenerationSourceError( '`@JsonEnum` can only be used on enum elements.', element: element, diff --git a/json_serializable/lib/src/json_key_utils.dart b/json_serializable/lib/src/json_key_utils.dart index a17e45666..4ab7742be 100644 --- a/json_serializable/lib/src/json_key_utils.dart +++ b/json_serializable/lib/src/json_key_utils.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/constant/value.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:build/build.dart'; import 'package:json_annotation/json_annotation.dart'; @@ -17,19 +17,19 @@ import 'utils.dart'; final _jsonKeyExpando = Expando>(); -KeyConfig jsonKeyForField(FieldElement field, ClassConfig classAnnotation) => +KeyConfig jsonKeyForField(FieldElement2 field, ClassConfig classAnnotation) => (_jsonKeyExpando[field] ??= Map.identity())[classAnnotation] ??= _from( field, classAnnotation, ); -KeyConfig _from(FieldElement element, ClassConfig classAnnotation) { +KeyConfig _from(FieldElement2 element, ClassConfig classAnnotation) { // If an annotation exists on `element` the source is a 'real' field. // If the result is `null`, check the getter – it is a property. // TODO: setters: github.com/google/json_serializable.dart/issues/24 final obj = jsonKeyAnnotation(element); - final ctorParamDefault = classAnnotation.ctorParamDefaults[element.name]; + final ctorParamDefault = classAnnotation.ctorParamDefaults[element.name3]; if (obj.isNull) { return _populateJsonKey( @@ -136,10 +136,10 @@ KeyConfig _from(FieldElement element, ClassConfig classAnnotation) { // the generated code will be invalid, so skipping until we're bored // later - final functionValue = objectValue.toFunctionValue()!; + final functionValue = objectValue.toFunctionValue2()!; final invokeConst = - functionValue is ConstructorElement && functionValue.isConst + functionValue is ConstructorElement2 && functionValue.isConst ? 'const ' : ''; @@ -185,7 +185,7 @@ KeyConfig _from(FieldElement element, ClassConfig classAnnotation) { } final enumValueNames = enumFields - .map((p) => p.name) + .map((p) => p.name3!) .toList(growable: false); final enumValueName = enumValueForDartObject( @@ -214,12 +214,12 @@ KeyConfig _from(FieldElement element, ClassConfig classAnnotation) { if (defaultValue != null && ctorParamDefault != null) { if (defaultValue == ctorParamDefault) { log.info( - 'The default value `$defaultValue` for `${element.name}` is defined ' + 'The default value `$defaultValue` for `${element.name3!}` is defined ' 'twice in the constructor and in the `JsonKey.defaultValue`.', ); } else { log.warning( - 'The constructor parameter for `${element.name}` has a default value ' + 'The constructor parameter for `${element.name3!}` has a default value ' '`$ctorParamDefault`, but the `JsonKey.defaultValue` value ' '`$defaultValue` will be used for missing or `null` values in JSON ' 'decoding.', @@ -231,7 +231,7 @@ KeyConfig _from(FieldElement element, ClassConfig classAnnotation) { final readValue = obj.read('readValue'); if (!readValue.isNull) { readValueFunctionName = readValue.objectValue - .toFunctionValue()! + .toFunctionValue2()! .qualifiedName; } @@ -278,7 +278,7 @@ KeyConfig _from(FieldElement element, ClassConfig classAnnotation) { KeyConfig _populateJsonKey( ClassConfig classAnnotation, - FieldElement element, { + FieldElement2 element, { required String? defaultValue, bool? disallowNullValue, bool? includeIfNull, @@ -307,7 +307,7 @@ KeyConfig _populateJsonKey( disallowNullValue, classAnnotation.includeIfNull, ), - name: name ?? encodedFieldName(classAnnotation.fieldRename, element.name), + name: name ?? encodedFieldName(classAnnotation.fieldRename, element.name3!), readValueFunctionName: readValueFunctionName, required: required ?? false, unknownEnumValue: unknownEnumValue, diff --git a/json_serializable/lib/src/json_literal_generator.dart b/json_serializable/lib/src/json_literal_generator.dart index 87f0acc08..9ce34d13a 100644 --- a/json_serializable/lib/src/json_literal_generator.dart +++ b/json_serializable/lib/src/json_literal_generator.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'dart:convert'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:build/build.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:path/path.dart' as p; @@ -17,7 +17,7 @@ class JsonLiteralGenerator extends GeneratorForAnnotation { @override Future generateForAnnotatedElement( - Element element, + Element2 element, ConstantReader annotation, BuildStep buildStep, ) async { @@ -39,7 +39,7 @@ class JsonLiteralGenerator extends GeneratorForAnnotation { final thing = jsonLiteralAsDart(content).toString(); final marked = asConst ? 'const' : 'final'; - return '$marked _\$${element.name}JsonLiteral = $thing;'; + return '$marked _\$${element.name3}JsonLiteral = $thing;'; } } diff --git a/json_serializable/lib/src/json_serializable_generator.dart b/json_serializable/lib/src/json_serializable_generator.dart index c69e86796..32b2796b3 100644 --- a/json_serializable/lib/src/json_serializable_generator.dart +++ b/json_serializable/lib/src/json_serializable_generator.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:build/build.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:source_gen/source_gen.dart'; @@ -54,11 +54,11 @@ class JsonSerializableGenerator @override Iterable generateForAnnotatedElement( - Element element, + Element2 element, ConstantReader annotation, BuildStep buildStep, ) { - if (element is! ClassElement || element is EnumElement) { + if (element is! ClassElement2 || element is EnumElement2) { throw InvalidGenerationSourceError( '`@JsonSerializable` can only be used on classes.', element: element, diff --git a/json_serializable/lib/src/type_helper.dart b/json_serializable/lib/src/type_helper.dart index 01add6bcf..868f3d9c5 100644 --- a/json_serializable/lib/src/type_helper.dart +++ b/json_serializable/lib/src/type_helper.dart @@ -2,7 +2,7 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'type_helpers/config_types.dart'; @@ -11,10 +11,10 @@ import 'type_helpers/config_types.dart'; /// [TypeHelper.deserialize]. abstract class TypeHelperContext { /// The annotated class that code is being generated for. - ClassElement get classElement; + ClassElement2 get classElement; /// The field that code is being generated for. - FieldElement get fieldElement; + FieldElement2 get fieldElement; /// [expression] may be just the name of the field or it may an expression /// representing the serialization of a value. diff --git a/json_serializable/lib/src/type_helper_ctx.dart b/json_serializable/lib/src/type_helper_ctx.dart index f6d355b15..f1433e05e 100644 --- a/json_serializable/lib/src/type_helper_ctx.dart +++ b/json_serializable/lib/src/type_helper_ctx.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/constant/value.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:source_helper/source_helper.dart'; @@ -17,7 +17,7 @@ import 'utils.dart'; TypeHelperCtx typeHelperContext( HelperCore helperCore, - FieldElement fieldElement, + FieldElement2 fieldElement, ) => TypeHelperCtx._(helperCore, fieldElement); class TypeHelperCtx @@ -25,10 +25,10 @@ class TypeHelperCtx final HelperCore _helperCore; @override - final FieldElement fieldElement; + final FieldElement2 fieldElement; @override - ClassElement get classElement => _helperCore.element; + ClassElement2 get classElement => _helperCore.element; @override ClassConfig get config => _helperCore.config; @@ -97,7 +97,7 @@ class _ConvertPair { _ConvertPair._(this.fromJson, this.toJson); - factory _ConvertPair(FieldElement element) { + factory _ConvertPair(FieldElement2 element) { var pair = _expando[element]; if (pair == null) { @@ -115,7 +115,7 @@ class _ConvertPair { } } -ConvertData? _convertData(DartObject obj, FieldElement element, bool isFrom) { +ConvertData? _convertData(DartObject obj, FieldElement2 element, bool isFrom) { final paramName = isFrom ? 'fromJson' : 'toJson'; final objectValue = obj.getField(paramName); @@ -123,20 +123,21 @@ ConvertData? _convertData(DartObject obj, FieldElement element, bool isFrom) { return null; } - final executableElement = objectValue.toFunctionValue()!; + final executableElement = objectValue.toFunctionValue2()!; - if (executableElement.parameters.isEmpty || - executableElement.parameters.first.isNamed || - executableElement.parameters.where((pe) => !pe.isOptional).length > 1) { + if (executableElement.formalParameters.isEmpty || + executableElement.formalParameters.first.isNamed || + executableElement.formalParameters.where((pe) => !pe.isOptional).length > + 1) { throwUnsupported( element, - 'The `$paramName` function `${executableElement.name}` must have one ' + 'The `$paramName` function `${executableElement.name3}` must have one ' 'positional parameter.', ); } final returnType = executableElement.returnType; - final argType = executableElement.parameters.first.type; + final argType = executableElement.formalParameters.first.type; if (isFrom) { final hasDefaultValue = !jsonKeyAnnotation( element, @@ -155,7 +156,7 @@ ConvertData? _convertData(DartObject obj, FieldElement element, bool isFrom) { final elementTypeCode = typeToCode(element.type); throwUnsupported( element, - 'The `$paramName` function `${executableElement.name}` return type ' + 'The `$paramName` function `${executableElement.name3}` return type ' '`$returnTypeCode` is not compatible with field type ' '`$elementTypeCode`.', ); @@ -171,7 +172,7 @@ ConvertData? _convertData(DartObject obj, FieldElement element, bool isFrom) { final elementTypeCode = typeToCode(element.type); throwUnsupported( element, - 'The `$paramName` function `${executableElement.name}` argument type ' + 'The `$paramName` function `${executableElement.name3}` argument type ' '`$argTypeCode` is not compatible with field type' ' `$elementTypeCode`.', ); diff --git a/json_serializable/lib/src/type_helpers/json_converter_helper.dart b/json_serializable/lib/src/type_helpers/json_converter_helper.dart index 778ffeeae..dc8a5c2ac 100644 --- a/json_serializable/lib/src/type_helpers/json_converter_helper.dart +++ b/json_serializable/lib/src/type_helpers/json_converter_helper.dart @@ -3,7 +3,7 @@ // BSD-style license that can be found in the LICENSE file. import 'package:analyzer/dart/constant/value.dart'; -import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:source_gen/source_gen.dart'; @@ -171,15 +171,19 @@ _JsonConvertData? _typeConverter( .whereType<_ConverterMatch>() .toList(); - var matchingAnnotations = converterMatches(ctx.fieldElement.metadata); + var matchingAnnotations = converterMatches( + ctx.fieldElement.getter2?.metadata2.annotations ?? [], + ); if (matchingAnnotations.isEmpty) { matchingAnnotations = converterMatches( - ctx.fieldElement.getter?.metadata ?? [], + ctx.fieldElement.metadata2.annotations, ); if (matchingAnnotations.isEmpty) { - matchingAnnotations = converterMatches(ctx.classElement.metadata); + matchingAnnotations = converterMatches( + ctx.classElement.metadata2.annotations, + ); if (matchingAnnotations.isEmpty) { matchingAnnotations = ctx.config.converters @@ -205,20 +209,20 @@ _JsonConvertData? _typeConverterFrom( final targetTypeCode = typeToCode(targetType); throw InvalidGenerationSourceError( 'Found more than one matching converter for `$targetTypeCode`.', - element: matchingAnnotations[1].elementAnnotation?.element, + element: matchingAnnotations[1].elementAnnotation?.element2, ); } final match = matchingAnnotations.single; - final annotationElement = match.elementAnnotation?.element; - if (annotationElement is PropertyAccessorElement) { - final enclosing = annotationElement.enclosingElement3; + final annotationElement = match.elementAnnotation?.element2; + if (annotationElement is PropertyAccessorElement2) { + final enclosing = annotationElement.enclosingElement2; - var accessString = annotationElement.name; + var accessString = annotationElement.name3!; - if (enclosing is ClassElement) { - accessString = '${enclosing.name}.$accessString'; + if (enclosing is ClassElement2) { + accessString = '${enclosing.name3}.$accessString'; } return _JsonConvertData.propertyAccess( @@ -234,7 +238,7 @@ _JsonConvertData? _typeConverterFrom( reviver.positionalArguments.isNotEmpty) { throw InvalidGenerationSourceError( 'Generators with constructor arguments are not supported.', - element: match.elementAnnotation?.element, + element: match.elementAnnotation?.element2, ); } @@ -277,10 +281,10 @@ _ConverterMatch? _compatibleMatch( ElementAnnotation? annotation, DartObject constantValue, ) { - final converterClassElement = constantValue.type!.element as ClassElement; + final converterClassElement = constantValue.type!.element3 as ClassElement2; final jsonConverterSuper = converterClassElement.allSupertypes - .where((e) => _jsonConverterChecker.isExactly(e.element)) + .where((e) => _jsonConverterChecker.isExactly(e.element3)) .singleOrNull; if (jsonConverterSuper == null) { @@ -304,13 +308,13 @@ _ConverterMatch? _compatibleMatch( } if (fieldType is TypeParameterType && targetType is TypeParameterType) { - assert(annotation?.element is! PropertyAccessorElement); - assert(converterClassElement.typeParameters.isNotEmpty); - if (converterClassElement.typeParameters.length > 1) { + assert(annotation?.element is! PropertyAccessorElement2); + assert(converterClassElement.typeParameters2.isNotEmpty); + if (converterClassElement.typeParameters2.length > 1) { throw InvalidGenerationSourceError( '`JsonConverter` implementations can have no more than one type ' - 'argument. `${converterClassElement.name}` has ' - '${converterClassElement.typeParameters.length}.', + 'argument. `${converterClassElement.name3}` has ' + '${converterClassElement.typeParameters2.length}.', element: converterClassElement, ); } diff --git a/json_serializable/lib/src/type_helpers/json_helper.dart b/json_serializable/lib/src/type_helpers/json_helper.dart index c2121ac80..4b9b2621b 100644 --- a/json_serializable/lib/src/type_helpers/json_helper.dart +++ b/json_serializable/lib/src/type_helpers/json_helper.dart @@ -2,7 +2,8 @@ // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. -import 'package:analyzer/dart/element/element.dart'; +// import 'package:analyzer/dart/ast/ast.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:source_gen/source_gen.dart'; @@ -42,16 +43,18 @@ class JsonHelper extends TypeHelper { var toJson = _toJsonMethod(interfaceType); if (toJson != null) { - // Using the `declaration` here so we get the original definition – + // Using the `baseElement` here so we get the original definition – // and not one with the generics already populated. - toJson = toJson.declaration; + toJson = toJson.baseElement; toJsonArgs.addAll( _helperParams( context.serialize, _encodeHelper, interfaceType, - toJson.parameters.where((element) => element.isRequiredPositional), + toJson.formalParameters.where( + (element) => element.isRequiredPositional, + ), toJson, ), ); @@ -75,15 +78,15 @@ class JsonHelper extends TypeHelper { return null; } - final classElement = targetType.element; + final classElement = targetType.element3; - final fromJsonCtor = classElement.constructors - .where((ce) => ce.name == 'fromJson') + final fromJsonCtor = classElement.constructors2 + .where((ce) => ce.name3 == 'fromJson') .singleOrNull; var output = expression; if (fromJsonCtor != null) { - final positionalParams = fromJsonCtor.parameters + final positionalParams = fromJsonCtor.formalParameters .where((element) => element.isPositional) .toList(); @@ -141,10 +144,10 @@ class JsonHelper extends TypeHelper { List _helperParams( Object? Function(DartType, String) execute, - TypeParameterType Function(ParameterElement, Element) paramMapper, + TypeParameterType Function(FormalParameterElement, Element2) paramMapper, InterfaceType type, - Iterable positionalParams, - Element targetElement, + Iterable positionalParams, + Element2 targetElement, ) { final rest = []; for (var param in positionalParams) { @@ -167,7 +170,10 @@ List _helperParams( return args; } -TypeParameterType _decodeHelper(ParameterElement param, Element targetElement) { +TypeParameterType _decodeHelper( + FormalParameterElement param, + Element2 targetElement, +) { final type = param.type; if (type is FunctionType && @@ -175,7 +181,7 @@ TypeParameterType _decodeHelper(ParameterElement param, Element targetElement) { type.normalParameterTypes.length == 1) { final funcReturnType = type.returnType; - if (param.name == fromJsonForName(funcReturnType.element!.name!)) { + if (param.name3 == fromJsonForName(funcReturnType.element!.name!)) { final funcParamType = type.normalParameterTypes.single; if ((funcParamType.isDartCoreObject && funcParamType.isNullableType) || @@ -195,7 +201,10 @@ TypeParameterType _decodeHelper(ParameterElement param, Element targetElement) { ); } -TypeParameterType _encodeHelper(ParameterElement param, Element targetElement) { +TypeParameterType _encodeHelper( + FormalParameterElement param, + Element2 targetElement, +) { final type = param.type; if (type is FunctionType && @@ -203,7 +212,7 @@ TypeParameterType _encodeHelper(ParameterElement param, Element targetElement) { type.normalParameterTypes.length == 1) { final funcParamType = type.normalParameterTypes.single; - if (param.name == toJsonForName(funcParamType.element!.name!)) { + if (param.name3 == toJsonForName(funcParamType.element!.name!)) { if (funcParamType is TypeParameterType) { return funcParamType; } @@ -272,7 +281,7 @@ ClassConfig? _annotation(ClassConfig config, InterfaceType source) { } final annotations = const TypeChecker.fromRuntime( JsonSerializable, - ).annotationsOfExact(source.element, throwOnUnresolved: false).toList(); + ).annotationsOfExact(source.element3, throwOnUnresolved: false).toList(); if (annotations.isEmpty) { return null; @@ -281,11 +290,11 @@ ClassConfig? _annotation(ClassConfig config, InterfaceType source) { return mergeConfig( config, ConstantReader(annotations.single), - classElement: source.element as ClassElement, + classElement: source.element3 as ClassElement2, ); } -MethodElement? _toJsonMethod(DartType type) => type.typeImplementations - .map((dt) => dt is InterfaceType ? dt.getMethod('toJson') : null) +MethodElement2? _toJsonMethod(DartType type) => type.typeImplementations + .map((dt) => dt is InterfaceType ? dt.getMethod2('toJson') : null) .where((me) => me != null) .firstOrNull; diff --git a/json_serializable/lib/src/utils.dart b/json_serializable/lib/src/utils.dart index 9f1d34bc7..42dffb9bf 100644 --- a/json_serializable/lib/src/utils.dart +++ b/json_serializable/lib/src/utils.dart @@ -4,6 +4,7 @@ import 'package:analyzer/dart/constant/value.dart'; import 'package:analyzer/dart/element/element.dart'; +import 'package:analyzer/dart/element/element2.dart'; import 'package:analyzer/dart/element/type.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:source_gen/source_gen.dart'; @@ -14,22 +15,22 @@ import 'type_helpers/config_types.dart'; const _jsonKeyChecker = TypeChecker.fromRuntime(JsonKey); -DartObject? _jsonKeyAnnotation(FieldElement element) => +DartObject? _jsonKeyAnnotation(FieldElement2 element) => _jsonKeyChecker.firstAnnotationOf(element) ?? - (element.getter == null + (element.getter2 == null ? null - : _jsonKeyChecker.firstAnnotationOf(element.getter!)); + : _jsonKeyChecker.firstAnnotationOf(element.getter2!)); -ConstantReader jsonKeyAnnotation(FieldElement element) => +ConstantReader jsonKeyAnnotation(FieldElement2 element) => ConstantReader(_jsonKeyAnnotation(element)); /// Returns `true` if [element] is annotated with [JsonKey]. -bool hasJsonKeyAnnotation(FieldElement element) => +bool hasJsonKeyAnnotation(FieldElement2 element) => _jsonKeyAnnotation(element) != null; -Never throwUnsupported(FieldElement element, String message) => +Never throwUnsupported(FieldElement2 element, String message) => throw InvalidGenerationSourceError( - 'Error with `@JsonKey` on the `${element.name}` field. $message', + 'Error with `@JsonKey` on the `${element.name3}` field. $message', element: element, ); @@ -79,7 +80,7 @@ JsonSerializable _valueForAnnotation(ConstantReader reader) => JsonSerializable( ClassConfig mergeConfig( ClassConfig config, ConstantReader reader, { - required ClassElement classElement, + required ClassElement2 classElement, }) { final annotation = _valueForAnnotation(reader); assert(config.ctorParamDefaults.isEmpty); @@ -93,9 +94,9 @@ ClassConfig mergeConfig( final paramDefaultValueMap = constructorInstance == null ? {} : Map.fromEntries( - constructorInstance.parameters + constructorInstance.formalParameters .where((element) => element.hasDefaultValue) - .map((e) => MapEntry(e.name, e.defaultValueCode!)), + .map((e) => MapEntry(e.name3!, e.defaultValueCode!)), ); final converters = reader.read('converters'); @@ -116,7 +117,7 @@ ClassConfig mergeConfig( fieldRename: annotation.fieldRename ?? config.fieldRename, genericArgumentFactories: annotation.genericArgumentFactories ?? - (classElement.typeParameters.isNotEmpty && + (classElement.typeParameters2.isNotEmpty && config.genericArgumentFactories), ignoreUnannotated: annotation.ignoreUnannotated ?? config.ignoreUnannotated, includeIfNull: annotation.includeIfNull ?? config.includeIfNull, @@ -125,8 +126,8 @@ ClassConfig mergeConfig( ); } -ConstructorElement? _constructorByNameOrNull( - ClassElement classElement, +ConstructorElement2? _constructorByNameOrNull( + ClassElement2 classElement, String name, ) { try { @@ -136,12 +137,12 @@ ConstructorElement? _constructorByNameOrNull( } } -ConstructorElement constructorByName(ClassElement classElement, String name) { - final className = classElement.name; +ConstructorElement2 constructorByName(ClassElement2 classElement, String name) { + final className = classElement.name3; - ConstructorElement? ctor; + ConstructorElement2? ctor; if (name.isEmpty) { - ctor = classElement.unnamedConstructor; + ctor = classElement.unnamedConstructor2; if (ctor == null) { throw InvalidGenerationSourceError( 'The class `$className` has no default constructor.', @@ -149,7 +150,7 @@ ConstructorElement constructorByName(ClassElement classElement, String name) { ); } } else { - ctor = classElement.getNamedConstructor(name); + ctor = classElement.getNamedConstructor2(name); if (ctor == null) { throw InvalidGenerationSourceError( 'The class `$className` does not have a constructor with the name ' @@ -166,9 +167,10 @@ ConstructorElement constructorByName(ClassElement classElement, String name) { /// with its values. /// /// Otherwise, `null`. -Iterable? iterateEnumFields(DartType targetType) { - if (targetType is InterfaceType && targetType.element is EnumElement) { - return targetType.element.fields.where((element) => element.isEnumConstant); +Iterable? iterateEnumFields(DartType targetType) { + if ( /*targetType is InterfaceType && */ targetType.element3 + is EnumElement2) { + return (targetType.element3 as EnumElement2).constants2; } return null; } @@ -247,24 +249,24 @@ String? defaultDecodeLogic( return null; } -extension ExecutableElementExtension on ExecutableElement { +extension ExecutableElementExtension on ExecutableElement2 { /// Returns the name of `this` qualified with the class name if it's a /// [MethodElement]. String get qualifiedName { - if (this is FunctionElement) { - return name; + if (this is TopLevelFunctionElement) { + return name3!; } - if (this is MethodElement) { - return '${enclosingElement3.name}.$name'; + if (this is MethodElement2) { + return '${enclosingElement2!.name3!}.${name3!}'; } - if (this is ConstructorElement) { - // Ignore the default constructor. - if (name.isEmpty) { - return '${enclosingElement3.name}'; + if (this is ConstructorElement2) { + // The default constructor. + if (name3 == 'new') { + return enclosingElement2!.name3!; } - return '${enclosingElement3.name}.$name'; + return '${enclosingElement2!.name3!}.${name3!}'; } throw UnsupportedError('Not sure how to support typeof $runtimeType'); diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index ec6022f17..8aa8d60a4 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -17,7 +17,7 @@ resolution: workspace dependencies: analyzer: '>=6.9.0 <8.0.0' async: ^2.10.0 - build: ^2.4.1 + build: ^3.0.0-dev build_config: ^1.1.0 dart_style: '>=2.3.7 <4.0.0' @@ -43,3 +43,15 @@ dev_dependencies: test_descriptor: ^2.0.0 test_process: ^2.0.0 yaml: ^3.0.0 + +dependency_overrides: + build: ^3.0.0-dev + source_gen: + git: + url: https://github.com/dart-lang/source_gen + path: source_gen + ref: 6c9702e7152e61b16c8adec3f3011bda738b0e29 + source_gen_test: + git: + url: https://github.com/kevmoo/source_gen_test + ref: 9036882e5d69620fa387c14e880ebbe19ed99fee diff --git a/json_serializable/test/src/_json_serializable_test_input.dart b/json_serializable/test/src/_json_serializable_test_input.dart index 4db90e56f..09deed525 100644 --- a/json_serializable/test/src/_json_serializable_test_input.dart +++ b/json_serializable/test/src/_json_serializable_test_input.dart @@ -277,7 +277,7 @@ class IgnoredFieldClass { @ShouldThrow( 'Cannot populate the required constructor argument: ignoredTrueField. It is ' 'assigned to a field not meant to be used in fromJson.', - element: '', + element: 'new', ) @JsonSerializable() class IgnoredFieldCtorClass { @@ -314,7 +314,7 @@ class IgnoreAndIncludeFromJsonFieldCtorClass { @ShouldThrow( 'Cannot populate the required constructor argument: ' '_privateField. It is assigned to a private field.', - element: '', + element: 'new', ) @JsonSerializable() class PrivateFieldCtorClass { diff --git a/json_serializable/test/src/json_converter_test_input.dart b/json_serializable/test/src/json_converter_test_input.dart index c06cc3fd2..1c082dd4c 100644 --- a/json_serializable/test/src/json_converter_test_input.dart +++ b/json_serializable/test/src/json_converter_test_input.dart @@ -129,7 +129,7 @@ class _BadConverter implements JsonConverter { @ShouldThrow( 'Found more than one matching converter for `Duration`.', - element: '', + element: 'new', ) @JsonSerializable() @_durationConverter @@ -154,7 +154,7 @@ class _DurationMillisecondConverter implements JsonConverter { @ShouldThrow( 'Generators with constructor arguments are not supported.', - element: '', + element: 'new', ) @JsonSerializable() @_ConverterWithCtorParams(42) From e7a3fad7b2c86554a761d182fdc5b0425bf38bfb Mon Sep 17 00:00:00 2001 From: David Morgan Date: Fri, 27 Jun 2025 08:31:07 +0200 Subject: [PATCH 2/4] Use published source_gen, refs for source_gen_test and source_helper. --- json_serializable/pubspec.yaml | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index 8aa8d60a4..e6f6fd264 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -28,7 +28,7 @@ dependencies: path: ^1.9.0 pub_semver: ^2.1.4 pubspec_parse: ^1.0.0 - source_gen: ^2.0.0 + source_gen: ^3.0.0-dev source_helper: ^1.3.4 dev_dependencies: @@ -38,20 +38,18 @@ dev_dependencies: build_verify: ^3.0.0 collection: ^1.17.0 logging: ^1.0.0 - source_gen_test: ^1.0.6 + source_gen_test: ^1.2.0-dev test: ^1.24.4 test_descriptor: ^2.0.0 test_process: ^2.0.0 yaml: ^3.0.0 dependency_overrides: - build: ^3.0.0-dev - source_gen: - git: - url: https://github.com/dart-lang/source_gen - path: source_gen - ref: 6c9702e7152e61b16c8adec3f3011bda738b0e29 source_gen_test: git: url: https://github.com/kevmoo/source_gen_test - ref: 9036882e5d69620fa387c14e880ebbe19ed99fee + ref: 8523d28a792cf2da9a3264ebe184b0ab64831fe0 + source_helper: + git: + url: https://github.com/google/source_helper.dart + ref: 8adebf1a6b18f5673157ab450e63cc7329c39e10 From fc05c2406a8c073668aef2fededfb659a8ed01f7 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Thu, 10 Jul 2025 09:02:06 +0200 Subject: [PATCH 3/4] Use published packages. --- json_serializable/pubspec.yaml | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index e6f6fd264..aad5a68d1 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -38,18 +38,8 @@ dev_dependencies: build_verify: ^3.0.0 collection: ^1.17.0 logging: ^1.0.0 - source_gen_test: ^1.2.0-dev + source_gen_test: ^1.3.0-dev test: ^1.24.4 test_descriptor: ^2.0.0 test_process: ^2.0.0 yaml: ^3.0.0 - -dependency_overrides: - source_gen_test: - git: - url: https://github.com/kevmoo/source_gen_test - ref: 8523d28a792cf2da9a3264ebe184b0ab64831fe0 - source_helper: - git: - url: https://github.com/google/source_helper.dart - ref: 8adebf1a6b18f5673157ab450e63cc7329c39e10 From 3e87ea505bbb3282c1928042d9142c8de9cedad5 Mon Sep 17 00:00:00 2001 From: David Morgan Date: Thu, 10 Jul 2025 09:23:21 +0200 Subject: [PATCH 4/4] Prepare to publish 6.10.0-dev. --- json_serializable/CHANGELOG.md | 2 +- json_serializable/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/json_serializable/CHANGELOG.md b/json_serializable/CHANGELOG.md index b807ab6eb..34b778c9f 100644 --- a/json_serializable/CHANGELOG.md +++ b/json_serializable/CHANGELOG.md @@ -1,4 +1,4 @@ -## 6.9.6-wip +## 6.10.0-dev - Switch to analyzer element2 model and `build: ^3.0.0-dev`. - Move `package:collection` to a dev dependency. diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index aad5a68d1..c32d46ee8 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -1,5 +1,5 @@ name: json_serializable -version: 6.9.6-wip +version: 6.10.0-dev description: >- Automatically generate code for converting to and from JSON by annotating Dart classes.