| Index: lib/src/codegen/js_codegen.dart
|
| diff --git a/lib/src/codegen/js_codegen.dart b/lib/src/codegen/js_codegen.dart
|
| index 6120774b567a2a6f43cc2ce6ba028abaa805e853..2cc5145cd91ef06fcdd65c433cc0d7eb00dab094 100644
|
| --- a/lib/src/codegen/js_codegen.dart
|
| +++ b/lib/src/codegen/js_codegen.dart
|
| @@ -311,33 +311,35 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| var from = getStaticType(node.expression);
|
| var to = node.type.type;
|
|
|
| + var fromExpr = _visit(node.expression);
|
| +
|
| // Skip the cast if it's not needed.
|
| - if (rules.isSubTypeOf(from, to)) return _visit(node.expression);
|
| + if (rules.isSubTypeOf(from, to)) return fromExpr;
|
|
|
| // All Dart number types map to a JS double.
|
| - if (rules.isNumType(from) &&
|
| - (rules.isIntType(to) || rules.isDoubleType(to))) {
|
| - // TODO(jmesserly): a lot of these checks are meaningless, as people use
|
| - // `num` to mean "any kind of number" rather than "could be null".
|
| - // The core libraries especially suffer from this problem, with many of
|
| - // the `num` methods returning `num`.
|
| + if (rules.isNumberInJS(from) && rules.isNumberInJS(to)) {
|
| + // Make sure to check when converting to int.
|
| + if (!rules.isIntType(from) && rules.isIntType(to)) {
|
| + return js.call('dart.asInt(#)', [fromExpr]);
|
| + }
|
| +
|
| if (!rules.isNonNullableType(from) && rules.isNonNullableType(to)) {
|
| // Converting from a nullable number to a non-nullable number
|
| // only requires a null check.
|
| - return js.call('dart.notNull(#)', _visit(node.expression));
|
| + // TODO(jmesserly): a lot of these checks are meaningless, as people use
|
| + // `num` to mean "any kind of number" rather than "could be null".
|
| + // The core libraries especially suffer from this problem, with many of
|
| + // the `num` methods returning `num`.
|
| + return js.call('dart.notNull(#)', fromExpr);
|
| } else {
|
| // A no-op in JavaScript.
|
| - return _visit(node.expression);
|
| + return fromExpr;
|
| }
|
| }
|
|
|
| - return _emitCast(node.expression, to);
|
| + return js.call('dart.as(#, #)', [fromExpr, _emitTypeName(to)]);
|
| }
|
|
|
| - _emitCast(Expression node, DartType type) => js.call('dart.as(#)', [
|
| - [_visit(node), _emitTypeName(type)]
|
| - ]);
|
| -
|
| @override
|
| visitIsExpression(IsExpression node) {
|
| // Generate `is` as `dart.is` or `typeof` depending on the RHS type.
|
| @@ -359,7 +361,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| }
|
|
|
| String _jsTypeofName(DartType t) {
|
| - if (rules.isIntType(t) || rules.isDoubleType(t)) return 'number';
|
| + if (rules.isNumberInJS(t)) return 'number';
|
| if (rules.isStringType(t)) return 'string';
|
| if (rules.isBoolType(t)) return 'boolean';
|
| return null;
|
| @@ -2166,10 +2168,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator {
|
| bool _isJSBuiltinType(DartType t) =>
|
| typeIsPrimitiveInJS(t) || rules.isStringType(t);
|
|
|
| - bool typeIsPrimitiveInJS(DartType t) => rules.isIntType(t) ||
|
| - rules.isDoubleType(t) ||
|
| - rules.isBoolType(t) ||
|
| - rules.isNumType(t);
|
| + bool typeIsPrimitiveInJS(DartType t) =>
|
| + rules.isNumberInJS(t) || rules.isBoolType(t);
|
|
|
| bool typeIsNonNullablePrimitiveInJS(DartType t) =>
|
| typeIsPrimitiveInJS(t) && rules.isNonNullableType(t);
|
| @@ -3263,9 +3263,15 @@ class JSGenerator extends CodeGenerator {
|
| var context = compiler.context;
|
| var src = context.sourceFactory.forUri('dart:_interceptors');
|
| var interceptors = context.computeLibraryElement(src);
|
| - for (var t in ['JSArray', 'JSString', 'JSInt', 'JSDouble', 'JSBool']) {
|
| + for (var t in ['JSArray', 'JSString', 'JSNumber', 'JSBool']) {
|
| _addExtensionType(interceptors.getType(t).type);
|
| }
|
| + // TODO(jmesserly): manually add `int` and `double`
|
| + // Unfortunately our current analyzer rejects "implements int".
|
| + // Fix was landed, so we can remove this hack once we're updated:
|
| + // https://github.com/dart-lang/sdk/commit/d7cd11f86a02f55269fc8d9843e7758ebeeb81c8
|
| + _addExtensionType(context.typeProvider.intType);
|
| + _addExtensionType(context.typeProvider.doubleType);
|
| }
|
|
|
| void _addExtensionType(InterfaceType t) {
|
|
|