Skip to content

Commit dbe976a

Browse files
Make casts to int safe in dart2wasm. (google#1416)
Co-authored-by: Kevin Moore <kevmoo@google.com>
1 parent 1694d6f commit dbe976a

File tree

51 files changed

+551
-423
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+551
-423
lines changed

_test_yaml/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ dev_dependencies:
1111
build_verify: ^3.0.0
1212
checked_yaml: any
1313
dart_flutter_team_lints: ^2.0.0
14-
json_annotation: ^4.7.0
14+
json_annotation: ^4.8.1
1515
json_serializable: any
1616
path: ^1.8.2
1717
test: ^1.6.0

_test_yaml/test/src/build_config.g.dart

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

example/lib/example.g.dart

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

example/lib/generic_response_class_example.g.dart

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

example/lib/json_converter_example.g.dart

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

example/lib/tuple_example.g.dart

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

json_annotation/lib/src/json_serializable.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class JsonSerializable {
181181
/// T Function(Object json) fromJsonT,
182182
/// ) {
183183
/// return Response<T>()
184-
/// ..status = json['status'] as int
184+
/// ..status = (json['status'] as num).toInt()
185185
/// ..value = fromJsonT(json['value']);
186186
/// }
187187
///

json_serializable/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
## 6.8.0-wip
22

33
- Add type arguments to `Map` literals used for `Record` serialization.
4-
- Added support for generating `ExampleJsonKeys`, exposing a secured way to access the json keys from the properties.
4+
- Added support for generating `ExampleJsonKeys`, exposing a secured way to
5+
access the json keys from the properties.
56
([#1164](https://github.com/google/json_serializable.dart/pull/1164))
7+
- Handle decoding an `int` value from a `double` literal.
8+
This now matches the behavior of `double` values being encoded as `int`.
69

710
## 6.7.1
811

json_serializable/lib/src/lambda_result.dart

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ class LambdaResult {
2020
final String lambda;
2121
final DartType? asContent;
2222

23-
String get _asContent => asContent == null ? '' : _asStatement(asContent!);
24-
25-
String get _fullExpression => '$expression$_asContent';
23+
String get _fullExpression =>
24+
asContent != null ? _cast(expression, asContent!) : expression;
2625

2726
LambdaResult(this.expression, this.lambda, {this.asContent});
2827

@@ -35,29 +34,35 @@ class LambdaResult {
3534
: '($closureArg) => $subField';
3635
}
3736

38-
String _asStatement(DartType type) {
39-
if (type.isLikeDynamic) {
40-
return '';
37+
String _cast(String expression, DartType targetType) {
38+
if (targetType.isLikeDynamic) {
39+
return expression;
4140
}
4241

43-
final nullableSuffix = type.isNullableType ? '?' : '';
42+
final nullableSuffix = targetType.isNullableType ? '?' : '';
4443

45-
if (coreIterableTypeChecker.isAssignableFromType(type)) {
46-
final itemType = coreIterableGenericType(type);
44+
if (coreIterableTypeChecker.isAssignableFromType(targetType)) {
45+
final itemType = coreIterableGenericType(targetType);
4746
if (itemType.isLikeDynamic) {
48-
return ' as List$nullableSuffix';
47+
return '$expression as List$nullableSuffix';
4948
}
5049
}
5150

52-
if (coreMapTypeChecker.isAssignableFromType(type)) {
53-
final args = type.typeArgumentsOf(coreMapTypeChecker)!;
51+
if (coreMapTypeChecker.isAssignableFromType(targetType)) {
52+
final args = targetType.typeArgumentsOf(coreMapTypeChecker)!;
5453
assert(args.length == 2);
5554

5655
if (args.every((e) => e.isLikeDynamic)) {
57-
return ' as Map$nullableSuffix';
56+
return '$expression as Map$nullableSuffix';
5857
}
5958
}
6059

61-
final typeCode = typeToCode(type);
62-
return ' as $typeCode';
60+
final defaultDecodeValue = defaultDecodeLogic(targetType, expression);
61+
62+
if (defaultDecodeValue != null) {
63+
return defaultDecodeValue;
64+
}
65+
66+
final typeCode = typeToCode(targetType);
67+
return '$expression as $typeCode';
6368
}

json_serializable/lib/src/type_helpers/duration_helper.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class DurationHelper extends TypeHelper {
4646

4747
return DefaultContainer(
4848
expression,
49-
'Duration(microseconds: $expression as int)',
49+
'Duration(microseconds: ($expression as num).toInt())',
5050
);
5151
}
5252
}

json_serializable/lib/src/type_helpers/value_helper.dart

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:analyzer/dart/element/type.dart';
6-
import 'package:source_helper/source_helper.dart';
76

87
import '../shared_checkers.dart';
98
import '../type_helper.dart';
@@ -35,22 +34,7 @@ class ValueHelper extends TypeHelper {
3534
String expression,
3635
TypeHelperContext context,
3736
bool defaultProvided,
38-
) {
39-
if (targetType.isDartCoreObject && !targetType.isNullableType) {
40-
final question = defaultProvided ? '?' : '';
41-
return '$expression as Object$question';
42-
} else if (targetType.isDartCoreObject || targetType is DynamicType) {
43-
// just return it as-is. We'll hope it's safe.
44-
return expression;
45-
} else if (targetType.isDartCoreDouble) {
46-
final targetTypeNullable = defaultProvided || targetType.isNullableType;
47-
final question = targetTypeNullable ? '?' : '';
48-
return '($expression as num$question)$question.toDouble()';
49-
} else if (simpleJsonTypeChecker.isAssignableFromType(targetType)) {
50-
final typeCode = typeToCode(targetType, forceNullable: defaultProvided);
51-
return '$expression as $typeCode';
52-
}
53-
54-
return null;
55-
}
37+
) =>
38+
defaultDecodeLogic(targetType, expression,
39+
defaultProvided: defaultProvided);
5640
}

json_serializable/lib/src/utils.dart

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:json_annotation/json_annotation.dart';
99
import 'package:source_gen/source_gen.dart';
1010
import 'package:source_helper/source_helper.dart';
1111

12+
import 'shared_checkers.dart';
1213
import 'type_helpers/config_types.dart';
1314

1415
const _jsonKeyChecker = TypeChecker.fromRuntime(JsonKey);
@@ -220,6 +221,33 @@ String typeToCode(
220221
throw UnimplementedError('(${type.runtimeType}) $type');
221222
}
222223

224+
String? defaultDecodeLogic(
225+
DartType targetType,
226+
String expression, {
227+
bool defaultProvided = false,
228+
}) {
229+
if (targetType.isDartCoreObject && !targetType.isNullableType) {
230+
final question = defaultProvided ? '?' : '';
231+
return '$expression as Object$question';
232+
} else if (targetType.isDartCoreObject || targetType is DynamicType) {
233+
// just return it as-is. We'll hope it's safe.
234+
return expression;
235+
} else if (targetType.isDartCoreDouble) {
236+
final targetTypeNullable = defaultProvided || targetType.isNullableType;
237+
final question = targetTypeNullable ? '?' : '';
238+
return '($expression as num$question)$question.toDouble()';
239+
} else if (targetType.isDartCoreInt) {
240+
final targetTypeNullable = defaultProvided || targetType.isNullableType;
241+
final question = targetTypeNullable ? '?' : '';
242+
return '($expression as num$question)$question.toInt()';
243+
} else if (simpleJsonTypeChecker.isAssignableFromType(targetType)) {
244+
final typeCode = typeToCode(targetType, forceNullable: defaultProvided);
245+
return '$expression as $typeCode';
246+
}
247+
248+
return null;
249+
}
250+
223251
extension ExecutableElementExtension on ExecutableElement {
224252
/// Returns the name of `this` qualified with the class name if it's a
225253
/// [MethodElement].

json_serializable/test/default_value/default_value.g.dart

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

json_serializable/test/default_value/default_value.g_any_map__checked.g.dart

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

0 commit comments

Comments
 (0)