| 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 abstract class ConstantVisitor<R> { | 5 abstract class ConstantVisitor<R> { |
| 6 R visitSentinel(SentinelConstant constant); | 6 R visitSentinel(SentinelConstant constant); |
| 7 R visitFunction(FunctionConstant constant); | 7 R visitFunction(FunctionConstant constant); |
| 8 R visitNull(NullConstant constant); | 8 R visitNull(NullConstant constant); |
| 9 R visitInt(IntConstant constant); | 9 R visitInt(IntConstant constant); |
| 10 R visitDouble(DoubleConstant constant); | 10 R visitDouble(DoubleConstant constant); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 abstract accept(ConstantVisitor); | 47 abstract accept(ConstantVisitor); |
| 48 } | 48 } |
| 49 | 49 |
| 50 class SentinelConstant extends Constant { | 50 class SentinelConstant extends Constant { |
| 51 const SentinelConstant(); | 51 const SentinelConstant(); |
| 52 static final SENTINEL = const SentinelConstant(); | 52 static final SENTINEL = const SentinelConstant(); |
| 53 | 53 |
| 54 List<Constant> getDependencies() => const <Constant>[]; | 54 List<Constant> getDependencies() => const <Constant>[]; |
| 55 | 55 |
| 56 // Just use a random value. | 56 // Just use a random value. |
| 57 int hashCode() => 24297418; | 57 int get hashCode => 24297418; |
| 58 | 58 |
| 59 bool isSentinel() => true; | 59 bool isSentinel() => true; |
| 60 | 60 |
| 61 accept(ConstantVisitor visitor) => visitor.visitSentinel(this); | 61 accept(ConstantVisitor visitor) => visitor.visitSentinel(this); |
| 62 | 62 |
| 63 DartType computeType(Compiler compiler) => compiler.types.dynamicType; | 63 DartType computeType(Compiler compiler) => compiler.types.dynamicType; |
| 64 } | 64 } |
| 65 | 65 |
| 66 class FunctionConstant extends Constant { | 66 class FunctionConstant extends Constant { |
| 67 Element element; | 67 Element element; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 78 String toString() => element.toString(); | 78 String toString() => element.toString(); |
| 79 List<Constant> getDependencies() => const <Constant>[]; | 79 List<Constant> getDependencies() => const <Constant>[]; |
| 80 DartString toDartString() { | 80 DartString toDartString() { |
| 81 return new DartString.literal(element.name.slowToString()); | 81 return new DartString.literal(element.name.slowToString()); |
| 82 } | 82 } |
| 83 | 83 |
| 84 DartType computeType(Compiler compiler) { | 84 DartType computeType(Compiler compiler) { |
| 85 return compiler.functionClass.computeType(compiler); | 85 return compiler.functionClass.computeType(compiler); |
| 86 } | 86 } |
| 87 | 87 |
| 88 int hashCode() => (17 * element.hashCode()) & 0x7fffffff; | 88 int get hashCode => (17 * element.hashCode) & 0x7fffffff; |
| 89 | 89 |
| 90 accept(ConstantVisitor visitor) => visitor.visitFunction(this); | 90 accept(ConstantVisitor visitor) => visitor.visitFunction(this); |
| 91 } | 91 } |
| 92 | 92 |
| 93 abstract class PrimitiveConstant extends Constant { | 93 abstract class PrimitiveConstant extends Constant { |
| 94 abstract get value; | 94 abstract get value; |
| 95 const PrimitiveConstant(); | 95 const PrimitiveConstant(); |
| 96 bool isPrimitive() => true; | 96 bool isPrimitive() => true; |
| 97 | 97 |
| 98 bool operator ==(var other) { | 98 bool operator ==(var other) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 119 | 119 |
| 120 DartType computeType(Compiler compiler) { | 120 DartType computeType(Compiler compiler) { |
| 121 return compiler.nullClass.computeType(compiler); | 121 return compiler.nullClass.computeType(compiler); |
| 122 } | 122 } |
| 123 | 123 |
| 124 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { | 124 void _writeJsCode(CodeBuffer buffer, ConstantHandler handler) { |
| 125 buffer.add(JsNull); | 125 buffer.add(JsNull); |
| 126 } | 126 } |
| 127 | 127 |
| 128 // The magic constant has no meaning. It is just a random value. | 128 // The magic constant has no meaning. It is just a random value. |
| 129 int hashCode() => 785965825; | 129 int get hashCode => 785965825; |
| 130 DartString toDartString() => const LiteralDartString("null"); | 130 DartString toDartString() => const LiteralDartString("null"); |
| 131 | 131 |
| 132 accept(ConstantVisitor visitor) => visitor.visitNull(this); | 132 accept(ConstantVisitor visitor) => visitor.visitNull(this); |
| 133 } | 133 } |
| 134 | 134 |
| 135 abstract class NumConstant extends PrimitiveConstant { | 135 abstract class NumConstant extends PrimitiveConstant { |
| 136 abstract num get value; | 136 abstract num get value; |
| 137 const NumConstant(); | 137 const NumConstant(); |
| 138 bool isNum() => true; | 138 bool isNum() => true; |
| 139 } | 139 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 168 // We have to override the equality operator so that ints and doubles are | 168 // We have to override the equality operator so that ints and doubles are |
| 169 // treated as separate constants. | 169 // treated as separate constants. |
| 170 // The is [:!IntConstant:] check at the beginning of the function makes sure | 170 // The is [:!IntConstant:] check at the beginning of the function makes sure |
| 171 // that we compare only equal to integer constants. | 171 // that we compare only equal to integer constants. |
| 172 bool operator ==(var other) { | 172 bool operator ==(var other) { |
| 173 if (other is !IntConstant) return false; | 173 if (other is !IntConstant) return false; |
| 174 IntConstant otherInt = other; | 174 IntConstant otherInt = other; |
| 175 return value == otherInt.value; | 175 return value == otherInt.value; |
| 176 } | 176 } |
| 177 | 177 |
| 178 int hashCode() => value.hashCode(); | 178 int get hashCode => value.hashCode; |
| 179 DartString toDartString() => new DartString.literal(value.toString()); | 179 DartString toDartString() => new DartString.literal(value.toString()); |
| 180 | 180 |
| 181 accept(ConstantVisitor visitor) => visitor.visitInt(this); | 181 accept(ConstantVisitor visitor) => visitor.visitInt(this); |
| 182 } | 182 } |
| 183 | 183 |
| 184 class DoubleConstant extends NumConstant { | 184 class DoubleConstant extends NumConstant { |
| 185 final double value; | 185 final double value; |
| 186 factory DoubleConstant(double value) { | 186 factory DoubleConstant(double value) { |
| 187 if (value.isNaN()) { | 187 if (value.isNaN()) { |
| 188 return const DoubleConstant._internal(double.NAN); | 188 return const DoubleConstant._internal(double.NAN); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 214 double otherValue = otherDouble.value; | 214 double otherValue = otherDouble.value; |
| 215 if (value == 0.0 && otherValue == 0.0) { | 215 if (value == 0.0 && otherValue == 0.0) { |
| 216 return value.isNegative() == otherValue.isNegative(); | 216 return value.isNegative() == otherValue.isNegative(); |
| 217 } else if (value.isNaN()) { | 217 } else if (value.isNaN()) { |
| 218 return otherValue.isNaN(); | 218 return otherValue.isNaN(); |
| 219 } else { | 219 } else { |
| 220 return value == otherValue; | 220 return value == otherValue; |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 | 223 |
| 224 int hashCode() => value.hashCode(); | 224 int get hashCode => value.hashCode; |
| 225 DartString toDartString() => new DartString.literal(value.toString()); | 225 DartString toDartString() => new DartString.literal(value.toString()); |
| 226 | 226 |
| 227 accept(ConstantVisitor visitor) => visitor.visitDouble(this); | 227 accept(ConstantVisitor visitor) => visitor.visitDouble(this); |
| 228 } | 228 } |
| 229 | 229 |
| 230 abstract class BoolConstant extends PrimitiveConstant { | 230 abstract class BoolConstant extends PrimitiveConstant { |
| 231 factory BoolConstant(value) { | 231 factory BoolConstant(value) { |
| 232 return value ? new TrueConstant() : new FalseConstant(); | 232 return value ? new TrueConstant() : new FalseConstant(); |
| 233 } | 233 } |
| 234 const BoolConstant._internal(); | 234 const BoolConstant._internal(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 246 | 246 |
| 247 factory TrueConstant() => const TrueConstant._internal(); | 247 factory TrueConstant() => const TrueConstant._internal(); |
| 248 const TrueConstant._internal() : super._internal(); | 248 const TrueConstant._internal() : super._internal(); |
| 249 bool isTrue() => true; | 249 bool isTrue() => true; |
| 250 | 250 |
| 251 FalseConstant negate() => new FalseConstant(); | 251 FalseConstant negate() => new FalseConstant(); |
| 252 | 252 |
| 253 bool operator ==(var other) => identical(this, other); | 253 bool operator ==(var other) => identical(this, other); |
| 254 // The magic constant is just a random value. It does not have any | 254 // The magic constant is just a random value. It does not have any |
| 255 // significance. | 255 // significance. |
| 256 int hashCode() => 499; | 256 int get hashCode => 499; |
| 257 DartString toDartString() => const LiteralDartString("true"); | 257 DartString toDartString() => const LiteralDartString("true"); |
| 258 | 258 |
| 259 accept(ConstantVisitor visitor) => visitor.visitTrue(this); | 259 accept(ConstantVisitor visitor) => visitor.visitTrue(this); |
| 260 } | 260 } |
| 261 | 261 |
| 262 class FalseConstant extends BoolConstant { | 262 class FalseConstant extends BoolConstant { |
| 263 final bool value = false; | 263 final bool value = false; |
| 264 | 264 |
| 265 factory FalseConstant() => const FalseConstant._internal(); | 265 factory FalseConstant() => const FalseConstant._internal(); |
| 266 const FalseConstant._internal() : super._internal(); | 266 const FalseConstant._internal() : super._internal(); |
| 267 bool isFalse() => true; | 267 bool isFalse() => true; |
| 268 | 268 |
| 269 TrueConstant negate() => new TrueConstant(); | 269 TrueConstant negate() => new TrueConstant(); |
| 270 | 270 |
| 271 bool operator ==(var other) => identical(this, other); | 271 bool operator ==(var other) => identical(this, other); |
| 272 // The magic constant is just a random value. It does not have any | 272 // The magic constant is just a random value. It does not have any |
| 273 // significance. | 273 // significance. |
| 274 int hashCode() => 536555975; | 274 int get hashCode => 536555975; |
| 275 DartString toDartString() => const LiteralDartString("false"); | 275 DartString toDartString() => const LiteralDartString("false"); |
| 276 | 276 |
| 277 accept(ConstantVisitor visitor) => visitor.visitFalse(this); | 277 accept(ConstantVisitor visitor) => visitor.visitFalse(this); |
| 278 } | 278 } |
| 279 | 279 |
| 280 class StringConstant extends PrimitiveConstant { | 280 class StringConstant extends PrimitiveConstant { |
| 281 final DartString value; | 281 final DartString value; |
| 282 int _hashCode; | 282 final int hashCode; |
| 283 final Node node; | 283 final Node node; |
| 284 | 284 |
| 285 StringConstant(this.value, this.node) { | 285 // TODO(floitsch): cache StringConstants. |
| 286 // TODO(floitsch): cache StringConstants. | 286 // TODO(floitsch): compute hashcode without calling toString() on the |
| 287 // TODO(floitsch): compute hashcode without calling toString() on the | 287 // DartString. |
| 288 // DartString. | 288 StringConstant(DartString value, this.node) |
| 289 _hashCode = value.slowToString().hashCode(); | 289 : this.value = value, |
| 290 } | 290 this.hashCode = value.slowToString().hashCode; |
| 291 bool isString() => true; | 291 bool isString() => true; |
| 292 | 292 |
| 293 DartType computeType(Compiler compiler) { | 293 DartType computeType(Compiler compiler) { |
| 294 return compiler.stringClass.computeType(compiler); | 294 return compiler.stringClass.computeType(compiler); |
| 295 } | 295 } |
| 296 | 296 |
| 297 bool operator ==(var other) { | 297 bool operator ==(var other) { |
| 298 if (other is !StringConstant) return false; | 298 if (other is !StringConstant) return false; |
| 299 StringConstant otherString = other; | 299 StringConstant otherString = other; |
| 300 return (_hashCode == otherString._hashCode) && (value == otherString.value); | 300 return (hashCode == otherString.hashCode) && (value == otherString.value); |
| 301 } | 301 } |
| 302 | 302 |
| 303 int hashCode() => _hashCode; | |
| 304 DartString toDartString() => value; | 303 DartString toDartString() => value; |
| 305 int get length => value.length; | 304 int get length => value.length; |
| 306 | 305 |
| 307 accept(ConstantVisitor visitor) => visitor.visitString(this); | 306 accept(ConstantVisitor visitor) => visitor.visitString(this); |
| 308 } | 307 } |
| 309 | 308 |
| 310 abstract class ObjectConstant extends Constant { | 309 abstract class ObjectConstant extends Constant { |
| 311 final DartType type; | 310 final DartType type; |
| 312 | 311 |
| 313 ObjectConstant(this.type); | 312 ObjectConstant(this.type); |
| 314 bool isObject() => true; | 313 bool isObject() => true; |
| 315 | 314 |
| 316 DartType computeType(Compiler compiler) => type; | 315 DartType computeType(Compiler compiler) => type; |
| 317 | 316 |
| 318 // TODO(1603): The class should be marked as abstract, but the VM doesn't | 317 // TODO(1603): The class should be marked as abstract, but the VM doesn't |
| 319 // currently allow this. | 318 // currently allow this. |
| 320 abstract int hashCode(); | 319 abstract int get hashCode; |
| 321 } | 320 } |
| 322 | 321 |
| 323 class ListConstant extends ObjectConstant { | 322 class ListConstant extends ObjectConstant { |
| 324 final List<Constant> entries; | 323 final List<Constant> entries; |
| 325 int _hashCode; | 324 final int hashCode; |
| 326 | 325 |
| 327 ListConstant(DartType type, this.entries) : super(type) { | 326 ListConstant(DartType type, List<Constant> entries) |
| 327 : this.entries = entries, |
| 328 hashCode = _computeHash(entries), |
| 329 super(type); |
| 330 bool isList() => true; |
| 331 |
| 332 static int _computeHash(List<Constant> entries) { |
| 328 // TODO(floitsch): create a better hash. | 333 // TODO(floitsch): create a better hash. |
| 329 int hash = 0; | 334 int hash = 0; |
| 330 for (Constant input in entries) hash ^= input.hashCode(); | 335 for (Constant input in entries) hash ^= input.hashCode; |
| 331 _hashCode = hash; | 336 return hash; |
| 332 } | 337 } |
| 333 bool isList() => true; | |
| 334 | 338 |
| 335 bool operator ==(var other) { | 339 bool operator ==(var other) { |
| 336 if (other is !ListConstant) return false; | 340 if (other is !ListConstant) return false; |
| 337 ListConstant otherList = other; | 341 ListConstant otherList = other; |
| 338 if (hashCode() != otherList.hashCode()) return false; | 342 if (hashCode != otherList.hashCode) return false; |
| 339 // TODO(floitsch): verify that the generic types are the same. | 343 // TODO(floitsch): verify that the generic types are the same. |
| 340 if (entries.length != otherList.entries.length) return false; | 344 if (entries.length != otherList.entries.length) return false; |
| 341 for (int i = 0; i < entries.length; i++) { | 345 for (int i = 0; i < entries.length; i++) { |
| 342 if (entries[i] != otherList.entries[i]) return false; | 346 if (entries[i] != otherList.entries[i]) return false; |
| 343 } | 347 } |
| 344 return true; | 348 return true; |
| 345 } | 349 } |
| 346 | 350 |
| 347 int hashCode() => _hashCode; | |
| 348 | |
| 349 List<Constant> getDependencies() => entries; | 351 List<Constant> getDependencies() => entries; |
| 350 | 352 |
| 351 int get length => entries.length; | 353 int get length => entries.length; |
| 352 | 354 |
| 353 accept(ConstantVisitor visitor) => visitor.visitList(this); | 355 accept(ConstantVisitor visitor) => visitor.visitList(this); |
| 354 } | 356 } |
| 355 | 357 |
| 356 class MapConstant extends ObjectConstant { | 358 class MapConstant extends ObjectConstant { |
| 357 /** | 359 /** |
| 358 * The [PROTO_PROPERTY] must not be used as normal property in any JavaScript | 360 * The [PROTO_PROPERTY] must not be used as normal property in any JavaScript |
| 359 * object. It would change the prototype chain. | 361 * object. It would change the prototype chain. |
| 360 */ | 362 */ |
| 361 static const LiteralDartString PROTO_PROPERTY = | 363 static const LiteralDartString PROTO_PROPERTY = |
| 362 const LiteralDartString("__proto__"); | 364 const LiteralDartString("__proto__"); |
| 363 | 365 |
| 364 /** The dart class implementing constant map literals. */ | 366 /** The dart class implementing constant map literals. */ |
| 365 static const SourceString DART_CLASS = const SourceString("ConstantMap"); | 367 static const SourceString DART_CLASS = const SourceString("ConstantMap"); |
| 366 static const SourceString DART_PROTO_CLASS = | 368 static const SourceString DART_PROTO_CLASS = |
| 367 const SourceString("ConstantProtoMap"); | 369 const SourceString("ConstantProtoMap"); |
| 368 static const SourceString LENGTH_NAME = const SourceString("length"); | 370 static const SourceString LENGTH_NAME = const SourceString("length"); |
| 369 static const SourceString JS_OBJECT_NAME = const SourceString("_jsObject"); | 371 static const SourceString JS_OBJECT_NAME = const SourceString("_jsObject"); |
| 370 static const SourceString KEYS_NAME = const SourceString("_keys"); | 372 static const SourceString KEYS_NAME = const SourceString("_keys"); |
| 371 static const SourceString PROTO_VALUE = const SourceString("_protoValue"); | 373 static const SourceString PROTO_VALUE = const SourceString("_protoValue"); |
| 372 | 374 |
| 373 final ListConstant keys; | 375 final ListConstant keys; |
| 374 final List<Constant> values; | 376 final List<Constant> values; |
| 375 final Constant protoValue; | 377 final Constant protoValue; |
| 376 int _hashCode; | 378 final int hashCode; |
| 377 | 379 |
| 378 MapConstant(DartType type, this.keys, this.values, this.protoValue) | 380 MapConstant(DartType type, this.keys, List<Constant> values, this.protoValue) |
| 379 : super(type) { | 381 : this.values = values, |
| 382 this.hashCode = computeHash(values), |
| 383 super(type); |
| 384 bool isMap() => true; |
| 385 |
| 386 static int computeHash(List<Constant> values) { |
| 380 // TODO(floitsch): create a better hash. | 387 // TODO(floitsch): create a better hash. |
| 381 int hash = 0; | 388 int hash = 0; |
| 382 for (Constant value in values) hash ^= value.hashCode(); | 389 for (Constant value in values) hash ^= value.hashCode; |
| 383 _hashCode = hash; | 390 return hash; |
| 384 } | 391 } |
| 385 bool isMap() => true; | |
| 386 | 392 |
| 387 bool operator ==(var other) { | 393 bool operator ==(var other) { |
| 388 if (other is !MapConstant) return false; | 394 if (other is !MapConstant) return false; |
| 389 MapConstant otherMap = other; | 395 MapConstant otherMap = other; |
| 390 if (hashCode() != otherMap.hashCode()) return false; | 396 if (hashCode != otherMap.hashCode) return false; |
| 391 // TODO(floitsch): verify that the generic types are the same. | 397 // TODO(floitsch): verify that the generic types are the same. |
| 392 if (keys != otherMap.keys) return false; | 398 if (keys != otherMap.keys) return false; |
| 393 for (int i = 0; i < values.length; i++) { | 399 for (int i = 0; i < values.length; i++) { |
| 394 if (values[i] != otherMap.values[i]) return false; | 400 if (values[i] != otherMap.values[i]) return false; |
| 395 } | 401 } |
| 396 return true; | 402 return true; |
| 397 } | 403 } |
| 398 | 404 |
| 399 int hashCode() => _hashCode; | |
| 400 | |
| 401 List<Constant> getDependencies() { | 405 List<Constant> getDependencies() { |
| 402 List<Constant> result = <Constant>[keys]; | 406 List<Constant> result = <Constant>[keys]; |
| 403 result.addAll(values); | 407 result.addAll(values); |
| 404 return result; | 408 return result; |
| 405 } | 409 } |
| 406 | 410 |
| 407 int get length => keys.length; | 411 int get length => keys.length; |
| 408 | 412 |
| 409 accept(ConstantVisitor visitor) => visitor.visitMap(this); | 413 accept(ConstantVisitor visitor) => visitor.visitMap(this); |
| 410 } | 414 } |
| 411 | 415 |
| 412 class ConstructedConstant extends ObjectConstant { | 416 class ConstructedConstant extends ObjectConstant { |
| 413 final List<Constant> fields; | 417 final List<Constant> fields; |
| 414 int _hashCode; | 418 final int hashCode; |
| 415 | 419 |
| 416 ConstructedConstant(DartType type, this.fields) : super(type) { | 420 ConstructedConstant(DartType type, List<Constant> fields) |
| 421 : this.fields = fields, |
| 422 hashCode = computeHash(type, fields), |
| 423 super(type) { |
| 417 assert(type != null); | 424 assert(type != null); |
| 425 } |
| 426 bool isConstructedObject() => true; |
| 427 |
| 428 static int computeHash(DartType type, List<Constant> fields) { |
| 418 // TODO(floitsch): create a better hash. | 429 // TODO(floitsch): create a better hash. |
| 419 int hash = 0; | 430 int hash = 0; |
| 420 for (Constant field in fields) { | 431 for (Constant field in fields) { |
| 421 hash ^= field.hashCode(); | 432 hash ^= field.hashCode; |
| 422 } | 433 } |
| 423 hash ^= type.element.hashCode(); | 434 hash ^= type.element.hashCode; |
| 424 _hashCode = hash; | 435 return hash; |
| 425 } | 436 } |
| 426 bool isConstructedObject() => true; | |
| 427 | 437 |
| 428 bool operator ==(var otherVar) { | 438 bool operator ==(var otherVar) { |
| 429 if (otherVar is !ConstructedConstant) return false; | 439 if (otherVar is !ConstructedConstant) return false; |
| 430 ConstructedConstant other = otherVar; | 440 ConstructedConstant other = otherVar; |
| 431 if (hashCode() != other.hashCode()) return false; | 441 if (hashCode != other.hashCode) return false; |
| 432 // TODO(floitsch): verify that the (generic) types are the same. | 442 // TODO(floitsch): verify that the (generic) types are the same. |
| 433 if (type.element != other.type.element) return false; | 443 if (type.element != other.type.element) return false; |
| 434 if (fields.length != other.fields.length) return false; | 444 if (fields.length != other.fields.length) return false; |
| 435 for (int i = 0; i < fields.length; i++) { | 445 for (int i = 0; i < fields.length; i++) { |
| 436 if (fields[i] != other.fields[i]) return false; | 446 if (fields[i] != other.fields[i]) return false; |
| 437 } | 447 } |
| 438 return true; | 448 return true; |
| 439 } | 449 } |
| 440 | 450 |
| 441 int hashCode() => _hashCode; | |
| 442 List<Constant> getDependencies() => fields; | 451 List<Constant> getDependencies() => fields; |
| 443 | 452 |
| 444 accept(ConstantVisitor visitor) => visitor.visitConstructed(this); | 453 accept(ConstantVisitor visitor) => visitor.visitConstructed(this); |
| 445 } | 454 } |
| OLD | NEW |