| 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 class ConstantEmitter { | 7 class ConstantEmitter { |
| 8 ConstantReferenceEmitter _referenceEmitter; | 8 ConstantReferenceEmitter _referenceEmitter; |
| 9 ConstantInitializerEmitter _initializerEmitter; | 9 ConstantLiteralEmitter _literalEmitter; |
| 10 | 10 |
| 11 ConstantEmitter(Compiler compiler, Namer namer) { | 11 ConstantEmitter(Compiler compiler, Namer namer) { |
| 12 _referenceEmitter = new ConstantReferenceEmitter(compiler, namer); | 12 _literalEmitter = new ConstantLiteralEmitter(compiler, namer, this); |
| 13 _initializerEmitter = new ConstantInitializerEmitter( | 13 _referenceEmitter = new ConstantReferenceEmitter(compiler, namer, this); |
| 14 compiler, namer, _referenceEmitter); | |
| 15 } | 14 } |
| 16 | 15 |
| 17 /** | 16 /** |
| 18 * Constructs an expression that is a reference to the constant. Uses a | 17 * Constructs an expression that is a reference to the constant. Uses a |
| 19 * canonical name unless the constant can be emitted multiple times (as for | 18 * canonical name unless the constant can be emitted multiple times (as for |
| 20 * numbers and strings). | 19 * numbers and strings). |
| 21 */ | 20 */ |
| 22 jsAst.Expression reference(Constant constant) { | 21 jsAst.Expression reference(Constant constant) { |
| 23 return _referenceEmitter.generate(constant); | 22 return _referenceEmitter.generate(constant); |
| 24 } | 23 } |
| 25 | 24 |
| 26 /** | 25 /** |
| 26 * Constructs a literal expression that evaluates to the constant. Uses a |
| 27 * canonical name unless the constant can be emitted multiple times (as for |
| 28 * numbers and strings). |
| 29 */ |
| 30 jsAst.Expression literal(Constant constant) { |
| 31 return _literalEmitter.generate(constant); |
| 32 } |
| 33 |
| 34 /** |
| 27 * Constructs an expression like [reference], but the expression is valid | 35 * Constructs an expression like [reference], but the expression is valid |
| 28 * during isolate initialization. | 36 * during isolate initialization. |
| 29 */ | 37 */ |
| 30 jsAst.Expression referenceInInitializationContext(Constant constant) { | 38 jsAst.Expression referenceInInitializationContext(Constant constant) { |
| 31 return _referenceEmitter.generateInInitializationContext(constant); | 39 return _referenceEmitter.generate(constant); |
| 32 } | 40 } |
| 33 | 41 |
| 34 /** | 42 /** |
| 35 * Constructs an expression used to initialize a canonicalized constant. | 43 * Constructs an expression used to initialize a canonicalized constant. |
| 36 */ | 44 */ |
| 37 jsAst.Expression initializationExpression(Constant constant) { | 45 jsAst.Expression initializationExpression(Constant constant) { |
| 38 return _initializerEmitter.generate(constant); | 46 return _literalEmitter.generate(constant); |
| 39 } | 47 } |
| 40 } | 48 } |
| 41 | 49 |
| 42 /** | 50 /** |
| 43 * Visitor for generating JavaScript expressions to refer to [Constant]s. | 51 * Visitor for generating JavaScript expressions to refer to [Constant]s. |
| 44 * Do not use directly, use methods from [ConstantEmitter]. | 52 * Do not use directly, use methods from [ConstantEmitter]. |
| 45 */ | 53 */ |
| 46 class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> { | 54 class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> { |
| 47 final Compiler compiler; | 55 final Compiler compiler; |
| 48 final Namer namer; | 56 final Namer namer; |
| 49 | 57 |
| 50 ConstantReferenceEmitter(this.compiler, this.namer); | 58 final ConstantEmitter constantEmitter; |
| 59 |
| 60 ConstantReferenceEmitter(this.compiler, this.namer, this.constantEmitter); |
| 51 | 61 |
| 52 jsAst.Expression generate(Constant constant) { | 62 jsAst.Expression generate(Constant constant) { |
| 53 return _visit(constant); | 63 return _visit(constant); |
| 54 } | 64 } |
| 55 | 65 |
| 56 jsAst.Expression generateInInitializationContext(Constant constant) { | |
| 57 return _visit(constant); | |
| 58 } | |
| 59 | |
| 60 jsAst.Expression _visit(Constant constant) { | 66 jsAst.Expression _visit(Constant constant) { |
| 61 return constant.accept(this); | 67 return constant.accept(this); |
| 62 } | 68 } |
| 63 | 69 |
| 70 jsAst.Expression emitCanonicalVersion(Constant constant) { |
| 71 String name = namer.constantName(constant); |
| 72 return new jsAst.PropertyAccess.field( |
| 73 new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name); |
| 74 } |
| 75 |
| 76 jsAst.Expression literal(Constant constant) { |
| 77 return constantEmitter.literal(constant); |
| 78 } |
| 79 |
| 64 jsAst.Expression visitFunction(FunctionConstant constant) { | 80 jsAst.Expression visitFunction(FunctionConstant constant) { |
| 65 return namer.isolateStaticClosureAccess(constant.element); | 81 return namer.isolateStaticClosureAccess(constant.element); |
| 66 } | 82 } |
| 67 | 83 |
| 68 jsAst.Expression visitNull(NullConstant constant) { | 84 jsAst.Expression visitNull(NullConstant constant) { |
| 69 return new jsAst.LiteralNull(); | 85 return literal(constant); |
| 70 } | 86 } |
| 71 | 87 |
| 72 jsAst.Expression visitInt(IntConstant constant) { | 88 jsAst.Expression visitInt(IntConstant constant) { |
| 73 return new jsAst.LiteralNumber('${constant.value}'); | 89 return literal(constant); |
| 74 } | 90 } |
| 75 | 91 |
| 76 jsAst.Expression visitDouble(DoubleConstant constant) { | 92 jsAst.Expression visitDouble(DoubleConstant constant) { |
| 77 double value = constant.value; | 93 return literal(constant); |
| 78 if (value.isNaN) { | |
| 79 return js("0/0"); | |
| 80 } else if (value == double.INFINITY) { | |
| 81 return js("1/0"); | |
| 82 } else if (value == -double.INFINITY) { | |
| 83 return js("-1/0"); | |
| 84 } else { | |
| 85 return new jsAst.LiteralNumber("$value"); | |
| 86 } | |
| 87 } | 94 } |
| 88 | 95 |
| 89 jsAst.Expression visitTrue(TrueConstant constant) { | 96 jsAst.Expression visitTrue(TrueConstant constant) { |
| 90 if (compiler.enableMinification) { | 97 return literal(constant); |
| 91 // Use !0 for true. | |
| 92 return js("!0"); | |
| 93 } else { | |
| 94 return js('true'); | |
| 95 } | |
| 96 } | 98 } |
| 97 | 99 |
| 98 jsAst.Expression visitFalse(FalseConstant constant) { | 100 jsAst.Expression visitFalse(FalseConstant constant) { |
| 99 if (compiler.enableMinification) { | 101 return literal(constant); |
| 100 // Use !1 for false. | |
| 101 return js("!1"); | |
| 102 } else { | |
| 103 return js('false'); | |
| 104 } | |
| 105 } | 102 } |
| 106 | 103 |
| 107 /** | 104 /** |
| 108 * Write the contents of the quoted string to a [CodeBuffer] in | 105 * Write the contents of the quoted string to a [CodeBuffer] in |
| 109 * a form that is valid as JavaScript string literal content. | 106 * a form that is valid as JavaScript string literal content. |
| 110 * The string is assumed quoted by double quote characters. | 107 * The string is assumed quoted by double quote characters. |
| 111 */ | 108 */ |
| 112 jsAst.Expression visitString(StringConstant constant) { | 109 jsAst.Expression visitString(StringConstant constant) { |
| 113 // TODO(sra): If the string is long *and repeated* (and not on a hot path) | 110 // TODO(sra): If the string is long *and repeated* (and not on a hot path) |
| 114 // then it should be assigned to a name. We don't have reference counts (or | 111 // then it should be assigned to a name. We don't have reference counts (or |
| 115 // profile information) here, so this is the wrong place. | 112 // profile information) here, so this is the wrong place. |
| 116 StringBuffer sb = new StringBuffer(); | 113 return literal(constant); |
| 117 writeJsonEscapedCharsOn(constant.value.slowToString(), sb); | |
| 118 return new jsAst.LiteralString('"$sb"'); | |
| 119 } | |
| 120 | |
| 121 jsAst.Expression emitCanonicalVersion(Constant constant) { | |
| 122 String name = namer.constantName(constant); | |
| 123 return new jsAst.PropertyAccess.field( | |
| 124 new jsAst.VariableUse(namer.globalObjectForConstant(constant)), name); | |
| 125 } | 114 } |
| 126 | 115 |
| 127 jsAst.Expression visitList(ListConstant constant) { | 116 jsAst.Expression visitList(ListConstant constant) { |
| 128 return emitCanonicalVersion(constant); | 117 return emitCanonicalVersion(constant); |
| 129 } | 118 } |
| 130 | 119 |
| 131 jsAst.Expression visitMap(MapConstant constant) { | 120 jsAst.Expression visitMap(MapConstant constant) { |
| 132 return emitCanonicalVersion(constant); | 121 return emitCanonicalVersion(constant); |
| 133 } | 122 } |
| 134 | 123 |
| 135 jsAst.Expression visitType(TypeConstant constant) { | 124 jsAst.Expression visitType(TypeConstant constant) { |
| 136 return emitCanonicalVersion(constant); | 125 return emitCanonicalVersion(constant); |
| 137 } | 126 } |
| 138 | 127 |
| 139 jsAst.Expression visitConstructed(ConstructedConstant constant) { | 128 jsAst.Expression visitConstructed(ConstructedConstant constant) { |
| 140 return emitCanonicalVersion(constant); | 129 return emitCanonicalVersion(constant); |
| 141 } | 130 } |
| 142 | 131 |
| 143 jsAst.Expression visitInterceptor(InterceptorConstant constant) { | 132 jsAst.Expression visitInterceptor(InterceptorConstant constant) { |
| 144 return emitCanonicalVersion(constant); | 133 return emitCanonicalVersion(constant); |
| 145 } | 134 } |
| 146 | 135 |
| 147 jsAst.Expression visitDummy(DummyConstant constant) { | 136 jsAst.Expression visitDummy(DummyConstant constant) { |
| 148 return new jsAst.LiteralNumber('0'); | 137 return literal(constant); |
| 138 } |
| 139 |
| 140 jsAst.Expression visitDeferred(DeferredConstant constant) { |
| 141 return emitCanonicalVersion(constant); |
| 149 } | 142 } |
| 150 } | 143 } |
| 151 | 144 |
| 152 /** | 145 /** |
| 153 * Visitor for generating JavaScript expressions to initialize [Constant]s. | 146 * Visitor for generating JavaScript expressions that litterally represent |
| 154 * Do not use directly; use methods from [ConstantEmitter]. | 147 * [Constant]s. These can be used for inlining constants or in initializers. |
| 148 * Do not use directly, use methods from [ConstantEmitter]. |
| 155 */ | 149 */ |
| 156 class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> { | 150 class ConstantLiteralEmitter implements ConstantVisitor<jsAst.Expression> { |
| 157 final Compiler compiler; | |
| 158 final Namer namer; | |
| 159 final ConstantReferenceEmitter referenceEmitter; | |
| 160 | 151 |
| 161 // Matches blank lines, comment lines and trailing comments that can't be part | 152 // Matches blank lines, comment lines and trailing comments that can't be part |
| 162 // of a string. | 153 // of a string. |
| 163 static final RegExp COMMENT_RE = | 154 static final RegExp COMMENT_RE = |
| 164 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true); | 155 new RegExp(r'''^ *(//.*)?\n| *//[^''"\n]*$''' , multiLine: true); |
| 165 | 156 |
| 166 ConstantInitializerEmitter(this.compiler, this.namer, this.referenceEmitter); | 157 final Compiler compiler; |
| 158 final Namer namer; |
| 159 final ConstantEmitter constantEmitter; |
| 160 |
| 161 ConstantLiteralEmitter(this.compiler, this.namer, this.constantEmitter); |
| 167 | 162 |
| 168 jsAst.Expression generate(Constant constant) { | 163 jsAst.Expression generate(Constant constant) { |
| 169 return _visit(constant); | 164 return _visit(constant); |
| 170 } | 165 } |
| 171 | 166 |
| 172 jsAst.Expression _visit(Constant constant) { | 167 jsAst.Expression _visit(Constant constant) { |
| 173 return constant.accept(this); | 168 return constant.accept(this); |
| 174 } | 169 } |
| 175 | 170 |
| 176 jsAst.Expression _reference(Constant constant) { | |
| 177 return referenceEmitter.generateInInitializationContext(constant); | |
| 178 } | |
| 179 | |
| 180 jsAst.Expression visitFunction(FunctionConstant constant) { | 171 jsAst.Expression visitFunction(FunctionConstant constant) { |
| 181 compiler.internalError(NO_LOCATION_SPANNABLE, | 172 compiler.internalError(NO_LOCATION_SPANNABLE, |
| 182 "The function constant does not need specific JS code."); | 173 "The function constant does not need specific JS code."); |
| 183 return null; | 174 return null; |
| 184 } | 175 } |
| 185 | 176 |
| 186 jsAst.Expression visitNull(NullConstant constant) { | 177 jsAst.Expression visitNull(NullConstant constant) { |
| 187 return _reference(constant); | 178 return new jsAst.LiteralNull(); |
| 188 } | 179 } |
| 189 | 180 |
| 190 jsAst.Expression visitInt(IntConstant constant) { | 181 jsAst.Expression visitInt(IntConstant constant) { |
| 191 return _reference(constant); | 182 return new jsAst.LiteralNumber('${constant.value}'); |
| 192 } | 183 } |
| 193 | 184 |
| 194 jsAst.Expression visitDouble(DoubleConstant constant) { | 185 jsAst.Expression visitDouble(DoubleConstant constant) { |
| 195 return _reference(constant); | 186 double value = constant.value; |
| 187 if (value.isNaN) { |
| 188 return js("0/0"); |
| 189 } else if (value == double.INFINITY) { |
| 190 return js("1/0"); |
| 191 } else if (value == -double.INFINITY) { |
| 192 return js("-1/0"); |
| 193 } else { |
| 194 return new jsAst.LiteralNumber("$value"); |
| 195 } |
| 196 } | 196 } |
| 197 | 197 |
| 198 jsAst.Expression visitTrue(TrueConstant constant) { | 198 jsAst.Expression visitTrue(TrueConstant constant) { |
| 199 return _reference(constant); | 199 if (compiler.enableMinification) { |
| 200 // Use !0 for true. |
| 201 return js("!0"); |
| 202 } else { |
| 203 return js('true'); |
| 204 } |
| 200 } | 205 } |
| 201 | 206 |
| 202 jsAst.Expression visitFalse(FalseConstant constant) { | 207 jsAst.Expression visitFalse(FalseConstant constant) { |
| 203 return _reference(constant); | 208 if (compiler.enableMinification) { |
| 209 // Use !1 for false. |
| 210 return js("!1"); |
| 211 } else { |
| 212 return js('false'); |
| 213 } |
| 204 } | 214 } |
| 205 | 215 |
| 216 /** |
| 217 * Write the contents of the quoted string to a [CodeBuffer] in |
| 218 * a form that is valid as JavaScript string literal content. |
| 219 * The string is assumed quoted by double quote characters. |
| 220 */ |
| 206 jsAst.Expression visitString(StringConstant constant) { | 221 jsAst.Expression visitString(StringConstant constant) { |
| 207 // TODO(sra): Some larger strings are worth sharing. | 222 StringBuffer sb = new StringBuffer(); |
| 208 return _reference(constant); | 223 writeJsonEscapedCharsOn(constant.value.slowToString(), sb); |
| 224 return new jsAst.LiteralString('"$sb"'); |
| 209 } | 225 } |
| 210 | 226 |
| 211 jsAst.Expression visitList(ListConstant constant) { | 227 jsAst.Expression visitList(ListConstant constant) { |
| 212 jsAst.Expression value = new jsAst.Call( | 228 jsAst.Expression value = new jsAst.Call( |
| 213 new jsAst.PropertyAccess.field( | 229 new jsAst.PropertyAccess.field( |
| 214 new jsAst.VariableUse(namer.isolateName), | 230 new jsAst.VariableUse(namer.isolateName), |
| 215 'makeConstantList'), | 231 'makeConstantList'), |
| 216 [new jsAst.ArrayInitializer.from(_array(constant.entries))]); | 232 [new jsAst.ArrayInitializer.from(_array(constant.entries))]); |
| 217 return maybeAddTypeArguments(constant.type, value); | 233 return maybeAddTypeArguments(constant.type, value); |
| 218 } | 234 } |
| 219 | 235 |
| 220 jsAst.Expression getJsConstructor(ClassElement element) { | 236 jsAst.Expression getJsConstructor(ClassElement element) { |
| 221 return namer.elementAccess(element); | 237 return namer.elementAccess(element); |
| 222 } | 238 } |
| 223 | 239 |
| 224 jsAst.Expression visitMap(MapConstant constant) { | 240 jsAst.Expression visitMap(MapConstant constant) { |
| 225 jsAst.Expression jsMap() { | 241 jsAst.Expression jsMap() { |
| 226 List<jsAst.Property> properties = <jsAst.Property>[]; | 242 List<jsAst.Property> properties = <jsAst.Property>[]; |
| 227 for (int i = 0; i < constant.keys.entries.length; i++) { | 243 for (int i = 0; i < constant.keys.entries.length; i++) { |
| 228 StringConstant key = constant.keys.entries[i]; | 244 StringConstant key = constant.keys.entries[i]; |
| 229 if (key.value == MapConstant.PROTO_PROPERTY) continue; | 245 if (key.value == MapConstant.PROTO_PROPERTY) continue; |
| 230 | 246 |
| 231 // Keys in literal maps must be emitted in place. | 247 // Keys in literal maps must be emitted in place. |
| 232 jsAst.Literal keyExpression = _visit(key); | 248 jsAst.Literal keyExpression = _visit(key); |
| 233 jsAst.Expression valueExpression = | 249 jsAst.Expression valueExpression = |
| 234 _reference(constant.values[i]); | 250 constantEmitter.reference(constant.values[i]); |
| 235 properties.add(new jsAst.Property(keyExpression, valueExpression)); | 251 properties.add(new jsAst.Property(keyExpression, valueExpression)); |
| 236 } | 252 } |
| 237 return new jsAst.ObjectInitializer(properties); | 253 return new jsAst.ObjectInitializer(properties); |
| 238 } | 254 } |
| 239 | 255 |
| 240 jsAst.Expression jsGeneralMap() { | 256 jsAst.Expression jsGeneralMap() { |
| 241 List<jsAst.Expression> data = <jsAst.Expression>[]; | 257 List<jsAst.Expression> data = <jsAst.Expression>[]; |
| 242 for (int i = 0; i < constant.keys.entries.length; i++) { | 258 for (int i = 0; i < constant.keys.entries.length; i++) { |
| 243 jsAst.Expression keyExpression = | 259 jsAst.Expression keyExpression = |
| 244 _reference(constant.keys.entries[i]); | 260 constantEmitter.reference(constant.keys.entries[i]); |
| 245 jsAst.Expression valueExpression = | 261 jsAst.Expression valueExpression = |
| 246 _reference(constant.values[i]); | 262 constantEmitter.reference(constant.values[i]); |
| 247 data.add(keyExpression); | 263 data.add(keyExpression); |
| 248 data.add(valueExpression); | 264 data.add(valueExpression); |
| 249 } | 265 } |
| 250 return new jsAst.ArrayInitializer.from(data); | 266 return new jsAst.ArrayInitializer.from(data); |
| 251 } | 267 } |
| 252 | 268 |
| 253 ClassElement classElement = constant.type.element; | 269 ClassElement classElement = constant.type.element; |
| 254 String className = classElement.name; | 270 String className = classElement.name; |
| 255 | 271 |
| 256 List<jsAst.Expression> arguments = <jsAst.Expression>[]; | 272 List<jsAst.Expression> arguments = <jsAst.Expression>[]; |
| 257 | 273 |
| 258 // The arguments of the JavaScript constructor for any given Dart class | 274 // The arguments of the JavaScript constructor for any given Dart class |
| 259 // are in the same order as the members of the class element. | 275 // are in the same order as the members of the class element. |
| 260 int emittedArgumentCount = 0; | 276 int emittedArgumentCount = 0; |
| 261 classElement.implementation.forEachInstanceField( | 277 classElement.implementation.forEachInstanceField( |
| 262 (ClassElement enclosing, Element field) { | 278 (ClassElement enclosing, Element field) { |
| 263 if (field.name == MapConstant.LENGTH_NAME) { | 279 if (field.name == MapConstant.LENGTH_NAME) { |
| 264 arguments.add( | 280 arguments.add( |
| 265 new jsAst.LiteralNumber('${constant.keys.entries.length}')); | 281 new jsAst.LiteralNumber('${constant.keys.entries.length}')); |
| 266 } else if (field.name == MapConstant.JS_OBJECT_NAME) { | 282 } else if (field.name == MapConstant.JS_OBJECT_NAME) { |
| 267 arguments.add(jsMap()); | 283 arguments.add(jsMap()); |
| 268 } else if (field.name == MapConstant.KEYS_NAME) { | 284 } else if (field.name == MapConstant.KEYS_NAME) { |
| 269 arguments.add(_reference(constant.keys)); | 285 arguments.add(constantEmitter.reference(constant.keys)); |
| 270 } else if (field.name == MapConstant.PROTO_VALUE) { | 286 } else if (field.name == MapConstant.PROTO_VALUE) { |
| 271 assert(constant.protoValue != null); | 287 assert(constant.protoValue != null); |
| 272 arguments.add(_reference(constant.protoValue)); | 288 arguments.add(constantEmitter.reference(constant.protoValue)); |
| 273 } else if (field.name == MapConstant.JS_DATA_NAME) { | 289 } else if (field.name == MapConstant.JS_DATA_NAME) { |
| 274 arguments.add(jsGeneralMap()); | 290 arguments.add(jsGeneralMap()); |
| 275 } else { | 291 } else { |
| 276 compiler.internalError(field, | 292 compiler.internalError(field, |
| 277 "Compiler has unexpected field ${field.name} for " | 293 "Compiler has unexpected field ${field.name} for " |
| 278 "${className}."); | 294 "${className}."); |
| 279 } | 295 } |
| 280 emittedArgumentCount++; | 296 emittedArgumentCount++; |
| 281 }, | 297 }, |
| 282 includeSuperAndInjectedMembers: true); | 298 includeSuperAndInjectedMembers: true); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 309 [typeName]); | 325 [typeName]); |
| 310 } | 326 } |
| 311 | 327 |
| 312 jsAst.Expression visitInterceptor(InterceptorConstant constant) { | 328 jsAst.Expression visitInterceptor(InterceptorConstant constant) { |
| 313 return new jsAst.PropertyAccess.field( | 329 return new jsAst.PropertyAccess.field( |
| 314 getJsConstructor(constant.dispatchedType.element), | 330 getJsConstructor(constant.dispatchedType.element), |
| 315 'prototype'); | 331 'prototype'); |
| 316 } | 332 } |
| 317 | 333 |
| 318 jsAst.Expression visitDummy(DummyConstant constant) { | 334 jsAst.Expression visitDummy(DummyConstant constant) { |
| 319 return _reference(constant); | 335 return new jsAst.LiteralNumber('0'); |
| 320 } | 336 } |
| 321 | 337 |
| 322 jsAst.Expression visitConstructed(ConstructedConstant constant) { | 338 jsAst.Expression visitConstructed(ConstructedConstant constant) { |
| 323 Element element = constant.type.element; | 339 Element element = constant.type.element; |
| 324 if (element.isForeign(compiler) | 340 if (element.isForeign(compiler) |
| 325 && element.name == 'JS_CONST') { | 341 && element.name == 'JS_CONST') { |
| 326 StringConstant str = constant.fields[0]; | 342 StringConstant str = constant.fields[0]; |
| 327 String value = str.value.slowToString(); | 343 String value = str.value.slowToString(); |
| 328 return new jsAst.LiteralExpression(stripComments(value)); | 344 return new jsAst.LiteralExpression(stripComments(value)); |
| 329 } | 345 } |
| 330 jsAst.New instantiation = new jsAst.New( | 346 jsAst.New instantiation = new jsAst.New( |
| 331 getJsConstructor(constant.type.element), | 347 getJsConstructor(constant.type.element), |
| 332 _array(constant.fields)); | 348 _array(constant.fields)); |
| 333 return maybeAddTypeArguments(constant.type, instantiation); | 349 return maybeAddTypeArguments(constant.type, instantiation); |
| 334 } | 350 } |
| 335 | 351 |
| 336 String stripComments(String rawJavaScript) { | 352 String stripComments(String rawJavaScript) { |
| 337 return rawJavaScript.replaceAll(COMMENT_RE, ''); | 353 return rawJavaScript.replaceAll(COMMENT_RE, ''); |
| 338 } | 354 } |
| 339 | 355 |
| 340 List<jsAst.Expression> _array(List<Constant> values) { | 356 List<jsAst.Expression> _array(List<Constant> values) { |
| 341 List<jsAst.Expression> valueList = <jsAst.Expression>[]; | 357 List<jsAst.Expression> valueList = <jsAst.Expression>[]; |
| 342 for (int i = 0; i < values.length; i++) { | 358 for (int i = 0; i < values.length; i++) { |
| 343 valueList.add(_reference(values[i])); | 359 valueList.add(constantEmitter.reference(values[i])); |
| 344 } | 360 } |
| 345 return valueList; | 361 return valueList; |
| 346 } | 362 } |
| 347 | 363 |
| 348 jsAst.Expression maybeAddTypeArguments(InterfaceType type, | 364 jsAst.Expression maybeAddTypeArguments(InterfaceType type, |
| 349 jsAst.Expression value) { | 365 jsAst.Expression value) { |
| 350 if (type is InterfaceType && | 366 if (type is InterfaceType && |
| 351 !type.treatAsRaw && | 367 !type.treatAsRaw && |
| 352 backend.classNeedsRti(type.element)) { | 368 backend.classNeedsRti(type.element)) { |
| 353 InterfaceType interface = type; | 369 InterfaceType interface = type; |
| 354 RuntimeTypes rti = backend.rti; | 370 RuntimeTypes rti = backend.rti; |
| 355 Iterable<String> arguments = interface.typeArguments | 371 Iterable<String> arguments = interface.typeArguments |
| 356 .toList(growable: false) | 372 .toList(growable: false) |
| 357 .map((DartType type) => | 373 .map((DartType type) => |
| 358 rti.getTypeRepresentationWithHashes(type, (_){})); | 374 rti.getTypeRepresentationWithHashes(type, (_){})); |
| 359 jsAst.Expression argumentList = | 375 jsAst.Expression argumentList = |
| 360 new jsAst.LiteralString('[${arguments.join(', ')}]'); | 376 new jsAst.LiteralString('[${arguments.join(', ')}]'); |
| 361 return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()), | 377 return new jsAst.Call(getHelperProperty(backend.getSetRuntimeTypeInfo()), |
| 362 [value, argumentList]); | 378 [value, argumentList]); |
| 363 } | 379 } |
| 364 return value; | 380 return value; |
| 365 } | 381 } |
| 382 |
| 383 jsAst.Expression visitDeferred(DeferredConstant constant) { |
| 384 return constantEmitter.reference(constant.referenced); |
| 385 } |
| 366 } | 386 } |
| OLD | NEW |