Skip to content

Commit b334072

Browse files
committed
Make some things illegal
1 parent a9ec35d commit b334072

5 files changed

+94
-34
lines changed

lib/src/json_serializable_generator.dart

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,14 @@ class JsonSerializableGenerator
111111

112112
var pairs = <String>[];
113113
fields.forEach((fieldName, field) {
114-
pairs.add("'${_fieldToJsonMapKey(fieldName, field)}': "
115-
"${_fieldToJsonMapValue(fieldName, field.type)}");
114+
try {
115+
pairs.add("'${_fieldToJsonMapKey(fieldName, field)}': "
116+
"${_fieldToJsonMapValue(fieldName, field.type)}");
117+
} on _UnsupportedTypeError {
118+
throw new InvalidGenerationSourceError(
119+
"Could not generate `toJson` code for `${friendlyNameForElement(field)}`.",
120+
todo: "Make sure all of the types are serializable.");
121+
}
116122
});
117123
buffer.writeln(pairs.join(','));
118124

@@ -246,7 +252,7 @@ class JsonSerializableGenerator
246252
return _mapFieldToJsonMapValue(expression, fieldType, depth);
247253
}
248254

249-
return "$expression /* unsafe */";
255+
throw new _UnsupportedTypeError(fieldType, expression);
250256
}
251257

252258
String _listFieldToJsonMapValue(
@@ -314,7 +320,7 @@ class JsonSerializableGenerator
314320
"$expression.keys,"
315321
"$expression.values.map(($substitute) => $subFieldValue))";
316322
}
317-
return "$expression /* unsafe */";
323+
throw new _UnsupportedTypeError(fieldType, expression);
318324
}
319325

320326
String _jsonMapAccessToField(String name, FieldElement field,
@@ -323,7 +329,14 @@ class JsonSerializableGenerator
323329
var result = "json['$name']";
324330

325331
var targetType = ctorParam?.type ?? field.type;
326-
return _writeAccessToJsonValue(result, targetType);
332+
333+
try {
334+
return _writeAccessToJsonValue(result, targetType);
335+
} on _UnsupportedTypeError {
336+
throw new InvalidGenerationSourceError(
337+
"Could not generate fromJson code for `${friendlyNameForElement(field)}`.",
338+
todo: "Make sure all of the types are serializable.");
339+
}
327340
}
328341

329342
String _writeAccessToJsonValue(String varExpression, DartType searchType,
@@ -370,7 +383,7 @@ class JsonSerializableGenerator
370383
_coreStringChecker.isExactlyType(keyArg);
371384

372385
if (!safeKey) {
373-
return "$varExpression /* unsafe key type */";
386+
throw new _UnsupportedTypeError(keyArg, varExpression);
374387
}
375388

376389
// this is the trivial case. Do a runtime cast to the known type of JSON
@@ -403,7 +416,7 @@ class JsonSerializableGenerator
403416
return "$varExpression as $searchType";
404417
}
405418

406-
return "$varExpression /* unsafe */";
419+
throw new _UnsupportedTypeError(searchType, varExpression);
407420
}
408421
}
409422

@@ -464,3 +477,10 @@ final _stringBoolNumChecker = new TypeChecker.any([
464477
new TypeChecker.fromUrl('dart:core#bool'),
465478
new TypeChecker.fromUrl('dart:core#num')
466479
]);
480+
481+
class _UnsupportedTypeError extends Error {
482+
final String expression;
483+
final DartType type;
484+
485+
_UnsupportedTypeError(this.type, this.expression);
486+
}

test/json_serializable_integration_test.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,13 +111,10 @@ void main() {
111111
'objectList',
112112
'intList',
113113
'dateTimeList',
114-
'stopWatch',
115-
'stopwatchList',
116114
'map',
117115
'stringStringMap',
118116
'stringIntMap',
119-
'stringDateTimeMap',
120-
'intDateTimeMap'
117+
'stringDateTimeMap'
121118
];
122119

123120
expect(json.keys, orderedEquals(expectedOrder));

test/json_serializable_test.dart

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,48 @@ void main() {
6363
});
6464
});
6565

66+
group('unserializable types', () {
67+
test('for toJson', () async {
68+
var element = await _getClassForCodeString('NoSerializeFieldType');
69+
70+
expect(
71+
_generator.generate(element, null),
72+
throwsInvalidGenerationSourceError(
73+
'Could not generate `toJson` code for `Stopwatch watch`.',
74+
'Make sure all of the types are serializable.'));
75+
});
76+
77+
test('for fromJson', () async {
78+
var element = await _getClassForCodeString('NoDeserializeFieldType');
79+
80+
expect(
81+
_generator.generate(element, null),
82+
throwsInvalidGenerationSourceError(
83+
'Could not generate fromJson code for `Stopwatch watch`.',
84+
'Make sure all of the types are serializable.'));
85+
});
86+
87+
test('for toJson in Map key', () async {
88+
var element = await _getClassForCodeString('NoSerializeBadKey');
89+
90+
expect(
91+
_generator.generate(element, null),
92+
throwsInvalidGenerationSourceError(
93+
'Could not generate `toJson` code for `Map<int, DateTime> intDateTimeMap`.',
94+
'Make sure all of the types are serializable.'));
95+
});
96+
97+
test('for fromJson', () async {
98+
var element = await _getClassForCodeString('NoDeserializeBadKey');
99+
100+
expect(
101+
_generator.generate(element, null),
102+
throwsInvalidGenerationSourceError(
103+
'Could not generate fromJson code for `Map<int, DateTime> intDateTimeMap`.',
104+
'Make sure all of the types are serializable.'));
105+
});
106+
});
107+
66108
test('class with final fields', () async {
67109
var element = await _getClassForCodeString('FinalFields');
68110
var generateResult = await _generator.generate(element, null);
@@ -234,13 +276,33 @@ class ParentObjectWithDynamicChildren {
234276
235277
@JsonSerializable()
236278
class UnknownCtorParamType {
237-
int number
279+
int number;
238280
239281
UnknownCtorParamType(Bob number) : this.number = number;
240282
}
241283
242284
@JsonSerializable()
243285
class UnknownFieldType {
244-
Bob number
286+
Bob number;
287+
}
288+
289+
@JsonSerializable(createFactory: false)
290+
class NoSerializeFieldType {
291+
Stopwatch watch;
292+
}
293+
294+
@JsonSerializable(createToJson: false)
295+
class NoDeserializeFieldType {
296+
Stopwatch watch;
297+
}
298+
299+
@JsonSerializable(createFactory: false)
300+
class NoSerializeBadKey {
301+
Map<int, DateTime> intDateTimeMap;
302+
}
303+
304+
@JsonSerializable(createToJson: false)
305+
class NoDeserializeBadKey {
306+
Map<int, DateTime> intDateTimeMap;
245307
}
246308
''';

test/test_files/json_test_example.dart

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,20 +53,11 @@ class KitchenSink extends Object with _$KitchenSinkSerializerMixin {
5353
List<int> intList;
5454
List<DateTime> dateTimeList;
5555

56-
/// Intentionally unsafe
57-
Stopwatch stopWatch;
58-
59-
/// Intentionally unsafe
60-
List<Stopwatch> stopwatchList;
61-
6256
Map map;
6357
Map<String, String> stringStringMap;
6458
Map<String, int> stringIntMap;
6559
Map<String, DateTime> stringDateTimeMap;
6660

67-
// Intentionally unsafe key
68-
Map<int, DateTime> intDateTimeMap;
69-
7061
//TODO(kevmoo) - finish this...
7162
bool operator ==(Object other) =>
7263
other is KitchenSink &&

test/test_files/json_test_example.g.dart

Lines changed: 2 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)