| 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 ConstantVisitor<R> { | 20 abstract class ConstantValueVisitor<R> { |
| 21 const ConstantVisitor(); | 21 const ConstantValueVisitor(); |
| 22 | 22 |
| 23 R visitFunction(FunctionConstant constant); | 23 R visitFunction(FunctionConstantValue constant); |
| 24 R visitNull(NullConstant constant); | 24 R visitNull(NullConstantValue constant); |
| 25 R visitInt(IntConstant constant); | 25 R visitInt(IntConstantValue constant); |
| 26 R visitDouble(DoubleConstant constant); | 26 R visitDouble(DoubleConstantValue constant); |
| 27 R visitTrue(TrueConstant constant); | 27 R visitTrue(TrueConstantValue constant); |
| 28 R visitFalse(FalseConstant constant); | 28 R visitFalse(FalseConstantValue constant); |
| 29 R visitString(StringConstant constant); | 29 R visitString(StringConstantValue constant); |
| 30 R visitList(ListConstant constant); | 30 R visitList(ListConstantValue constant); |
| 31 R visitMap(MapConstant constant); | 31 R visitMap(MapConstantValue constant); |
| 32 R visitConstructed(ConstructedConstant constant); | 32 R visitConstructed(ConstructedConstantValue constant); |
| 33 R visitType(TypeConstant constant); | 33 R visitType(TypeConstantValue constant); |
| 34 R visitInterceptor(InterceptorConstant constant); | 34 R visitInterceptor(InterceptorConstantValue constant); |
| 35 R visitDummy(DummyConstant constant); | 35 R visitDummy(DummyConstantValue constant); |
| 36 R visitDeferred(DeferredConstant constant); | 36 R visitDeferred(DeferredConstantValue constant); |
| 37 } | 37 } |
| 38 | 38 |
| 39 // TODO(johnniwinther): Rename this to `ConstantValue`. | 39 abstract class ConstantValue { |
| 40 abstract class Constant { | 40 const ConstantValue(); |
| 41 const Constant(); | |
| 42 | 41 |
| 43 bool get isNull => false; | 42 bool get isNull => false; |
| 44 bool get isBool => false; | 43 bool get isBool => false; |
| 45 bool get isTrue => false; | 44 bool get isTrue => false; |
| 46 bool get isFalse => false; | 45 bool get isFalse => false; |
| 47 bool get isInt => false; | 46 bool get isInt => false; |
| 48 bool get isDouble => false; | 47 bool get isDouble => false; |
| 49 bool get isNum => false; | 48 bool get isNum => false; |
| 50 bool get isString => false; | 49 bool get isString => false; |
| 51 bool get isList => false; | 50 bool get isList => false; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 63 bool get isNaN => false; | 62 bool get isNaN => false; |
| 64 bool get isMinusZero => false; | 63 bool get isMinusZero => false; |
| 65 bool get isZero => false; | 64 bool get isZero => false; |
| 66 bool get isOne => false; | 65 bool get isOne => false; |
| 67 | 66 |
| 68 // TODO(johnniwinther): Replace with a 'type' getter. | 67 // TODO(johnniwinther): Replace with a 'type' getter. |
| 69 DartType computeType(Compiler compiler); | 68 DartType computeType(Compiler compiler); |
| 70 | 69 |
| 71 ti.TypeMask computeMask(Compiler compiler); | 70 ti.TypeMask computeMask(Compiler compiler); |
| 72 | 71 |
| 73 List<Constant> getDependencies(); | 72 List<ConstantValue> getDependencies(); |
| 74 | 73 |
| 75 accept(ConstantVisitor visitor); | 74 accept(ConstantValueVisitor visitor); |
| 76 | 75 |
| 77 /// The value of this constant in Dart syntax, if possible. | 76 /// The value of this constant in Dart syntax, if possible. |
| 78 /// | 77 /// |
| 79 /// For [ConstructedConstant]s there is no way to create a valid const | 78 /// For [ConstructedConstantValue]s there is no way to create a valid const |
| 80 /// expression from the value so the unparse of these is best effort. | 79 /// expression from the value so the unparse of these is best effort. |
| 81 /// | 80 /// |
| 82 /// For the synthetic constants, [DeferredConstant], [DummyConstant], | 81 /// For the synthetic constants, [DeferredConstantValue], |
| 83 /// [InterceptorConstant] the unparse is descriptive only. | 82 /// [DummyConstantValue], [InterceptorConstantValue] the unparse is |
| 83 /// descriptive only. |
| 84 String unparse(); | 84 String unparse(); |
| 85 | 85 |
| 86 /// Returns a structured representation of this constant suited for debugging. | 86 /// Returns a structured representation of this constant suited for debugging. |
| 87 String toStructuredString(); | 87 String toStructuredString(); |
| 88 | 88 |
| 89 String toString() { | 89 String toString() { |
| 90 assertDebugMode("Use Constant.unparse() or Constant.toStructuredString() " | 90 assertDebugMode("Use Constant.unparse() or Constant.toStructuredString() " |
| 91 "instead of Constant.toString()."); | 91 "instead of Constant.toString()."); |
| 92 return toStructuredString(); | 92 return toStructuredString(); |
| 93 } | 93 } |
| 94 } | 94 } |
| 95 | 95 |
| 96 class FunctionConstant extends Constant { | 96 class FunctionConstantValue extends ConstantValue { |
| 97 Element element; | 97 Element element; |
| 98 | 98 |
| 99 FunctionConstant(this.element); | 99 FunctionConstantValue(this.element); |
| 100 | 100 |
| 101 bool get isFunction => true; | 101 bool get isFunction => true; |
| 102 | 102 |
| 103 bool operator ==(var other) { | 103 bool operator ==(var other) { |
| 104 if (other is !FunctionConstant) return false; | 104 if (other is !FunctionConstantValue) return false; |
| 105 return identical(other.element, element); | 105 return identical(other.element, element); |
| 106 } | 106 } |
| 107 | 107 |
| 108 List<Constant> getDependencies() => const <Constant>[]; | 108 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 109 | 109 |
| 110 DartString toDartString() { | 110 DartString toDartString() { |
| 111 return new DartString.literal(element.name); | 111 return new DartString.literal(element.name); |
| 112 } | 112 } |
| 113 | 113 |
| 114 // TODO(johnniwinther): remove computeType. | 114 // TODO(johnniwinther): remove computeType. |
| 115 DartType computeType(Compiler compiler) => element.computeType(compiler); | 115 DartType computeType(Compiler compiler) => element.computeType(compiler); |
| 116 | 116 |
| 117 ti.TypeMask computeMask(Compiler compiler) { | 117 ti.TypeMask computeMask(Compiler compiler) { |
| 118 return compiler.typesTask.functionType; | 118 return compiler.typesTask.functionType; |
| 119 } | 119 } |
| 120 | 120 |
| 121 int get hashCode => (17 * element.hashCode) & 0x7fffffff; | 121 int get hashCode => (17 * element.hashCode) & 0x7fffffff; |
| 122 | 122 |
| 123 accept(ConstantVisitor visitor) => visitor.visitFunction(this); | 123 accept(ConstantValueVisitor visitor) => visitor.visitFunction(this); |
| 124 | 124 |
| 125 String unparse() { | 125 String unparse() { |
| 126 if (element.isStatic) { | 126 if (element.isStatic) { |
| 127 return '${element.enclosingClass.name}.${element.name}'; | 127 return '${element.enclosingClass.name}.${element.name}'; |
| 128 } else { | 128 } else { |
| 129 return '${element.name}'; | 129 return '${element.name}'; |
| 130 } | 130 } |
| 131 } | 131 } |
| 132 | 132 |
| 133 String toStructuredString() { | 133 String toStructuredString() { |
| 134 return 'FunctionConstant(${unparse()})'; | 134 return 'FunctionConstant(${unparse()})'; |
| 135 } | 135 } |
| 136 } | 136 } |
| 137 | 137 |
| 138 abstract class PrimitiveConstant extends Constant { | 138 abstract class PrimitiveConstantValue extends ConstantValue { |
| 139 // TODO(johnniwinther): Rename to `primitiveValue`. | 139 get primitiveValue; |
| 140 get value; | |
| 141 | 140 |
| 142 const PrimitiveConstant(); | 141 const PrimitiveConstantValue(); |
| 143 | 142 |
| 144 bool get isPrimitive => true; | 143 bool get isPrimitive => true; |
| 145 | 144 |
| 146 bool operator ==(var other) { | 145 bool operator ==(var other) { |
| 147 if (other is !PrimitiveConstant) return false; | 146 if (other is !PrimitiveConstantValue) return false; |
| 148 PrimitiveConstant otherPrimitive = other; | 147 PrimitiveConstantValue otherPrimitive = other; |
| 149 // We use == instead of 'identical' so that DartStrings compare correctly. | 148 // We use == instead of 'identical' so that DartStrings compare correctly. |
| 150 return value == otherPrimitive.value; | 149 return primitiveValue == otherPrimitive.primitiveValue; |
| 151 } | 150 } |
| 152 | 151 |
| 153 int get hashCode => throw new UnsupportedError('PrimitiveConstant.hashCode'); | 152 int get hashCode => throw new UnsupportedError('PrimitiveConstant.hashCode'); |
| 154 | 153 |
| 155 // Primitive constants don't have dependencies. | 154 // Primitive constants don't have dependencies. |
| 156 List<Constant> getDependencies() => const <Constant>[]; | 155 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 157 | 156 |
| 158 DartString toDartString(); | 157 DartString toDartString(); |
| 159 | 158 |
| 160 /// This value in Dart syntax. | 159 /// This value in Dart syntax. |
| 161 String unparse() => value.toString(); | 160 String unparse() => primitiveValue.toString(); |
| 162 } | 161 } |
| 163 | 162 |
| 164 class NullConstant extends PrimitiveConstant { | 163 class NullConstantValue extends PrimitiveConstantValue { |
| 165 /** The value a Dart null is compiled to in JavaScript. */ | 164 /** The value a Dart null is compiled to in JavaScript. */ |
| 166 static const String JsNull = "null"; | 165 static const String JsNull = "null"; |
| 167 | 166 |
| 168 factory NullConstant() => const NullConstant._internal(); | 167 factory NullConstantValue() => const NullConstantValue._internal(); |
| 169 | 168 |
| 170 const NullConstant._internal(); | 169 const NullConstantValue._internal(); |
| 171 | 170 |
| 172 bool get isNull => true; | 171 bool get isNull => true; |
| 173 | 172 |
| 174 get value => null; | 173 get primitiveValue => null; |
| 175 | 174 |
| 176 DartType computeType(Compiler compiler) { | 175 DartType computeType(Compiler compiler) { |
| 177 return compiler.nullClass.computeType(compiler); | 176 return compiler.nullClass.computeType(compiler); |
| 178 } | 177 } |
| 179 | 178 |
| 180 ti.TypeMask computeMask(Compiler compiler) { | 179 ti.TypeMask computeMask(Compiler compiler) { |
| 181 return compiler.typesTask.nullType; | 180 return compiler.typesTask.nullType; |
| 182 } | 181 } |
| 183 | 182 |
| 184 // The magic constant has no meaning. It is just a random value. | 183 // The magic constant has no meaning. It is just a random value. |
| 185 int get hashCode => 785965825; | 184 int get hashCode => 785965825; |
| 186 | 185 |
| 187 DartString toDartString() => const LiteralDartString("null"); | 186 DartString toDartString() => const LiteralDartString("null"); |
| 188 | 187 |
| 189 accept(ConstantVisitor visitor) => visitor.visitNull(this); | 188 accept(ConstantValueVisitor visitor) => visitor.visitNull(this); |
| 190 | 189 |
| 191 String toStructuredString() => 'NullConstant'; | 190 String toStructuredString() => 'NullConstant'; |
| 192 } | 191 } |
| 193 | 192 |
| 194 abstract class NumConstant extends PrimitiveConstant { | 193 abstract class NumConstantValue extends PrimitiveConstantValue { |
| 195 const NumConstant(); | 194 const NumConstantValue(); |
| 196 | 195 |
| 197 num get value; | 196 num get primitiveValue; |
| 198 | 197 |
| 199 bool get isNum => true; | 198 bool get isNum => true; |
| 200 } | 199 } |
| 201 | 200 |
| 202 class IntConstant extends NumConstant { | 201 class IntConstantValue extends NumConstantValue { |
| 203 final int value; | 202 final int primitiveValue; |
| 204 | 203 |
| 205 factory IntConstant(int value) { | 204 factory IntConstantValue(int value) { |
| 206 switch (value) { | 205 switch (value) { |
| 207 case 0: return const IntConstant._internal(0); | 206 case 0: return const IntConstantValue._internal(0); |
| 208 case 1: return const IntConstant._internal(1); | 207 case 1: return const IntConstantValue._internal(1); |
| 209 case 2: return const IntConstant._internal(2); | 208 case 2: return const IntConstantValue._internal(2); |
| 210 case 3: return const IntConstant._internal(3); | 209 case 3: return const IntConstantValue._internal(3); |
| 211 case 4: return const IntConstant._internal(4); | 210 case 4: return const IntConstantValue._internal(4); |
| 212 case 5: return const IntConstant._internal(5); | 211 case 5: return const IntConstantValue._internal(5); |
| 213 case 6: return const IntConstant._internal(6); | 212 case 6: return const IntConstantValue._internal(6); |
| 214 case 7: return const IntConstant._internal(7); | 213 case 7: return const IntConstantValue._internal(7); |
| 215 case 8: return const IntConstant._internal(8); | 214 case 8: return const IntConstantValue._internal(8); |
| 216 case 9: return const IntConstant._internal(9); | 215 case 9: return const IntConstantValue._internal(9); |
| 217 case 10: return const IntConstant._internal(10); | 216 case 10: return const IntConstantValue._internal(10); |
| 218 case -1: return const IntConstant._internal(-1); | 217 case -1: return const IntConstantValue._internal(-1); |
| 219 case -2: return const IntConstant._internal(-2); | 218 case -2: return const IntConstantValue._internal(-2); |
| 220 default: return new IntConstant._internal(value); | 219 default: return new IntConstantValue._internal(value); |
| 221 } | 220 } |
| 222 } | 221 } |
| 223 | 222 |
| 224 const IntConstant._internal(this.value); | 223 const IntConstantValue._internal(this.primitiveValue); |
| 225 | 224 |
| 226 bool get isInt => true; | 225 bool get isInt => true; |
| 227 | 226 |
| 228 bool isUInt31() => value >= 0 && value < (1 << 31); | 227 bool isUInt31() => primitiveValue >= 0 && primitiveValue < (1 << 31); |
| 229 | 228 |
| 230 bool isUInt32() => value >= 0 && value < (1 << 32); | 229 bool isUInt32() => primitiveValue >= 0 && primitiveValue < (1 << 32); |
| 231 | 230 |
| 232 bool isPositive() => value >= 0; | 231 bool isPositive() => primitiveValue >= 0; |
| 233 | 232 |
| 234 bool get isZero => value == 0; | 233 bool get isZero => primitiveValue == 0; |
| 235 | 234 |
| 236 bool get isOne => value == 1; | 235 bool get isOne => primitiveValue == 1; |
| 237 | 236 |
| 238 DartType computeType(Compiler compiler) { | 237 DartType computeType(Compiler compiler) { |
| 239 return compiler.intClass.rawType; | 238 return compiler.intClass.rawType; |
| 240 } | 239 } |
| 241 | 240 |
| 242 ti.TypeMask computeMask(Compiler compiler) { | 241 ti.TypeMask computeMask(Compiler compiler) { |
| 243 if (isUInt31()) return compiler.typesTask.uint31Type; | 242 if (isUInt31()) return compiler.typesTask.uint31Type; |
| 244 if (isUInt32()) return compiler.typesTask.uint32Type; | 243 if (isUInt32()) return compiler.typesTask.uint32Type; |
| 245 if (isPositive()) return compiler.typesTask.positiveIntType; | 244 if (isPositive()) return compiler.typesTask.positiveIntType; |
| 246 return compiler.typesTask.intType; | 245 return compiler.typesTask.intType; |
| 247 } | 246 } |
| 248 | 247 |
| 249 // We have to override the equality operator so that ints and doubles are | 248 // We have to override the equality operator so that ints and doubles are |
| 250 // treated as separate constants. | 249 // treated as separate constants. |
| 251 // The is [:!IntConstant:] check at the beginning of the function makes sure | 250 // The is [:!IntConstant:] check at the beginning of the function makes sure |
| 252 // that we compare only equal to integer constants. | 251 // that we compare only equal to integer constants. |
| 253 bool operator ==(var other) { | 252 bool operator ==(var other) { |
| 254 if (other is !IntConstant) return false; | 253 if (other is !IntConstantValue) return false; |
| 255 IntConstant otherInt = other; | 254 IntConstantValue otherInt = other; |
| 256 return value == otherInt.value; | 255 return primitiveValue == otherInt.primitiveValue; |
| 257 } | 256 } |
| 258 | 257 |
| 259 int get hashCode => value & SMI_MASK; | 258 int get hashCode => primitiveValue & SMI_MASK; |
| 260 | 259 |
| 261 DartString toDartString() => new DartString.literal(value.toString()); | 260 DartString toDartString() { |
| 261 return new DartString.literal(primitiveValue.toString()); |
| 262 } |
| 262 | 263 |
| 263 accept(ConstantVisitor visitor) => visitor.visitInt(this); | 264 accept(ConstantValueVisitor visitor) => visitor.visitInt(this); |
| 264 | 265 |
| 265 String toStructuredString() => 'IntConstant(${unparse()})'; | 266 String toStructuredString() => 'IntConstant(${unparse()})'; |
| 266 } | 267 } |
| 267 | 268 |
| 268 class DoubleConstant extends NumConstant { | 269 class DoubleConstantValue extends NumConstantValue { |
| 269 final double value; | 270 final double primitiveValue; |
| 270 | 271 |
| 271 factory DoubleConstant(double value) { | 272 factory DoubleConstantValue(double value) { |
| 272 if (value.isNaN) { | 273 if (value.isNaN) { |
| 273 return const DoubleConstant._internal(double.NAN); | 274 return const DoubleConstantValue._internal(double.NAN); |
| 274 } else if (value == double.INFINITY) { | 275 } else if (value == double.INFINITY) { |
| 275 return const DoubleConstant._internal(double.INFINITY); | 276 return const DoubleConstantValue._internal(double.INFINITY); |
| 276 } else if (value == -double.INFINITY) { | 277 } else if (value == -double.INFINITY) { |
| 277 return const DoubleConstant._internal(-double.INFINITY); | 278 return const DoubleConstantValue._internal(-double.INFINITY); |
| 278 } else if (value == 0.0 && !value.isNegative) { | 279 } else if (value == 0.0 && !value.isNegative) { |
| 279 return const DoubleConstant._internal(0.0); | 280 return const DoubleConstantValue._internal(0.0); |
| 280 } else if (value == 1.0) { | 281 } else if (value == 1.0) { |
| 281 return const DoubleConstant._internal(1.0); | 282 return const DoubleConstantValue._internal(1.0); |
| 282 } else { | 283 } else { |
| 283 return new DoubleConstant._internal(value); | 284 return new DoubleConstantValue._internal(value); |
| 284 } | 285 } |
| 285 } | 286 } |
| 286 | 287 |
| 287 const DoubleConstant._internal(this.value); | 288 const DoubleConstantValue._internal(this.primitiveValue); |
| 288 | 289 |
| 289 bool get isDouble => true; | 290 bool get isDouble => true; |
| 290 | 291 |
| 291 bool get isNaN => value.isNaN; | 292 bool get isNaN => primitiveValue.isNaN; |
| 292 | 293 |
| 293 // We need to check for the negative sign since -0.0 == 0.0. | 294 // We need to check for the negative sign since -0.0 == 0.0. |
| 294 bool get isMinusZero => value == 0.0 && value.isNegative; | 295 bool get isMinusZero => primitiveValue == 0.0 && primitiveValue.isNegative; |
| 295 | 296 |
| 296 bool get isZero => value == 0.0; | 297 bool get isZero => primitiveValue == 0.0; |
| 297 | 298 |
| 298 bool get isOne => value == 1.0; | 299 bool get isOne => primitiveValue == 1.0; |
| 299 | 300 |
| 300 DartType computeType(Compiler compiler) { | 301 DartType computeType(Compiler compiler) { |
| 301 return compiler.doubleClass.rawType; | 302 return compiler.doubleClass.rawType; |
| 302 } | 303 } |
| 303 | 304 |
| 304 ti.TypeMask computeMask(Compiler compiler) { | 305 ti.TypeMask computeMask(Compiler compiler) { |
| 305 // We have to distinguish -0.0 from 0, but for all practical purposes | 306 // We have to distinguish -0.0 from 0, but for all practical purposes |
| 306 // -0.0 is an integer. | 307 // -0.0 is an integer. |
| 307 // TODO(17235): this kind of special casing should only happen in the | 308 // TODO(17235): this kind of special casing should only happen in the |
| 308 // backend. | 309 // backend. |
| 309 if (isMinusZero && compiler.backend.constantSystem.isInt(this)) { | 310 if (isMinusZero && compiler.backend.constantSystem.isInt(this)) { |
| 310 return compiler.typesTask.uint31Type; | 311 return compiler.typesTask.uint31Type; |
| 311 } | 312 } |
| 312 assert(!compiler.backend.constantSystem.isInt(this)); | 313 assert(!compiler.backend.constantSystem.isInt(this)); |
| 313 return compiler.typesTask.doubleType; | 314 return compiler.typesTask.doubleType; |
| 314 } | 315 } |
| 315 | 316 |
| 316 bool operator ==(var other) { | 317 bool operator ==(var other) { |
| 317 if (other is !DoubleConstant) return false; | 318 if (other is !DoubleConstantValue) return false; |
| 318 DoubleConstant otherDouble = other; | 319 DoubleConstantValue otherDouble = other; |
| 319 double otherValue = otherDouble.value; | 320 double otherValue = otherDouble.primitiveValue; |
| 320 if (value == 0.0 && otherValue == 0.0) { | 321 if (primitiveValue == 0.0 && otherValue == 0.0) { |
| 321 return value.isNegative == otherValue.isNegative; | 322 return primitiveValue.isNegative == otherValue.isNegative; |
| 322 } else if (value.isNaN) { | 323 } else if (primitiveValue.isNaN) { |
| 323 return otherValue.isNaN; | 324 return otherValue.isNaN; |
| 324 } else { | 325 } else { |
| 325 return value == otherValue; | 326 return primitiveValue == otherValue; |
| 326 } | 327 } |
| 327 } | 328 } |
| 328 | 329 |
| 329 int get hashCode => value.hashCode; | 330 int get hashCode => primitiveValue.hashCode; |
| 330 | 331 |
| 331 DartString toDartString() => new DartString.literal(value.toString()); | 332 DartString toDartString() { |
| 333 return new DartString.literal(primitiveValue.toString()); |
| 334 } |
| 332 | 335 |
| 333 accept(ConstantVisitor visitor) => visitor.visitDouble(this); | 336 accept(ConstantValueVisitor visitor) => visitor.visitDouble(this); |
| 334 | 337 |
| 335 String toStructuredString() => 'DoubleConstant(${unparse()})'; | 338 String toStructuredString() => 'DoubleConstant(${unparse()})'; |
| 336 } | 339 } |
| 337 | 340 |
| 338 abstract class BoolConstant extends PrimitiveConstant { | 341 abstract class BoolConstantValue extends PrimitiveConstantValue { |
| 339 factory BoolConstant(value) { | 342 factory BoolConstantValue(value) { |
| 340 return value ? new TrueConstant() : new FalseConstant(); | 343 return value ? new TrueConstantValue() : new FalseConstantValue(); |
| 341 } | 344 } |
| 342 | 345 |
| 343 const BoolConstant._internal(); | 346 const BoolConstantValue._internal(); |
| 344 | 347 |
| 345 bool get isBool => true; | 348 bool get isBool => true; |
| 346 | 349 |
| 347 DartType computeType(Compiler compiler) { | 350 DartType computeType(Compiler compiler) { |
| 348 return compiler.boolClass.rawType; | 351 return compiler.boolClass.rawType; |
| 349 } | 352 } |
| 350 | 353 |
| 351 ti.TypeMask computeMask(Compiler compiler) { | 354 ti.TypeMask computeMask(Compiler compiler) { |
| 352 return compiler.typesTask.boolType; | 355 return compiler.typesTask.boolType; |
| 353 } | 356 } |
| 354 | 357 |
| 355 BoolConstant negate(); | 358 BoolConstantValue negate(); |
| 356 | 359 |
| 357 String toStructuredString() => 'BoolConstant(${unparse()})'; | 360 String toStructuredString() => 'BoolConstant(${unparse()})'; |
| 358 } | 361 } |
| 359 | 362 |
| 360 class TrueConstant extends BoolConstant { | 363 class TrueConstantValue extends BoolConstantValue { |
| 361 factory TrueConstant() => const TrueConstant._internal(); | 364 factory TrueConstantValue() => const TrueConstantValue._internal(); |
| 362 | 365 |
| 363 const TrueConstant._internal() : super._internal(); | 366 const TrueConstantValue._internal() : super._internal(); |
| 364 | 367 |
| 365 bool get isTrue => true; | 368 bool get isTrue => true; |
| 366 | 369 |
| 367 bool get value => true; | 370 bool get primitiveValue => true; |
| 368 | 371 |
| 369 FalseConstant negate() => new FalseConstant(); | 372 FalseConstantValue negate() => new FalseConstantValue(); |
| 370 | 373 |
| 371 bool operator ==(var other) => identical(this, other); | 374 bool operator ==(var other) => identical(this, other); |
| 372 | 375 |
| 373 // The magic constant is just a random value. It does not have any | 376 // The magic constant is just a random value. It does not have any |
| 374 // significance. | 377 // significance. |
| 375 int get hashCode => 499; | 378 int get hashCode => 499; |
| 376 | 379 |
| 377 DartString toDartString() => const LiteralDartString("true"); | 380 DartString toDartString() => const LiteralDartString("true"); |
| 378 | 381 |
| 379 accept(ConstantVisitor visitor) => visitor.visitTrue(this); | 382 accept(ConstantValueVisitor visitor) => visitor.visitTrue(this); |
| 380 } | 383 } |
| 381 | 384 |
| 382 class FalseConstant extends BoolConstant { | 385 class FalseConstantValue extends BoolConstantValue { |
| 383 factory FalseConstant() => const FalseConstant._internal(); | 386 factory FalseConstantValue() => const FalseConstantValue._internal(); |
| 384 | 387 |
| 385 const FalseConstant._internal() : super._internal(); | 388 const FalseConstantValue._internal() : super._internal(); |
| 386 | 389 |
| 387 bool get isFalse => true; | 390 bool get isFalse => true; |
| 388 | 391 |
| 389 bool get value => false; | 392 bool get primitiveValue => false; |
| 390 | 393 |
| 391 TrueConstant negate() => new TrueConstant(); | 394 TrueConstantValue negate() => new TrueConstantValue(); |
| 392 | 395 |
| 393 bool operator ==(var other) => identical(this, other); | 396 bool operator ==(var other) => identical(this, other); |
| 394 | 397 |
| 395 // The magic constant is just a random value. It does not have any | 398 // The magic constant is just a random value. It does not have any |
| 396 // significance. | 399 // significance. |
| 397 int get hashCode => 536555975; | 400 int get hashCode => 536555975; |
| 398 | 401 |
| 399 DartString toDartString() => const LiteralDartString("false"); | 402 DartString toDartString() => const LiteralDartString("false"); |
| 400 | 403 |
| 401 accept(ConstantVisitor visitor) => visitor.visitFalse(this); | 404 accept(ConstantValueVisitor visitor) => visitor.visitFalse(this); |
| 402 } | 405 } |
| 403 | 406 |
| 404 class StringConstant extends PrimitiveConstant { | 407 class StringConstantValue extends PrimitiveConstantValue { |
| 405 final DartString value; | 408 final DartString primitiveValue; |
| 406 | 409 |
| 407 final int hashCode; | 410 final int hashCode; |
| 408 | 411 |
| 409 // TODO(floitsch): cache StringConstants. | 412 // TODO(floitsch): cache StringConstants. |
| 410 // TODO(floitsch): compute hashcode without calling toString() on the | 413 // TODO(floitsch): compute hashcode without calling toString() on the |
| 411 // DartString. | 414 // DartString. |
| 412 StringConstant(DartString value) | 415 StringConstantValue(DartString value) |
| 413 : this.value = value, | 416 : this.primitiveValue = value, |
| 414 this.hashCode = value.slowToString().hashCode; | 417 this.hashCode = value.slowToString().hashCode; |
| 415 | 418 |
| 416 bool get isString => true; | 419 bool get isString => true; |
| 417 | 420 |
| 418 DartType computeType(Compiler compiler) { | 421 DartType computeType(Compiler compiler) { |
| 419 return compiler.stringClass.rawType; | 422 return compiler.stringClass.rawType; |
| 420 } | 423 } |
| 421 | 424 |
| 422 ti.TypeMask computeMask(Compiler compiler) { | 425 ti.TypeMask computeMask(Compiler compiler) { |
| 423 return compiler.typesTask.stringType; | 426 return compiler.typesTask.stringType; |
| 424 } | 427 } |
| 425 | 428 |
| 426 bool operator ==(var other) { | 429 bool operator ==(var other) { |
| 427 if (other is !StringConstant) return false; | 430 if (other is !StringConstantValue) return false; |
| 428 StringConstant otherString = other; | 431 StringConstantValue otherString = other; |
| 429 return (hashCode == otherString.hashCode) && (value == otherString.value); | 432 return hashCode == otherString.hashCode && |
| 433 primitiveValue == otherString.primitiveValue; |
| 430 } | 434 } |
| 431 | 435 |
| 432 DartString toDartString() => value; | 436 DartString toDartString() => primitiveValue; |
| 433 | 437 |
| 434 int get length => value.length; | 438 int get length => primitiveValue.length; |
| 435 | 439 |
| 436 accept(ConstantVisitor visitor) => visitor.visitString(this); | 440 accept(ConstantValueVisitor visitor) => visitor.visitString(this); |
| 437 | 441 |
| 438 // TODO(johnniwinther): Ensure correct escaping. | 442 // TODO(johnniwinther): Ensure correct escaping. |
| 439 String unparse() => '"${value.slowToString()}"'; | 443 String unparse() => '"${primitiveValue.slowToString()}"'; |
| 440 | 444 |
| 441 String toStructuredString() => 'StringConstant(${unparse()})'; | 445 String toStructuredString() => 'StringConstant(${unparse()})'; |
| 442 } | 446 } |
| 443 | 447 |
| 444 abstract class ObjectConstant extends Constant { | 448 abstract class ObjectConstantValue extends ConstantValue { |
| 445 final InterfaceType type; | 449 final InterfaceType type; |
| 446 | 450 |
| 447 ObjectConstant(this.type); | 451 ObjectConstantValue(this.type); |
| 448 | 452 |
| 449 bool get isObject => true; | 453 bool get isObject => true; |
| 450 | 454 |
| 451 DartType computeType(Compiler compiler) => type; | 455 DartType computeType(Compiler compiler) => type; |
| 452 | 456 |
| 453 void _unparseTypeArguments(StringBuffer sb) { | 457 void _unparseTypeArguments(StringBuffer sb) { |
| 454 if (!type.treatAsRaw) { | 458 if (!type.treatAsRaw) { |
| 455 sb.write('<'); | 459 sb.write('<'); |
| 456 sb.write(type.typeArguments.join(', ')); | 460 sb.write(type.typeArguments.join(', ')); |
| 457 sb.write('>'); | 461 sb.write('>'); |
| 458 } | 462 } |
| 459 } | 463 } |
| 460 } | 464 } |
| 461 | 465 |
| 462 class TypeConstant extends ObjectConstant { | 466 class TypeConstantValue extends ObjectConstantValue { |
| 463 /// The user type that this constant represents. | 467 /// The user type that this constant represents. |
| 464 final DartType representedType; | 468 final DartType representedType; |
| 465 | 469 |
| 466 TypeConstant(this.representedType, InterfaceType type) : super(type); | 470 TypeConstantValue(this.representedType, InterfaceType type) : super(type); |
| 467 | 471 |
| 468 bool get isType => true; | 472 bool get isType => true; |
| 469 | 473 |
| 470 bool operator ==(other) { | 474 bool operator ==(other) { |
| 471 return other is TypeConstant && representedType == other.representedType; | 475 return other is TypeConstantValue && |
| 476 representedType == other.representedType; |
| 472 } | 477 } |
| 473 | 478 |
| 474 ti.TypeMask computeMask(Compiler compiler) { | 479 ti.TypeMask computeMask(Compiler compiler) { |
| 475 return compiler.typesTask.typeType; | 480 return compiler.typesTask.typeType; |
| 476 } | 481 } |
| 477 | 482 |
| 478 int get hashCode => representedType.hashCode * 13; | 483 int get hashCode => representedType.hashCode * 13; |
| 479 | 484 |
| 480 List<Constant> getDependencies() => const <Constant>[]; | 485 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 481 | 486 |
| 482 accept(ConstantVisitor visitor) => visitor.visitType(this); | 487 accept(ConstantValueVisitor visitor) => visitor.visitType(this); |
| 483 | 488 |
| 484 String unparse() => '$representedType'; | 489 String unparse() => '$representedType'; |
| 485 | 490 |
| 486 String toStructuredString() => 'TypeConstant(${representedType})'; | 491 String toStructuredString() => 'TypeConstant(${representedType})'; |
| 487 } | 492 } |
| 488 | 493 |
| 489 class ListConstant extends ObjectConstant { | 494 class ListConstantValue extends ObjectConstantValue { |
| 490 final List<Constant> entries; | 495 final List<ConstantValue> entries; |
| 491 final int hashCode; | 496 final int hashCode; |
| 492 | 497 |
| 493 ListConstant(InterfaceType type, List<Constant> entries) | 498 ListConstantValue(InterfaceType type, List<ConstantValue> entries) |
| 494 : this.entries = entries, | 499 : this.entries = entries, |
| 495 hashCode = _computeHash(type, entries), | 500 hashCode = _computeHash(type, entries), |
| 496 super(type); | 501 super(type); |
| 497 | 502 |
| 498 bool get isList => true; | 503 bool get isList => true; |
| 499 | 504 |
| 500 static int _computeHash(DartType type, List<Constant> entries) { | 505 static int _computeHash(DartType type, List<ConstantValue> entries) { |
| 501 // TODO(floitsch): create a better hash. | 506 // TODO(floitsch): create a better hash. |
| 502 int hash = 7; | 507 int hash = 7; |
| 503 for (Constant input in entries) { | 508 for (ConstantValue input in entries) { |
| 504 hash ^= input.hashCode; | 509 hash ^= input.hashCode; |
| 505 } | 510 } |
| 506 hash ^= type.hashCode; | 511 hash ^= type.hashCode; |
| 507 return hash; | 512 return hash; |
| 508 } | 513 } |
| 509 | 514 |
| 510 bool operator ==(var other) { | 515 bool operator ==(var other) { |
| 511 if (other is !ListConstant) return false; | 516 if (other is !ListConstantValue) return false; |
| 512 ListConstant otherList = other; | 517 ListConstantValue otherList = other; |
| 513 if (hashCode != otherList.hashCode) return false; | 518 if (hashCode != otherList.hashCode) return false; |
| 514 if (type != otherList.type) return false; | 519 if (type != otherList.type) return false; |
| 515 if (entries.length != otherList.entries.length) return false; | 520 if (entries.length != otherList.entries.length) return false; |
| 516 for (int i = 0; i < entries.length; i++) { | 521 for (int i = 0; i < entries.length; i++) { |
| 517 if (entries[i] != otherList.entries[i]) return false; | 522 if (entries[i] != otherList.entries[i]) return false; |
| 518 } | 523 } |
| 519 return true; | 524 return true; |
| 520 } | 525 } |
| 521 | 526 |
| 522 List<Constant> getDependencies() => entries; | 527 List<ConstantValue> getDependencies() => entries; |
| 523 | 528 |
| 524 int get length => entries.length; | 529 int get length => entries.length; |
| 525 | 530 |
| 526 ti.TypeMask computeMask(Compiler compiler) { | 531 ti.TypeMask computeMask(Compiler compiler) { |
| 527 return compiler.typesTask.constListType; | 532 return compiler.typesTask.constListType; |
| 528 } | 533 } |
| 529 | 534 |
| 530 accept(ConstantVisitor visitor) => visitor.visitList(this); | 535 accept(ConstantValueVisitor visitor) => visitor.visitList(this); |
| 531 | 536 |
| 532 String unparse() { | 537 String unparse() { |
| 533 StringBuffer sb = new StringBuffer(); | 538 StringBuffer sb = new StringBuffer(); |
| 534 _unparseTypeArguments(sb); | 539 _unparseTypeArguments(sb); |
| 535 sb.write('['); | 540 sb.write('['); |
| 536 for (int i = 0 ; i < length ; i++) { | 541 for (int i = 0 ; i < length ; i++) { |
| 537 if (i > 0) sb.write(','); | 542 if (i > 0) sb.write(','); |
| 538 sb.write(entries[i].unparse()); | 543 sb.write(entries[i].unparse()); |
| 539 } | 544 } |
| 540 sb.write(']'); | 545 sb.write(']'); |
| 541 return sb.toString(); | 546 return sb.toString(); |
| 542 } | 547 } |
| 543 | 548 |
| 544 String toStructuredString() { | 549 String toStructuredString() { |
| 545 StringBuffer sb = new StringBuffer(); | 550 StringBuffer sb = new StringBuffer(); |
| 546 sb.write('ListConstant(['); | 551 sb.write('ListConstant(['); |
| 547 for (int i = 0 ; i < length ; i++) { | 552 for (int i = 0 ; i < length ; i++) { |
| 548 if (i > 0) sb.write(','); | 553 if (i > 0) sb.write(','); |
| 549 sb.write(entries[i].toStructuredString()); | 554 sb.write(entries[i].toStructuredString()); |
| 550 } | 555 } |
| 551 sb.write('])'); | 556 sb.write('])'); |
| 552 return sb.toString(); | 557 return sb.toString(); |
| 553 } | 558 } |
| 554 } | 559 } |
| 555 | 560 |
| 556 class MapConstant extends ObjectConstant { | 561 class MapConstantValue extends ObjectConstantValue { |
| 557 final List<Constant> keys; | 562 final List<ConstantValue> keys; |
| 558 final List<Constant> values; | 563 final List<ConstantValue> values; |
| 559 final int hashCode; | 564 final int hashCode; |
| 560 | 565 |
| 561 MapConstant(InterfaceType type, List<Constant> keys, List<Constant> values) | 566 MapConstantValue(InterfaceType type, |
| 567 List<ConstantValue> keys, |
| 568 List<ConstantValue> values) |
| 562 : this.keys = keys, | 569 : this.keys = keys, |
| 563 this.values = values, | 570 this.values = values, |
| 564 this.hashCode = computeHash(type, keys, values), | 571 this.hashCode = computeHash(type, keys, values), |
| 565 super(type) { | 572 super(type) { |
| 566 assert(keys.length == values.length); | 573 assert(keys.length == values.length); |
| 567 } | 574 } |
| 568 | 575 |
| 569 bool get isMap => true; | 576 bool get isMap => true; |
| 570 | 577 |
| 571 static int computeHash(DartType type, | 578 static int computeHash(DartType type, |
| 572 List<Constant> keys, | 579 List<ConstantValue> keys, |
| 573 List<Constant> values) { | 580 List<ConstantValue> values) { |
| 574 // TODO(floitsch): create a better hash. | 581 // TODO(floitsch): create a better hash. |
| 575 int hash = 0; | 582 int hash = 0; |
| 576 for (Constant key in keys) { | 583 for (ConstantValue key in keys) { |
| 577 hash ^= key.hashCode; | 584 hash ^= key.hashCode; |
| 578 } | 585 } |
| 579 for (Constant value in values) { | 586 for (ConstantValue value in values) { |
| 580 hash ^= value.hashCode; | 587 hash ^= value.hashCode; |
| 581 } | 588 } |
| 582 hash ^= type.hashCode; | 589 hash ^= type.hashCode; |
| 583 return hash; | 590 return hash; |
| 584 } | 591 } |
| 585 | 592 |
| 586 ti.TypeMask computeMask(Compiler compiler) { | 593 ti.TypeMask computeMask(Compiler compiler) { |
| 587 return compiler.typesTask.constMapType; | 594 return compiler.typesTask.constMapType; |
| 588 } | 595 } |
| 589 | 596 |
| 590 bool operator ==(var other) { | 597 bool operator ==(var other) { |
| 591 if (other is !MapConstant) return false; | 598 if (other is !MapConstantValue) return false; |
| 592 MapConstant otherMap = other; | 599 MapConstantValue otherMap = other; |
| 593 if (hashCode != otherMap.hashCode) return false; | 600 if (hashCode != otherMap.hashCode) return false; |
| 594 if (type != other.type) return false; | 601 if (type != other.type) return false; |
| 595 if (length != other.length) return false; | 602 if (length != other.length) return false; |
| 596 for (int i = 0; i < length; i++) { | 603 for (int i = 0; i < length; i++) { |
| 597 if (keys[i] != otherMap.keys[i]) return false; | 604 if (keys[i] != otherMap.keys[i]) return false; |
| 598 if (values[i] != otherMap.values[i]) return false; | 605 if (values[i] != otherMap.values[i]) return false; |
| 599 } | 606 } |
| 600 return true; | 607 return true; |
| 601 } | 608 } |
| 602 | 609 |
| 603 List<Constant> getDependencies() { | 610 List<ConstantValue> getDependencies() { |
| 604 List<Constant> result = <Constant>[]; | 611 List<ConstantValue> result = <ConstantValue>[]; |
| 605 result.addAll(keys); | 612 result.addAll(keys); |
| 606 result.addAll(values); | 613 result.addAll(values); |
| 607 return result; | 614 return result; |
| 608 } | 615 } |
| 609 | 616 |
| 610 int get length => keys.length; | 617 int get length => keys.length; |
| 611 | 618 |
| 612 accept(ConstantVisitor visitor) => visitor.visitMap(this); | 619 accept(ConstantValueVisitor visitor) => visitor.visitMap(this); |
| 613 | 620 |
| 614 String unparse() { | 621 String unparse() { |
| 615 StringBuffer sb = new StringBuffer(); | 622 StringBuffer sb = new StringBuffer(); |
| 616 _unparseTypeArguments(sb); | 623 _unparseTypeArguments(sb); |
| 617 sb.write('{'); | 624 sb.write('{'); |
| 618 for (int i = 0 ; i < length ; i++) { | 625 for (int i = 0 ; i < length ; i++) { |
| 619 if (i > 0) sb.write(','); | 626 if (i > 0) sb.write(','); |
| 620 sb.write(keys[i].unparse()); | 627 sb.write(keys[i].unparse()); |
| 621 sb.write(':'); | 628 sb.write(':'); |
| 622 sb.write(values[i].unparse()); | 629 sb.write(values[i].unparse()); |
| 623 } | 630 } |
| 624 sb.write('}'); | 631 sb.write('}'); |
| 625 return sb.toString(); | 632 return sb.toString(); |
| 626 } | 633 } |
| 627 | 634 |
| 628 String toStructuredString() { | 635 String toStructuredString() { |
| 629 StringBuffer sb = new StringBuffer(); | 636 StringBuffer sb = new StringBuffer(); |
| 630 sb.write('MapConstant({'); | 637 sb.write('MapConstant({'); |
| 631 for (int i = 0; i < length; i++) { | 638 for (int i = 0; i < length; i++) { |
| 632 if (i > 0) sb.write(','); | 639 if (i > 0) sb.write(','); |
| 633 sb.write(keys[i].toStructuredString()); | 640 sb.write(keys[i].toStructuredString()); |
| 634 sb.write(':'); | 641 sb.write(':'); |
| 635 sb.write(values[i].toStructuredString()); | 642 sb.write(values[i].toStructuredString()); |
| 636 } | 643 } |
| 637 sb.write('})'); | 644 sb.write('})'); |
| 638 return sb.toString(); | 645 return sb.toString(); |
| 639 } | 646 } |
| 640 } | 647 } |
| 641 | 648 |
| 642 class InterceptorConstant extends Constant { | 649 class InterceptorConstantValue extends ConstantValue { |
| 643 /// The type for which this interceptor holds the methods. The constant | 650 /// The type for which this interceptor holds the methods. The constant |
| 644 /// is a dispatch table for this type. | 651 /// is a dispatch table for this type. |
| 645 final DartType dispatchedType; | 652 final DartType dispatchedType; |
| 646 | 653 |
| 647 InterceptorConstant(this.dispatchedType); | 654 InterceptorConstantValue(this.dispatchedType); |
| 648 | 655 |
| 649 bool get isInterceptor => true; | 656 bool get isInterceptor => true; |
| 650 | 657 |
| 651 bool operator ==(other) { | 658 bool operator ==(other) { |
| 652 return other is InterceptorConstant | 659 return other is InterceptorConstantValue |
| 653 && dispatchedType == other.dispatchedType; | 660 && dispatchedType == other.dispatchedType; |
| 654 } | 661 } |
| 655 | 662 |
| 656 int get hashCode => dispatchedType.hashCode * 43; | 663 int get hashCode => dispatchedType.hashCode * 43; |
| 657 | 664 |
| 658 List<Constant> getDependencies() => const <Constant>[]; | 665 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 659 | 666 |
| 660 accept(ConstantVisitor visitor) => visitor.visitInterceptor(this); | 667 accept(ConstantValueVisitor visitor) => visitor.visitInterceptor(this); |
| 661 | 668 |
| 662 DartType computeType(Compiler compiler) => const DynamicType(); | 669 DartType computeType(Compiler compiler) => const DynamicType(); |
| 663 | 670 |
| 664 ti.TypeMask computeMask(Compiler compiler) { | 671 ti.TypeMask computeMask(Compiler compiler) { |
| 665 return compiler.typesTask.nonNullType; | 672 return compiler.typesTask.nonNullType; |
| 666 } | 673 } |
| 667 | 674 |
| 668 String unparse() { | 675 String unparse() { |
| 669 return 'interceptor($dispatchedType)'; | 676 return 'interceptor($dispatchedType)'; |
| 670 } | 677 } |
| 671 | 678 |
| 672 String toStructuredString() { | 679 String toStructuredString() { |
| 673 return 'InterceptorConstant(${dispatchedType.getStringAsDeclared("o")})'; | 680 return 'InterceptorConstant(${dispatchedType.getStringAsDeclared("o")})'; |
| 674 } | 681 } |
| 675 } | 682 } |
| 676 | 683 |
| 677 class DummyConstant extends Constant { | 684 class DummyConstantValue extends ConstantValue { |
| 678 final ti.TypeMask typeMask; | 685 final ti.TypeMask typeMask; |
| 679 | 686 |
| 680 DummyConstant(this.typeMask); | 687 DummyConstantValue(this.typeMask); |
| 681 | 688 |
| 682 bool get isDummy => true; | 689 bool get isDummy => true; |
| 683 | 690 |
| 684 bool operator ==(other) { | 691 bool operator ==(other) { |
| 685 return other is DummyConstant | 692 return other is DummyConstantValue |
| 686 && typeMask == other.typeMask; | 693 && typeMask == other.typeMask; |
| 687 } | 694 } |
| 688 | 695 |
| 689 get hashCode => typeMask.hashCode; | 696 get hashCode => typeMask.hashCode; |
| 690 | 697 |
| 691 List<Constant> getDependencies() => const <Constant>[]; | 698 List<ConstantValue> getDependencies() => const <ConstantValue>[]; |
| 692 | 699 |
| 693 accept(ConstantVisitor visitor) => visitor.visitDummy(this); | 700 accept(ConstantValueVisitor visitor) => visitor.visitDummy(this); |
| 694 | 701 |
| 695 DartType computeType(Compiler compiler) => const DynamicType(); | 702 DartType computeType(Compiler compiler) => const DynamicType(); |
| 696 | 703 |
| 697 ti.TypeMask computeMask(Compiler compiler) => typeMask; | 704 ti.TypeMask computeMask(Compiler compiler) => typeMask; |
| 698 | 705 |
| 699 String unparse() => 'dummy($typeMask)'; | 706 String unparse() => 'dummy($typeMask)'; |
| 700 | 707 |
| 701 String toStructuredString() => 'DummyConstant($typeMask)'; | 708 String toStructuredString() => 'DummyConstant($typeMask)'; |
| 702 } | 709 } |
| 703 | 710 |
| 704 class ConstructedConstant extends ObjectConstant { | 711 class ConstructedConstantValue extends ObjectConstantValue { |
| 705 final List<Constant> fields; | 712 final List<ConstantValue> fields; |
| 706 final int hashCode; | 713 final int hashCode; |
| 707 | 714 |
| 708 ConstructedConstant(InterfaceType type, List<Constant> fields) | 715 ConstructedConstantValue(InterfaceType type, List<ConstantValue> fields) |
| 709 : this.fields = fields, | 716 : this.fields = fields, |
| 710 hashCode = computeHash(type, fields), | 717 hashCode = computeHash(type, fields), |
| 711 super(type) { | 718 super(type) { |
| 712 assert(type != null); | 719 assert(type != null); |
| 713 } | 720 } |
| 714 | 721 |
| 715 bool get isConstructedObject => true; | 722 bool get isConstructedObject => true; |
| 716 | 723 |
| 717 static int computeHash(DartType type, List<Constant> fields) { | 724 static int computeHash(DartType type, List<ConstantValue> fields) { |
| 718 // TODO(floitsch): create a better hash. | 725 // TODO(floitsch): create a better hash. |
| 719 int hash = 0; | 726 int hash = 0; |
| 720 for (Constant field in fields) { | 727 for (ConstantValue field in fields) { |
| 721 hash ^= field.hashCode; | 728 hash ^= field.hashCode; |
| 722 } | 729 } |
| 723 hash ^= type.hashCode; | 730 hash ^= type.hashCode; |
| 724 return hash; | 731 return hash; |
| 725 } | 732 } |
| 726 | 733 |
| 727 bool operator ==(var otherVar) { | 734 bool operator ==(var otherVar) { |
| 728 if (otherVar is !ConstructedConstant) return false; | 735 if (otherVar is !ConstructedConstantValue) return false; |
| 729 ConstructedConstant other = otherVar; | 736 ConstructedConstantValue other = otherVar; |
| 730 if (hashCode != other.hashCode) return false; | 737 if (hashCode != other.hashCode) return false; |
| 731 if (type != other.type) return false; | 738 if (type != other.type) return false; |
| 732 if (fields.length != other.fields.length) return false; | 739 if (fields.length != other.fields.length) return false; |
| 733 for (int i = 0; i < fields.length; i++) { | 740 for (int i = 0; i < fields.length; i++) { |
| 734 if (fields[i] != other.fields[i]) return false; | 741 if (fields[i] != other.fields[i]) return false; |
| 735 } | 742 } |
| 736 return true; | 743 return true; |
| 737 } | 744 } |
| 738 | 745 |
| 739 List<Constant> getDependencies() => fields; | 746 List<ConstantValue> getDependencies() => fields; |
| 740 | 747 |
| 741 ti.TypeMask computeMask(Compiler compiler) { | 748 ti.TypeMask computeMask(Compiler compiler) { |
| 742 if (compiler.backend.isInterceptorClass(type.element)) { | 749 if (compiler.backend.isInterceptorClass(type.element)) { |
| 743 return compiler.typesTask.nonNullType; | 750 return compiler.typesTask.nonNullType; |
| 744 } | 751 } |
| 745 return new ti.TypeMask.nonNullExact(type.element, compiler.world); | 752 return new ti.TypeMask.nonNullExact(type.element, compiler.world); |
| 746 } | 753 } |
| 747 | 754 |
| 748 accept(ConstantVisitor visitor) => visitor.visitConstructed(this); | 755 accept(ConstantValueVisitor visitor) => visitor.visitConstructed(this); |
| 749 | 756 |
| 750 Map<Element, Constant> get fieldElements { | 757 Map<Element, ConstantValue> get fieldElements { |
| 751 // TODO(ahe): Refactor constant system to store this information directly. | 758 // TODO(ahe): Refactor constant system to store this information directly. |
| 752 ClassElement classElement = type.element; | 759 ClassElement classElement = type.element; |
| 753 int count = 0; | 760 int count = 0; |
| 754 Map<Element, Constant> result = new Map<Element, Constant>(); | 761 Map<Element, ConstantValue> result = new Map<Element, ConstantValue>(); |
| 755 classElement.implementation.forEachInstanceField((holder, field) { | 762 classElement.implementation.forEachInstanceField((holder, field) { |
| 756 result[field] = fields[count++]; | 763 result[field] = fields[count++]; |
| 757 }, includeSuperAndInjectedMembers: true); | 764 }, includeSuperAndInjectedMembers: true); |
| 758 return result; | 765 return result; |
| 759 } | 766 } |
| 760 | 767 |
| 761 String unparse() { | 768 String unparse() { |
| 762 StringBuffer sb = new StringBuffer(); | 769 StringBuffer sb = new StringBuffer(); |
| 763 sb.write(type.name); | 770 sb.write(type.name); |
| 764 _unparseTypeArguments(sb); | 771 _unparseTypeArguments(sb); |
| 765 sb.write('('); | 772 sb.write('('); |
| 766 int i = 0; | 773 int i = 0; |
| 767 fieldElements.forEach((Element field, Constant value) { | 774 fieldElements.forEach((Element field, ConstantValue value) { |
| 768 if (i > 0) sb.write(','); | 775 if (i > 0) sb.write(','); |
| 769 sb.write(field.name); | 776 sb.write(field.name); |
| 770 sb.write('='); | 777 sb.write('='); |
| 771 sb.write(value.unparse()); | 778 sb.write(value.unparse()); |
| 772 i++; | 779 i++; |
| 773 }); | 780 }); |
| 774 sb.write(')'); | 781 sb.write(')'); |
| 775 return sb.toString(); | 782 return sb.toString(); |
| 776 } | 783 } |
| 777 | 784 |
| 778 String toStructuredString() { | 785 String toStructuredString() { |
| 779 StringBuffer sb = new StringBuffer(); | 786 StringBuffer sb = new StringBuffer(); |
| 780 sb.write('ConstructedConstant('); | 787 sb.write('ConstructedConstant('); |
| 781 sb.write(type); | 788 sb.write(type); |
| 782 sb.write('('); | 789 sb.write('('); |
| 783 int i = 0; | 790 int i = 0; |
| 784 fieldElements.forEach((Element field, Constant value) { | 791 fieldElements.forEach((Element field, ConstantValue value) { |
| 785 if (i > 0) sb.write(','); | 792 if (i > 0) sb.write(','); |
| 786 sb.write(field.name); | 793 sb.write(field.name); |
| 787 sb.write('='); | 794 sb.write('='); |
| 788 sb.write(value.toStructuredString()); | 795 sb.write(value.toStructuredString()); |
| 789 i++; | 796 i++; |
| 790 }); | 797 }); |
| 791 sb.write('))'); | 798 sb.write('))'); |
| 792 return sb.toString(); | 799 return sb.toString(); |
| 793 } | 800 } |
| 794 } | 801 } |
| 795 | 802 |
| 796 /// A reference to a constant in another output unit. | 803 /// A reference to a constant in another output unit. |
| 797 /// Used for referring to deferred constants. | 804 /// Used for referring to deferred constants. |
| 798 class DeferredConstant extends Constant { | 805 class DeferredConstantValue extends ConstantValue { |
| 799 DeferredConstant(this.referenced, this.prefix); | 806 DeferredConstantValue(this.referenced, this.prefix); |
| 800 | 807 |
| 801 final Constant referenced; | 808 final ConstantValue referenced; |
| 802 final PrefixElement prefix; | 809 final PrefixElement prefix; |
| 803 | 810 |
| 804 bool get isReference => true; | 811 bool get isReference => true; |
| 805 | 812 |
| 806 bool operator ==(other) { | 813 bool operator ==(other) { |
| 807 return other is DeferredConstant | 814 return other is DeferredConstantValue |
| 808 && referenced == other.referenced | 815 && referenced == other.referenced |
| 809 && prefix == other.prefix; | 816 && prefix == other.prefix; |
| 810 } | 817 } |
| 811 | 818 |
| 812 get hashCode => (referenced.hashCode * 17 + prefix.hashCode) & 0x3fffffff; | 819 get hashCode => (referenced.hashCode * 17 + prefix.hashCode) & 0x3fffffff; |
| 813 | 820 |
| 814 List<Constant> getDependencies() => <Constant>[referenced]; | 821 List<ConstantValue> getDependencies() => <ConstantValue>[referenced]; |
| 815 | 822 |
| 816 accept(ConstantVisitor visitor) => visitor.visitDeferred(this); | 823 accept(ConstantValueVisitor visitor) => visitor.visitDeferred(this); |
| 817 | 824 |
| 818 DartType computeType(Compiler compiler) => referenced.computeType(compiler); | 825 DartType computeType(Compiler compiler) => referenced.computeType(compiler); |
| 819 | 826 |
| 820 ti.TypeMask computeMask(Compiler compiler) { | 827 ti.TypeMask computeMask(Compiler compiler) { |
| 821 return referenced.computeMask(compiler); | 828 return referenced.computeMask(compiler); |
| 822 } | 829 } |
| 823 | 830 |
| 824 String unparse() => 'deferred(${referenced.unparse()})'; | 831 String unparse() => 'deferred(${referenced.unparse()})'; |
| 825 | 832 |
| 826 String toStructuredString() => 'DeferredConstant($referenced)'; | 833 String toStructuredString() => 'DeferredConstant($referenced)'; |
| 827 } | 834 } |
| OLD | NEW |