Skip to content

2 cleanup commits #222

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 17 additions & 22 deletions json_serializable/lib/src/generator_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import 'package:json_annotation/json_annotation.dart';
import 'package:source_gen/source_gen.dart';

import 'constants.dart';
import 'json_key_helpers.dart';
import 'json_key_with_conversion.dart';
import 'json_literal_generator.dart';
import 'json_serializable_generator.dart';
import 'type_helper.dart';
Expand Down Expand Up @@ -128,7 +128,7 @@ class _GeneratorHelper {
<String, FieldElement>{}, (map, field) {
if (!field.isPublic) {
unavailableReasons[field.name] = 'It is assigned to a private field.';
} else if (jsonKeyFor(field).ignore == true) {
} else if (_jsonKeyFor(field).ignore) {
unavailableReasons[field.name] = 'It is assigned to an ignored field.';
} else {
map[field.name] = field;
Expand Down Expand Up @@ -249,8 +249,9 @@ class _GeneratorHelper {
args.add('allowedKeys: $allowKeysLiteral');
}

var requiredKeys =
accessibleFields.values.where((fe) => jsonKeyFor(fe).required).toList();
var requiredKeys = accessibleFields.values
.where((fe) => _jsonKeyFor(fe).required)
.toList();
if (requiredKeys.isNotEmpty) {
var requiredKeyLiteral =
jsonLiteralAsDart(requiredKeys.map(_nameAccess).toList(), true);
Expand Down Expand Up @@ -428,7 +429,7 @@ class ${_wrapperClassName(true)} extends \$JsonMapWrapper {
throw _createInvalidGenerationError('fromJson', field, e);
}

var defaultValue = jsonKeyFor(field).defaultValue;
var defaultValue = _jsonKeyFor(field).defaultValue;
if (defaultValue != null) {
if (!contextHelper.nullable) {
throwUnsupported(field,
Expand All @@ -440,11 +441,11 @@ class ${_wrapperClassName(true)} extends \$JsonMapWrapper {
return value;
}

TypeHelperContext _getHelperContext(FieldElement field) {
var key = jsonKeyFor(field);
return new TypeHelperContext(_generator, field.metadata, _nullable(field),
key.fromJsonData, key.toJsonData);
}
JsonKeyWithConversion _jsonKeyFor(FieldElement field) =>
new JsonKeyWithConversion(field, _annotation);

TypeHelperContext _getHelperContext(FieldElement field) =>
new TypeHelperContext(_generator, field.metadata, _jsonKeyFor(field));

/// Returns `true` if the field can be written to JSON 'naively' – meaning
/// we can avoid checking for `null`.
Expand All @@ -454,20 +455,14 @@ class ${_wrapperClassName(true)} extends \$JsonMapWrapper {
/// or
/// `nullable` is `false`.
bool _writeJsonValueNaive(FieldElement field) =>
(jsonKeyFor(field).includeIfNull ?? _annotation.includeIfNull) ||
!_nullable(field);

/// Returns `true` if the field should be treated as potentially nullable.
///
/// If no [JsonKey] annotation is present on the field, `true` is returned.
bool _nullable(FieldElement field) =>
jsonKeyFor(field).nullable ?? _annotation.nullable;
}
_jsonKeyFor(field).includeIfNull || !_jsonKeyFor(field).nullable;

String _nameAccess(FieldElement field) => jsonKeyFor(field).name ?? field.name;
String _nameAccess(FieldElement field) =>
_jsonKeyFor(field).name ?? field.name;

String _safeNameAccess(FieldElement field) =>
escapeDartString(_nameAccess(field));
String _safeNameAccess(FieldElement field) =>
escapeDartString(_nameAccess(field));
}

InvalidGenerationSourceError _createInvalidGenerationError(
String targetMember, FieldElement field, UnsupportedTypeError e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,23 @@ import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/constant/value.dart';

import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart' show alwaysThrows;
import 'package:source_gen/source_gen.dart';

import 'json_literal_generator.dart';
import 'utils.dart';

@alwaysThrows
void throwUnsupported(FieldElement element, String message) =>
throw new InvalidGenerationSourceError(
'Error with `@JsonKey` on `${element.name}`. $message',
element: element);

final _jsonKeyExpando = new Expando<JsonKeyWithConversion>();

final _jsonKeyChecker = const TypeChecker.fromRuntime(JsonKey);

JsonKeyWithConversion jsonKeyFor(FieldElement element) {
var key = _jsonKeyExpando[element];

if (key == null) {
_jsonKeyExpando[element] = key = _from(element);
}

return key;
}

JsonKeyWithConversion _from(FieldElement element) {
JsonKeyWithConversion _from(
FieldElement element, JsonSerializable 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(kevmoo) setters: github.com/dart-lang/json_serializable/issues/24
var obj = _jsonKeyChecker.firstAnnotationOfExact(element) ??
_jsonKeyChecker.firstAnnotationOfExact(element.getter);

if (obj == null) {
return const JsonKeyWithConversion._empty();
return new JsonKeyWithConversion._(classAnnotation);
}
var fromJsonName = _getFunctionName(obj, element, true);
var toJsonName = _getFunctionName(obj, element, false);
Expand Down Expand Up @@ -113,15 +95,15 @@ JsonKeyWithConversion _from(FieldElement element) {
}
}

return new JsonKeyWithConversion._(
obj.getField('name').toStringValue(),
obj.getField('nullable').toBoolValue(),
obj.getField('includeIfNull').toBoolValue(),
obj.getField('ignore').toBoolValue(),
defaultValueLiteral,
obj.getField('required').toBoolValue(),
fromJsonName,
toJsonName);
return new JsonKeyWithConversion._(classAnnotation,
name: obj.getField('name').toStringValue(),
nullable: obj.getField('nullable').toBoolValue(),
includeIfNull: obj.getField('includeIfNull').toBoolValue(),
ignore: obj.getField('ignore').toBoolValue(),
defaultValue: defaultValueLiteral,
required: obj.getField('required').toBoolValue(),
fromJsonData: fromJsonName,
toJsonData: toJsonName);
}

class ConvertData {
Expand All @@ -132,28 +114,30 @@ class ConvertData {
}

class JsonKeyWithConversion extends JsonKey {
static final _jsonKeyExpando = new Expando<JsonKeyWithConversion>();

final ConvertData fromJsonData;
final ConvertData toJsonData;

const JsonKeyWithConversion._empty()
: fromJsonData = null,
toJsonData = null,
super(required: false);
factory JsonKeyWithConversion(
FieldElement element, JsonSerializable classAnnotation) =>
_jsonKeyExpando[element] ??= _from(element, classAnnotation);

JsonKeyWithConversion._(
String name,
bool nullable,
bool includeIfNull,
bool ignore,
Object defaultValue,
bool required,
this.fromJsonData,
this.toJsonData)
: super(
JsonSerializable classAnnotation, {
String name,
bool nullable,
bool includeIfNull,
bool ignore,
Object defaultValue,
bool required,
this.fromJsonData,
this.toJsonData,
}) : super(
name: name,
nullable: nullable,
includeIfNull: includeIfNull,
ignore: ignore,
nullable: nullable ?? classAnnotation.nullable,
includeIfNull: includeIfNull ?? classAnnotation.includeIfNull,
ignore: ignore ?? false,
defaultValue: defaultValue,
required: required ?? false);
}
Expand Down
22 changes: 10 additions & 12 deletions json_serializable/lib/src/type_helper_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,29 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';

import 'json_key_helpers.dart';
import 'json_key_with_conversion.dart';
import 'json_serializable_generator.dart';
import 'type_helper.dart';

class TypeHelperContext implements SerializeContext, DeserializeContext {
@override
final List<ElementAnnotation> metadata;

final JsonSerializableGenerator _generator;
final JsonKeyWithConversion _key;

@override
bool get useWrappers => _generator.useWrappers;

@override
final List<ElementAnnotation> metadata;
bool get anyMap => _generator.anyMap;

@override
final bool nullable;
bool get nullable => _key.nullable;

final ConvertData fromJsonData;
final ConvertData toJsonData;

// This is effectively private to TypeHelpers outside this package.
// Consider exposing it if there is interest
bool get anyMap => _generator.anyMap;
ConvertData get fromJsonData => _key.fromJsonData;
ConvertData get toJsonData => _key.toJsonData;

TypeHelperContext(this._generator, this.metadata, this.nullable,
this.fromJsonData, this.toJsonData);
TypeHelperContext(this._generator, this.metadata, this._key);

@override
String serialize(DartType targetType, String expression) => _run(
Expand Down
7 changes: 7 additions & 0 deletions json_serializable/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,15 @@ import 'package:analyzer/src/dart/resolver/inheritance_manager.dart'
show InheritanceManager;

import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart' show alwaysThrows;
import 'package:source_gen/source_gen.dart';

@alwaysThrows
void throwUnsupported(FieldElement element, String message) =>
throw new InvalidGenerationSourceError(
'Error with `@JsonKey` on `${element.name}`. $message',
element: element);

JsonSerializable valueForAnnotation(ConstantReader annotation) =>
new JsonSerializable(
disallowUnrecognizedKeys:
Expand Down