Skip to content

Add "implicit-dynamic: false" strong mode analyzer option support for generated files #73

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

Closed
wants to merge 7 commits into from
1 change: 1 addition & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false
errors:
unused_element: error
unused_import: error
Expand Down
16 changes: 8 additions & 8 deletions json_serializable/example/example.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Person _$PersonFromJson(Map<String, dynamic> json) => new Person(
? null
: DateTime.parse(json['last-order'] as String),
orders: (json['orders'] as List)
.map((e) => new Order.fromJson(e as Map<String, dynamic>))
.map((dynamic e) => new Order.fromJson(e as Map<String, dynamic>))
.toList());

abstract class _$PersonSerializerMixin {
Expand Down Expand Up @@ -88,22 +88,22 @@ Item _$ItemFromJson(Map<String, dynamic> json) => new Item()
// Generator: JsonLiteralGenerator
// **************************************************************************

final _$glossaryDataJsonLiteral = {
'glossary': {
final _$glossaryDataJsonLiteral = <String, dynamic>{
'glossary': <String, dynamic>{
'title': 'example glossary',
'GlossDiv': {
'GlossDiv': <String, dynamic>{
'title': 'S',
'GlossList': {
'GlossEntry': {
'GlossList': <String, dynamic>{
'GlossEntry': <String, dynamic>{
'ID': 'SGML',
'SortAs': 'SGML',
'GlossTerm': 'Standard Generalized Markup Language',
'Acronym': 'SGML',
'Abbrev': 'ISO 8879:1986',
'GlossDef': {
'GlossDef': <String, dynamic>{
'para':
'A meta-markup language, used to create markup languages such as DocBook.',
'GlossSeeAlso': ['GML', 'XML']
'GlossSeeAlso': <dynamic>['GML', 'XML']
},
'GlossSee': 'markup'
}
Expand Down
10 changes: 5 additions & 5 deletions json_serializable/lib/src/json_literal_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class JsonLiteralGenerator extends GeneratorForAnnotation<JsonLiteral> {
var sourcePathDir = p.dirname(buildStep.inputId.path);
var fileId = new AssetId(buildStep.inputId.package,
p.join(sourcePathDir, annotation.read('path').stringValue));
var content = JSON.decode(await buildStep.readAsString(fileId));
dynamic content = JSON.decode(await buildStep.readAsString(fileId));

var asConst = annotation.read('asConst').boolValue;

Expand All @@ -50,8 +50,8 @@ String _jsonLiteralAsDart(dynamic value, bool asConst) {

if (value is List) {
var listItems =
value.map((v) => _jsonLiteralAsDart(v, asConst)).join(',\n');
return '${asConst ? 'const' : ''}[$listItems]';
value.map((dynamic v) => _jsonLiteralAsDart(v, asConst)).join(',\n');
return '${asConst ? 'const' : ''}<dynamic>[$listItems]';
}

if (value is Map<String, dynamic>) return _jsonMapAsDart(value, asConst);
Expand All @@ -65,10 +65,10 @@ String _jsonMapAsDart(Map<String, dynamic> value, bool asConst) {
if (asConst) {
buffer.write('const ');
}
buffer.write('{');
buffer.write('<String, dynamic>{');

var first = true;
value.forEach((k, v) {
value.forEach((k, dynamic v) {
if (first) {
first = false;
} else {
Expand Down
8 changes: 4 additions & 4 deletions json_serializable/lib/src/json_serializable_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class JsonSerializableGenerator
new JsonSerializableGenerator(
useWrappers: useWrappers,
typeHelpers: new List.unmodifiable(
[typeHelpers, _defaultHelpers].expand((e) => e)));
[typeHelpers, _defaultHelpers].expand<TypeHelper>((e) => e)));

@override
Future<String> generateForAnnotatedElement(
Expand Down Expand Up @@ -94,7 +94,7 @@ class JsonSerializableGenerator
// Explicitly using `LinkedHashMap` – we want these ordered.
var fields = new LinkedHashMap<String, FieldElement>.fromIterable(
fieldsList,
key: (f) => (f as FieldElement).name);
key: (FieldElement f) => f.name);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be key: (Object f) => (f as FieldElement).name);

or you get https://travis-ci.org/dart-lang/json_serializable/jobs/308340768#L588

uses_dynamic_as_bottom


// Get the constructor to use for the factory

Expand Down Expand Up @@ -380,15 +380,15 @@ void $toJsonMapHelperName(String key, dynamic value) {
.writeln('$className ${prefix}FromJson(Map<String, dynamic> json) =>');
buffer.write(' new $className(');
buffer.writeAll(
ctorArguments.map((paramElement) => _deserializeForField(
ctorArguments.map<String>((paramElement) => _deserializeForField(
fields[paramElement.name], classSupportNullable,
ctorParam: paramElement)),
', ');
if (ctorArguments.isNotEmpty && ctorNamedArguments.isNotEmpty) {
buffer.write(', ');
}
buffer.writeAll(
ctorNamedArguments.map((paramElement) =>
ctorNamedArguments.map<String>((paramElement) =>
'${paramElement.name}: ' +
_deserializeForField(
fields[paramElement.name], classSupportNullable,
Expand Down
10 changes: 6 additions & 4 deletions json_serializable/lib/src/type_helpers/iterable_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ class IterableHelper extends TypeHelper {

var keyType = args[0];

var iterableGenericType = _getIterableGenericType(targetType);

// This block will yield a regular list, which works fine for JSON
// Although it's possible that child elements may be marked unsafe

var isList = _coreListChecker.isAssignableFromType(targetType);
var subFieldValue = context.serialize(
_getIterableGenericType(targetType), _closureArg, nullable);
var subFieldValue =
context.serialize(iterableGenericType, _closureArg, nullable);

var optionalQuestion = nullable ? '?' : '';

Expand All @@ -44,7 +46,7 @@ class IterableHelper extends TypeHelper {

// TODO: the type could be imported from a library with a prefix!
expression =
'${expression}${optionalQuestion}.map(($_closureArg) => $subFieldValue)';
'${expression}${optionalQuestion}.map((${iterableGenericType.toString()} $_closureArg) => $subFieldValue)';

// expression now represents an Iterable (even if it started as a List
// ...resetting `isList` to `false`.
Expand Down Expand Up @@ -79,7 +81,7 @@ class IterableHelper extends TypeHelper {
var optionalQuestion = nullable ? '?' : '';

var output =
'($expression as List)${optionalQuestion}.map(($_closureArg) => $itemSubVal)';
'($expression as List)${optionalQuestion}.map((dynamic $_closureArg) => $itemSubVal)';

if (_coreListChecker.isAssignableFromType(targetType)) {
output += '${optionalQuestion}.toList()';
Expand Down
4 changes: 2 additions & 2 deletions json_serializable/lib/src/type_helpers/map_helper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class MapHelper extends TypeHelper {

var result = 'new Map<String, dynamic>.fromIterables('
'$expression.keys,'
'$expression.values.map(($_closureArg) => $subFieldValue))';
'$expression.values.map<dynamic>(($_closureArg) => $subFieldValue))';

return commonNullPrefix(nullable, expression, result);
}
Expand Down Expand Up @@ -82,7 +82,7 @@ class MapHelper extends TypeHelper {

var result = 'new Map<String, $valueArg>.fromIterables('
'($expression as Map<String, dynamic>).keys,'
'($expression as Map).values.map(($_closureArg) => $itemSubVal))';
'($expression as Map).values.map((dynamic $_closureArg) => $itemSubVal))';

return commonNullPrefix(nullable, expression, result);
}
Expand Down
2 changes: 1 addition & 1 deletion json_serializable/lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ String friendlyNameForElement(Element element) {
}

/// Logs to STDERR with wrapper stars to make things readable during build.
void log(object) {
void log(Object object) {
stderr.writeln(['***', object, '***'].join('\n'));
}

Expand Down
2 changes: 1 addition & 1 deletion json_serializable/test/json_literal_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import 'package:path/path.dart' as p;
import 'test_files/json_literal.dart';
import 'test_utils.dart';

main() {
void main() {
test('literal round-trip', () {
var dataFilePath =
p.join(getPackagePath(), 'test', 'test_files', 'data.json');
Expand Down
18 changes: 10 additions & 8 deletions json_serializable/test/json_serializable_integration_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void main() {
});

test('empty json', () {
var person = new Person.fromJson({});
var person = new Person.fromJson(<String, dynamic>{});
expect(person.dateOfBirth, isNull);
roundTripPerson(person);
});
Expand Down Expand Up @@ -66,18 +66,19 @@ void main() {
});

test('almost empty json', () {
var order = new Order.fromJson({'category': 'top'});
var order = new Order.fromJson(<String, String>{'category': 'top'});
expect(order.items, isEmpty);
expect(order.category, Category.top);
roundTripOrder(order);
});

test('required, but missing enum value fails', () {
expect(() => new Order.fromJson({}), throwsStateError);
expect(() => new Order.fromJson(<String, dynamic>{}), throwsStateError);
});

test('mismatched enum value fails', () {
expect(() => new Order.fromJson({'category': 'weird'}), throwsStateError);
expect(() => new Order.fromJson(<String, String>{'category': 'weird'}),
throwsStateError);
});

test('platform', () {
Expand All @@ -99,21 +100,22 @@ void main() {
}

test('empty json', () {
var item = new Item.fromJson({});
var item = new Item.fromJson(<String, dynamic>{});
expect(item.saleDates, isNull);
roundTripItem(item);

expect(item.toJson().keys, orderedEquals(['price', 'saleDates', 'rates']),
expect(item.toJson().keys,
orderedEquals(<String>['price', 'saleDates', 'rates']),
reason: 'Omits null `itemNumber`');
});

test('set itemNumber - with custom JSON key', () {
var item = new Item.fromJson({'item-number': 42});
var item = new Item.fromJson(<String, int>{'item-number': 42});
expect(item.itemNumber, 42);
roundTripItem(item);

expect(item.toJson().keys,
orderedEquals(['price', 'item-number', 'saleDates', 'rates']),
orderedEquals(<String>['price', 'item-number', 'saleDates', 'rates']),
reason: 'Includes non-null `itemNumber` - with custom key');
});
});
Expand Down
9 changes: 6 additions & 3 deletions json_serializable/test/json_serializable_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ void _registerTests(JsonSerializableGenerator generator) {
: DateTime.parse(json['dateOfBirth'] as String)
..dynamicType = json['dynamicType']
..varType = json['varType']
..listOfInts = (json['listOfInts'] as List)?.map((e) => e as int)?.toList();
..listOfInts =
(json['listOfInts'] as List)?.map((dynamic e) => e as int)?.toList();

abstract class _$PersonSerializerMixin {
String get firstName;
Expand Down Expand Up @@ -217,8 +218,10 @@ abstract class _$OrderSerializerMixin {
test('class with list of int is cast for strong mode', () async {
var output = await runForElementNamed('Person');

expect(output,
contains("json['listOfInts'] as List)?.map((e) => e as int)"));
expect(
output,
contains(
"json['listOfInts'] as List)?.map((dynamic e) => e as int)"));
});
});

Expand Down
4 changes: 2 additions & 2 deletions json_serializable/test/kitchen_sink_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void _nonNullableTests(
});

test('with empty json fails deserialization', () {
expect(() => fromJson({}), throwsNoSuchMethodError);
expect(() => fromJson(<String, dynamic>{}), throwsNoSuchMethodError);
});
_sharedTests(ctor, fromJson);
}
Expand Down Expand Up @@ -203,7 +203,7 @@ void _sharedTests(
test('JSON keys should be defined in field/property order', () {
/// Explicitly setting values from [_excludeIfNullKeys] to ensure
/// they exist for KitchenSink where they are excluded when null
var item = ctor(iterable: [])
var item = ctor(iterable: <dynamic>[])
..dateTime = new DateTime.now()
..dateTimeList = []
..crazyComplex = []
Expand Down
16 changes: 8 additions & 8 deletions json_serializable/test/test_files/json_literal.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ part of json_serializable.example;
// Generator: JsonLiteralGenerator
// **************************************************************************

final _$dataJsonLiteral = [
final _$dataJsonLiteral = <dynamic>[
'simple string',
"'string with single quotes'",
'"string with double quotes"',
Expand All @@ -27,17 +27,17 @@ final _$dataJsonLiteral = [
5,
5.5351,
-5.5,
{},
{
<String, dynamic>{},
<String, dynamic>{
'null': null,
'int': 42,
'double': 42.0,
'string': 'string',
'list': [],
'list': <dynamic>[],
'bool': true
}
];
const _$asConstJsonLiteral = const [
const _$asConstJsonLiteral = const <dynamic>[
'simple string',
"'string with single quotes'",
'"string with double quotes"',
Expand All @@ -54,13 +54,13 @@ const _$asConstJsonLiteral = const [
5,
5.5351,
-5.5,
const {},
const {
const <String, dynamic>{},
const <String, dynamic>{
'null': null,
'int': 42,
'double': 42.0,
'string': 'string',
'list': const [],
'list': const <dynamic>[],
'bool': true
}
];
3 changes: 2 additions & 1 deletion json_serializable/test/test_files/json_test_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ class Item extends Object with _$ItemSerializerMixin {
_deepEquals(saleDates, other.saleDates);
}

bool _deepEquals(a, b) => const DeepCollectionEquality().equals(a, b);
bool _deepEquals(dynamic a, dynamic b) =>
const DeepCollectionEquality().equals(a, b);

class Platform {
final String description;
Expand Down
Loading