| 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 class Constant implements Hashable { | 5 class Constant implements Hashable { |
| 6 const Constant(); | 6 const Constant(); |
| 7 | 7 |
| 8 bool isNull() => false; | 8 bool isNull() => false; |
| 9 bool isBool() => false; | 9 bool isBool() => false; |
| 10 bool isTrue() => false; | 10 bool isTrue() => false; |
| 11 bool isFalse() => false; | 11 bool isFalse() => false; |
| 12 bool isInt() => false; | 12 bool isInt() => false; |
| 13 bool isDouble() => false; | 13 bool isDouble() => false; |
| 14 bool isNum() => false; | 14 bool isNum() => false; |
| 15 bool isString() => false; | 15 bool isString() => false; |
| 16 bool isList() => false; | 16 bool isList() => false; |
| 17 bool isMap() => false; | 17 bool isMap() => false; |
| 18 bool isConstructedObject() => false; | 18 bool isConstructedObject() => false; |
| 19 /** Returns true if the constant is null, a bool, a number or a string. */ | 19 /** Returns true if the constant is null, a bool, a number or a string. */ |
| 20 bool isPrimitive() => false; | 20 bool isPrimitive() => false; |
| 21 /** Returns true if the constant is a list, a map or a constructed object. */ | 21 /** Returns true if the constant is a list, a map or a constructed object. */ |
| 22 bool isObject() => false; | 22 bool isObject() => false; |
| 23 | 23 |
| 24 abstract void writeJsCode(StringBuffer buffer, ConstantHandler handler); | 24 abstract void _writeJsCode(StringBuffer buffer, ConstantHandler handler); |
| 25 /** | 25 /** |
| 26 * Unless the constant can be emitted multiple times (as for numbers and | 26 * Unless the constant can be emitted multiple times (as for numbers and |
| 27 * strings) adds its canonical name to the buffer. | 27 * strings) adds its canonical name to the buffer. |
| 28 */ | 28 */ |
| 29 abstract void writeCanonicalizedJsCode(StringBuffer buffer, | 29 abstract void _writeCanonicalizedJsCode(StringBuffer buffer, |
| 30 ConstantHandler handler); | 30 ConstantHandler handler); |
| 31 abstract List<Constant> getDependencies(); | 31 abstract List<Constant> getDependencies(); |
| 32 } | 32 } |
| 33 | 33 |
| 34 class PrimitiveConstant extends Constant { | 34 class PrimitiveConstant extends Constant { |
| 35 abstract get value(); | 35 abstract get value(); |
| 36 const PrimitiveConstant(); | 36 const PrimitiveConstant(); |
| 37 bool isPrimitive() => true; | 37 bool isPrimitive() => true; |
| 38 | 38 |
| 39 bool operator ==(var other) { | 39 bool operator ==(var other) { |
| 40 if (other is !PrimitiveConstant) return false; | 40 if (other is !PrimitiveConstant) return false; |
| 41 PrimitiveConstant otherPrimitive = other; | 41 PrimitiveConstant otherPrimitive = other; |
| 42 // We use == instead of === so that DartStrings compare correctly. | 42 // We use == instead of === so that DartStrings compare correctly. |
| 43 return value == otherPrimitive.value; | 43 return value == otherPrimitive.value; |
| 44 } | 44 } |
| 45 | 45 |
| 46 String toString() => value.toString(); | 46 String toString() => value.toString(); |
| 47 // Primitive constants don't have dependencies. | 47 // Primitive constants don't have dependencies. |
| 48 List<Constant> getDependencies() => const <Constant>[]; | 48 List<Constant> getDependencies() => const <Constant>[]; |
| 49 abstract DartString toDartString(); | 49 abstract DartString toDartString(); |
| 50 | 50 |
| 51 void writeCanonicalizedJsCode(StringBuffer buffer, ConstantHandler handler) { | 51 void _writeCanonicalizedJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 52 writeJsCode(buffer, handler); | 52 _writeJsCode(buffer, handler); |
| 53 } | 53 } |
| 54 } | 54 } |
| 55 | 55 |
| 56 class NullConstant extends PrimitiveConstant { | 56 class NullConstant extends PrimitiveConstant { |
| 57 factory NullConstant() => const NullConstant._internal(); | 57 factory NullConstant() => const NullConstant._internal(); |
| 58 const NullConstant._internal(); | 58 const NullConstant._internal(); |
| 59 bool isNull() => true; | 59 bool isNull() => true; |
| 60 get value() => null; | 60 get value() => null; |
| 61 | 61 |
| 62 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 62 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 63 buffer.add("(void 0)"); | 63 buffer.add("(void 0)"); |
| 64 } | 64 } |
| 65 | 65 |
| 66 // The magic constant has no meaning. It is just a random value. | 66 // The magic constant has no meaning. It is just a random value. |
| 67 int hashCode() => 785965825; | 67 int hashCode() => 785965825; |
| 68 DartString toDartString() => const LiteralDartString("null"); | 68 DartString toDartString() => const LiteralDartString("null"); |
| 69 } | 69 } |
| 70 | 70 |
| 71 class NumConstant extends PrimitiveConstant { | 71 class NumConstant extends PrimitiveConstant { |
| 72 abstract num get value(); | 72 abstract num get value(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 90 case 9: return const IntConstant._internal(9); | 90 case 9: return const IntConstant._internal(9); |
| 91 case 10: return const IntConstant._internal(10); | 91 case 10: return const IntConstant._internal(10); |
| 92 case -1: return const IntConstant._internal(-1); | 92 case -1: return const IntConstant._internal(-1); |
| 93 case -2: return const IntConstant._internal(-2); | 93 case -2: return const IntConstant._internal(-2); |
| 94 default: return new IntConstant._internal(value); | 94 default: return new IntConstant._internal(value); |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 const IntConstant._internal(this.value); | 97 const IntConstant._internal(this.value); |
| 98 bool isInt() => true; | 98 bool isInt() => true; |
| 99 | 99 |
| 100 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 100 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 101 buffer.add("$value"); | 101 buffer.add("$value"); |
| 102 } | 102 } |
| 103 | 103 |
| 104 // We have to override the equality operator so that ints and doubles are | 104 // We have to override the equality operator so that ints and doubles are |
| 105 // treated as separate constants. | 105 // treated as separate constants. |
| 106 // The is [:!IntConstant:] check at the beginning of the function makes sure | 106 // The is [:!IntConstant:] check at the beginning of the function makes sure |
| 107 // that we compare only equal to integer constants. | 107 // that we compare only equal to integer constants. |
| 108 bool operator ==(var other) { | 108 bool operator ==(var other) { |
| 109 if (other is !IntConstant) return false; | 109 if (other is !IntConstant) return false; |
| 110 IntConstant otherInt = other; | 110 IntConstant otherInt = other; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 128 return const DoubleConstant._internal(0.0); | 128 return const DoubleConstant._internal(0.0); |
| 129 } else if (value == 1.0) { | 129 } else if (value == 1.0) { |
| 130 return const DoubleConstant._internal(1.0); | 130 return const DoubleConstant._internal(1.0); |
| 131 } else { | 131 } else { |
| 132 return new DoubleConstant._internal(value); | 132 return new DoubleConstant._internal(value); |
| 133 } | 133 } |
| 134 } | 134 } |
| 135 const DoubleConstant._internal(this.value); | 135 const DoubleConstant._internal(this.value); |
| 136 bool isDouble() => true; | 136 bool isDouble() => true; |
| 137 | 137 |
| 138 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 138 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 139 if (value.isNaN()) { | 139 if (value.isNaN()) { |
| 140 buffer.add("(0/0)"); | 140 buffer.add("(0/0)"); |
| 141 } else if (value == double.INFINITY) { | 141 } else if (value == double.INFINITY) { |
| 142 buffer.add("(1/0)"); | 142 buffer.add("(1/0)"); |
| 143 } else if (value == -double.INFINITY) { | 143 } else if (value == -double.INFINITY) { |
| 144 buffer.add("(-1/0)"); | 144 buffer.add("(-1/0)"); |
| 145 } else { | 145 } else { |
| 146 buffer.add("$value"); | 146 buffer.add("$value"); |
| 147 } | 147 } |
| 148 } | 148 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 179 abstract BoolConstant negate(); | 179 abstract BoolConstant negate(); |
| 180 } | 180 } |
| 181 | 181 |
| 182 class TrueConstant extends BoolConstant { | 182 class TrueConstant extends BoolConstant { |
| 183 final bool value = true; | 183 final bool value = true; |
| 184 | 184 |
| 185 factory TrueConstant() => const TrueConstant._internal(); | 185 factory TrueConstant() => const TrueConstant._internal(); |
| 186 const TrueConstant._internal() : super._internal(); | 186 const TrueConstant._internal() : super._internal(); |
| 187 bool isTrue() => true; | 187 bool isTrue() => true; |
| 188 | 188 |
| 189 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 189 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 190 buffer.add("true"); | 190 buffer.add("true"); |
| 191 } | 191 } |
| 192 | 192 |
| 193 FalseConstant negate() => new FalseConstant(); | 193 FalseConstant negate() => new FalseConstant(); |
| 194 | 194 |
| 195 bool operator ==(var other) => this === other; | 195 bool operator ==(var other) => this === other; |
| 196 // The magic constant is just a random value. It does not have any | 196 // The magic constant is just a random value. It does not have any |
| 197 // significance. | 197 // significance. |
| 198 int hashCode() => 499; | 198 int hashCode() => 499; |
| 199 DartString toDartString() => const LiteralDartString("true"); | 199 DartString toDartString() => const LiteralDartString("true"); |
| 200 } | 200 } |
| 201 | 201 |
| 202 class FalseConstant extends BoolConstant { | 202 class FalseConstant extends BoolConstant { |
| 203 final bool value = false; | 203 final bool value = false; |
| 204 | 204 |
| 205 factory FalseConstant() => const FalseConstant._internal(); | 205 factory FalseConstant() => const FalseConstant._internal(); |
| 206 const FalseConstant._internal() : super._internal(); | 206 const FalseConstant._internal() : super._internal(); |
| 207 bool isFalse() => true; | 207 bool isFalse() => true; |
| 208 | 208 |
| 209 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 209 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 210 buffer.add("false"); | 210 buffer.add("false"); |
| 211 } | 211 } |
| 212 | 212 |
| 213 TrueConstant negate() => new TrueConstant(); | 213 TrueConstant negate() => new TrueConstant(); |
| 214 | 214 |
| 215 bool operator ==(var other) => this === other; | 215 bool operator ==(var other) => this === other; |
| 216 // The magic constant is just a random value. It does not have any | 216 // The magic constant is just a random value. It does not have any |
| 217 // significance. | 217 // significance. |
| 218 int hashCode() => 536555975; | 218 int hashCode() => 536555975; |
| 219 DartString toDartString() => const LiteralDartString("false"); | 219 DartString toDartString() => const LiteralDartString("false"); |
| 220 } | 220 } |
| 221 | 221 |
| 222 class StringConstant extends PrimitiveConstant { | 222 class StringConstant extends PrimitiveConstant { |
| 223 final DartString value; | 223 final DartString value; |
| 224 int _hashCode; | 224 int _hashCode; |
| 225 | 225 |
| 226 StringConstant(this.value) { | 226 StringConstant(this.value) { |
| 227 // TODO(floitsch): cache StringConstants. | 227 // TODO(floitsch): cache StringConstants. |
| 228 // TODO(floitsch): compute hashcode without calling toString() on the | 228 // TODO(floitsch): compute hashcode without calling toString() on the |
| 229 // DartString. | 229 // DartString. |
| 230 _hashCode = value.slowToString().hashCode(); | 230 _hashCode = value.slowToString().hashCode(); |
| 231 } | 231 } |
| 232 bool isString() => true; | 232 bool isString() => true; |
| 233 | 233 |
| 234 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 234 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 235 buffer.add("'"); | 235 buffer.add("'"); |
| 236 ConstantHandler.writeEscapedString(value, buffer, (reason) { | 236 ConstantHandler.writeEscapedString(value, buffer, (reason) { |
| 237 throw new CompilerCancelledException(reason); | 237 throw new CompilerCancelledException(reason); |
| 238 }); | 238 }); |
| 239 buffer.add("'"); | 239 buffer.add("'"); |
| 240 } | 240 } |
| 241 | 241 |
| 242 bool operator ==(var other) { | 242 bool operator ==(var other) { |
| 243 if (other is !StringConstant) return false; | 243 if (other is !StringConstant) return false; |
| 244 StringConstant otherString = other; | 244 StringConstant otherString = other; |
| 245 return (_hashCode == otherString._hashCode) && (value == otherString.value); | 245 return (_hashCode == otherString._hashCode) && (value == otherString.value); |
| 246 } | 246 } |
| 247 | 247 |
| 248 int hashCode() => _hashCode; | 248 int hashCode() => _hashCode; |
| 249 DartString toDartString() => value; | 249 DartString toDartString() => value; |
| 250 } | 250 } |
| 251 | 251 |
| 252 class ObjectConstant extends Constant { | 252 class ObjectConstant extends Constant { |
| 253 final Type type; | 253 final Type type; |
| 254 | 254 |
| 255 ObjectConstant(this.type); | 255 ObjectConstant(this.type); |
| 256 bool isObject() => true; | 256 bool isObject() => true; |
| 257 | 257 |
| 258 // TODO(1603): The class should be marked as abstract, but the VM doesn't | 258 // TODO(1603): The class should be marked as abstract, but the VM doesn't |
| 259 // currently allow this. | 259 // currently allow this. |
| 260 abstract int hashCode(); | 260 abstract int hashCode(); |
| 261 | 261 |
| 262 void writeCanonicalizedJsCode(StringBuffer buffer, ConstantHandler handler) { | 262 void _writeCanonicalizedJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 263 String name = handler.getNameForConstant(this); | 263 String name = handler.getNameForConstant(this); |
| 264 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype"; | 264 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype"; |
| 265 buffer.add("$isolatePrototype.$name"); | 265 buffer.add("$isolatePrototype.$name"); |
| 266 } | 266 } |
| 267 } | 267 } |
| 268 | 268 |
| 269 class ListConstant extends ObjectConstant { | 269 class ListConstant extends ObjectConstant { |
| 270 final List<Constant> entries; | 270 final List<Constant> entries; |
| 271 int _hashCode; | 271 int _hashCode; |
| 272 | 272 |
| 273 ListConstant(Type type, this.entries) : super(type) { | 273 ListConstant(Type type, this.entries) : super(type) { |
| 274 // TODO(floitsch): create a better hash. | 274 // TODO(floitsch): create a better hash. |
| 275 int hash = 0; | 275 int hash = 0; |
| 276 for (Constant input in entries) hash ^= input.hashCode(); | 276 for (Constant input in entries) hash ^= input.hashCode(); |
| 277 _hashCode = hash; | 277 _hashCode = hash; |
| 278 } | 278 } |
| 279 bool isList() => true; | 279 bool isList() => true; |
| 280 | 280 |
| 281 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 281 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 282 // TODO(floitsch): we should not need to go through the compiler to make | 282 // TODO(floitsch): we should not need to go through the compiler to make |
| 283 // the list constant. | 283 // the list constant. |
| 284 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype"; | 284 String isolatePrototype = "${handler.compiler.namer.ISOLATE}.prototype"; |
| 285 buffer.add("$isolatePrototype.makeConstantList"); | 285 buffer.add("$isolatePrototype.makeConstantList"); |
| 286 buffer.add("(["); | 286 buffer.add("(["); |
| 287 for (int i = 0; i < entries.length; i++) { | 287 for (int i = 0; i < entries.length; i++) { |
| 288 if (i != 0) buffer.add(", "); | 288 if (i != 0) buffer.add(", "); |
| 289 Constant entry = entries[i]; | 289 Constant entry = entries[i]; |
| 290 entry.writeCanonicalizedJsCode(buffer, handler); | 290 handler.writeConstant(buffer, entry); |
| 291 } | 291 } |
| 292 buffer.add("])"); | 292 buffer.add("])"); |
| 293 } | 293 } |
| 294 | 294 |
| 295 bool operator ==(var other) { | 295 bool operator ==(var other) { |
| 296 if (other is !ListConstant) return false; | 296 if (other is !ListConstant) return false; |
| 297 ListConstant otherList = other; | 297 ListConstant otherList = other; |
| 298 if (hashCode() != otherList.hashCode()) return false; | 298 if (hashCode() != otherList.hashCode()) return false; |
| 299 // TODO(floitsch): verify that the generic types are the same. | 299 // TODO(floitsch): verify that the generic types are the same. |
| 300 if (entries.length != otherList.entries.length) return false; | 300 if (entries.length != otherList.entries.length) return false; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 | 332 |
| 333 MapConstant(Type type, this.keys, this.values, this.protoValue) | 333 MapConstant(Type type, this.keys, this.values, this.protoValue) |
| 334 : super(type) { | 334 : super(type) { |
| 335 // TODO(floitsch): create a better hash. | 335 // TODO(floitsch): create a better hash. |
| 336 int hash = 0; | 336 int hash = 0; |
| 337 for (Constant value in values) hash ^= value.hashCode(); | 337 for (Constant value in values) hash ^= value.hashCode(); |
| 338 _hashCode = hash; | 338 _hashCode = hash; |
| 339 } | 339 } |
| 340 bool isMap() => true; | 340 bool isMap() => true; |
| 341 | 341 |
| 342 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 342 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 343 | 343 |
| 344 void writeJsMap() { | 344 void writeJsMap() { |
| 345 buffer.add("{"); | 345 buffer.add("{"); |
| 346 int valueIndex = 0; | 346 int valueIndex = 0; |
| 347 for (int i = 0; i < keys.entries.length; i++) { | 347 for (int i = 0; i < keys.entries.length; i++) { |
| 348 StringConstant key = keys.entries[i]; | 348 StringConstant key = keys.entries[i]; |
| 349 if (key.value == const LiteralDartString(PROTO_PROPERTY)) continue; | 349 if (key.value == const LiteralDartString(PROTO_PROPERTY)) continue; |
| 350 | 350 |
| 351 if (valueIndex != 0) buffer.add(", "); | 351 if (valueIndex != 0) buffer.add(", "); |
| 352 | 352 |
| 353 key.writeJsCode(buffer, handler); | 353 key._writeJsCode(buffer, handler); |
| 354 buffer.add(": "); | 354 buffer.add(": "); |
| 355 Constant value = values[valueIndex++]; | 355 Constant value = values[valueIndex++]; |
| 356 value.writeCanonicalizedJsCode(buffer, handler); | 356 handler.writeConstant(buffer, value); |
| 357 } | 357 } |
| 358 buffer.add("}"); | 358 buffer.add("}"); |
| 359 if (valueIndex != values.length) { | 359 if (valueIndex != values.length) { |
| 360 handler.compiler.internalError("Bad value count."); | 360 handler.compiler.internalError("Bad value count."); |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 | 363 |
| 364 void badFieldCountError() { | 364 void badFieldCountError() { |
| 365 handler.compiler.internalError( | 365 handler.compiler.internalError( |
| 366 "Compiler and ConstantMap disagree on number of fields."); | 366 "Compiler and ConstantMap disagree on number of fields."); |
| 367 } | 367 } |
| 368 | 368 |
| 369 ClassElement classElement = type.element; | 369 ClassElement classElement = type.element; |
| 370 buffer.add("new "); | 370 buffer.add("new "); |
| 371 buffer.add(handler.getJsConstructor(classElement)); | 371 buffer.add(handler.getJsConstructor(classElement)); |
| 372 buffer.add("("); | 372 buffer.add("("); |
| 373 // The arguments of the JavaScript constructor for any given Dart class | 373 // The arguments of the JavaScript constructor for any given Dart class |
| 374 // are in the same order as the members of the class element. | 374 // are in the same order as the members of the class element. |
| 375 int emittedArgumentCount = 0; | 375 int emittedArgumentCount = 0; |
| 376 classElement.forEachInstanceField( | 376 classElement.forEachInstanceField( |
| 377 includeBackendMembers: true, | 377 includeBackendMembers: true, |
| 378 includeSuperMembers: true, | 378 includeSuperMembers: true, |
| 379 f: (ClassElement enclosing, Element field) { | 379 f: (ClassElement enclosing, Element field) { |
| 380 if (emittedArgumentCount != 0) buffer.add(", "); | 380 if (emittedArgumentCount != 0) buffer.add(", "); |
| 381 if (field.name == LENGTH_NAME) { | 381 if (field.name == LENGTH_NAME) { |
| 382 buffer.add(keys.entries.length); | 382 buffer.add(keys.entries.length); |
| 383 } else if (field.name == JS_OBJECT_NAME) { | 383 } else if (field.name == JS_OBJECT_NAME) { |
| 384 writeJsMap(); | 384 writeJsMap(); |
| 385 } else if (field.name == KEYS_NAME) { | 385 } else if (field.name == KEYS_NAME) { |
| 386 keys.writeCanonicalizedJsCode(buffer, handler); | 386 handler.writeConstant(buffer, keys); |
| 387 } else if (field.name == PROTO_VALUE) { | 387 } else if (field.name == PROTO_VALUE) { |
| 388 assert(protoValue !== null); | 388 assert(protoValue !== null); |
| 389 protoValue.writeCanonicalizedJsCode(buffer, handler); | 389 handler.writeConstant(buffer, protoValue); |
| 390 } else { | 390 } else { |
| 391 badFieldCountError(); | 391 badFieldCountError(); |
| 392 } | 392 } |
| 393 emittedArgumentCount++; | 393 emittedArgumentCount++; |
| 394 }); | 394 }); |
| 395 if ((protoValue === null && emittedArgumentCount != 3) || | 395 if ((protoValue === null && emittedArgumentCount != 3) || |
| 396 (protoValue !== null && emittedArgumentCount != 4)) { | 396 (protoValue !== null && emittedArgumentCount != 4)) { |
| 397 badFieldCountError(); | 397 badFieldCountError(); |
| 398 } | 398 } |
| 399 buffer.add(")"); | 399 buffer.add(")"); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 429 // TODO(floitsch): create a better hash. | 429 // TODO(floitsch): create a better hash. |
| 430 int hash = 0; | 430 int hash = 0; |
| 431 for (Constant field in fields) { | 431 for (Constant field in fields) { |
| 432 hash ^= field.hashCode(); | 432 hash ^= field.hashCode(); |
| 433 } | 433 } |
| 434 hash ^= type.element.hashCode(); | 434 hash ^= type.element.hashCode(); |
| 435 _hashCode = hash; | 435 _hashCode = hash; |
| 436 } | 436 } |
| 437 bool isConstructedObject() => true; | 437 bool isConstructedObject() => true; |
| 438 | 438 |
| 439 void writeJsCode(StringBuffer buffer, ConstantHandler handler) { | 439 void _writeJsCode(StringBuffer buffer, ConstantHandler handler) { |
| 440 buffer.add("new "); | 440 buffer.add("new "); |
| 441 buffer.add(handler.getJsConstructor(type.element)); | 441 buffer.add(handler.getJsConstructor(type.element)); |
| 442 buffer.add("("); | 442 buffer.add("("); |
| 443 for (int i = 0; i < fields.length; i++) { | 443 for (int i = 0; i < fields.length; i++) { |
| 444 if (i != 0) buffer.add(", "); | 444 if (i != 0) buffer.add(", "); |
| 445 Constant field = fields[i]; | 445 Constant field = fields[i]; |
| 446 field.writeCanonicalizedJsCode(buffer, handler); | 446 handler.writeConstant(buffer, field); |
| 447 } | 447 } |
| 448 buffer.add(")"); | 448 buffer.add(")"); |
| 449 } | 449 } |
| 450 | 450 |
| 451 bool operator ==(var otherVar) { | 451 bool operator ==(var otherVar) { |
| 452 if (otherVar is !ConstructedConstant) return false; | 452 if (otherVar is !ConstructedConstant) return false; |
| 453 ConstructedConstant other = otherVar; | 453 ConstructedConstant other = otherVar; |
| 454 if (hashCode() != other.hashCode()) return false; | 454 if (hashCode() != other.hashCode()) return false; |
| 455 // TODO(floitsch): verify that the (generic) types are the same. | 455 // TODO(floitsch): verify that the (generic) types are the same. |
| 456 if (type.element != other.type.element) return false; | 456 if (type.element != other.type.element) return false; |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 601 } | 601 } |
| 602 | 602 |
| 603 compiledConstants.forEach((Constant key, ignored) => addConstant(key)); | 603 compiledConstants.forEach((Constant key, ignored) => addConstant(key)); |
| 604 return result; | 604 return result; |
| 605 } | 605 } |
| 606 | 606 |
| 607 String getNameForConstant(Constant constant) { | 607 String getNameForConstant(Constant constant) { |
| 608 return compiledConstants[constant]; | 608 return compiledConstants[constant]; |
| 609 } | 609 } |
| 610 | 610 |
| 611 /** This function writes the constant in non-canonicalized form. */ |
| 611 StringBuffer writeJsCode(StringBuffer buffer, Constant value) { | 612 StringBuffer writeJsCode(StringBuffer buffer, Constant value) { |
| 612 value.writeJsCode(buffer, this); | 613 value._writeJsCode(buffer, this); |
| 613 return buffer; | 614 return buffer; |
| 614 } | 615 } |
| 615 | 616 |
| 617 StringBuffer writeConstant(StringBuffer buffer, Constant value) { |
| 618 value._writeCanonicalizedJsCode(buffer, this); |
| 619 return buffer; |
| 620 } |
| 621 |
| 616 StringBuffer writeJsCodeForVariable(StringBuffer buffer, | 622 StringBuffer writeJsCodeForVariable(StringBuffer buffer, |
| 617 VariableElement element) { | 623 VariableElement element) { |
| 618 if (!initialVariableValues.containsKey(element)) { | 624 if (!initialVariableValues.containsKey(element)) { |
| 619 compiler.internalError("No initial value for given element", | 625 compiler.internalError("No initial value for given element", |
| 620 element: element); | 626 element: element); |
| 621 } | 627 } |
| 622 Constant constant = initialVariableValues[element]; | 628 Constant constant = initialVariableValues[element]; |
| 623 if (constant.isObject()) { | 629 writeConstant(buffer, constant); |
| 624 String name = compiledConstants[constant]; | |
| 625 buffer.add("${compiler.namer.ISOLATE}.prototype.$name"); | |
| 626 } else { | |
| 627 writeJsCode(buffer, constant); | |
| 628 } | |
| 629 return buffer; | 630 return buffer; |
| 630 } | 631 } |
| 631 | 632 |
| 632 /** | 633 /** |
| 633 * Write the contents of the quoted string to a [StringBuffer] in | 634 * Write the contents of the quoted string to a [StringBuffer] in |
| 634 * a form that is valid as JavaScript string literal content. | 635 * a form that is valid as JavaScript string literal content. |
| 635 * The string is assumed quoted by single quote characters. | 636 * The string is assumed quoted by single quote characters. |
| 636 */ | 637 */ |
| 637 static void writeEscapedString(DartString string, | 638 static void writeEscapedString(DartString string, |
| 638 StringBuffer buffer, | 639 StringBuffer buffer, |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 Constant fieldValue = fieldValues[field]; | 1125 Constant fieldValue = fieldValues[field]; |
| 1125 if (fieldValue === null) { | 1126 if (fieldValue === null) { |
| 1126 // Use the default value. | 1127 // Use the default value. |
| 1127 fieldValue = compiler.compileVariable(field); | 1128 fieldValue = compiler.compileVariable(field); |
| 1128 } | 1129 } |
| 1129 jsNewArguments.add(fieldValue); | 1130 jsNewArguments.add(fieldValue); |
| 1130 }); | 1131 }); |
| 1131 return jsNewArguments; | 1132 return jsNewArguments; |
| 1132 } | 1133 } |
| 1133 } | 1134 } |
| OLD | NEW |