Chromium Code Reviews| 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..f0d25586d5f679519d6e3c64c97758c1d057f02c 100644 |
| --- a/lib/src/codegen/js_codegen.dart |
| +++ b/lib/src/codegen/js_codegen.dart |
| @@ -311,33 +311,32 @@ 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)) { |
| + // TODO(jmesserly): explicit check from num to int or double to int? |
|
Leaf
2015/09/18 22:37:49
I think this changes the semantics a little, since
Jennifer Messerly
2015/09/18 22:42:27
I think previously double -> int was a cast. Howev
Jennifer Messerly
2015/09/18 22:44:36
so from a type system perspective, if JSNumber can
Leaf
2015/09/18 22:57:48
I'm not hard set on this, but I'm just a little wo
|
| + |
| 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 +358,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 +2165,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 +3260,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) { |