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 part of js_backend; | 5 part of js_backend; |
6 | 6 |
7 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant); | 7 typedef jsAst.Expression _ConstantReferenceGenerator(ConstantValue constant); |
8 | 8 |
| 9 typedef jsAst.Expression _ConstantListGenerator(jsAst.Expression array); |
| 10 |
9 /** | 11 /** |
10 * Generates the JavaScript expressions for constants. | 12 * Generates the JavaScript expressions for constants. |
11 * | 13 * |
12 * It uses a given [constantReferenceGenerator] to reference nested constants | 14 * It uses a given [constantReferenceGenerator] to reference nested constants |
13 * (if there are some). It is hence up to that function to decide which | 15 * (if there are some). It is hence up to that function to decide which |
14 * constants should be inlined or not. | 16 * constants should be inlined or not. |
15 */ | 17 */ |
16 class ConstantEmitter | 18 class ConstantEmitter |
17 implements ConstantValueVisitor<jsAst.Expression, Null> { | 19 implements ConstantValueVisitor<jsAst.Expression, Null> { |
18 | 20 |
19 // Matches blank lines, comment lines and trailing comments that can't be part | 21 // Matches blank lines, comment lines and trailing comments that can't be part |
20 // of a string. | 22 // of a string. |
21 static final RegExp COMMENT_RE = | 23 static final RegExp COMMENT_RE = |
22 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true); | 24 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true); |
23 | 25 |
24 final Compiler compiler; | 26 final Compiler compiler; |
25 final Namer namer; | 27 final Namer namer; |
26 final _ConstantReferenceGenerator constantReferenceGenerator; | 28 final _ConstantReferenceGenerator constantReferenceGenerator; |
27 final jsAst.Template makeConstantListTemplate; | 29 final _ConstantListGenerator makeConstantList; |
28 | 30 |
29 /** | 31 /** |
30 * The given [constantReferenceGenerator] function must, when invoked with a | 32 * The given [constantReferenceGenerator] function must, when invoked with a |
31 * constant, either return a reference or return its literal expression if it | 33 * constant, either return a reference or return its literal expression if it |
32 * can be inlined. | 34 * can be inlined. |
33 */ | 35 */ |
34 ConstantEmitter( | 36 ConstantEmitter( |
35 this.compiler, | 37 this.compiler, |
36 this.namer, | 38 this.namer, |
37 jsAst.Expression this.constantReferenceGenerator(ConstantValue constant), | 39 jsAst.Expression this.constantReferenceGenerator(ConstantValue constant), |
38 this.makeConstantListTemplate); | 40 this.makeConstantList); |
39 | 41 |
40 /** | 42 /** |
41 * Constructs a literal expression that evaluates to the constant. Uses a | 43 * Constructs a literal expression that evaluates to the constant. Uses a |
42 * canonical name unless the constant can be emitted multiple times (as for | 44 * canonical name unless the constant can be emitted multiple times (as for |
43 * numbers and strings). | 45 * numbers and strings). |
44 */ | 46 */ |
45 jsAst.Expression generate(ConstantValue constant) { | 47 jsAst.Expression generate(ConstantValue constant) { |
46 return _visit(constant); | 48 return _visit(constant); |
47 } | 49 } |
48 | 50 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 writeJsonEscapedCharsOn(constant.primitiveValue.slowToString(), sb); | 155 writeJsonEscapedCharsOn(constant.primitiveValue.slowToString(), sb); |
154 return new jsAst.LiteralString('"$sb"'); | 156 return new jsAst.LiteralString('"$sb"'); |
155 } | 157 } |
156 | 158 |
157 @override | 159 @override |
158 jsAst.Expression visitList(ListConstantValue constant, [_]) { | 160 jsAst.Expression visitList(ListConstantValue constant, [_]) { |
159 List<jsAst.Expression> elements = constant.entries | 161 List<jsAst.Expression> elements = constant.entries |
160 .map(constantReferenceGenerator) | 162 .map(constantReferenceGenerator) |
161 .toList(growable: false); | 163 .toList(growable: false); |
162 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements); | 164 jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements); |
163 jsAst.Expression value = makeConstantListTemplate.instantiate([array]); | 165 jsAst.Expression value = makeConstantList(array); |
164 return maybeAddTypeArguments(constant.type, value); | 166 return maybeAddTypeArguments(constant.type, value); |
165 } | 167 } |
166 | 168 |
167 @override | 169 @override |
168 jsAst.Expression visitMap(JavaScriptMapConstant constant, [_]) { | 170 jsAst.Expression visitMap(JavaScriptMapConstant constant, [_]) { |
169 jsAst.Expression jsMap() { | 171 jsAst.Expression jsMap() { |
170 List<jsAst.Property> properties = <jsAst.Property>[]; | 172 List<jsAst.Property> properties = <jsAst.Property>[]; |
171 for (int i = 0; i < constant.length; i++) { | 173 for (int i = 0; i < constant.length; i++) { |
172 StringConstantValue key = constant.keys[i]; | 174 StringConstantValue key = constant.keys[i]; |
173 if (key.primitiveValue == JavaScriptMapConstant.PROTO_PROPERTY) { | 175 if (key.primitiveValue == JavaScriptMapConstant.PROTO_PROPERTY) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 245 |
244 JavaScriptBackend get backend => compiler.backend; | 246 JavaScriptBackend get backend => compiler.backend; |
245 | 247 |
246 jsAst.PropertyAccess getHelperProperty(Element helper) { | 248 jsAst.PropertyAccess getHelperProperty(Element helper) { |
247 return backend.emitter.staticFunctionAccess(helper); | 249 return backend.emitter.staticFunctionAccess(helper); |
248 } | 250 } |
249 | 251 |
250 @override | 252 @override |
251 jsAst.Expression visitType(TypeConstantValue constant, [_]) { | 253 jsAst.Expression visitType(TypeConstantValue constant, [_]) { |
252 DartType type = constant.representedType; | 254 DartType type = constant.representedType; |
253 String name = namer.runtimeTypeName(type.element); | 255 jsAst.Name typeName = namer.runtimeTypeName(type.element); |
254 jsAst.Expression typeName = new jsAst.LiteralString("'$name'"); | |
255 return new jsAst.Call(getHelperProperty(backend.getCreateRuntimeType()), | 256 return new jsAst.Call(getHelperProperty(backend.getCreateRuntimeType()), |
256 [typeName]); | 257 [js.quoteName(typeName)]); |
257 } | 258 } |
258 | 259 |
259 @override | 260 @override |
260 jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) { | 261 jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) { |
261 ClassElement interceptorClass = constant.dispatchedType.element; | 262 ClassElement interceptorClass = constant.dispatchedType.element; |
262 return backend.emitter.interceptorPrototypeAccess(interceptorClass); | 263 return backend.emitter.interceptorPrototypeAccess(interceptorClass); |
263 } | 264 } |
264 | 265 |
265 @override | 266 @override |
266 jsAst.Expression visitSynthetic(SyntheticConstantValue constant, [_]) { | 267 jsAst.Expression visitSynthetic(SyntheticConstantValue constant, [_]) { |
267 switch (constant.kind) { | 268 switch (constant.kind) { |
268 case SyntheticConstantKind.DUMMY_INTERCEPTOR: | 269 case SyntheticConstantKind.DUMMY_INTERCEPTOR: |
269 case SyntheticConstantKind.EMPTY_VALUE: | 270 case SyntheticConstantKind.EMPTY_VALUE: |
270 return new jsAst.LiteralNumber('0'); | 271 return new jsAst.LiteralNumber('0'); |
271 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: | 272 case SyntheticConstantKind.TYPEVARIABLE_REFERENCE: |
| 273 case SyntheticConstantKind.NAME: |
272 return constant.payload; | 274 return constant.payload; |
273 default: | 275 default: |
274 compiler.internalError(NO_LOCATION_SPANNABLE, | 276 compiler.internalError(NO_LOCATION_SPANNABLE, |
275 "Unexpected DummyConstantKind ${constant.kind}"); | 277 "Unexpected DummyConstantKind ${constant.kind}"); |
276 return null; | 278 return null; |
277 } | 279 } |
278 } | 280 } |
279 | 281 |
280 @override | 282 @override |
281 jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) { | 283 jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) { |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 [value, argumentList]); | 317 [value, argumentList]); |
316 } | 318 } |
317 return value; | 319 return value; |
318 } | 320 } |
319 | 321 |
320 @override | 322 @override |
321 jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) { | 323 jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) { |
322 return constantReferenceGenerator(constant.referenced); | 324 return constantReferenceGenerator(constant.referenced); |
323 } | 325 } |
324 } | 326 } |
OLD | NEW |