| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Generates JS helpers for dart:core. This used to be in a file "core.js". | 6 * Generates JS helpers for dart:core. This used to be in a file "core.js". |
| 7 * Having them in Dart code means we can easily control which are generated. | 7 * Having them in Dart code means we can easily control which are generated. |
| 8 */ | 8 */ |
| 9 // TODO(jmesserly): one idea to make this cleaner: put these as private "native" | 9 // TODO(jmesserly): one idea to make this cleaner: put these as private "native" |
| 10 // methods somewhere in a library that we import. This would be rather elegant | 10 // methods somewhere in a library that we import. This would be rather elegant |
| 11 // because they'd get the right name collision behavior, conversions, | 11 // because they'd get the right name collision behavior, conversions, |
| 12 // include-if-used, etc for free. Not sure if it's worth doing that. | 12 // include-if-used, etc for free. Not sure if it's worth doing that. |
| 13 class CoreJs { | 13 class CoreJs { |
| 14 // These values track if the helper is actually used. If it is we generate it. | 14 // These values track if the helper is actually used. If it is we generate it. |
| 15 bool useThrow = false; | 15 bool useThrow = false; |
| 16 bool useNotNullBool = false; | 16 bool useNotNullBool = false; |
| 17 bool useIndex = false; | 17 bool useIndex = false; |
| 18 bool useSetIndex = false; | 18 bool useSetIndex = false; |
| 19 | 19 |
| 20 bool useWrap0 = false; | 20 bool useWrap0 = false; |
| 21 bool useWrap1 = false; | 21 bool useWrap1 = false; |
| 22 bool useWrap2 = false; |
| 22 bool useIsolates = false; | 23 bool useIsolates = false; |
| 23 | 24 |
| 24 // These helpers had to switch to a new pattern, because they can be generated | 25 // These helpers had to switch to a new pattern, because they can be generated |
| 25 // after everything else. | 26 // after everything else. |
| 26 bool _generatedTypeNameOf = false; | 27 bool _generatedTypeNameOf = false; |
| 27 bool _generatedDynamicProto = false; | 28 bool _generatedDynamicProto = false; |
| 28 bool _generatedDynamicSetMetadata = false; | 29 bool _generatedDynamicSetMetadata = false; |
| 29 bool _generatedInherits = false; | 30 bool _generatedInherits = false; |
| 30 bool _generatedDefProp = false; | 31 bool _generatedDefProp = false; |
| 31 bool _generatedBind = false; | 32 bool _generatedBind = false; |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 173 } | 174 } |
| 174 | 175 |
| 175 if (useSetIndex) { | 176 if (useSetIndex) { |
| 176 markCorelibTypeUsed('NoSuchMethodException'); | 177 markCorelibTypeUsed('NoSuchMethodException'); |
| 177 ensureDefProp(); | 178 ensureDefProp(); |
| 178 _emit(options.disableBoundsChecks ? | 179 _emit(options.disableBoundsChecks ? |
| 179 _SETINDEX_OPERATORS : _CHECKED_SETINDEX_OPERATORS); | 180 _SETINDEX_OPERATORS : _CHECKED_SETINDEX_OPERATORS); |
| 180 } | 181 } |
| 181 | 182 |
| 182 if (!useIsolates) { | 183 if (!useIsolates) { |
| 183 if (useWrap0) { | 184 if (useWrap0) _emit(_EMPTY_WRAP_CALL0_FUNCTION); |
| 184 _emit(_EMPTY_WRAP_CALL0_FUNCTION); | 185 if (useWrap1) _emit(_EMPTY_WRAP_CALL1_FUNCTION); |
| 185 } | 186 if (useWrap2) _emit(_EMPTY_WRAP_CALL2_FUNCTION); |
| 186 if (useWrap1) { | |
| 187 _emit(_EMPTY_WRAP_CALL1_FUNCTION); | |
| 188 } | |
| 189 } | 187 } |
| 190 | 188 |
| 191 // Write operator helpers | 189 // Write operator helpers |
| 192 for (var opImpl in orderValuesByKeys(_usedOperators)) { | 190 for (var opImpl in orderValuesByKeys(_usedOperators)) { |
| 193 _emit(opImpl); | 191 _emit(opImpl); |
| 194 } | 192 } |
| 195 | 193 |
| 196 if (world.dom != null) { | 194 if (world.dom != null || world.html != null) { |
| 197 ensureTypeNameOf(); | 195 ensureTypeNameOf(); |
| 198 ensureDefProp(); | 196 ensureDefProp(); |
| 199 // TODO(jmesserly): we need to find a way to avoid conflicts with other | 197 // TODO(jmesserly): we need to find a way to avoid conflicts with other |
| 200 // generated "typeName" fields. Ideally we wouldn't be patching 'Object' | 198 // generated "typeName" fields. Ideally we wouldn't be patching 'Object' |
| 201 // here. | 199 // here. |
| 202 _emit('\$defProp(Object.prototype, "get\$typeName", ' | 200 _emit('\$defProp(Object.prototype, "get\$typeName", ' |
| 203 'Object.prototype.\$typeNameOf);'); | 201 'Object.prototype.\$typeNameOf);'); |
| 204 } | 202 } |
| 205 } | 203 } |
| 206 } | 204 } |
| (...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 /** Snippet for `$wrap_call$0`, in case it was not necessary. */ | 599 /** Snippet for `$wrap_call$0`, in case it was not necessary. */ |
| 602 final String _EMPTY_WRAP_CALL0_FUNCTION = @""" | 600 final String _EMPTY_WRAP_CALL0_FUNCTION = @""" |
| 603 function $wrap_call$0(fn) { return fn; } | 601 function $wrap_call$0(fn) { return fn; } |
| 604 """; | 602 """; |
| 605 | 603 |
| 606 /** Snippet for `$wrap_call$1`, in case it was not necessary. */ | 604 /** Snippet for `$wrap_call$1`, in case it was not necessary. */ |
| 607 final String _EMPTY_WRAP_CALL1_FUNCTION = @""" | 605 final String _EMPTY_WRAP_CALL1_FUNCTION = @""" |
| 608 function $wrap_call$1(fn) { return fn; }; | 606 function $wrap_call$1(fn) { return fn; }; |
| 609 """; | 607 """; |
| 610 | 608 |
| 609 /** Snippet for `$wrap_call$2`, in case it was not necessary. */ |
| 610 final String _EMPTY_WRAP_CALL2_FUNCTION = @""" |
| 611 function $wrap_call$2(fn) { return fn; }; |
| 612 """; |
| 613 |
| 611 /** Snippet that initializes Function.prototype.bind. */ | 614 /** Snippet that initializes Function.prototype.bind. */ |
| 612 final String _BIND_CODE = @""" | 615 final String _BIND_CODE = @""" |
| 613 Function.prototype.bind = Function.prototype.bind || | 616 Function.prototype.bind = Function.prototype.bind || |
| 614 function(thisObj) { | 617 function(thisObj) { |
| 615 var func = this; | 618 var func = this; |
| 616 var funcLength = func.$length || func.length; | 619 var funcLength = func.$length || func.length; |
| 617 var argsLength = arguments.length; | 620 var argsLength = arguments.length; |
| 618 if (argsLength > 1) { | 621 if (argsLength > 1) { |
| 619 var boundArgs = Array.prototype.slice.call(arguments, 1); | 622 var boundArgs = Array.prototype.slice.call(arguments, 1); |
| 620 var bound = function() { | 623 var bound = function() { |
| 621 // Prepend the bound arguments to the current arguments. | 624 // Prepend the bound arguments to the current arguments. |
| 622 var newArgs = Array.prototype.slice.call(arguments); | 625 var newArgs = Array.prototype.slice.call(arguments); |
| 623 Array.prototype.unshift.apply(newArgs, boundArgs); | 626 Array.prototype.unshift.apply(newArgs, boundArgs); |
| 624 return func.apply(thisObj, newArgs); | 627 return func.apply(thisObj, newArgs); |
| 625 }; | 628 }; |
| 626 bound.$length = Math.max(0, funcLength - (argsLength - 1)); | 629 bound.$length = Math.max(0, funcLength - (argsLength - 1)); |
| 627 return bound; | 630 return bound; |
| 628 } else { | 631 } else { |
| 629 var bound = function() { | 632 var bound = function() { |
| 630 return func.apply(thisObj, arguments); | 633 return func.apply(thisObj, arguments); |
| 631 }; | 634 }; |
| 632 bound.$length = funcLength; | 635 bound.$length = funcLength; |
| 633 return bound; | 636 return bound; |
| 634 } | 637 } |
| 635 }; | 638 }; |
| 636 """; | 639 """; |
| OLD | NEW |