Chromium Code Reviews| Index: tool/input_sdk/private/js_number.dart |
| diff --git a/tool/input_sdk/private/js_number.dart b/tool/input_sdk/private/js_number.dart |
| index ced02db358b9ef666af8bdb1d48b3668134a56b8..b30bd0997a923afbe99368e79d8c104c6681363b 100644 |
| --- a/tool/input_sdk/private/js_number.dart |
| +++ b/tool/input_sdk/private/js_number.dart |
| @@ -5,15 +5,11 @@ |
| part of dart._interceptors; |
| /** |
| - * The super interceptor class for [JSInt] and [JSDouble]. The compiler |
| - * recognizes this class as an interceptor, and changes references to |
| - * [:this:] to actually use the receiver of the method, which is |
| - * generated as an extra argument added to each member. |
| - * |
| - * Note that none of the methods here delegate to a method defined on JSInt or |
| - * JSDouble. This is exploited in [tryComputeConstantInterceptor]. |
| + * The implementation of Dart's int & double methods. |
| + * These are made available as extension methods on `Number` in JS. |
| */ |
| -class JSNumber extends Interceptor implements num { |
| +@JsPeerInterface(name: 'Number') |
| +class JSNumber extends Interceptor implements int, double { |
| const JSNumber(); |
| int compareTo(num b) { |
| @@ -51,15 +47,15 @@ class JSNumber extends Interceptor implements num { |
| bool get isFinite => JS('bool', r'isFinite(#)', this); |
| - num remainder(num b) { |
| + JSNumber remainder(num b) { |
| checkNull(b); // TODO(ngeoffray): This is not specified but co19 tests it. |
| if (b is! num) throw new ArgumentError(b); |
| return JS('num', r'# % #', this, b); |
| } |
| - num abs() => JS('num', r'Math.abs(#)', this); |
| + JSNumber abs() => JS('num', r'Math.abs(#)', this); |
| - num get sign => this > 0 ? 1 : this < 0 ? -1 : this; |
| + JSNumber get sign => this > 0 ? 1 : this < 0 ? -1 : this; |
| static const int _MIN_INT32 = -0x80000000; |
| static const int _MAX_INT32 = 0x7FFFFFFF; |
| @@ -105,9 +101,7 @@ class JSNumber extends Interceptor implements num { |
| return this; |
| } |
| - // The return type is intentionally omitted to avoid type checker warnings |
| - // from assigning JSNumber to double. |
| - toDouble() => this; |
| + double toDouble() => this; |
| String toStringAsFixed(int fractionDigits) { |
| checkInt(fractionDigits); |
| @@ -186,14 +180,14 @@ class JSNumber extends Interceptor implements num { |
| int get hashCode => JS('int', '# & 0x1FFFFFFF', this); |
| - num operator -() => JS('num', r'-#', this); |
| + JSNumber operator -() => JS('num', r'-#', this); |
| - num operator +(num other) { |
| + JSNumber operator +(num other) { |
| if (other is !num) throw new ArgumentError(other); |
| return JS('num', '# + #', this, other); |
| } |
| - num operator -(num other) { |
| + JSNumber operator -(num other) { |
| if (other is !num) throw new ArgumentError(other); |
| return JS('num', '# - #', this, other); |
| } |
| @@ -203,16 +197,16 @@ class JSNumber extends Interceptor implements num { |
| return JS('double', '# / #', this, other); |
| } |
| - num operator *(num other) { |
| + JSNumber operator *(num other) { |
| if (other is !num) throw new ArgumentError(other); |
| return JS('num', '# * #', this, other); |
| } |
| - num operator %(num other) { |
| + JSNumber operator %(num other) { |
| if (other is !num) throw new ArgumentError(other); |
| // Euclidean Modulo. |
| num result = JS('num', r'# % #', this, other); |
| - if (result == 0) return 0; // Make sure we don't return -0.0. |
| + if (result == 0) return (0 as JSNumber); // Make sure we don't return -0.0. |
| if (result > 0) return result; |
| if (JS('num', '#', other) < 0) { |
| return result - JS('num', '#', other); |
| @@ -248,43 +242,44 @@ class JSNumber extends Interceptor implements num { |
| // we define these methods on number for now but we need to decide |
| // the grain at which we do the type checks. |
| - num operator <<(num other) { |
| + int operator <<(num other) { |
| if (other is !num) throw new ArgumentError(other); |
|
Leaf
2015/09/18 22:37:49
I don't know how much we want to assume DDC strong
Jennifer Messerly
2015/09/18 22:42:27
ah, good point. Interesting that isn't a hint (dea
Jennifer Messerly
2015/09/18 23:53:06
fixed kind of ... we still need the null checks th
|
| if (JS('num', '#', other) < 0) throw new ArgumentError(other); |
| return _shlPositive(other); |
| } |
| - num _shlPositive(num other) { |
| + int _shlPositive(num other) { |
| // JavaScript only looks at the last 5 bits of the shift-amount. Shifting |
| // by 33 is hence equivalent to a shift by 1. |
| return JS('bool', r'# > 31', other) |
| ? 0 |
| - : JS('JSUInt32', r'(# << #) >>> 0', this, other); |
| + : JS('int', r'(# << #) >>> 0', this, other); |
| } |
| - num operator >>(num other) { |
| + int operator >>(num other) { |
| + // TODO(jmesserly): what's this from? Delete? |
| if (false) _shrReceiverPositive(other); |
| if (other is !num) throw new ArgumentError(other); |
| if (JS('num', '#', other) < 0) throw new ArgumentError(other); |
| return _shrOtherPositive(other); |
| } |
| - num _shrOtherPositive(num other) { |
| + int _shrOtherPositive(num other) { |
| return JS('num', '#', this) > 0 |
| ? _shrBothPositive(other) |
| // For negative numbers we just clamp the shift-by amount. |
| // `this` could be negative but not have its 31st bit set. |
| // The ">>" would then shift in 0s instead of 1s. Therefore |
| // we cannot simply return 0xFFFFFFFF. |
| - : JS('JSUInt32', r'(# >> #) >>> 0', this, other > 31 ? 31 : other); |
| + : JS('int', r'(# >> #) >>> 0', this, other > 31 ? 31 : other); |
| } |
| - num _shrReceiverPositive(num other) { |
| + int _shrReceiverPositive(num other) { |
| if (JS('num', '#', other) < 0) throw new ArgumentError(other); |
| return _shrBothPositive(other); |
| } |
| - num _shrBothPositive(num other) { |
| + int _shrBothPositive(num other) { |
| return JS('bool', r'# > 31', other) |
| // JavaScript only looks at the last 5 bits of the shift-amount. In JS |
| // shifting by 33 is hence equivalent to a shift by 1. Shortcut the |
| @@ -293,22 +288,22 @@ class JSNumber extends Interceptor implements num { |
| // Given that `this` is positive we must not use '>>'. Otherwise a |
| // number that has the 31st bit set would be treated as negative and |
| // shift in ones. |
| - : JS('JSUInt32', r'# >>> #', this, other); |
| + : JS('int', r'# >>> #', this, other); |
| } |
| - num operator &(num other) { |
| + int operator &(num other) { |
| if (other is !num) throw new ArgumentError(other); |
| - return JS('JSUInt32', r'(# & #) >>> 0', this, other); |
| + return JS('int', r'(# & #) >>> 0', this, other); |
| } |
| - num operator |(num other) { |
| + int operator |(num other) { |
| if (other is !num) throw new ArgumentError(other); |
| - return JS('JSUInt32', r'(# | #) >>> 0', this, other); |
| + return JS('int', r'(# | #) >>> 0', this, other); |
| } |
| - num operator ^(num other) { |
| + int operator ^(num other) { |
| if (other is !num) throw new ArgumentError(other); |
| - return JS('JSUInt32', r'(# ^ #) >>> 0', this, other); |
| + return JS('int', r'(# ^ #) >>> 0', this, other); |
| } |
| bool operator <(num other) { |
| @@ -331,23 +326,10 @@ class JSNumber extends Interceptor implements num { |
| return JS('bool', '# >= #', this, other); |
| } |
| - Type get runtimeType => num; |
| -} |
| - |
| -/** |
| - * The interceptor class for [int]s. |
| - * |
| - * This class implements double since in JavaScript all numbers are doubles, so |
| - * while we want to treat `2.0` as an integer for some operations, its |
| - * interceptor should answer `true` to `is double`. |
| - */ |
| -// TODO(jmesserly): for dev_compiler all numbers will get `int` members at |
| -// runtime for dynamic dispatch. We can fix by checking it at dispatch time. |
| -// TODO(jmesserly): merge with JSNumber? That would simplify generated code, |
| -// and dart_runtime's extension mechanism. |
| -@JsPeerInterface(name: 'Number') |
| -class JSInt extends JSNumber implements int, double { |
| - const JSInt(); |
| + // int members. |
| + // TODO(jmesserly): all numbers will have these in dynamic dispatch. |
| + // We can fix by checking it at dispatch time but we'd need to structure them |
| + // differently. |
| bool get isEven => (this & 1) == 0; |
| @@ -412,16 +394,5 @@ class JSInt extends JSNumber implements int, double { |
| return i; |
| } |
| - Type get runtimeType => int; |
| - |
| - int operator ~() => JS('JSUInt32', r'(~#) >>> 0', this); |
| + int operator ~() => JS('int', r'(~#) >>> 0', this); |
| } |
| - |
| -class JSDouble extends JSNumber implements double { |
| - const JSDouble(); |
| - Type get runtimeType => double; |
| -} |
| - |
| -class JSPositiveInt extends JSInt {} |
| -class JSUInt32 extends JSPositiveInt {} |
| -class JSUInt31 extends JSUInt32 {} |