| 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 |