| 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 library dart2js.constants.values; | 5 library dart2js.constants.values; |
| 6 | 6 |
| 7 import '../dart_types.dart'; | 7 import '../dart_types.dart'; |
| 8 import '../dart2jslib.dart' | 8 import '../dart2jslib.dart' |
| 9 show assertDebugMode, | 9 show assertDebugMode, |
| 10 Compiler; | 10 Compiler; |
| 11 import '../elements/elements.dart' | 11 import '../elements/elements.dart' |
| 12 show ClassElement, | 12 show ClassElement, |
| 13 Element, | 13 Element, |
| 14 FunctionElement, | 14 FunctionElement, |
| 15 PrefixElement; | 15 PrefixElement; |
| 16 import '../tree/tree.dart' hide unparse; | 16 import '../tree/tree.dart' hide unparse; |
| 17 import '../types/types.dart' as ti show TypeMask; | 17 import '../types/types.dart' as ti show TypeMask; |
| 18 import '../util/util.dart' show SMI_MASK; | 18 import '../util/util.dart' show SMI_MASK; |
| 19 | 19 |
| 20 abstract class ConstantValueVisitor<R> { | 20 abstract class ConstantValueVisitor<R, A> { |
| 21 const ConstantValueVisitor(); | 21 const ConstantValueVisitor(); |
| 22 | 22 |
| 23 R visitFunction(FunctionConstantValue constant); | 23 R visitFunction(FunctionConstantValue constant, A arg); |
| 24 R visitNull(NullConstantValue constant); | 24 R visitNull(NullConstantValue constant, A arg); |
| 25 R visitInt(IntConstantValue constant); | 25 R visitInt(IntConstantValue constant, A arg); |
| 26 R visitDouble(DoubleConstantValue constant); | 26 R visitDouble(DoubleConstantValue constant, A arg); |
| 27 R visitTrue(TrueConstantValue constant); | 27 R visitBool(BoolConstantValue constant, A arg); |
| 28 R visitFalse(FalseConstantValue constant); | 28 R visitString(StringConstantValue constant, A arg); |
| 29 R visitString(StringConstantValue constant); | 29 R visitList(ListConstantValue constant, A arg); |
| 30 R visitList(ListConstantValue constant); | 30 R visitMap(MapConstantValue constant, A arg); |
| 31 R visitMap(MapConstantValue constant); | 31 R visitConstructed(ConstructedConstantValue constant, A arg); |
| 32 R visitConstructed(ConstructedConstantValue constant); | 32 R visitType(TypeConstantValue constant, A arg); |
| 33 R visitType(TypeConstantValue constant); | 33 R visitInterceptor(InterceptorConstantValue constant, A arg); |
| 34 R visitInterceptor(InterceptorConstantValue constant); | 34 R visitDummy(DummyConstantValue constant, A arg); |
| 35 R visitDummy(DummyConstantValue constant); | 35 R visitDeferred(DeferredConstantValue constant, A arg); |
| 36 R visitDeferred(DeferredConstantValue constant); | |
| 37 } | 36 } |
| 38 | 37 |
| 39 abstract class ConstantValue { | 38 abstract class ConstantValue { |
| 40 const ConstantValue(); | 39 const ConstantValue(); |
| 41 | 40 |
| 42 bool get isNull => false; | 41 bool get isNull => false; |
| 43 bool get isBool => false; | 42 bool get isBool => false; |
| 44 bool get isTrue => false; | 43 bool get isTrue => false; |
| 45 bool get isFalse => false; | 44 bool get isFalse => false; |
| 46 bool get isInt => false; | 45 bool get isInt => false; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 60 bool get isDummy => false; | 59 bool get isDummy => false; |
| 61 | 60 |
| 62 bool get isNaN => false; | 61 bool get isNaN => false; |
| 63 bool get isMinusZero => false; | 62 bool get isMinusZero => false; |
| 64 bool get isZero => false; | 63 bool get isZero => false; |
| 65 bool get isOne => false; | 64 bool get isOne => false; |
| 66 | 65 |
| 67 // TODO(johnniwinther): Replace with a 'type' getter. | 66 // TODO(johnniwinther): Replace with a 'type' getter. |
| 68 DartType computeType(Compiler compiler); | 67 DartType computeType(Compiler compiler); |
| 69 | 68 |
| 70 ti.TypeMask computeMask(Compiler compiler); | |
| 71 | |
| 72 List<ConstantValue> getDependencies(); | 69 List<ConstantValue> getDependencies(); |
| 73 | 70 |
| 74 accept(ConstantValueVisitor visitor); | 71 accept(ConstantValueVisitor visitor, arg); |
| 75 | 72 |
| 76 /// The value of this constant in Dart syntax, if possible. | 73 /// The value of this constant in Dart syntax, if possible. |
| 77 /// | 74 /// |
| 78 /// For [ConstructedConstantValue]s there is no way to create a valid const | 75 /// For [ConstructedConstantValue]s there is no way to create a valid const |
| 79 /// expression from the value so the unparse of these is best effort. | 76 /// expression from the value so the unparse of these is best effort. |
| 80 /// | 77 /// |
| 81 /// For the synthetic constants, [DeferredConstantValue], | 78 /// For the synthetic constants, [DeferredConstantValue], |
| 82 /// [DummyConstantValue], [InterceptorConstantValue] the unparse is | 79 /// [DummyConstantValue], [InterceptorConstantValue] the unparse is |
| 83 /// descriptive only. | 80 /// descriptive only. |
| 84 String unparse(); | 81 String unparse(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 107 | 104 |
| 108 List<ConstantValue> getDependencies() => const <ConstantValue>[]; | 105 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 109 | 106 |
| 110 DartString toDartString() { | 107 DartString toDartString() { |
| 111 return new DartString.literal(element.name); | 108 return new DartString.literal(element.name); |
| 112 } | 109 } |
| 113 | 110 |
| 114 // TODO(johnniwinther): remove computeType. | 111 // TODO(johnniwinther): remove computeType. |
| 115 DartType computeType(Compiler compiler) => element.computeType(compiler); | 112 DartType computeType(Compiler compiler) => element.computeType(compiler); |
| 116 | 113 |
| 117 ti.TypeMask computeMask(Compiler compiler) { | |
| 118 return compiler.typesTask.functionType; | |
| 119 } | |
| 120 | |
| 121 int get hashCode => (17 * element.hashCode) & 0x7fffffff; | 114 int get hashCode => (17 * element.hashCode) & 0x7fffffff; |
| 122 | 115 |
| 123 accept(ConstantValueVisitor visitor) => visitor.visitFunction(this); | 116 accept(ConstantValueVisitor visitor, arg) => visitor.visitFunction(this, arg); |
| 124 | 117 |
| 125 String unparse() { | 118 String unparse() { |
| 126 if (element.isStatic) { | 119 if (element.isStatic) { |
| 127 return '${element.enclosingClass.name}.${element.name}'; | 120 return '${element.enclosingClass.name}.${element.name}'; |
| 128 } else { | 121 } else { |
| 129 return '${element.name}'; | 122 return '${element.name}'; |
| 130 } | 123 } |
| 131 } | 124 } |
| 132 | 125 |
| 133 String toStructuredString() { | 126 String toStructuredString() { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 const NullConstantValue._internal(); | 162 const NullConstantValue._internal(); |
| 170 | 163 |
| 171 bool get isNull => true; | 164 bool get isNull => true; |
| 172 | 165 |
| 173 get primitiveValue => null; | 166 get primitiveValue => null; |
| 174 | 167 |
| 175 DartType computeType(Compiler compiler) { | 168 DartType computeType(Compiler compiler) { |
| 176 return compiler.nullClass.computeType(compiler); | 169 return compiler.nullClass.computeType(compiler); |
| 177 } | 170 } |
| 178 | 171 |
| 179 ti.TypeMask computeMask(Compiler compiler) { | |
| 180 return compiler.typesTask.nullType; | |
| 181 } | |
| 182 | |
| 183 // The magic constant has no meaning. It is just a random value. | 172 // The magic constant has no meaning. It is just a random value. |
| 184 int get hashCode => 785965825; | 173 int get hashCode => 785965825; |
| 185 | 174 |
| 186 DartString toDartString() => const LiteralDartString("null"); | 175 DartString toDartString() => const LiteralDartString("null"); |
| 187 | 176 |
| 188 accept(ConstantValueVisitor visitor) => visitor.visitNull(this); | 177 accept(ConstantValueVisitor visitor, arg) => visitor.visitNull(this, arg); |
| 189 | 178 |
| 190 String toStructuredString() => 'NullConstant'; | 179 String toStructuredString() => 'NullConstant'; |
| 191 } | 180 } |
| 192 | 181 |
| 193 abstract class NumConstantValue extends PrimitiveConstantValue { | 182 abstract class NumConstantValue extends PrimitiveConstantValue { |
| 194 const NumConstantValue(); | 183 const NumConstantValue(); |
| 195 | 184 |
| 196 num get primitiveValue; | 185 num get primitiveValue; |
| 197 | 186 |
| 198 bool get isNum => true; | 187 bool get isNum => true; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 bool isPositive() => primitiveValue >= 0; | 220 bool isPositive() => primitiveValue >= 0; |
| 232 | 221 |
| 233 bool get isZero => primitiveValue == 0; | 222 bool get isZero => primitiveValue == 0; |
| 234 | 223 |
| 235 bool get isOne => primitiveValue == 1; | 224 bool get isOne => primitiveValue == 1; |
| 236 | 225 |
| 237 DartType computeType(Compiler compiler) { | 226 DartType computeType(Compiler compiler) { |
| 238 return compiler.intClass.rawType; | 227 return compiler.intClass.rawType; |
| 239 } | 228 } |
| 240 | 229 |
| 241 ti.TypeMask computeMask(Compiler compiler) { | |
| 242 if (isUInt31()) return compiler.typesTask.uint31Type; | |
| 243 if (isUInt32()) return compiler.typesTask.uint32Type; | |
| 244 if (isPositive()) return compiler.typesTask.positiveIntType; | |
| 245 return compiler.typesTask.intType; | |
| 246 } | |
| 247 | |
| 248 // We have to override the equality operator so that ints and doubles are | 230 // We have to override the equality operator so that ints and doubles are |
| 249 // treated as separate constants. | 231 // treated as separate constants. |
| 250 // The is [:!IntConstant:] check at the beginning of the function makes sure | 232 // The is [:!IntConstant:] check at the beginning of the function makes sure |
| 251 // that we compare only equal to integer constants. | 233 // that we compare only equal to integer constants. |
| 252 bool operator ==(var other) { | 234 bool operator ==(var other) { |
| 253 if (other is !IntConstantValue) return false; | 235 if (other is !IntConstantValue) return false; |
| 254 IntConstantValue otherInt = other; | 236 IntConstantValue otherInt = other; |
| 255 return primitiveValue == otherInt.primitiveValue; | 237 return primitiveValue == otherInt.primitiveValue; |
| 256 } | 238 } |
| 257 | 239 |
| 258 int get hashCode => primitiveValue & SMI_MASK; | 240 int get hashCode => primitiveValue & SMI_MASK; |
| 259 | 241 |
| 260 DartString toDartString() { | 242 DartString toDartString() { |
| 261 return new DartString.literal(primitiveValue.toString()); | 243 return new DartString.literal(primitiveValue.toString()); |
| 262 } | 244 } |
| 263 | 245 |
| 264 accept(ConstantValueVisitor visitor) => visitor.visitInt(this); | 246 accept(ConstantValueVisitor visitor, arg) => visitor.visitInt(this, arg); |
| 265 | 247 |
| 266 String toStructuredString() => 'IntConstant(${unparse()})'; | 248 String toStructuredString() => 'IntConstant(${unparse()})'; |
| 267 } | 249 } |
| 268 | 250 |
| 269 class DoubleConstantValue extends NumConstantValue { | 251 class DoubleConstantValue extends NumConstantValue { |
| 270 final double primitiveValue; | 252 final double primitiveValue; |
| 271 | 253 |
| 272 factory DoubleConstantValue(double value) { | 254 factory DoubleConstantValue(double value) { |
| 273 if (value.isNaN) { | 255 if (value.isNaN) { |
| 274 return const DoubleConstantValue._internal(double.NAN); | 256 return const DoubleConstantValue._internal(double.NAN); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 295 bool get isMinusZero => primitiveValue == 0.0 && primitiveValue.isNegative; | 277 bool get isMinusZero => primitiveValue == 0.0 && primitiveValue.isNegative; |
| 296 | 278 |
| 297 bool get isZero => primitiveValue == 0.0; | 279 bool get isZero => primitiveValue == 0.0; |
| 298 | 280 |
| 299 bool get isOne => primitiveValue == 1.0; | 281 bool get isOne => primitiveValue == 1.0; |
| 300 | 282 |
| 301 DartType computeType(Compiler compiler) { | 283 DartType computeType(Compiler compiler) { |
| 302 return compiler.doubleClass.rawType; | 284 return compiler.doubleClass.rawType; |
| 303 } | 285 } |
| 304 | 286 |
| 305 ti.TypeMask computeMask(Compiler compiler) { | |
| 306 // We have to distinguish -0.0 from 0, but for all practical purposes | |
| 307 // -0.0 is an integer. | |
| 308 // TODO(17235): this kind of special casing should only happen in the | |
| 309 // backend. | |
| 310 if (isMinusZero && compiler.backend.constantSystem.isInt(this)) { | |
| 311 return compiler.typesTask.uint31Type; | |
| 312 } | |
| 313 assert(!compiler.backend.constantSystem.isInt(this)); | |
| 314 return compiler.typesTask.doubleType; | |
| 315 } | |
| 316 | |
| 317 bool operator ==(var other) { | 287 bool operator ==(var other) { |
| 318 if (other is !DoubleConstantValue) return false; | 288 if (other is !DoubleConstantValue) return false; |
| 319 DoubleConstantValue otherDouble = other; | 289 DoubleConstantValue otherDouble = other; |
| 320 double otherValue = otherDouble.primitiveValue; | 290 double otherValue = otherDouble.primitiveValue; |
| 321 if (primitiveValue == 0.0 && otherValue == 0.0) { | 291 if (primitiveValue == 0.0 && otherValue == 0.0) { |
| 322 return primitiveValue.isNegative == otherValue.isNegative; | 292 return primitiveValue.isNegative == otherValue.isNegative; |
| 323 } else if (primitiveValue.isNaN) { | 293 } else if (primitiveValue.isNaN) { |
| 324 return otherValue.isNaN; | 294 return otherValue.isNaN; |
| 325 } else { | 295 } else { |
| 326 return primitiveValue == otherValue; | 296 return primitiveValue == otherValue; |
| 327 } | 297 } |
| 328 } | 298 } |
| 329 | 299 |
| 330 int get hashCode => primitiveValue.hashCode; | 300 int get hashCode => primitiveValue.hashCode; |
| 331 | 301 |
| 332 DartString toDartString() { | 302 DartString toDartString() { |
| 333 return new DartString.literal(primitiveValue.toString()); | 303 return new DartString.literal(primitiveValue.toString()); |
| 334 } | 304 } |
| 335 | 305 |
| 336 accept(ConstantValueVisitor visitor) => visitor.visitDouble(this); | 306 accept(ConstantValueVisitor visitor, arg) => visitor.visitDouble(this, arg); |
| 337 | 307 |
| 338 String toStructuredString() => 'DoubleConstant(${unparse()})'; | 308 String toStructuredString() => 'DoubleConstant(${unparse()})'; |
| 339 } | 309 } |
| 340 | 310 |
| 341 abstract class BoolConstantValue extends PrimitiveConstantValue { | 311 abstract class BoolConstantValue extends PrimitiveConstantValue { |
| 342 factory BoolConstantValue(value) { | 312 factory BoolConstantValue(value) { |
| 343 return value ? new TrueConstantValue() : new FalseConstantValue(); | 313 return value ? new TrueConstantValue() : new FalseConstantValue(); |
| 344 } | 314 } |
| 345 | 315 |
| 346 const BoolConstantValue._internal(); | 316 const BoolConstantValue._internal(); |
| 347 | 317 |
| 348 bool get isBool => true; | 318 bool get isBool => true; |
| 349 | 319 |
| 350 DartType computeType(Compiler compiler) { | 320 DartType computeType(Compiler compiler) { |
| 351 return compiler.boolClass.rawType; | 321 return compiler.boolClass.rawType; |
| 352 } | 322 } |
| 353 | 323 |
| 354 ti.TypeMask computeMask(Compiler compiler) { | |
| 355 return compiler.typesTask.boolType; | |
| 356 } | |
| 357 | |
| 358 BoolConstantValue negate(); | 324 BoolConstantValue negate(); |
| 359 | 325 |
| 326 accept(ConstantValueVisitor visitor, arg) => visitor.visitBool(this, arg); |
| 327 |
| 360 String toStructuredString() => 'BoolConstant(${unparse()})'; | 328 String toStructuredString() => 'BoolConstant(${unparse()})'; |
| 361 } | 329 } |
| 362 | 330 |
| 363 class TrueConstantValue extends BoolConstantValue { | 331 class TrueConstantValue extends BoolConstantValue { |
| 364 factory TrueConstantValue() => const TrueConstantValue._internal(); | 332 factory TrueConstantValue() => const TrueConstantValue._internal(); |
| 365 | 333 |
| 366 const TrueConstantValue._internal() : super._internal(); | 334 const TrueConstantValue._internal() : super._internal(); |
| 367 | 335 |
| 368 bool get isTrue => true; | 336 bool get isTrue => true; |
| 369 | 337 |
| 370 bool get primitiveValue => true; | 338 bool get primitiveValue => true; |
| 371 | 339 |
| 372 FalseConstantValue negate() => new FalseConstantValue(); | 340 FalseConstantValue negate() => new FalseConstantValue(); |
| 373 | 341 |
| 374 bool operator ==(var other) => identical(this, other); | 342 bool operator ==(var other) => identical(this, other); |
| 375 | 343 |
| 376 // The magic constant is just a random value. It does not have any | 344 // The magic constant is just a random value. It does not have any |
| 377 // significance. | 345 // significance. |
| 378 int get hashCode => 499; | 346 int get hashCode => 499; |
| 379 | 347 |
| 380 DartString toDartString() => const LiteralDartString("true"); | 348 DartString toDartString() => const LiteralDartString("true"); |
| 381 | |
| 382 accept(ConstantValueVisitor visitor) => visitor.visitTrue(this); | |
| 383 } | 349 } |
| 384 | 350 |
| 385 class FalseConstantValue extends BoolConstantValue { | 351 class FalseConstantValue extends BoolConstantValue { |
| 386 factory FalseConstantValue() => const FalseConstantValue._internal(); | 352 factory FalseConstantValue() => const FalseConstantValue._internal(); |
| 387 | 353 |
| 388 const FalseConstantValue._internal() : super._internal(); | 354 const FalseConstantValue._internal() : super._internal(); |
| 389 | 355 |
| 390 bool get isFalse => true; | 356 bool get isFalse => true; |
| 391 | 357 |
| 392 bool get primitiveValue => false; | 358 bool get primitiveValue => false; |
| 393 | 359 |
| 394 TrueConstantValue negate() => new TrueConstantValue(); | 360 TrueConstantValue negate() => new TrueConstantValue(); |
| 395 | 361 |
| 396 bool operator ==(var other) => identical(this, other); | 362 bool operator ==(var other) => identical(this, other); |
| 397 | 363 |
| 398 // The magic constant is just a random value. It does not have any | 364 // The magic constant is just a random value. It does not have any |
| 399 // significance. | 365 // significance. |
| 400 int get hashCode => 536555975; | 366 int get hashCode => 536555975; |
| 401 | 367 |
| 402 DartString toDartString() => const LiteralDartString("false"); | 368 DartString toDartString() => const LiteralDartString("false"); |
| 403 | |
| 404 accept(ConstantValueVisitor visitor) => visitor.visitFalse(this); | |
| 405 } | 369 } |
| 406 | 370 |
| 407 class StringConstantValue extends PrimitiveConstantValue { | 371 class StringConstantValue extends PrimitiveConstantValue { |
| 408 final DartString primitiveValue; | 372 final DartString primitiveValue; |
| 409 | 373 |
| 410 final int hashCode; | 374 final int hashCode; |
| 411 | 375 |
| 412 // TODO(floitsch): cache StringConstants. | 376 // TODO(floitsch): cache StringConstants. |
| 413 // TODO(floitsch): compute hashcode without calling toString() on the | 377 // TODO(floitsch): compute hashcode without calling toString() on the |
| 414 // DartString. | 378 // DartString. |
| 415 StringConstantValue(DartString value) | 379 StringConstantValue(DartString value) |
| 416 : this.primitiveValue = value, | 380 : this.primitiveValue = value, |
| 417 this.hashCode = value.slowToString().hashCode; | 381 this.hashCode = value.slowToString().hashCode; |
| 418 | 382 |
| 419 bool get isString => true; | 383 bool get isString => true; |
| 420 | 384 |
| 421 DartType computeType(Compiler compiler) { | 385 DartType computeType(Compiler compiler) { |
| 422 return compiler.stringClass.rawType; | 386 return compiler.stringClass.rawType; |
| 423 } | 387 } |
| 424 | 388 |
| 425 ti.TypeMask computeMask(Compiler compiler) { | |
| 426 return compiler.typesTask.stringType; | |
| 427 } | |
| 428 | |
| 429 bool operator ==(var other) { | 389 bool operator ==(var other) { |
| 430 if (other is !StringConstantValue) return false; | 390 if (other is !StringConstantValue) return false; |
| 431 StringConstantValue otherString = other; | 391 StringConstantValue otherString = other; |
| 432 return hashCode == otherString.hashCode && | 392 return hashCode == otherString.hashCode && |
| 433 primitiveValue == otherString.primitiveValue; | 393 primitiveValue == otherString.primitiveValue; |
| 434 } | 394 } |
| 435 | 395 |
| 436 DartString toDartString() => primitiveValue; | 396 DartString toDartString() => primitiveValue; |
| 437 | 397 |
| 438 int get length => primitiveValue.length; | 398 int get length => primitiveValue.length; |
| 439 | 399 |
| 440 accept(ConstantValueVisitor visitor) => visitor.visitString(this); | 400 accept(ConstantValueVisitor visitor, arg) => visitor.visitString(this, arg); |
| 441 | 401 |
| 442 // TODO(johnniwinther): Ensure correct escaping. | 402 // TODO(johnniwinther): Ensure correct escaping. |
| 443 String unparse() => '"${primitiveValue.slowToString()}"'; | 403 String unparse() => '"${primitiveValue.slowToString()}"'; |
| 444 | 404 |
| 445 String toStructuredString() => 'StringConstant(${unparse()})'; | 405 String toStructuredString() => 'StringConstant(${unparse()})'; |
| 446 } | 406 } |
| 447 | 407 |
| 448 abstract class ObjectConstantValue extends ConstantValue { | 408 abstract class ObjectConstantValue extends ConstantValue { |
| 449 final InterfaceType type; | 409 final InterfaceType type; |
| 450 | 410 |
| 451 ObjectConstantValue(this.type); | 411 ObjectConstantValue(this.type); |
| 452 | 412 |
| 453 bool get isObject => true; | 413 bool get isObject => true; |
| 454 | 414 |
| 455 DartType computeType(Compiler compiler) => type; | 415 DartType computeType(Compiler compiler) => type; |
| 456 | 416 |
| 457 void _unparseTypeArguments(StringBuffer sb) { | 417 void _unparseTypeArguments(StringBuffer sb) { |
| 458 if (!type.treatAsRaw) { | 418 if (!type.treatAsRaw) { |
| 459 sb.write('<'); | 419 sb.write('<'); |
| 460 sb.write(type.typeArguments.join(', ')); | 420 sb.write(type.typeArguments.join(', ')); |
| 461 sb.write('>'); | 421 sb.write('>'); |
| 462 } | 422 } |
| 463 } | 423 } |
| 464 } | 424 } |
| 465 | 425 |
| 466 class TypeConstantValue extends ObjectConstantValue { | 426 class TypeConstantValue extends ObjectConstantValue { |
| 467 /// The user type that this constant represents. | 427 /// The user type that this constant represents. |
| 468 final DartType representedType; | 428 final DartType representedType; |
| 469 | 429 |
| 470 TypeConstantValue(this.representedType, InterfaceType type) : super(type); | 430 TypeConstantValue(this.representedType, InterfaceType type) : super(type); |
| 471 | 431 |
| 472 bool get isType => true; | 432 bool get isType => true; |
| 473 | 433 |
| 474 bool operator ==(other) { | 434 bool operator ==(other) { |
| 475 return other is TypeConstantValue && | 435 return other is TypeConstantValue && |
| 476 representedType == other.representedType; | 436 representedType == other.representedType; |
| 477 } | 437 } |
| 478 | 438 |
| 479 ti.TypeMask computeMask(Compiler compiler) { | |
| 480 return compiler.typesTask.typeType; | |
| 481 } | |
| 482 | |
| 483 int get hashCode => representedType.hashCode * 13; | 439 int get hashCode => representedType.hashCode * 13; |
| 484 | 440 |
| 485 List<ConstantValue> getDependencies() => const <ConstantValue>[]; | 441 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 486 | 442 |
| 487 accept(ConstantValueVisitor visitor) => visitor.visitType(this); | 443 accept(ConstantValueVisitor visitor, arg) => visitor.visitType(this, arg); |
| 488 | 444 |
| 489 String unparse() => '$representedType'; | 445 String unparse() => '$representedType'; |
| 490 | 446 |
| 491 String toStructuredString() => 'TypeConstant(${representedType})'; | 447 String toStructuredString() => 'TypeConstant(${representedType})'; |
| 492 } | 448 } |
| 493 | 449 |
| 494 class ListConstantValue extends ObjectConstantValue { | 450 class ListConstantValue extends ObjectConstantValue { |
| 495 final List<ConstantValue> entries; | 451 final List<ConstantValue> entries; |
| 496 final int hashCode; | 452 final int hashCode; |
| 497 | 453 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 521 for (int i = 0; i < entries.length; i++) { | 477 for (int i = 0; i < entries.length; i++) { |
| 522 if (entries[i] != otherList.entries[i]) return false; | 478 if (entries[i] != otherList.entries[i]) return false; |
| 523 } | 479 } |
| 524 return true; | 480 return true; |
| 525 } | 481 } |
| 526 | 482 |
| 527 List<ConstantValue> getDependencies() => entries; | 483 List<ConstantValue> getDependencies() => entries; |
| 528 | 484 |
| 529 int get length => entries.length; | 485 int get length => entries.length; |
| 530 | 486 |
| 531 ti.TypeMask computeMask(Compiler compiler) { | 487 accept(ConstantValueVisitor visitor, arg) => visitor.visitList(this, arg); |
| 532 return compiler.typesTask.constListType; | |
| 533 } | |
| 534 | |
| 535 accept(ConstantValueVisitor visitor) => visitor.visitList(this); | |
| 536 | 488 |
| 537 String unparse() { | 489 String unparse() { |
| 538 StringBuffer sb = new StringBuffer(); | 490 StringBuffer sb = new StringBuffer(); |
| 539 _unparseTypeArguments(sb); | 491 _unparseTypeArguments(sb); |
| 540 sb.write('['); | 492 sb.write('['); |
| 541 for (int i = 0 ; i < length ; i++) { | 493 for (int i = 0 ; i < length ; i++) { |
| 542 if (i > 0) sb.write(','); | 494 if (i > 0) sb.write(','); |
| 543 sb.write(entries[i].unparse()); | 495 sb.write(entries[i].unparse()); |
| 544 } | 496 } |
| 545 sb.write(']'); | 497 sb.write(']'); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 for (ConstantValue key in keys) { | 535 for (ConstantValue key in keys) { |
| 584 hash ^= key.hashCode; | 536 hash ^= key.hashCode; |
| 585 } | 537 } |
| 586 for (ConstantValue value in values) { | 538 for (ConstantValue value in values) { |
| 587 hash ^= value.hashCode; | 539 hash ^= value.hashCode; |
| 588 } | 540 } |
| 589 hash ^= type.hashCode; | 541 hash ^= type.hashCode; |
| 590 return hash; | 542 return hash; |
| 591 } | 543 } |
| 592 | 544 |
| 593 ti.TypeMask computeMask(Compiler compiler) { | |
| 594 return compiler.typesTask.constMapType; | |
| 595 } | |
| 596 | |
| 597 bool operator ==(var other) { | 545 bool operator ==(var other) { |
| 598 if (other is !MapConstantValue) return false; | 546 if (other is !MapConstantValue) return false; |
| 599 MapConstantValue otherMap = other; | 547 MapConstantValue otherMap = other; |
| 600 if (hashCode != otherMap.hashCode) return false; | 548 if (hashCode != otherMap.hashCode) return false; |
| 601 if (type != other.type) return false; | 549 if (type != other.type) return false; |
| 602 if (length != other.length) return false; | 550 if (length != other.length) return false; |
| 603 for (int i = 0; i < length; i++) { | 551 for (int i = 0; i < length; i++) { |
| 604 if (keys[i] != otherMap.keys[i]) return false; | 552 if (keys[i] != otherMap.keys[i]) return false; |
| 605 if (values[i] != otherMap.values[i]) return false; | 553 if (values[i] != otherMap.values[i]) return false; |
| 606 } | 554 } |
| 607 return true; | 555 return true; |
| 608 } | 556 } |
| 609 | 557 |
| 610 List<ConstantValue> getDependencies() { | 558 List<ConstantValue> getDependencies() { |
| 611 List<ConstantValue> result = <ConstantValue>[]; | 559 List<ConstantValue> result = <ConstantValue>[]; |
| 612 result.addAll(keys); | 560 result.addAll(keys); |
| 613 result.addAll(values); | 561 result.addAll(values); |
| 614 return result; | 562 return result; |
| 615 } | 563 } |
| 616 | 564 |
| 617 int get length => keys.length; | 565 int get length => keys.length; |
| 618 | 566 |
| 619 accept(ConstantValueVisitor visitor) => visitor.visitMap(this); | 567 accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg); |
| 620 | 568 |
| 621 String unparse() { | 569 String unparse() { |
| 622 StringBuffer sb = new StringBuffer(); | 570 StringBuffer sb = new StringBuffer(); |
| 623 _unparseTypeArguments(sb); | 571 _unparseTypeArguments(sb); |
| 624 sb.write('{'); | 572 sb.write('{'); |
| 625 for (int i = 0 ; i < length ; i++) { | 573 for (int i = 0 ; i < length ; i++) { |
| 626 if (i > 0) sb.write(','); | 574 if (i > 0) sb.write(','); |
| 627 sb.write(keys[i].unparse()); | 575 sb.write(keys[i].unparse()); |
| 628 sb.write(':'); | 576 sb.write(':'); |
| 629 sb.write(values[i].unparse()); | 577 sb.write(values[i].unparse()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 657 | 605 |
| 658 bool operator ==(other) { | 606 bool operator ==(other) { |
| 659 return other is InterceptorConstantValue | 607 return other is InterceptorConstantValue |
| 660 && dispatchedType == other.dispatchedType; | 608 && dispatchedType == other.dispatchedType; |
| 661 } | 609 } |
| 662 | 610 |
| 663 int get hashCode => dispatchedType.hashCode * 43; | 611 int get hashCode => dispatchedType.hashCode * 43; |
| 664 | 612 |
| 665 List<ConstantValue> getDependencies() => const <ConstantValue>[]; | 613 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 666 | 614 |
| 667 accept(ConstantValueVisitor visitor) => visitor.visitInterceptor(this); | 615 accept(ConstantValueVisitor visitor, arg) { |
| 616 return visitor.visitInterceptor(this, arg); |
| 617 } |
| 668 | 618 |
| 669 DartType computeType(Compiler compiler) => const DynamicType(); | 619 DartType computeType(Compiler compiler) => const DynamicType(); |
| 670 | 620 |
| 671 ti.TypeMask computeMask(Compiler compiler) { | |
| 672 return compiler.typesTask.nonNullType; | |
| 673 } | |
| 674 | |
| 675 String unparse() { | 621 String unparse() { |
| 676 return 'interceptor($dispatchedType)'; | 622 return 'interceptor($dispatchedType)'; |
| 677 } | 623 } |
| 678 | 624 |
| 679 String toStructuredString() { | 625 String toStructuredString() { |
| 680 return 'InterceptorConstant(${dispatchedType.getStringAsDeclared("o")})'; | 626 return 'InterceptorConstant(${dispatchedType.getStringAsDeclared("o")})'; |
| 681 } | 627 } |
| 682 } | 628 } |
| 683 | 629 |
| 630 // TODO(johnniwinther): Remove this class. |
| 684 class DummyConstantValue extends ConstantValue { | 631 class DummyConstantValue extends ConstantValue { |
| 685 final ti.TypeMask typeMask; | 632 final ti.TypeMask typeMask; |
| 686 | 633 |
| 687 DummyConstantValue(this.typeMask); | 634 DummyConstantValue(this.typeMask); |
| 688 | 635 |
| 689 bool get isDummy => true; | 636 bool get isDummy => true; |
| 690 | 637 |
| 691 bool operator ==(other) { | 638 bool operator ==(other) { |
| 692 return other is DummyConstantValue | 639 return other is DummyConstantValue |
| 693 && typeMask == other.typeMask; | 640 && typeMask == other.typeMask; |
| 694 } | 641 } |
| 695 | 642 |
| 696 get hashCode => typeMask.hashCode; | 643 get hashCode => typeMask.hashCode; |
| 697 | 644 |
| 698 List<ConstantValue> getDependencies() => const <ConstantValue>[]; | 645 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 699 | 646 |
| 700 accept(ConstantValueVisitor visitor) => visitor.visitDummy(this); | 647 accept(ConstantValueVisitor visitor, arg) => visitor.visitDummy(this, arg); |
| 701 | 648 |
| 702 DartType computeType(Compiler compiler) => const DynamicType(); | 649 DartType computeType(Compiler compiler) => const DynamicType(); |
| 703 | 650 |
| 704 ti.TypeMask computeMask(Compiler compiler) => typeMask; | |
| 705 | |
| 706 String unparse() => 'dummy($typeMask)'; | 651 String unparse() => 'dummy($typeMask)'; |
| 707 | 652 |
| 708 String toStructuredString() => 'DummyConstant($typeMask)'; | 653 String toStructuredString() => 'DummyConstant($typeMask)'; |
| 709 } | 654 } |
| 710 | 655 |
| 711 class ConstructedConstantValue extends ObjectConstantValue { | 656 class ConstructedConstantValue extends ObjectConstantValue { |
| 712 final List<ConstantValue> fields; | 657 final List<ConstantValue> fields; |
| 713 final int hashCode; | 658 final int hashCode; |
| 714 | 659 |
| 715 ConstructedConstantValue(InterfaceType type, List<ConstantValue> fields) | 660 ConstructedConstantValue(InterfaceType type, List<ConstantValue> fields) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 738 if (type != other.type) return false; | 683 if (type != other.type) return false; |
| 739 if (fields.length != other.fields.length) return false; | 684 if (fields.length != other.fields.length) return false; |
| 740 for (int i = 0; i < fields.length; i++) { | 685 for (int i = 0; i < fields.length; i++) { |
| 741 if (fields[i] != other.fields[i]) return false; | 686 if (fields[i] != other.fields[i]) return false; |
| 742 } | 687 } |
| 743 return true; | 688 return true; |
| 744 } | 689 } |
| 745 | 690 |
| 746 List<ConstantValue> getDependencies() => fields; | 691 List<ConstantValue> getDependencies() => fields; |
| 747 | 692 |
| 748 ti.TypeMask computeMask(Compiler compiler) { | 693 accept(ConstantValueVisitor visitor, arg) { |
| 749 if (compiler.backend.isInterceptorClass(type.element)) { | 694 return visitor.visitConstructed(this, arg); |
| 750 return compiler.typesTask.nonNullType; | |
| 751 } | |
| 752 return new ti.TypeMask.nonNullExact(type.element, compiler.world); | |
| 753 } | 695 } |
| 754 | 696 |
| 755 accept(ConstantValueVisitor visitor) => visitor.visitConstructed(this); | |
| 756 | |
| 757 Map<Element, ConstantValue> get fieldElements { | 697 Map<Element, ConstantValue> get fieldElements { |
| 758 // TODO(ahe): Refactor constant system to store this information directly. | 698 // TODO(ahe): Refactor constant system to store this information directly. |
| 759 ClassElement classElement = type.element; | 699 ClassElement classElement = type.element; |
| 760 int count = 0; | 700 int count = 0; |
| 761 Map<Element, ConstantValue> result = new Map<Element, ConstantValue>(); | 701 Map<Element, ConstantValue> result = new Map<Element, ConstantValue>(); |
| 762 classElement.implementation.forEachInstanceField((holder, field) { | 702 classElement.implementation.forEachInstanceField((holder, field) { |
| 763 result[field] = fields[count++]; | 703 result[field] = fields[count++]; |
| 764 }, includeSuperAndInjectedMembers: true); | 704 }, includeSuperAndInjectedMembers: true); |
| 765 return result; | 705 return result; |
| 766 } | 706 } |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 813 bool operator ==(other) { | 753 bool operator ==(other) { |
| 814 return other is DeferredConstantValue | 754 return other is DeferredConstantValue |
| 815 && referenced == other.referenced | 755 && referenced == other.referenced |
| 816 && prefix == other.prefix; | 756 && prefix == other.prefix; |
| 817 } | 757 } |
| 818 | 758 |
| 819 get hashCode => (referenced.hashCode * 17 + prefix.hashCode) & 0x3fffffff; | 759 get hashCode => (referenced.hashCode * 17 + prefix.hashCode) & 0x3fffffff; |
| 820 | 760 |
| 821 List<ConstantValue> getDependencies() => <ConstantValue>[referenced]; | 761 List<ConstantValue> getDependencies() => <ConstantValue>[referenced]; |
| 822 | 762 |
| 823 accept(ConstantValueVisitor visitor) => visitor.visitDeferred(this); | 763 accept(ConstantValueVisitor visitor, arg) => visitor.visitDeferred(this, arg); |
| 824 | 764 |
| 825 DartType computeType(Compiler compiler) => referenced.computeType(compiler); | 765 DartType computeType(Compiler compiler) => referenced.computeType(compiler); |
| 826 | 766 |
| 827 ti.TypeMask computeMask(Compiler compiler) { | |
| 828 return referenced.computeMask(compiler); | |
| 829 } | |
| 830 | |
| 831 String unparse() => 'deferred(${referenced.unparse()})'; | 767 String unparse() => 'deferred(${referenced.unparse()})'; |
| 832 | 768 |
| 833 String toStructuredString() => 'DeferredConstant($referenced)'; | 769 String toStructuredString() => 'DeferredConstant($referenced)'; |
| 834 } | 770 } |
| OLD | NEW |