| 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 ConstantInitializerEmitter _initializerEmitter; |
| 10 | 10 |
| 11 ConstantEmitter(Compiler compiler, Namer namer) { | 11 ConstantEmitter(Compiler compiler, Namer namer) { |
| 12 _referenceEmitter = new ConstantReferenceEmitter(compiler, namer); | 12 _referenceEmitter = new ConstantReferenceEmitter(compiler, namer); |
| 13 _initializerEmitter = new ConstantInitializerEmitter( | 13 _initializerEmitter = new ConstantInitializerEmitter( |
| 14 compiler, namer, _referenceEmitter); | 14 compiler, namer, _referenceEmitter); |
| 15 } | 15 } |
| 16 | 16 |
| 17 /** | 17 /** |
| 18 * Constructs an expression that is a reference to the constant. Uses a | 18 * 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 | 19 * canonical name unless the constant can be emitted multiple times (as for |
| 20 * numbers and strings). | 20 * numbers and strings). |
| 21 */ | 21 */ |
| 22 js.Expression reference(Constant constant) { | 22 jsAst.Expression reference(Constant constant) { |
| 23 return _referenceEmitter.generate(constant); | 23 return _referenceEmitter.generate(constant); |
| 24 } | 24 } |
| 25 | 25 |
| 26 /** | 26 /** |
| 27 * Constructs an expression like [reference], but the expression is valid | 27 * Constructs an expression like [reference], but the expression is valid |
| 28 * during isolate initialization. | 28 * during isolate initialization. |
| 29 */ | 29 */ |
| 30 js.Expression referenceInInitializationContext(Constant constant) { | 30 jsAst.Expression referenceInInitializationContext(Constant constant) { |
| 31 return _referenceEmitter.generateInInitializationContext(constant); | 31 return _referenceEmitter.generateInInitializationContext(constant); |
| 32 } | 32 } |
| 33 | 33 |
| 34 /** | 34 /** |
| 35 * Constructs an expression used to initialize a canonicalized constant. | 35 * Constructs an expression used to initialize a canonicalized constant. |
| 36 */ | 36 */ |
| 37 js.Expression initializationExpression(Constant constant) { | 37 jsAst.Expression initializationExpression(Constant constant) { |
| 38 return _initializerEmitter.generate(constant); | 38 return _initializerEmitter.generate(constant); |
| 39 } | 39 } |
| 40 } | 40 } |
| 41 | 41 |
| 42 /** | 42 /** |
| 43 * Visitor for generating JavaScript expressions to refer to [Constant]s. | 43 * Visitor for generating JavaScript expressions to refer to [Constant]s. |
| 44 * Do not use directly, use methods from [ConstantEmitter]. | 44 * Do not use directly, use methods from [ConstantEmitter]. |
| 45 */ | 45 */ |
| 46 class ConstantReferenceEmitter implements ConstantVisitor<js.Expression> { | 46 class ConstantReferenceEmitter implements ConstantVisitor<jsAst.Expression> { |
| 47 final Compiler compiler; | 47 final Compiler compiler; |
| 48 final Namer namer; | 48 final Namer namer; |
| 49 bool inIsolateInitializationContext = false; | 49 bool inIsolateInitializationContext = false; |
| 50 | 50 |
| 51 ConstantReferenceEmitter(this.compiler, this.namer); | 51 ConstantReferenceEmitter(this.compiler, this.namer); |
| 52 | 52 |
| 53 js.Expression generate(Constant constant) { | 53 jsAst.Expression generate(Constant constant) { |
| 54 inIsolateInitializationContext = false; | 54 inIsolateInitializationContext = false; |
| 55 return _visit(constant); | 55 return _visit(constant); |
| 56 } | 56 } |
| 57 | 57 |
| 58 js.Expression generateInInitializationContext(Constant constant) { | 58 jsAst.Expression generateInInitializationContext(Constant constant) { |
| 59 inIsolateInitializationContext = true; | 59 inIsolateInitializationContext = true; |
| 60 return _visit(constant); | 60 return _visit(constant); |
| 61 } | 61 } |
| 62 | 62 |
| 63 js.Expression _visit(Constant constant) { | 63 jsAst.Expression _visit(Constant constant) { |
| 64 return constant.accept(this); | 64 return constant.accept(this); |
| 65 } | 65 } |
| 66 | 66 |
| 67 js.Expression visitSentinel(SentinelConstant constant) { | 67 jsAst.Expression visitSentinel(SentinelConstant constant) { |
| 68 return new js.VariableUse(namer.CURRENT_ISOLATE); | 68 return new jsAst.VariableUse(namer.CURRENT_ISOLATE); |
| 69 } | 69 } |
| 70 | 70 |
| 71 js.Expression visitFunction(FunctionConstant constant) { | 71 jsAst.Expression visitFunction(FunctionConstant constant) { |
| 72 return inIsolateInitializationContext | 72 return inIsolateInitializationContext |
| 73 ? new js.VariableUse(namer.isolatePropertiesAccess(constant.element)) | 73 ? new jsAst.VariableUse(namer.isolatePropertiesAccess(constant.element)) |
| 74 : new js.VariableUse(namer.isolateAccess(constant.element)); | 74 : new jsAst.VariableUse(namer.isolateAccess(constant.element)); |
| 75 } | 75 } |
| 76 | 76 |
| 77 js.Expression visitNull(NullConstant constant) { | 77 jsAst.Expression visitNull(NullConstant constant) { |
| 78 return new js.LiteralNull(); | 78 return new jsAst.LiteralNull(); |
| 79 } | 79 } |
| 80 | 80 |
| 81 js.Expression visitInt(IntConstant constant) { | 81 jsAst.Expression visitInt(IntConstant constant) { |
| 82 return new js.LiteralNumber('${constant.value}'); | 82 return new jsAst.LiteralNumber('${constant.value}'); |
| 83 } | 83 } |
| 84 | 84 |
| 85 js.Expression visitDouble(DoubleConstant constant) { | 85 jsAst.Expression visitDouble(DoubleConstant constant) { |
| 86 double value = constant.value; | 86 double value = constant.value; |
| 87 if (value.isNaN) { | 87 if (value.isNaN) { |
| 88 return new js.LiteralNumber("(0/0)"); | 88 return new jsAst.LiteralNumber("(0/0)"); |
| 89 } else if (value == double.INFINITY) { | 89 } else if (value == double.INFINITY) { |
| 90 return new js.LiteralNumber("(1/0)"); | 90 return new jsAst.LiteralNumber("(1/0)"); |
| 91 } else if (value == -double.INFINITY) { | 91 } else if (value == -double.INFINITY) { |
| 92 return new js.LiteralNumber("(-1/0)"); | 92 return new jsAst.LiteralNumber("(-1/0)"); |
| 93 } else { | 93 } else { |
| 94 return new js.LiteralNumber("$value"); | 94 return new jsAst.LiteralNumber("$value"); |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 | 97 |
| 98 js.Expression visitTrue(TrueConstant constant) { | 98 jsAst.Expression visitTrue(TrueConstant constant) { |
| 99 if (compiler.enableMinification) { | 99 if (compiler.enableMinification) { |
| 100 // Use !0 for true. | 100 // Use !0 for true. |
| 101 return new js.Prefix("!", new js.LiteralNumber("0")); | 101 return new jsAst.Prefix("!", new jsAst.LiteralNumber("0")); |
| 102 } else { | 102 } else { |
| 103 return new js.LiteralBool(true); | 103 return new jsAst.LiteralBool(true); |
| 104 } | 104 } |
| 105 | 105 |
| 106 } | 106 } |
| 107 | 107 |
| 108 js.Expression visitFalse(FalseConstant constant) { | 108 jsAst.Expression visitFalse(FalseConstant constant) { |
| 109 if (compiler.enableMinification) { | 109 if (compiler.enableMinification) { |
| 110 // Use !1 for false. | 110 // Use !1 for false. |
| 111 return new js.Prefix("!", new js.LiteralNumber("1")); | 111 return new jsAst.Prefix("!", new jsAst.LiteralNumber("1")); |
| 112 } else { | 112 } else { |
| 113 return new js.LiteralBool(false); | 113 return new jsAst.LiteralBool(false); |
| 114 } | 114 } |
| 115 } | 115 } |
| 116 | 116 |
| 117 /** | 117 /** |
| 118 * Write the contents of the quoted string to a [CodeBuffer] in | 118 * Write the contents of the quoted string to a [CodeBuffer] in |
| 119 * a form that is valid as JavaScript string literal content. | 119 * a form that is valid as JavaScript string literal content. |
| 120 * The string is assumed quoted by double quote characters. | 120 * The string is assumed quoted by double quote characters. |
| 121 */ | 121 */ |
| 122 js.Expression visitString(StringConstant constant) { | 122 jsAst.Expression visitString(StringConstant constant) { |
| 123 // TODO(sra): If the string is long *and repeated* (and not on a hot path) | 123 // TODO(sra): If the string is long *and repeated* (and not on a hot path) |
| 124 // then it should be assigned to a name. We don't have reference counts (or | 124 // then it should be assigned to a name. We don't have reference counts (or |
| 125 // profile information) here, so this is the wrong place. | 125 // profile information) here, so this is the wrong place. |
| 126 StringBuffer sb = new StringBuffer(); | 126 StringBuffer sb = new StringBuffer(); |
| 127 writeJsonEscapedCharsOn(constant.value.slowToString(), sb); | 127 writeJsonEscapedCharsOn(constant.value.slowToString(), sb); |
| 128 return new js.LiteralString('"$sb"'); | 128 return new jsAst.LiteralString('"$sb"'); |
| 129 } | 129 } |
| 130 | 130 |
| 131 js.Expression emitCanonicalVersion(Constant constant) { | 131 jsAst.Expression emitCanonicalVersion(Constant constant) { |
| 132 String name = namer.constantName(constant); | 132 String name = namer.constantName(constant); |
| 133 if (inIsolateInitializationContext) { | 133 if (inIsolateInitializationContext) { |
| 134 // $isolateName.$isolatePropertiesName.$name | 134 // $isolateName.$isolatePropertiesName.$name |
| 135 return new js.PropertyAccess.field( | 135 return new jsAst.PropertyAccess.field( |
| 136 new js.PropertyAccess.field( | 136 new jsAst.PropertyAccess.field( |
| 137 new js.VariableUse(namer.isolateName), | 137 new jsAst.VariableUse(namer.isolateName), |
| 138 namer.isolatePropertiesName), | 138 namer.isolatePropertiesName), |
| 139 name); | 139 name); |
| 140 } else { | 140 } else { |
| 141 return new js.PropertyAccess.field( | 141 return new jsAst.PropertyAccess.field( |
| 142 new js.VariableUse(namer.CURRENT_ISOLATE), | 142 new jsAst.VariableUse(namer.CURRENT_ISOLATE), |
| 143 name); | 143 name); |
| 144 } | 144 } |
| 145 } | 145 } |
| 146 | 146 |
| 147 js.Expression visitList(ListConstant constant) { | 147 jsAst.Expression visitList(ListConstant constant) { |
| 148 return emitCanonicalVersion(constant); | 148 return emitCanonicalVersion(constant); |
| 149 } | 149 } |
| 150 | 150 |
| 151 js.Expression visitMap(MapConstant constant) { | 151 jsAst.Expression visitMap(MapConstant constant) { |
| 152 return emitCanonicalVersion(constant); | 152 return emitCanonicalVersion(constant); |
| 153 } | 153 } |
| 154 | 154 |
| 155 js.Expression visitType(TypeConstant constant) { | 155 jsAst.Expression visitType(TypeConstant constant) { |
| 156 return emitCanonicalVersion(constant); | 156 return emitCanonicalVersion(constant); |
| 157 } | 157 } |
| 158 | 158 |
| 159 js.Expression visitConstructed(ConstructedConstant constant) { | 159 jsAst.Expression visitConstructed(ConstructedConstant constant) { |
| 160 return emitCanonicalVersion(constant); | 160 return emitCanonicalVersion(constant); |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 | 163 |
| 164 /** | 164 /** |
| 165 * Visitor for generating JavaScript expressions to initialize [Constant]s. | 165 * Visitor for generating JavaScript expressions to initialize [Constant]s. |
| 166 * Do not use directly; use methods from [ConstantEmitter]. | 166 * Do not use directly; use methods from [ConstantEmitter]. |
| 167 */ | 167 */ |
| 168 class ConstantInitializerEmitter implements ConstantVisitor<js.Expression> { | 168 class ConstantInitializerEmitter implements ConstantVisitor<jsAst.Expression> { |
| 169 final Compiler compiler; | 169 final Compiler compiler; |
| 170 final Namer namer; | 170 final Namer namer; |
| 171 final ConstantReferenceEmitter referenceEmitter; | 171 final ConstantReferenceEmitter referenceEmitter; |
| 172 | 172 |
| 173 ConstantInitializerEmitter(this.compiler, this.namer, this.referenceEmitter); | 173 ConstantInitializerEmitter(this.compiler, this.namer, this.referenceEmitter); |
| 174 | 174 |
| 175 js.Expression generate(Constant constant) { | 175 jsAst.Expression generate(Constant constant) { |
| 176 return _visit(constant); | 176 return _visit(constant); |
| 177 } | 177 } |
| 178 | 178 |
| 179 js.Expression _visit(Constant constant) { | 179 jsAst.Expression _visit(Constant constant) { |
| 180 return constant.accept(this); | 180 return constant.accept(this); |
| 181 } | 181 } |
| 182 | 182 |
| 183 js.Expression _reference(Constant constant) { | 183 jsAst.Expression _reference(Constant constant) { |
| 184 return referenceEmitter.generateInInitializationContext(constant); | 184 return referenceEmitter.generateInInitializationContext(constant); |
| 185 } | 185 } |
| 186 | 186 |
| 187 js.Expression visitSentinel(SentinelConstant constant) { | 187 jsAst.Expression visitSentinel(SentinelConstant constant) { |
| 188 compiler.internalError( | 188 compiler.internalError( |
| 189 "The parameter sentinel constant does not need specific JS code"); | 189 "The parameter sentinel constant does not need specific JS code"); |
| 190 } | 190 } |
| 191 | 191 |
| 192 js.Expression visitFunction(FunctionConstant constant) { | 192 jsAst.Expression visitFunction(FunctionConstant constant) { |
| 193 compiler.internalError( | 193 compiler.internalError( |
| 194 "The function constant does not need specific JS code"); | 194 "The function constant does not need specific JS code"); |
| 195 } | 195 } |
| 196 | 196 |
| 197 js.Expression visitNull(NullConstant constant) { | 197 jsAst.Expression visitNull(NullConstant constant) { |
| 198 return _reference(constant); | 198 return _reference(constant); |
| 199 } | 199 } |
| 200 | 200 |
| 201 js.Expression visitInt(IntConstant constant) { | 201 jsAst.Expression visitInt(IntConstant constant) { |
| 202 return _reference(constant); | 202 return _reference(constant); |
| 203 } | 203 } |
| 204 | 204 |
| 205 js.Expression visitDouble(DoubleConstant constant) { | 205 jsAst.Expression visitDouble(DoubleConstant constant) { |
| 206 return _reference(constant); | 206 return _reference(constant); |
| 207 } | 207 } |
| 208 | 208 |
| 209 js.Expression visitTrue(TrueConstant constant) { | 209 jsAst.Expression visitTrue(TrueConstant constant) { |
| 210 return _reference(constant); | 210 return _reference(constant); |
| 211 } | 211 } |
| 212 | 212 |
| 213 js.Expression visitFalse(FalseConstant constant) { | 213 jsAst.Expression visitFalse(FalseConstant constant) { |
| 214 return _reference(constant); | 214 return _reference(constant); |
| 215 } | 215 } |
| 216 | 216 |
| 217 js.Expression visitString(StringConstant constant) { | 217 jsAst.Expression visitString(StringConstant constant) { |
| 218 // TODO(sra): Some larger strings are worth sharing. | 218 // TODO(sra): Some larger strings are worth sharing. |
| 219 return _reference(constant); | 219 return _reference(constant); |
| 220 } | 220 } |
| 221 | 221 |
| 222 js.Expression visitList(ListConstant constant) { | 222 jsAst.Expression visitList(ListConstant constant) { |
| 223 return new js.Call( | 223 return new jsAst.Call( |
| 224 new js.PropertyAccess.field( | 224 new jsAst.PropertyAccess.field( |
| 225 new js.VariableUse(namer.isolateName), | 225 new jsAst.VariableUse(namer.isolateName), |
| 226 'makeConstantList'), | 226 'makeConstantList'), |
| 227 [new js.ArrayInitializer.from(_array(constant.entries))]); | 227 [new jsAst.ArrayInitializer.from(_array(constant.entries))]); |
| 228 } | 228 } |
| 229 | 229 |
| 230 String getJsConstructor(ClassElement element) { | 230 String getJsConstructor(ClassElement element) { |
| 231 return namer.isolatePropertiesAccess(element); | 231 return namer.isolatePropertiesAccess(element); |
| 232 } | 232 } |
| 233 | 233 |
| 234 js.Expression visitMap(MapConstant constant) { | 234 jsAst.Expression visitMap(MapConstant constant) { |
| 235 js.Expression jsMap() { | 235 jsAst.Expression jsMap() { |
| 236 List<js.Property> properties = <js.Property>[]; | 236 List<jsAst.Property> properties = <jsAst.Property>[]; |
| 237 int valueIndex = 0; | 237 int valueIndex = 0; |
| 238 for (int i = 0; i < constant.keys.entries.length; i++) { | 238 for (int i = 0; i < constant.keys.entries.length; i++) { |
| 239 StringConstant key = constant.keys.entries[i]; | 239 StringConstant key = constant.keys.entries[i]; |
| 240 if (key.value == MapConstant.PROTO_PROPERTY) continue; | 240 if (key.value == MapConstant.PROTO_PROPERTY) continue; |
| 241 | 241 |
| 242 // Keys in literal maps must be emitted in place. | 242 // Keys in literal maps must be emitted in place. |
| 243 js.Literal keyExpression = _visit(key); | 243 jsAst.Literal keyExpression = _visit(key); |
| 244 js.Expression valueExpression = | 244 jsAst.Expression valueExpression = |
| 245 _reference(constant.values[valueIndex++]); | 245 _reference(constant.values[valueIndex++]); |
| 246 properties.add(new js.Property(keyExpression, valueExpression)); | 246 properties.add(new jsAst.Property(keyExpression, valueExpression)); |
| 247 } | 247 } |
| 248 if (valueIndex != constant.values.length) { | 248 if (valueIndex != constant.values.length) { |
| 249 compiler.internalError("Bad value count."); | 249 compiler.internalError("Bad value count."); |
| 250 } | 250 } |
| 251 return new js.ObjectInitializer(properties); | 251 return new jsAst.ObjectInitializer(properties); |
| 252 } | 252 } |
| 253 | 253 |
| 254 void badFieldCountError() { | 254 void badFieldCountError() { |
| 255 compiler.internalError( | 255 compiler.internalError( |
| 256 "Compiler and ConstantMap disagree on number of fields."); | 256 "Compiler and ConstantMap disagree on number of fields."); |
| 257 } | 257 } |
| 258 | 258 |
| 259 ClassElement classElement = constant.type.element; | 259 ClassElement classElement = constant.type.element; |
| 260 | 260 |
| 261 List<js.Expression> arguments = <js.Expression>[]; | 261 List<jsAst.Expression> arguments = <jsAst.Expression>[]; |
| 262 | 262 |
| 263 // The arguments of the JavaScript constructor for any given Dart class | 263 // The arguments of the JavaScript constructor for any given Dart class |
| 264 // are in the same order as the members of the class element. | 264 // are in the same order as the members of the class element. |
| 265 int emittedArgumentCount = 0; | 265 int emittedArgumentCount = 0; |
| 266 classElement.implementation.forEachInstanceField( | 266 classElement.implementation.forEachInstanceField( |
| 267 (ClassElement enclosing, Element field) { | 267 (ClassElement enclosing, Element field) { |
| 268 if (field.name == MapConstant.LENGTH_NAME) { | 268 if (field.name == MapConstant.LENGTH_NAME) { |
| 269 arguments.add( | 269 arguments.add( |
| 270 new js.LiteralNumber('${constant.keys.entries.length}')); | 270 new jsAst.LiteralNumber('${constant.keys.entries.length}')); |
| 271 } else if (field.name == MapConstant.JS_OBJECT_NAME) { | 271 } else if (field.name == MapConstant.JS_OBJECT_NAME) { |
| 272 arguments.add(jsMap()); | 272 arguments.add(jsMap()); |
| 273 } else if (field.name == MapConstant.KEYS_NAME) { | 273 } else if (field.name == MapConstant.KEYS_NAME) { |
| 274 arguments.add(_reference(constant.keys)); | 274 arguments.add(_reference(constant.keys)); |
| 275 } else if (field.name == MapConstant.PROTO_VALUE) { | 275 } else if (field.name == MapConstant.PROTO_VALUE) { |
| 276 assert(constant.protoValue != null); | 276 assert(constant.protoValue != null); |
| 277 arguments.add(_reference(constant.protoValue)); | 277 arguments.add(_reference(constant.protoValue)); |
| 278 } else { | 278 } else { |
| 279 badFieldCountError(); | 279 badFieldCountError(); |
| 280 } | 280 } |
| 281 emittedArgumentCount++; | 281 emittedArgumentCount++; |
| 282 }, | 282 }, |
| 283 includeBackendMembers: true, | 283 includeBackendMembers: true, |
| 284 includeSuperMembers: true); | 284 includeSuperMembers: true); |
| 285 | 285 |
| 286 if ((constant.protoValue == null && emittedArgumentCount != 3) || | 286 if ((constant.protoValue == null && emittedArgumentCount != 3) || |
| 287 (constant.protoValue != null && emittedArgumentCount != 4)) { | 287 (constant.protoValue != null && emittedArgumentCount != 4)) { |
| 288 badFieldCountError(); | 288 badFieldCountError(); |
| 289 } | 289 } |
| 290 | 290 |
| 291 return new js.New( | 291 return new jsAst.New( |
| 292 new js.VariableUse(getJsConstructor(classElement)), | 292 new jsAst.VariableUse(getJsConstructor(classElement)), |
| 293 arguments); | 293 arguments); |
| 294 } | 294 } |
| 295 | 295 |
| 296 js.Expression visitType(TypeConstant constant) { | 296 jsAst.Expression visitType(TypeConstant constant) { |
| 297 SourceString helperSourceName = const SourceString('createRuntimeType'); | 297 SourceString helperSourceName = const SourceString('createRuntimeType'); |
| 298 Element helper = compiler.findHelper(helperSourceName); | 298 Element helper = compiler.findHelper(helperSourceName); |
| 299 JavaScriptBackend backend = compiler.backend; | 299 JavaScriptBackend backend = compiler.backend; |
| 300 String helperName = backend.namer.getName(helper); | 300 String helperName = backend.namer.getName(helper); |
| 301 DartType type = constant.representedType; | 301 DartType type = constant.representedType; |
| 302 Element element = type.element; | 302 Element element = type.element; |
| 303 String name = backend.rti.getRawTypeRepresentation(type); | 303 String name = backend.rti.getRawTypeRepresentation(type); |
| 304 js.Expression typeName = new js.LiteralString("'$name'"); | 304 jsAst.Expression typeName = new jsAst.LiteralString("'$name'"); |
| 305 return new js.Call( | 305 return new jsAst.Call( |
| 306 new js.PropertyAccess.field( | 306 new jsAst.PropertyAccess.field( |
| 307 new js.VariableUse(namer.CURRENT_ISOLATE), | 307 new jsAst.VariableUse(namer.CURRENT_ISOLATE), |
| 308 helperName), | 308 helperName), |
| 309 [typeName]); | 309 [typeName]); |
| 310 } | 310 } |
| 311 | 311 |
| 312 js.Expression visitConstructed(ConstructedConstant constant) { | 312 jsAst.Expression visitConstructed(ConstructedConstant constant) { |
| 313 return new js.New( | 313 return new jsAst.New( |
| 314 new js.VariableUse(getJsConstructor(constant.type.element)), | 314 new jsAst.VariableUse(getJsConstructor(constant.type.element)), |
| 315 _array(constant.fields)); | 315 _array(constant.fields)); |
| 316 } | 316 } |
| 317 | 317 |
| 318 List<js.Expression> _array(List<Constant> values) { | 318 List<jsAst.Expression> _array(List<Constant> values) { |
| 319 List<js.Expression> valueList = <js.Expression>[]; | 319 List<jsAst.Expression> valueList = <jsAst.Expression>[]; |
| 320 for (int i = 0; i < values.length; i++) { | 320 for (int i = 0; i < values.length; i++) { |
| 321 valueList.add(_reference(values[i])); | 321 valueList.add(_reference(values[i])); |
| 322 } | 322 } |
| 323 return valueList; | 323 return valueList; |
| 324 } | 324 } |
| 325 } | 325 } |
| OLD | NEW |