Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1480)

Side by Side Diff: sdk/lib/_internal/compiler/js_lib/foreign_helper.dart

Issue 1212513002: sdk files reorganization to make dart2js a proper package (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: renamed Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library _foreign_helper;
6
7 import 'dart:_js_embedded_names' show JsGetName, JsBuiltin;
8
9 /**
10 * Emits a JavaScript code fragment parameterized by arguments.
11 *
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.
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
16 * on the number of arguments.
17 *
18 * The [typeDescription] argument is interpreted as a description of the
19 * behavior of the JavaScript code. Currently it describes the side effects
20 * types that may be returned by the expression, with the additional behavior
21 * that the returned values may be fresh instances of the types. The type
22 * information must be correct as it is trusted by the compiler in
23 * optimizations, and it must be precise as possible since it is used for native
24 * live type analysis to tree-shake large parts of the DOM libraries. If poorly
25 * written, the [typeDescription] will cause unnecessarily bloated programs.
26 * (You can check for this by compiling with `--verbose`; there is an info
27 * message describing the number of native (DOM) types that can be removed,
28 * which usually should be greater than zero.)
29 *
30 * The [typeDescription] must be a [String]. Two forms of it are supported:
31 *
32 * 1) a union of types separated by vertical bar `|` symbols, e.g.
33 * `"num|String"` describes the union of numbers and Strings. There is no
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.
37 *
38 * If `null` is possible, it must be specified explicitly, e.g.
39 * `"String|Null"`. [typeDescription] has several extensions to help describe
40 * the behavior more accurately. In addition to the union type already
41 * described:
42 *
43 * + `=Object` is a plain JavaScript object. Some DOM methods return
44 * instances that have no corresponding Dart type (e.g. cross-frame
45 * documents), `=Object` can be used to describe these untyped' values.
46 *
47 * + `var` (or empty string). If the entire [typeDescription] is `var` (or
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.
84 *
85 * Guidelines:
86 *
87 * + Do not use any parameter, local, method or field names in the
88 * [codeTemplate]. These names are all subject to arbitrary renaming by the
89 * compiler. Pass the values in via `#` substition, and test with the
90 * `--minify` dart2js command-line option.
91 *
92 * + The substituted expressions are values, not locations.
93 *
94 * JS('void', '# += "x"', this.field);
95 *
96 * `this.field` might not be a substituted as a reference to the field. The
97 * generated code might accidentally work as intended, but it also might be
98 *
99 * var t1 = this.field;
100 * t1 += "x";
101 *
102 * or
103 *
104 * this.get$field() += "x";
105 *
106 * The remedy in this case is to expand the `+=` operator, leaving all
107 * references to the Dart field as Dart code:
108 *
109 * this.field = JS('String', '# + "x"', this.field);
110 *
111 * + Never use `#` in function bodies.
112 *
113 * This is a variation on the previous guideline. Since `#` is replaced with
114 * an *expression* and the expression is only valid in the immediate context,
115 * `#` should never appear in a function body. Doing so might defer the
116 * evaluation of the expression, and its side effects, until the function is
117 * called.
118 *
119 * For example,
120 *
121 * var value = foo();
122 * var f = JS('', 'function(){return #}', value)
123 *
124 * might result in no immediate call to `foo` and a call to `foo` on every
125 * call to the JavaScript function bound to `f`. This is better:
126 *
127 * var f = JS('',
128 * '(function(val) { return function(){return val}; })(#)', value);
129 *
130 * Since `#` occurs in the immediately evaluated expression, the expression
131 * is immediately evaluated and bound to `val` in the immediate call.
132 *
133 *
134 * Additional notes.
135 *
136 * In the future we may extend [typeDescription] to include other aspects of the
137 * behavior, for example, separating the returned types from the instantiated
138 * types to allow the compiler to perform more optimizations around the code.
139 *
140 * This might be an extension of [JS] or a new function similar to [JS] with
141 * additional arguments for the new information.
142 */
143 // Add additional optional arguments if needed. The method is treated internally
144 // as a variable argument method.
145 external JS(String typeDescription, String codeTemplate,
146 [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11]);
147
148 /**
149 * Returns the isolate in which this code is running.
150 */
151 external IsolateContext JS_CURRENT_ISOLATE_CONTEXT();
152
153 abstract class IsolateContext {
154 /// Holds a (native) JavaScript instance of Isolate, see
155 /// finishIsolateConstructorFunction in emitter.dart.
156 get isolateStatics;
157 }
158
159 /**
160 * Invokes [function] in the context of [isolate].
161 */
162 external JS_CALL_IN_ISOLATE(isolate, Function function);
163
164 /**
165 * Converts the Dart closure [function] into a JavaScript closure.
166 *
167 * Warning: This is no different from [RAW_DART_FUNCTION_REF] which means care
168 * must be taken to store the current isolate.
169 */
170 external DART_CLOSURE_TO_JS(Function function);
171
172 /**
173 * Returns a raw reference to the JavaScript function which implements
174 * [function].
175 *
176 * Warning: this is dangerous, you should probably use
177 * [DART_CLOSURE_TO_JS] instead. The returned object is not a valid
178 * Dart closure, does not store the isolate context or arity.
179 *
180 * A valid example of where this can be used is as the second argument
181 * to V8's Error.captureStackTrace. See
182 * https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi.
183 */
184 external RAW_DART_FUNCTION_REF(Function function);
185
186 /**
187 * Sets the current isolate to [isolate].
188 */
189 external void JS_SET_CURRENT_ISOLATE(isolate);
190
191 /**
192 * Returns the interceptor for class [type]. The interceptor is the type's
193 * constructor's `prototype` property. [type] will typically be the class, not
194 * an interface, e.g. `JS_INTERCEPTOR_CONSTANT(JSInt)`, not
195 * `JS_INTERCEPTOR_CONSTANT(int)`.
196 */
197 external JS_INTERCEPTOR_CONSTANT(Type type);
198
199 /**
200 * Returns the object corresponding to Namer.CURRENT_ISOLATE.
201 */
202 external JS_CURRENT_ISOLATE();
203
204 /// Returns the JS name for [name] from the Namer.
205 external String JS_GET_NAME(JsGetName name);
206
207 /// Reads an embedded global.
208 ///
209 /// The [name] should be a constant defined in the `_embedded_names` library.
210 external JS_EMBEDDED_GLOBAL(String typeDescription, String name);
211
212 /// Instructs the compiler to execute the [builtinName] action at the call-site.
213 ///
214 /// The [builtin] should be a constant defined in the `_embedded_names`
215 /// library.
216 // Add additional optional arguments if needed. The method is treated internally
217 // as a variable argument method.
218 external JS_BUILTIN(String typeDescription, JsBuiltin builtin,
219 [arg0, arg1, arg2, arg3, arg4, arg5, arg6,
220 arg7, arg8, arg9, arg10, arg11]);
221
222 /// Returns the state of a flag that is determined by the state of the compiler
223 /// when the program has been analyzed.
224 external bool JS_GET_FLAG(String name);
225
226 /**
227 * Pretend [code] is executed. Generates no executable code. This is used to
228 * model effects at some other point in external code. For example, the
229 * following models an assignment to foo with an unknown value.
230 *
231 * var foo;
232 *
233 * main() {
234 * JS_EFFECT((_){ foo = _; })
235 * }
236 *
237 * TODO(sra): Replace this hack with something to mark the volatile or
238 * externally initialized elements.
239 */
240 void JS_EFFECT(Function code) { code(null); }
241
242 /**
243 * Use this class for creating constants that hold JavaScript code.
244 * For example:
245 *
246 * const constant = JS_CONST('typeof window != "undefined");
247 *
248 * This code will generate:
249 * $.JS_CONST_1 = typeof window != "undefined";
250 */
251 class JS_CONST {
252 final String code;
253 const JS_CONST(this.code);
254 }
255
256 /**
257 * JavaScript string concatenation. Inputs must be Strings. Corresponds to the
258 * HStringConcat SSA instruction and may be constant-folded.
259 */
260 String JS_STRING_CONCAT(String a, String b) {
261 // This body is unused, only here for type analysis.
262 return JS('String', '# + #', a, b);
263 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698