| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 library _foreign_helper; | 5 library _foreign_helper; |
| 6 | 6 |
| 7 import 'dart:_js_embedded_names' show JsGetName; | 7 import 'dart:_js_embedded_names' show JsGetName; |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * Emits a JavaScript code fragment parameterized by arguments. | 10 * Emits a JavaScript code fragment parameterized by arguments. |
| 11 * | 11 * |
| 12 * Hash characters `#` in the [codeTemplate] are replaced in left-to-right order | 12 * Hash characters `#` in the [codeTemplate] are replaced in left-to-right order |
| 13 * with expressions that contain the values of, or evaluate to, the arguments. | 13 * with expressions that contain the values of, or evaluate to, the arguments. |
| 14 * The number of hash marks must match the number or arguments. Although | 14 * The number of hash marks must match the number or arguments. Although |
| 15 * declared with arguments [arg0] through [arg2], the form actually has no limit | 15 * declared with arguments [arg0] through [arg2], the form actually has no limit |
| 16 * on the number of arguments. | 16 * on the number of arguments. |
| 17 * | 17 * |
| 18 * The [typeDescription] argument is interpreted as a description of the | 18 * The [typeDescription] argument is interpreted as a description of the |
| 19 * behavior of the JavaScript code. Currently it describes the types that may | 19 * behavior of the JavaScript code. Currently it describes the side effects |
| 20 * be returned by the expression, with the additional behavior that the returned | 20 * types that may be returned by the expression, with the additional behavior |
| 21 * values may be fresh instances of the types. The type information must be | 21 * that the returned values may be fresh instances of the types. The type |
| 22 * correct as it is trusted by the compiler in optimizations, and it must be | 22 * information must be correct as it is trusted by the compiler in |
| 23 * precise as possible since it is used for native live type analysis to | 23 * optimizations, and it must be precise as possible since it is used for native |
| 24 * tree-shake large parts of the DOM libraries. If poorly written, the | 24 * live type analysis to tree-shake large parts of the DOM libraries. If poorly |
| 25 * [typeDescription] will cause unnecessarily bloated programs. (You can check | 25 * written, the [typeDescription] will cause unnecessarily bloated programs. |
| 26 * for this by compiling with `--verbose`; there is an info message describing | 26 * (You can check for this by compiling with `--verbose`; there is an info |
| 27 * the number of native (DOM) types that can be removed, which usually should be | 27 * message describing the number of native (DOM) types that can be removed, |
| 28 * greater than zero.) | 28 * which usually should be greater than zero.) |
| 29 * | 29 * |
| 30 * The [typeDescription] is a [String] which contains a union of types separated | 30 * The [typeDescription] must be a [String]. Two forms of it are supported: |
| 31 * by vertical bar `|` symbols, e.g. `"num|String"` describes the union of | |
| 32 * numbers and Strings. There is no type in Dart that is this precise. The | |
| 33 * Dart alternative would be `Object` or `dynamic`, but these types imply that | |
| 34 * the JS-code might also be creating instances of all the DOM types. If `null` | |
| 35 * is possible, it must be specified explicitly, e.g. `"String|Null"`. | |
| 36 * [typeDescription] has several extensions to help describe the behavior more | |
| 37 * accurately. In addition to the union type already described: | |
| 38 * | 31 * |
| 39 * + `=Object` is a plain JavaScript object. Some DOM methods return instances | 32 * 1) a union of types separated by vertical bar `|` symbols, e.g. |
| 40 * that have no corresponing Dart type (e.g. cross-frame documents), | 33 * `"num|String"` describes the union of numbers and Strings. There is no |
| 41 * `=Object` can be used to describe these untyped' values. | 34 * type in Dart that is this precise. The Dart alternative would be `Object` |
| 35 * or `dynamic`, but these types imply that the JS-code might also be |
| 36 * creating instances of all the DOM types. |
| 42 * | 37 * |
| 43 * + `var` (or empty string). If the entire [typeDescription] is `var` (or | 38 * If `null` is possible, it must be specified explicitly, e.g. |
| 44 * empty string) then the type is `dynamic` but the code is known to not | 39 * `"String|Null"`. [typeDescription] has several extensions to help describe |
| 45 * create any instances. | 40 * the behavior more accurately. In addition to the union type already |
| 41 * described: |
| 46 * | 42 * |
| 47 * Examples: | 43 * + `=Object` is a plain JavaScript object. Some DOM methods return |
| 44 * instances that have no corresponing Dart type (e.g. cross-frame |
| 45 * documents), `=Object` can be used to describe these untyped' values. |
| 48 * | 46 * |
| 49 * // Parent window might be an opaque cross-frame window. | 47 * + `var` (or empty string). If the entire [typeDescription] is `var` (or |
| 50 * var thing = JS('=Object|Window', '#.parent', myWindow); | 48 * empty string) then the type is `dynamic` but the code is known to not |
| 49 * create any instances. |
| 50 * |
| 51 * Examples: |
| 52 * |
| 53 * // Parent window might be an opaque cross-frame window. |
| 54 * var thing = JS('=Object|Window', '#.parent', myWindow); |
| 55 * |
| 56 * 2) a sequence of the form `<tag>:<value>;` where `<tag>` is one of |
| 57 * `creates`, `returns`, `effects` or `depends`. |
| 58 * |
| 59 * The first two tags are used to specify the created and returned types of |
| 60 * the expression. The value of `creates` and `returns` is a type string as |
| 61 * defined in 1). |
| 62 * |
| 63 * The tags `effects` and `depends` encode the side effects of this call. |
| 64 * They can be omitted, in which case the expression is parsed and a safe |
| 65 * conservative side-effect estimation is computed. |
| 66 * |
| 67 * The values of `effects` and `depends` may be 'all', 'none' or a |
| 68 * comma-separated list of 'no-index', 'no-instance' and 'no-static'. |
| 69 * |
| 70 * The value 'all' indicates that the call affects/depends on every |
| 71 * side-effect. The flag 'none' signals that the call does not affect |
| 72 * (resp. depends on) anything. |
| 73 * |
| 74 * The value 'no-index' indicates that the call does *not* do (resp. depends |
| 75 * on) any array index-store. The flag 'no-instance' indicates that the call |
| 76 * does not modify (resp. depends on) any instance variable. Similarly, |
| 77 * the 'no-static' value indicates that the call does not modify (resp. |
| 78 * depends on) any static variable. |
| 79 * |
| 80 * The `effects` and `depends` flag must be used in tandem. Either both are |
| 81 * specified or none is. |
| 82 * |
| 83 * Each tag (including the type tags) may only occur once in the sequence. |
| 51 * | 84 * |
| 52 * Guidelines: | 85 * Guidelines: |
| 53 * | 86 * |
| 54 * + Do not use any parameter, local, method or field names in the | 87 * + Do not use any parameter, local, method or field names in the |
| 55 * [codeTemplate]. These names are all subject to arbitrary renaming by the | 88 * [codeTemplate]. These names are all subject to arbitrary renaming by the |
| 56 * compiler. Pass the values in via `#` substition, and test with the | 89 * compiler. Pass the values in via `#` substition, and test with the |
| 57 * `--minify` dart2js command-line option. | 90 * `--minify` dart2js command-line option. |
| 58 * | 91 * |
| 59 * + The substituted expressions are values, not locations. | 92 * + The substituted expressions are values, not locations. |
| 60 * | 93 * |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 * '(function(val) { return function(){return val}; })(#)', value); | 128 * '(function(val) { return function(){return val}; })(#)', value); |
| 96 * | 129 * |
| 97 * Since `#` occurs in the immediately evaluated expression, the expression | 130 * Since `#` occurs in the immediately evaluated expression, the expression |
| 98 * is immediately evaluated and bound to `val` in the immediate call. | 131 * is immediately evaluated and bound to `val` in the immediate call. |
| 99 * | 132 * |
| 100 * | 133 * |
| 101 * Additional notes. | 134 * Additional notes. |
| 102 * | 135 * |
| 103 * In the future we may extend [typeDescription] to include other aspects of the | 136 * In the future we may extend [typeDescription] to include other aspects of the |
| 104 * behavior, for example, separating the returned types from the instantiated | 137 * behavior, for example, separating the returned types from the instantiated |
| 105 * types, or including effects to allow the compiler to perform more | 138 * types to allow the compiler to perform more optimizations around the code. |
| 106 * optimizations around the code. This might be an extension of [JS] or a new | 139 * |
| 107 * function similar to [JS] with additional arguments for the new information. | 140 * This might be an extension of [JS] or a new function similar to [JS] with |
| 141 * additional arguments for the new information. |
| 108 */ | 142 */ |
| 109 // Add additional optional arguments if needed. The method is treated internally | 143 // Add additional optional arguments if needed. The method is treated internally |
| 110 // as a variable argument method. | 144 // as a variable argument method. |
| 111 JS(String typeDescription, String codeTemplate, | 145 JS(String typeDescription, String codeTemplate, |
| 112 [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11]) | 146 [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11]) |
| 113 {} | 147 {} |
| 114 | 148 |
| 115 /** | 149 /** |
| 116 * Returns the isolate in which this code is running. | 150 * Returns the isolate in which this code is running. |
| 117 */ | 151 */ |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 } | 318 } |
| 285 | 319 |
| 286 /** | 320 /** |
| 287 * JavaScript string concatenation. Inputs must be Strings. Corresponds to the | 321 * JavaScript string concatenation. Inputs must be Strings. Corresponds to the |
| 288 * HStringConcat SSA instruction and may be constant-folded. | 322 * HStringConcat SSA instruction and may be constant-folded. |
| 289 */ | 323 */ |
| 290 String JS_STRING_CONCAT(String a, String b) { | 324 String JS_STRING_CONCAT(String a, String b) { |
| 291 // This body is unused, only here for type analysis. | 325 // This body is unused, only here for type analysis. |
| 292 return JS('String', '# + #', a, b); | 326 return JS('String', '# + #', a, b); |
| 293 } | 327 } |
| OLD | NEW |