Skip to content

Commit

Permalink
Merge branch 'google:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
ssabdb committed May 24, 2022
2 parents 1de6aef + 8aadb45 commit 399ea63
Show file tree
Hide file tree
Showing 29 changed files with 315 additions and 169 deletions.
2 changes: 2 additions & 0 deletions checked_yaml/pubspec.yaml
Expand Up @@ -22,5 +22,7 @@ dev_dependencies:
test_process: ^2.0.0

dependency_overrides:
json_annotation:
path: ../json_annotation
json_serializable:
path: ../json_serializable
7 changes: 6 additions & 1 deletion json_annotation/CHANGELOG.md
@@ -1,3 +1,8 @@
## 4.6.0

- Added `JsonSerializable(converters: <JsonConverter>[])`
([#1072](https://github.com/google/json_serializable.dart/issues/1072))

## 4.5.0

- Added `FieldRename.screamingSnake`.
Expand Down Expand Up @@ -38,7 +43,7 @@

## 4.0.1

- Fix a potential error with `checked: true` when `ArgumentError.message` is
- Fix a potential error with `checked: true` when `ArgumentError.message` is
`null`.
- Updated `JsonSerializable.fromJson` to handle `null` values.
- Deprecate `JsonSerializable` `defaults` and `withDefaults()`.
Expand Down
31 changes: 31 additions & 0 deletions json_annotation/lib/src/json_converter.dart
Expand Up @@ -8,6 +8,37 @@
///
/// [S] is the type of the value stored in JSON. It must be a valid JSON type
/// such as [String], [int], or [Map<String, dynamic>].
///
///
/// [JsonConverter]s can be placed either on the class:
///
/// ```dart
/// class MyConverter extends JsonConverter<Value, JSON> {
/// // TODO
/// }
///
/// @JsonSerializable()
/// @MyJsonConverter()
/// class Example {}
/// ```
///
/// or on a property:
///
/// ```dart
/// @JsonSerializable()
/// @MyJsonConverter()
/// class Example {
/// @MyJsonConverter()
/// final Value property;
/// }
/// ```
///
/// Or finally, passed to the annotation:
///
///```dart
/// @JsonSerializable(converters: [MyConverter()])
/// class Example {}
/// ```
abstract class JsonConverter<T, S> {
const JsonConverter();

Expand Down
36 changes: 36 additions & 0 deletions json_annotation/lib/src/json_serializable.dart
Expand Up @@ -6,6 +6,7 @@ import 'package:meta/meta_meta.dart';

import 'allowed_keys_helpers.dart';
import 'checked_helpers.dart';
import 'json_converter.dart';
import 'json_key.dart';

part 'json_serializable.g.dart';
Expand Down Expand Up @@ -190,6 +191,40 @@ class JsonSerializable {
/// `includeIfNull`, that value takes precedent.
final bool? includeIfNull;

/// A list of [JsonConverter] to apply to this class.
///
/// Writing:
///
/// ```dart
/// @JsonSerializable(converters: [MyJsonConverter()])
/// class Example {...}
/// ```
///
/// is equivalent to writing:
///
/// ```dart
/// @JsonSerializable()
/// @MyJsonConverter()
/// class Example {...}
/// ```
///
/// The main difference is that this allows reusing a custom
/// [JsonSerializable] over multiple classes:
///
/// ```dart
/// const myCustomAnnotation = JsonSerializable(
/// converters: [MyJsonConverter()],
/// );
///
/// @myCustomAnnotation
/// class Example {...}
///
/// @myCustomAnnotation
/// class Another {...}
/// ```
@JsonKey(ignore: true)
final List<JsonConverter>? converters;

/// Creates a new [JsonSerializable] instance.
const JsonSerializable({
@Deprecated('Has no effect') bool? nullable,
Expand All @@ -203,6 +238,7 @@ class JsonSerializable {
this.fieldRename,
this.ignoreUnannotated,
this.includeIfNull,
this.converters,
this.genericArgumentFactories,
});

Expand Down
2 changes: 1 addition & 1 deletion json_annotation/pubspec.yaml
@@ -1,5 +1,5 @@
name: json_annotation
version: 4.5.0
version: 4.6.0
description: >-
Classes and helper functions that support JSON code generation via the
`json_serializable` package.
Expand Down
2 changes: 2 additions & 0 deletions json_serializable/CHANGELOG.md
Expand Up @@ -2,6 +2,8 @@

- Added support for using a `JsonConverter<MyClass, Object>` on properties
of type `MyClass?`. ([#822](https://github.com/google/json_serializable.dart/issues/822))
- Added support for `JsonSerializable(converters: <JsonConverter>[])`
([#1072](https://github.com/google/json_serializable.dart/issues/1072))

## 6.2.0

Expand Down
16 changes: 8 additions & 8 deletions json_serializable/README.md
Expand Up @@ -199,14 +199,14 @@ targets:
[`Enum`]: https://api.dart.dev/stable/dart-core/Enum-class.html
[`int`]: https://api.dart.dev/stable/dart-core/int-class.html
[`Iterable`]: https://api.dart.dev/stable/dart-core/Iterable-class.html
[`JsonConverter`]: https://pub.dev/documentation/json_annotation/4.5.0/json_annotation/JsonConverter-class.html
[`JsonEnum`]: https://pub.dev/documentation/json_annotation/4.5.0/json_annotation/JsonEnum-class.html
[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/4.5.0/json_annotation/JsonKey/fromJson.html
[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/4.5.0/json_annotation/JsonKey/toJson.html
[`JsonKey`]: https://pub.dev/documentation/json_annotation/4.5.0/json_annotation/JsonKey-class.html
[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/4.5.0/json_annotation/JsonLiteral-class.html
[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/4.5.0/json_annotation/JsonSerializable-class.html
[`JsonValue`]: https://pub.dev/documentation/json_annotation/4.5.0/json_annotation/JsonValue-class.html
[`JsonConverter`]: https://pub.dev/documentation/json_annotation/4.6.0/json_annotation/JsonConverter-class.html
[`JsonEnum`]: https://pub.dev/documentation/json_annotation/4.6.0/json_annotation/JsonEnum-class.html
[`JsonKey.fromJson`]: https://pub.dev/documentation/json_annotation/4.6.0/json_annotation/JsonKey/fromJson.html
[`JsonKey.toJson`]: https://pub.dev/documentation/json_annotation/4.6.0/json_annotation/JsonKey/toJson.html
[`JsonKey`]: https://pub.dev/documentation/json_annotation/4.6.0/json_annotation/JsonKey-class.html
[`JsonLiteral`]: https://pub.dev/documentation/json_annotation/4.6.0/json_annotation/JsonLiteral-class.html
[`JsonSerializable`]: https://pub.dev/documentation/json_annotation/4.6.0/json_annotation/JsonSerializable-class.html
[`JsonValue`]: https://pub.dev/documentation/json_annotation/4.6.0/json_annotation/JsonValue-class.html
[`List`]: https://api.dart.dev/stable/dart-core/List-class.html
[`Map`]: https://api.dart.dev/stable/dart-core/Map-class.html
[`num`]: https://api.dart.dev/stable/dart-core/num-class.html
Expand Down
2 changes: 1 addition & 1 deletion json_serializable/lib/src/check_dependencies.dart
Expand Up @@ -10,7 +10,7 @@ import 'package:pubspec_parse/pubspec_parse.dart';

const _productionDirectories = {'lib', 'bin'};
const _annotationPkgName = 'json_annotation';
final requiredJsonAnnotationMinVersion = Version.parse('4.5.0');
final requiredJsonAnnotationMinVersion = Version.parse('4.6.0');

Future<void> pubspecHasRightVersion(BuildStep buildStep) async {
final segments = buildStep.inputId.pathSegments;
Expand Down
1 change: 1 addition & 0 deletions json_serializable/lib/src/decode_helper.dart
Expand Up @@ -278,6 +278,7 @@ _ConstructorData _writeConstructorInvocation(

for (final arg in ctor.parameters) {
if (!availableConstructorParameters.contains(arg.name)) {
// ignore: deprecated_member_use
if (arg.isNotOptional) {
var msg = 'Cannot populate the required constructor '
'argument: ${arg.name}.';
Expand Down
2 changes: 1 addition & 1 deletion json_serializable/lib/src/json_serializable_generator.dart
Expand Up @@ -20,7 +20,7 @@ class JsonSerializableGenerator
extends GeneratorForAnnotation<JsonSerializable> {
final Settings _settings;

JsonSerializable get config => _settings.config;
JsonSerializable get config => _settings.config.toJsonSerializable();

JsonSerializableGenerator.fromSettings(this._settings);

Expand Down
29 changes: 5 additions & 24 deletions json_serializable/lib/src/settings.dart
Expand Up @@ -43,38 +43,19 @@ class Settings {
GenericFactoryHelper(),
].followedBy(_typeHelpers).followedBy(_coreHelpers);

final JsonSerializable _config;

// #CHANGE WHEN UPDATING json_annotation
ClassConfig get config => ClassConfig(
checked: _config.checked ?? ClassConfig.defaults.checked,
anyMap: _config.anyMap ?? ClassConfig.defaults.anyMap,
constructor: _config.constructor ?? ClassConfig.defaults.constructor,
createFactory:
_config.createFactory ?? ClassConfig.defaults.createFactory,
createToJson: _config.createToJson ?? ClassConfig.defaults.createToJson,
ignoreUnannotated:
_config.ignoreUnannotated ?? ClassConfig.defaults.ignoreUnannotated,
explicitToJson:
_config.explicitToJson ?? ClassConfig.defaults.explicitToJson,
includeIfNull:
_config.includeIfNull ?? ClassConfig.defaults.includeIfNull,
genericArgumentFactories: _config.genericArgumentFactories ??
ClassConfig.defaults.genericArgumentFactories,
fieldRename: _config.fieldRename ?? ClassConfig.defaults.fieldRename,
disallowUnrecognizedKeys: _config.disallowUnrecognizedKeys ??
ClassConfig.defaults.disallowUnrecognizedKeys,
);
final ClassConfig config;

/// Creates an instance of [Settings].
///
/// If [typeHelpers] is not provided, the built-in helpers are used:
/// [BigIntHelper], [DateTimeHelper], [DurationHelper], [JsonHelper], and
/// [UriHelper].
const Settings({
Settings({
JsonSerializable? config,
List<TypeHelper>? typeHelpers,
}) : _config = config ?? ClassConfig.defaults,
}) : config = config != null
? ClassConfig.fromJsonSerializable(config)
: ClassConfig.defaults,
_typeHelpers = typeHelpers ?? defaultHelpers;

/// Creates an instance of [Settings].
Expand Down
93 changes: 41 additions & 52 deletions json_serializable/lib/src/type_helpers/config_types.dart
Expand Up @@ -2,6 +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/constant/value.dart';
import 'package:json_annotation/json_annotation.dart';

/// Represents values from [JsonKey] when merged with local configuration.
Expand Down Expand Up @@ -38,41 +39,20 @@ class KeyConfig {
/// configuration.
///
/// Values are all known, so types are non-nullable.
class ClassConfig implements JsonSerializable {
@override
class ClassConfig {
final bool anyMap;

@override
final bool checked;

@override
final String constructor;

@override
final bool createFactory;

@override
final bool createToJson;

@override
final bool disallowUnrecognizedKeys;

@override
final bool explicitToJson;

@override
final FieldRename fieldRename;

@override
final bool genericArgumentFactories;

@override
final bool ignoreUnannotated;

@override
final bool includeIfNull;

final Map<String, String> ctorParamDefaults;
final List<DartObject> converters;

const ClassConfig({
required this.anyMap,
Expand All @@ -86,9 +66,33 @@ class ClassConfig implements JsonSerializable {
required this.genericArgumentFactories,
required this.ignoreUnannotated,
required this.includeIfNull,
this.converters = const [],
this.ctorParamDefaults = const {},
});

factory ClassConfig.fromJsonSerializable(JsonSerializable config) =>
// #CHANGE WHEN UPDATING json_annotation
ClassConfig(
checked: config.checked ?? ClassConfig.defaults.checked,
anyMap: config.anyMap ?? ClassConfig.defaults.anyMap,
constructor: config.constructor ?? ClassConfig.defaults.constructor,
createFactory:
config.createFactory ?? ClassConfig.defaults.createFactory,
createToJson: config.createToJson ?? ClassConfig.defaults.createToJson,
ignoreUnannotated:
config.ignoreUnannotated ?? ClassConfig.defaults.ignoreUnannotated,
explicitToJson:
config.explicitToJson ?? ClassConfig.defaults.explicitToJson,
includeIfNull:
config.includeIfNull ?? ClassConfig.defaults.includeIfNull,
genericArgumentFactories: config.genericArgumentFactories ??
ClassConfig.defaults.genericArgumentFactories,
fieldRename: config.fieldRename ?? ClassConfig.defaults.fieldRename,
disallowUnrecognizedKeys: config.disallowUnrecognizedKeys ??
ClassConfig.defaults.disallowUnrecognizedKeys,
// TODO typeConverters = []
);

/// An instance of [JsonSerializable] with all fields set to their default
/// values.
static const defaults = ClassConfig(
Expand All @@ -105,33 +109,18 @@ class ClassConfig implements JsonSerializable {
includeIfNull: true,
);

@override
Map<String, dynamic> toJson() => _$JsonSerializableToJson(this);

@override
JsonSerializable withDefaults() => this;
JsonSerializable toJsonSerializable() => JsonSerializable(
checked: checked,
anyMap: anyMap,
constructor: constructor,
createFactory: createFactory,
createToJson: createToJson,
ignoreUnannotated: ignoreUnannotated,
explicitToJson: explicitToJson,
includeIfNull: includeIfNull,
genericArgumentFactories: genericArgumentFactories,
fieldRename: fieldRename,
disallowUnrecognizedKeys: disallowUnrecognizedKeys,
// TODO typeConverters = []
);
}

const _$FieldRenameEnumMap = {
FieldRename.none: 'none',
FieldRename.kebab: 'kebab',
FieldRename.snake: 'snake',
FieldRename.pascal: 'pascal',
FieldRename.screamingSnake: 'screamingSnake',
};

// #CHANGE WHEN UPDATING json_annotation
Map<String, dynamic> _$JsonSerializableToJson(JsonSerializable instance) =>
<String, dynamic>{
'any_map': instance.anyMap,
'checked': instance.checked,
'constructor': instance.constructor,
'create_factory': instance.createFactory,
'create_to_json': instance.createToJson,
'disallow_unrecognized_keys': instance.disallowUnrecognizedKeys,
'explicit_to_json': instance.explicitToJson,
'field_rename': _$FieldRenameEnumMap[instance.fieldRename],
'generic_argument_factories': instance.genericArgumentFactories,
'ignore_unannotated': instance.ignoreUnannotated,
'include_if_null': instance.includeIfNull,
};

0 comments on commit 399ea63

Please sign in to comment.