| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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.expressions; | 5 library dart2js.constants.expressions; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../constants/constant_system.dart'; | 8 import '../constants/constant_system.dart'; |
| 9 import '../core_types.dart'; | 9 import '../core_types.dart'; |
| 10 import '../dart_types.dart'; | 10 import '../dart_types.dart'; |
| 11 import '../elements/elements.dart' show | 11 import '../elements/elements.dart' |
| 12 ConstructorElement, | 12 show |
| 13 Element, | 13 ConstructorElement, |
| 14 FieldElement, | 14 Element, |
| 15 FunctionElement, | 15 FieldElement, |
| 16 PrefixElement, | 16 FunctionElement, |
| 17 VariableElement; | 17 PrefixElement, |
| 18 VariableElement; |
| 18 import '../resolution/operators.dart'; | 19 import '../resolution/operators.dart'; |
| 19 import '../tree/tree.dart' show | 20 import '../tree/tree.dart' show DartString; |
| 20 DartString; | 21 import '../universe/call_structure.dart' show CallStructure; |
| 21 import '../universe/call_structure.dart' show | |
| 22 CallStructure; | |
| 23 import 'evaluation.dart'; | 22 import 'evaluation.dart'; |
| 24 import 'values.dart'; | 23 import 'values.dart'; |
| 25 | 24 |
| 26 enum ConstantExpressionKind { | 25 enum ConstantExpressionKind { |
| 27 BINARY, | 26 BINARY, |
| 28 BOOL, | 27 BOOL, |
| 29 BOOL_FROM_ENVIRONMENT, | 28 BOOL_FROM_ENVIRONMENT, |
| 30 CONCATENATE, | 29 CONCATENATE, |
| 31 CONDITIONAL, | 30 CONDITIONAL, |
| 32 CONSTRUCTED, | 31 CONSTRUCTED, |
| 33 DEFERRED, | 32 DEFERRED, |
| 34 DOUBLE, | 33 DOUBLE, |
| 35 ERRONEOUS, | 34 ERRONEOUS, |
| 36 FUNCTION, | 35 FUNCTION, |
| 37 IDENTICAL, | 36 IDENTICAL, |
| 38 INT, | 37 INT, |
| 39 INT_FROM_ENVIRONMENT, | 38 INT_FROM_ENVIRONMENT, |
| 40 LIST, | 39 LIST, |
| 41 MAP, | 40 MAP, |
| 42 NULL, | 41 NULL, |
| 43 STRING, | 42 STRING, |
| 44 STRING_FROM_ENVIRONMENT, | 43 STRING_FROM_ENVIRONMENT, |
| 45 STRING_LENGTH, | 44 STRING_LENGTH, |
| 46 SYMBOL, | 45 SYMBOL, |
| 47 SYNTHETIC, | 46 SYNTHETIC, |
| 48 TYPE, | 47 TYPE, |
| 49 UNARY, | 48 UNARY, |
| 50 VARIABLE, | 49 VARIABLE, |
| 51 | |
| 52 POSITIONAL_REFERENCE, | 50 POSITIONAL_REFERENCE, |
| 53 NAMED_REFERENCE, | 51 NAMED_REFERENCE, |
| 54 } | 52 } |
| 55 | 53 |
| 56 /// An expression that is a compile-time constant. | 54 /// An expression that is a compile-time constant. |
| 57 /// | 55 /// |
| 58 /// Whereas [ConstantValue] represent a compile-time value, a | 56 /// Whereas [ConstantValue] represent a compile-time value, a |
| 59 /// [ConstantExpression] represents an expression for creating a constant. | 57 /// [ConstantExpression] represents an expression for creating a constant. |
| 60 /// | 58 /// |
| 61 /// There is no one-to-one mapping between [ConstantExpression] and | 59 /// There is no one-to-one mapping between [ConstantExpression] and |
| 62 /// [ConstantValue], because different expressions can denote the same constant. | 60 /// [ConstantValue], because different expressions can denote the same constant. |
| 63 /// For instance, multiple `const` constructors may be used to create the same | 61 /// For instance, multiple `const` constructors may be used to create the same |
| 64 /// object, and different `const` variables may hold the same value. | 62 /// object, and different `const` variables may hold the same value. |
| 65 abstract class ConstantExpression { | 63 abstract class ConstantExpression { |
| 66 int _hashCode; | 64 int _hashCode; |
| 67 | 65 |
| 68 ConstantExpressionKind get kind; | 66 ConstantExpressionKind get kind; |
| 69 | 67 |
| 70 // TODO(johnniwinther): Unify precedence handled between constants, front-end | 68 // TODO(johnniwinther): Unify precedence handled between constants, front-end |
| 71 // and back-end. | 69 // and back-end. |
| 72 int get precedence => 16; | 70 int get precedence => 16; |
| 73 | 71 |
| 74 accept(ConstantExpressionVisitor visitor, [context]); | 72 accept(ConstantExpressionVisitor visitor, [context]); |
| 75 | 73 |
| 76 /// Substitute free variables using arguments. | 74 /// Substitute free variables using arguments. |
| 77 ConstantExpression apply(NormalizedArguments arguments) => this; | 75 ConstantExpression apply(NormalizedArguments arguments) => this; |
| 78 | 76 |
| 79 /// Compute the [ConstantValue] for this expression using the [environment] | 77 /// Compute the [ConstantValue] for this expression using the [environment] |
| 80 /// and the [constantSystem]. | 78 /// and the [constantSystem]. |
| 81 ConstantValue evaluate(Environment environment, | 79 ConstantValue evaluate( |
| 82 ConstantSystem constantSystem); | 80 Environment environment, ConstantSystem constantSystem); |
| 83 | 81 |
| 84 /// Returns the type of this constant expression, if it is independent of the | 82 /// Returns the type of this constant expression, if it is independent of the |
| 85 /// environment values. | 83 /// environment values. |
| 86 DartType getKnownType(CoreTypes coreTypes) => null; | 84 DartType getKnownType(CoreTypes coreTypes) => null; |
| 87 | 85 |
| 88 String getText() { | 86 String getText() { |
| 89 ConstExpPrinter printer = new ConstExpPrinter(); | 87 ConstExpPrinter printer = new ConstExpPrinter(); |
| 90 accept(printer); | 88 accept(printer); |
| 91 return printer.toString(); | 89 return printer.toString(); |
| 92 } | 90 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 105 bool operator ==(other) { | 103 bool operator ==(other) { |
| 106 if (identical(this, other)) return true; | 104 if (identical(this, other)) return true; |
| 107 if (other is! ConstantExpression) return false; | 105 if (other is! ConstantExpression) return false; |
| 108 if (kind != other.kind) return false; | 106 if (kind != other.kind) return false; |
| 109 if (hashCode != other.hashCode) return false; | 107 if (hashCode != other.hashCode) return false; |
| 110 return _equals(other); | 108 return _equals(other); |
| 111 } | 109 } |
| 112 | 110 |
| 113 String toString() { | 111 String toString() { |
| 114 assertDebugMode('Use ConstantExpression.getText() instead of ' | 112 assertDebugMode('Use ConstantExpression.getText() instead of ' |
| 115 'ConstantExpression.toString()'); | 113 'ConstantExpression.toString()'); |
| 116 return getText(); | 114 return getText(); |
| 117 } | 115 } |
| 118 } | 116 } |
| 119 | 117 |
| 120 /// A synthetic constant used to recover from errors. | 118 /// A synthetic constant used to recover from errors. |
| 121 class ErroneousConstantExpression extends ConstantExpression { | 119 class ErroneousConstantExpression extends ConstantExpression { |
| 122 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS; | 120 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS; |
| 123 | 121 |
| 124 accept(ConstantExpressionVisitor visitor, [context]) { | 122 accept(ConstantExpressionVisitor visitor, [context]) { |
| 125 // Do nothing. This is an error. | 123 // Do nothing. This is an error. |
| 126 } | 124 } |
| 127 | 125 |
| 128 @override | 126 @override |
| 129 ConstantValue evaluate(Environment environment, | 127 ConstantValue evaluate( |
| 130 ConstantSystem constantSystem) { | 128 Environment environment, ConstantSystem constantSystem) { |
| 131 // TODO(johnniwinther): Use non-constant values for errors. | 129 // TODO(johnniwinther): Use non-constant values for errors. |
| 132 return new NonConstantValue(); | 130 return new NonConstantValue(); |
| 133 } | 131 } |
| 134 | 132 |
| 135 @override | 133 @override |
| 136 int _computeHashCode() => 13; | 134 int _computeHashCode() => 13; |
| 137 | 135 |
| 138 @override | 136 @override |
| 139 bool _equals(ErroneousConstantExpression other) => true; | 137 bool _equals(ErroneousConstantExpression other) => true; |
| 140 } | 138 } |
| 141 | 139 |
| 142 // TODO(johnniwinther): Avoid the need for this class. | 140 // TODO(johnniwinther): Avoid the need for this class. |
| 143 class SyntheticConstantExpression extends ConstantExpression { | 141 class SyntheticConstantExpression extends ConstantExpression { |
| 144 final SyntheticConstantValue value; | 142 final SyntheticConstantValue value; |
| 145 | 143 |
| 146 SyntheticConstantExpression(this.value); | 144 SyntheticConstantExpression(this.value); |
| 147 | 145 |
| 148 @override | 146 @override |
| 149 ConstantValue evaluate(Environment environment, | 147 ConstantValue evaluate( |
| 150 ConstantSystem constantSystem) { | 148 Environment environment, ConstantSystem constantSystem) { |
| 151 return value; | 149 return value; |
| 152 } | 150 } |
| 153 | 151 |
| 154 @override | 152 @override |
| 155 int _computeHashCode() => 13 * value.hashCode; | 153 int _computeHashCode() => 13 * value.hashCode; |
| 156 | 154 |
| 157 accept(ConstantExpressionVisitor visitor, [context]) { | 155 accept(ConstantExpressionVisitor visitor, [context]) { |
| 158 throw "unsupported"; | 156 throw "unsupported"; |
| 159 } | 157 } |
| 160 | 158 |
| 161 @override | 159 @override |
| 162 bool _equals(SyntheticConstantExpression other) { | 160 bool _equals(SyntheticConstantExpression other) { |
| 163 return value == other.value; | 161 return value == other.value; |
| 164 } | 162 } |
| 165 | 163 |
| 166 ConstantExpressionKind get kind => ConstantExpressionKind.SYNTHETIC; | 164 ConstantExpressionKind get kind => ConstantExpressionKind.SYNTHETIC; |
| 167 } | 165 } |
| 168 | 166 |
| 169 | |
| 170 | |
| 171 /// A boolean, int, double, string, or null constant. | 167 /// A boolean, int, double, string, or null constant. |
| 172 abstract class PrimitiveConstantExpression extends ConstantExpression { | 168 abstract class PrimitiveConstantExpression extends ConstantExpression { |
| 173 /// The primitive value of this contant expression. | 169 /// The primitive value of this contant expression. |
| 174 get primitiveValue; | 170 get primitiveValue; |
| 175 } | 171 } |
| 176 | 172 |
| 177 /// Boolean literal constant. | 173 /// Boolean literal constant. |
| 178 class BoolConstantExpression extends PrimitiveConstantExpression { | 174 class BoolConstantExpression extends PrimitiveConstantExpression { |
| 179 final bool primitiveValue; | 175 final bool primitiveValue; |
| 180 | 176 |
| 181 BoolConstantExpression(this.primitiveValue); | 177 BoolConstantExpression(this.primitiveValue); |
| 182 | 178 |
| 183 ConstantExpressionKind get kind => ConstantExpressionKind.BOOL; | 179 ConstantExpressionKind get kind => ConstantExpressionKind.BOOL; |
| 184 | 180 |
| 185 accept(ConstantExpressionVisitor visitor, [context]) { | 181 accept(ConstantExpressionVisitor visitor, [context]) { |
| 186 return visitor.visitBool(this, context); | 182 return visitor.visitBool(this, context); |
| 187 } | 183 } |
| 188 | 184 |
| 189 @override | 185 @override |
| 190 ConstantValue evaluate(Environment environment, | 186 ConstantValue evaluate( |
| 191 ConstantSystem constantSystem) { | 187 Environment environment, ConstantSystem constantSystem) { |
| 192 return constantSystem.createBool(primitiveValue); | 188 return constantSystem.createBool(primitiveValue); |
| 193 } | 189 } |
| 194 | 190 |
| 195 @override | 191 @override |
| 196 int _computeHashCode() => 13 * primitiveValue.hashCode; | 192 int _computeHashCode() => 13 * primitiveValue.hashCode; |
| 197 | 193 |
| 198 @override | 194 @override |
| 199 bool _equals(BoolConstantExpression other) { | 195 bool _equals(BoolConstantExpression other) { |
| 200 return primitiveValue == other.primitiveValue; | 196 return primitiveValue == other.primitiveValue; |
| 201 } | 197 } |
| 202 | 198 |
| 203 @override | 199 @override |
| 204 DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; | 200 DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; |
| 205 } | 201 } |
| 206 | 202 |
| 207 /// Integer literal constant. | 203 /// Integer literal constant. |
| 208 class IntConstantExpression extends PrimitiveConstantExpression { | 204 class IntConstantExpression extends PrimitiveConstantExpression { |
| 209 final int primitiveValue; | 205 final int primitiveValue; |
| 210 | 206 |
| 211 IntConstantExpression(this.primitiveValue); | 207 IntConstantExpression(this.primitiveValue); |
| 212 | 208 |
| 213 ConstantExpressionKind get kind => ConstantExpressionKind.INT; | 209 ConstantExpressionKind get kind => ConstantExpressionKind.INT; |
| 214 | 210 |
| 215 accept(ConstantExpressionVisitor visitor, [context]) { | 211 accept(ConstantExpressionVisitor visitor, [context]) { |
| 216 return visitor.visitInt(this, context); | 212 return visitor.visitInt(this, context); |
| 217 } | 213 } |
| 218 | 214 |
| 219 @override | 215 @override |
| 220 ConstantValue evaluate(Environment environment, | 216 ConstantValue evaluate( |
| 221 ConstantSystem constantSystem) { | 217 Environment environment, ConstantSystem constantSystem) { |
| 222 return constantSystem.createInt(primitiveValue); | 218 return constantSystem.createInt(primitiveValue); |
| 223 } | 219 } |
| 224 | 220 |
| 225 @override | 221 @override |
| 226 int _computeHashCode() => 17 * primitiveValue.hashCode; | 222 int _computeHashCode() => 17 * primitiveValue.hashCode; |
| 227 | 223 |
| 228 @override | 224 @override |
| 229 bool _equals(IntConstantExpression other) { | 225 bool _equals(IntConstantExpression other) { |
| 230 return primitiveValue == other.primitiveValue; | 226 return primitiveValue == other.primitiveValue; |
| 231 } | 227 } |
| 232 | 228 |
| 233 @override | 229 @override |
| 234 DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; | 230 DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; |
| 235 } | 231 } |
| 236 | 232 |
| 237 /// Double literal constant. | 233 /// Double literal constant. |
| 238 class DoubleConstantExpression extends PrimitiveConstantExpression { | 234 class DoubleConstantExpression extends PrimitiveConstantExpression { |
| 239 final double primitiveValue; | 235 final double primitiveValue; |
| 240 | 236 |
| 241 DoubleConstantExpression(this.primitiveValue); | 237 DoubleConstantExpression(this.primitiveValue); |
| 242 | 238 |
| 243 ConstantExpressionKind get kind => ConstantExpressionKind.DOUBLE; | 239 ConstantExpressionKind get kind => ConstantExpressionKind.DOUBLE; |
| 244 | 240 |
| 245 accept(ConstantExpressionVisitor visitor, [context]) { | 241 accept(ConstantExpressionVisitor visitor, [context]) { |
| 246 return visitor.visitDouble(this, context); | 242 return visitor.visitDouble(this, context); |
| 247 } | 243 } |
| 248 | 244 |
| 249 @override | 245 @override |
| 250 ConstantValue evaluate(Environment environment, | 246 ConstantValue evaluate( |
| 251 ConstantSystem constantSystem) { | 247 Environment environment, ConstantSystem constantSystem) { |
| 252 return constantSystem.createDouble(primitiveValue); | 248 return constantSystem.createDouble(primitiveValue); |
| 253 } | 249 } |
| 254 | 250 |
| 255 @override | 251 @override |
| 256 int _computeHashCode() => 19 * primitiveValue.hashCode; | 252 int _computeHashCode() => 19 * primitiveValue.hashCode; |
| 257 | 253 |
| 258 @override | 254 @override |
| 259 bool _equals(DoubleConstantExpression other) { | 255 bool _equals(DoubleConstantExpression other) { |
| 260 return primitiveValue == other.primitiveValue; | 256 return primitiveValue == other.primitiveValue; |
| 261 } | 257 } |
| 262 | 258 |
| 263 @override | 259 @override |
| 264 DartType getKnownType(CoreTypes coreTypes) => coreTypes.doubleType; | 260 DartType getKnownType(CoreTypes coreTypes) => coreTypes.doubleType; |
| 265 } | 261 } |
| 266 | 262 |
| 267 /// String literal constant. | 263 /// String literal constant. |
| 268 class StringConstantExpression extends PrimitiveConstantExpression { | 264 class StringConstantExpression extends PrimitiveConstantExpression { |
| 269 final String primitiveValue; | 265 final String primitiveValue; |
| 270 | 266 |
| 271 StringConstantExpression(this.primitiveValue); | 267 StringConstantExpression(this.primitiveValue); |
| 272 | 268 |
| 273 ConstantExpressionKind get kind => ConstantExpressionKind.STRING; | 269 ConstantExpressionKind get kind => ConstantExpressionKind.STRING; |
| 274 | 270 |
| 275 accept(ConstantExpressionVisitor visitor, [context]) { | 271 accept(ConstantExpressionVisitor visitor, [context]) { |
| 276 return visitor.visitString(this, context); | 272 return visitor.visitString(this, context); |
| 277 } | 273 } |
| 278 | 274 |
| 279 @override | 275 @override |
| 280 ConstantValue evaluate(Environment environment, | 276 ConstantValue evaluate( |
| 281 ConstantSystem constantSystem) { | 277 Environment environment, ConstantSystem constantSystem) { |
| 282 return constantSystem.createString(new DartString.literal(primitiveValue)); | 278 return constantSystem.createString(new DartString.literal(primitiveValue)); |
| 283 } | 279 } |
| 284 | 280 |
| 285 @override | 281 @override |
| 286 int _computeHashCode() => 23 * primitiveValue.hashCode; | 282 int _computeHashCode() => 23 * primitiveValue.hashCode; |
| 287 | 283 |
| 288 @override | 284 @override |
| 289 bool _equals(StringConstantExpression other) { | 285 bool _equals(StringConstantExpression other) { |
| 290 return primitiveValue == other.primitiveValue; | 286 return primitiveValue == other.primitiveValue; |
| 291 } | 287 } |
| 292 | 288 |
| 293 @override | 289 @override |
| 294 DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType; | 290 DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType; |
| 295 } | 291 } |
| 296 | 292 |
| 297 /// Null literal constant. | 293 /// Null literal constant. |
| 298 class NullConstantExpression extends PrimitiveConstantExpression { | 294 class NullConstantExpression extends PrimitiveConstantExpression { |
| 299 NullConstantExpression(); | 295 NullConstantExpression(); |
| 300 | 296 |
| 301 ConstantExpressionKind get kind => ConstantExpressionKind.NULL; | 297 ConstantExpressionKind get kind => ConstantExpressionKind.NULL; |
| 302 | 298 |
| 303 accept(ConstantExpressionVisitor visitor, [context]) { | 299 accept(ConstantExpressionVisitor visitor, [context]) { |
| 304 return visitor.visitNull(this, context); | 300 return visitor.visitNull(this, context); |
| 305 } | 301 } |
| 306 | 302 |
| 307 @override | 303 @override |
| 308 ConstantValue evaluate(Environment environment, | 304 ConstantValue evaluate( |
| 309 ConstantSystem constantSystem) { | 305 Environment environment, ConstantSystem constantSystem) { |
| 310 return constantSystem.createNull(); | 306 return constantSystem.createNull(); |
| 311 } | 307 } |
| 312 | 308 |
| 313 get primitiveValue => null; | 309 get primitiveValue => null; |
| 314 | 310 |
| 315 @override | 311 @override |
| 316 int _computeHashCode() => 29; | 312 int _computeHashCode() => 29; |
| 317 | 313 |
| 318 @override | 314 @override |
| 319 bool _equals(NullConstantExpression other) => true; | 315 bool _equals(NullConstantExpression other) => true; |
| 320 | 316 |
| 321 @override | 317 @override |
| 322 DartType getKnownType(CoreTypes coreTypes) => coreTypes.nullType; | 318 DartType getKnownType(CoreTypes coreTypes) => coreTypes.nullType; |
| 323 } | 319 } |
| 324 | 320 |
| 325 /// Literal list constant. | 321 /// Literal list constant. |
| 326 class ListConstantExpression extends ConstantExpression { | 322 class ListConstantExpression extends ConstantExpression { |
| 327 final InterfaceType type; | 323 final InterfaceType type; |
| 328 final List<ConstantExpression> values; | 324 final List<ConstantExpression> values; |
| 329 | 325 |
| 330 ListConstantExpression(this.type, this.values); | 326 ListConstantExpression(this.type, this.values); |
| 331 | 327 |
| 332 ConstantExpressionKind get kind => ConstantExpressionKind.LIST; | 328 ConstantExpressionKind get kind => ConstantExpressionKind.LIST; |
| 333 | 329 |
| 334 accept(ConstantExpressionVisitor visitor, [context]) { | 330 accept(ConstantExpressionVisitor visitor, [context]) { |
| 335 return visitor.visitList(this, context); | 331 return visitor.visitList(this, context); |
| 336 } | 332 } |
| 337 | 333 |
| 338 @override | 334 @override |
| 339 ConstantValue evaluate(Environment environment, | 335 ConstantValue evaluate( |
| 340 ConstantSystem constantSystem) { | 336 Environment environment, ConstantSystem constantSystem) { |
| 341 return constantSystem.createList(type, | 337 return constantSystem.createList(type, |
| 342 values.map((v) => v.evaluate(environment, constantSystem)).toList()); | 338 values.map((v) => v.evaluate(environment, constantSystem)).toList()); |
| 343 } | 339 } |
| 344 | 340 |
| 345 ConstantExpression apply(NormalizedArguments arguments) { | 341 ConstantExpression apply(NormalizedArguments arguments) { |
| 346 return new ListConstantExpression( | 342 return new ListConstantExpression( |
| 347 type, values.map((v) => v.apply(arguments)).toList()); | 343 type, values.map((v) => v.apply(arguments)).toList()); |
| 348 } | 344 } |
| 349 | 345 |
| 350 @override | 346 @override |
| (...skipping 27 matching lines...) Expand all Loading... |
| 378 | 374 |
| 379 MapConstantExpression(this.type, this.keys, this.values); | 375 MapConstantExpression(this.type, this.keys, this.values); |
| 380 | 376 |
| 381 ConstantExpressionKind get kind => ConstantExpressionKind.MAP; | 377 ConstantExpressionKind get kind => ConstantExpressionKind.MAP; |
| 382 | 378 |
| 383 accept(ConstantExpressionVisitor visitor, [context]) { | 379 accept(ConstantExpressionVisitor visitor, [context]) { |
| 384 return visitor.visitMap(this, context); | 380 return visitor.visitMap(this, context); |
| 385 } | 381 } |
| 386 | 382 |
| 387 @override | 383 @override |
| 388 ConstantValue evaluate(Environment environment, | 384 ConstantValue evaluate( |
| 389 ConstantSystem constantSystem) { | 385 Environment environment, ConstantSystem constantSystem) { |
| 390 return constantSystem.createMap(environment.compiler, | 386 return constantSystem.createMap( |
| 387 environment.compiler, |
| 391 type, | 388 type, |
| 392 keys.map((k) => k.evaluate(environment, constantSystem)).toList(), | 389 keys.map((k) => k.evaluate(environment, constantSystem)).toList(), |
| 393 values.map((v) => v.evaluate(environment, constantSystem)).toList()); | 390 values.map((v) => v.evaluate(environment, constantSystem)).toList()); |
| 394 } | 391 } |
| 395 | 392 |
| 396 ConstantExpression apply(NormalizedArguments arguments) { | 393 ConstantExpression apply(NormalizedArguments arguments) { |
| 397 return new MapConstantExpression( | 394 return new MapConstantExpression( |
| 398 type, | 395 type, |
| 399 keys.map((k) => k.apply(arguments)).toList(), | 396 keys.map((k) => k.apply(arguments)).toList(), |
| 400 values.map((v) => v.apply(arguments)).toList()); | 397 values.map((v) => v.apply(arguments)).toList()); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 425 } | 422 } |
| 426 | 423 |
| 427 /// Invocation of a const constructor. | 424 /// Invocation of a const constructor. |
| 428 class ConstructedConstantExpression extends ConstantExpression { | 425 class ConstructedConstantExpression extends ConstantExpression { |
| 429 final InterfaceType type; | 426 final InterfaceType type; |
| 430 final ConstructorElement target; | 427 final ConstructorElement target; |
| 431 final CallStructure callStructure; | 428 final CallStructure callStructure; |
| 432 final List<ConstantExpression> arguments; | 429 final List<ConstantExpression> arguments; |
| 433 | 430 |
| 434 ConstructedConstantExpression( | 431 ConstructedConstantExpression( |
| 435 this.type, | 432 this.type, this.target, this.callStructure, this.arguments) { |
| 436 this.target, | |
| 437 this.callStructure, | |
| 438 this.arguments) { | |
| 439 assert(type.element == target.enclosingClass); | 433 assert(type.element == target.enclosingClass); |
| 440 assert(!arguments.contains(null)); | 434 assert(!arguments.contains(null)); |
| 441 } | 435 } |
| 442 | 436 |
| 443 ConstantExpressionKind get kind => ConstantExpressionKind.CONSTRUCTED; | 437 ConstantExpressionKind get kind => ConstantExpressionKind.CONSTRUCTED; |
| 444 | 438 |
| 445 accept(ConstantExpressionVisitor visitor, [context]) { | 439 accept(ConstantExpressionVisitor visitor, [context]) { |
| 446 return visitor.visitConstructed(this, context); | 440 return visitor.visitConstructed(this, context); |
| 447 } | 441 } |
| 448 | 442 |
| 449 Map<FieldElement, ConstantExpression> computeInstanceFields() { | 443 Map<FieldElement, ConstantExpression> computeInstanceFields() { |
| 450 return target.constantConstructor.computeInstanceFields( | 444 return target.constantConstructor |
| 451 arguments, callStructure); | 445 .computeInstanceFields(arguments, callStructure); |
| 452 } | 446 } |
| 453 | 447 |
| 454 InterfaceType computeInstanceType() { | 448 InterfaceType computeInstanceType() { |
| 455 return target.constantConstructor.computeInstanceType(type); | 449 return target.constantConstructor.computeInstanceType(type); |
| 456 } | 450 } |
| 457 | 451 |
| 458 ConstructedConstantExpression apply(NormalizedArguments arguments) { | 452 ConstructedConstantExpression apply(NormalizedArguments arguments) { |
| 459 return new ConstructedConstantExpression( | 453 return new ConstructedConstantExpression(type, target, callStructure, |
| 460 type, target, callStructure, | |
| 461 this.arguments.map((a) => a.apply(arguments)).toList()); | 454 this.arguments.map((a) => a.apply(arguments)).toList()); |
| 462 } | 455 } |
| 463 | 456 |
| 464 @override | 457 @override |
| 465 ConstantValue evaluate(Environment environment, | 458 ConstantValue evaluate( |
| 466 ConstantSystem constantSystem) { | 459 Environment environment, ConstantSystem constantSystem) { |
| 467 Map<FieldElement, ConstantValue> fieldValues = | 460 Map<FieldElement, ConstantValue> fieldValues = |
| 468 <FieldElement, ConstantValue>{}; | 461 <FieldElement, ConstantValue>{}; |
| 469 computeInstanceFields().forEach( | 462 computeInstanceFields() |
| 470 (FieldElement field, ConstantExpression constant) { | 463 .forEach((FieldElement field, ConstantExpression constant) { |
| 471 fieldValues[field] = constant.evaluate(environment, constantSystem); | 464 fieldValues[field] = constant.evaluate(environment, constantSystem); |
| 472 }); | 465 }); |
| 473 return new ConstructedConstantValue(computeInstanceType(), fieldValues); | 466 return new ConstructedConstantValue(computeInstanceType(), fieldValues); |
| 474 } | 467 } |
| 475 | 468 |
| 476 @override | 469 @override |
| 477 int _computeHashCode() { | 470 int _computeHashCode() { |
| 478 int hashCode = | 471 int hashCode = |
| 479 13 * type.hashCode + | 472 13 * type.hashCode + 17 * target.hashCode + 19 * callStructure.hashCode; |
| 480 17 * target.hashCode + | |
| 481 19 * callStructure.hashCode; | |
| 482 for (ConstantExpression value in arguments) { | 473 for (ConstantExpression value in arguments) { |
| 483 hashCode ^= 23 * value.hashCode; | 474 hashCode ^= 23 * value.hashCode; |
| 484 } | 475 } |
| 485 return hashCode; | 476 return hashCode; |
| 486 } | 477 } |
| 487 | 478 |
| 488 @override | 479 @override |
| 489 bool _equals(ConstructedConstantExpression other) { | 480 bool _equals(ConstructedConstantExpression other) { |
| 490 if (type != other.type) return false; | 481 if (type != other.type) return false; |
| 491 if (target != other.target) return false; | 482 if (target != other.target) return false; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 508 accept(ConstantExpressionVisitor visitor, [context]) { | 499 accept(ConstantExpressionVisitor visitor, [context]) { |
| 509 return visitor.visitConcatenate(this, context); | 500 return visitor.visitConcatenate(this, context); |
| 510 } | 501 } |
| 511 | 502 |
| 512 ConstantExpression apply(NormalizedArguments arguments) { | 503 ConstantExpression apply(NormalizedArguments arguments) { |
| 513 return new ConcatenateConstantExpression( | 504 return new ConcatenateConstantExpression( |
| 514 expressions.map((a) => a.apply(arguments)).toList()); | 505 expressions.map((a) => a.apply(arguments)).toList()); |
| 515 } | 506 } |
| 516 | 507 |
| 517 @override | 508 @override |
| 518 ConstantValue evaluate(Environment environment, | 509 ConstantValue evaluate( |
| 519 ConstantSystem constantSystem) { | 510 Environment environment, ConstantSystem constantSystem) { |
| 520 DartString accumulator; | 511 DartString accumulator; |
| 521 for (ConstantExpression expression in expressions) { | 512 for (ConstantExpression expression in expressions) { |
| 522 ConstantValue value = expression.evaluate(environment, constantSystem); | 513 ConstantValue value = expression.evaluate(environment, constantSystem); |
| 523 DartString valueString; | 514 DartString valueString; |
| 524 if (value.isNum || value.isBool) { | 515 if (value.isNum || value.isBool) { |
| 525 PrimitiveConstantValue primitive = value; | 516 PrimitiveConstantValue primitive = value; |
| 526 valueString = | 517 valueString = |
| 527 new DartString.literal(primitive.primitiveValue.toString()); | 518 new DartString.literal(primitive.primitiveValue.toString()); |
| 528 } else if (value.isString) { | 519 } else if (value.isString) { |
| 529 PrimitiveConstantValue primitive = value; | 520 PrimitiveConstantValue primitive = value; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 | 569 |
| 579 @override | 570 @override |
| 580 int _computeHashCode() => 13 * name.hashCode; | 571 int _computeHashCode() => 13 * name.hashCode; |
| 581 | 572 |
| 582 @override | 573 @override |
| 583 bool _equals(SymbolConstantExpression other) { | 574 bool _equals(SymbolConstantExpression other) { |
| 584 return name == other.name; | 575 return name == other.name; |
| 585 } | 576 } |
| 586 | 577 |
| 587 @override | 578 @override |
| 588 ConstantValue evaluate(Environment environment, | 579 ConstantValue evaluate( |
| 589 ConstantSystem constantSystem) { | 580 Environment environment, ConstantSystem constantSystem) { |
| 590 // TODO(johnniwinther): Implement this. | 581 // TODO(johnniwinther): Implement this. |
| 591 throw new UnsupportedError('SymbolConstantExpression.evaluate'); | 582 throw new UnsupportedError('SymbolConstantExpression.evaluate'); |
| 592 } | 583 } |
| 593 | 584 |
| 594 @override | 585 @override |
| 595 DartType getKnownType(CoreTypes coreTypes) => coreTypes.symbolType; | 586 DartType getKnownType(CoreTypes coreTypes) => coreTypes.symbolType; |
| 596 } | 587 } |
| 597 | 588 |
| 598 /// Type literal. | 589 /// Type literal. |
| 599 class TypeConstantExpression extends ConstantExpression { | 590 class TypeConstantExpression extends ConstantExpression { |
| 600 /// Either [DynamicType] or a raw [GenericType]. | 591 /// Either [DynamicType] or a raw [GenericType]. |
| 601 final DartType type; | 592 final DartType type; |
| 602 | 593 |
| 603 TypeConstantExpression(this.type) { | 594 TypeConstantExpression(this.type) { |
| 604 assert(type is GenericType || type is DynamicType); | 595 assert(type is GenericType || type is DynamicType); |
| 605 } | 596 } |
| 606 | 597 |
| 607 ConstantExpressionKind get kind => ConstantExpressionKind.TYPE; | 598 ConstantExpressionKind get kind => ConstantExpressionKind.TYPE; |
| 608 | 599 |
| 609 accept(ConstantExpressionVisitor visitor, [context]) { | 600 accept(ConstantExpressionVisitor visitor, [context]) { |
| 610 return visitor.visitType(this, context); | 601 return visitor.visitType(this, context); |
| 611 } | 602 } |
| 612 | 603 |
| 613 @override | 604 @override |
| 614 ConstantValue evaluate(Environment environment, | 605 ConstantValue evaluate( |
| 615 ConstantSystem constantSystem) { | 606 Environment environment, ConstantSystem constantSystem) { |
| 616 return constantSystem.createType(environment.compiler, type); | 607 return constantSystem.createType(environment.compiler, type); |
| 617 } | 608 } |
| 618 | 609 |
| 619 @override | 610 @override |
| 620 int _computeHashCode() => 13 * type.hashCode; | 611 int _computeHashCode() => 13 * type.hashCode; |
| 621 | 612 |
| 622 @override | 613 @override |
| 623 bool _equals(TypeConstantExpression other) { | 614 bool _equals(TypeConstantExpression other) { |
| 624 return type == other.type; | 615 return type == other.type; |
| 625 } | 616 } |
| 626 | 617 |
| 627 @override | 618 @override |
| 628 DartType getKnownType(CoreTypes coreTypes) => coreTypes.typeType; | 619 DartType getKnownType(CoreTypes coreTypes) => coreTypes.typeType; |
| 629 } | 620 } |
| 630 | 621 |
| 631 /// Reference to a constant local, top-level, or static variable. | 622 /// Reference to a constant local, top-level, or static variable. |
| 632 class VariableConstantExpression extends ConstantExpression { | 623 class VariableConstantExpression extends ConstantExpression { |
| 633 final VariableElement element; | 624 final VariableElement element; |
| 634 | 625 |
| 635 VariableConstantExpression(this.element); | 626 VariableConstantExpression(this.element); |
| 636 | 627 |
| 637 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE; | 628 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE; |
| 638 | 629 |
| 639 accept(ConstantExpressionVisitor visitor, [context]) { | 630 accept(ConstantExpressionVisitor visitor, [context]) { |
| 640 return visitor.visitVariable(this, context); | 631 return visitor.visitVariable(this, context); |
| 641 } | 632 } |
| 642 | 633 |
| 643 @override | 634 @override |
| 644 ConstantValue evaluate(Environment environment, | 635 ConstantValue evaluate( |
| 645 ConstantSystem constantSystem) { | 636 Environment environment, ConstantSystem constantSystem) { |
| 646 return element.constant.evaluate(environment, constantSystem); | 637 return element.constant.evaluate(environment, constantSystem); |
| 647 } | 638 } |
| 648 | 639 |
| 649 @override | 640 @override |
| 650 int _computeHashCode() => 13 * element.hashCode; | 641 int _computeHashCode() => 13 * element.hashCode; |
| 651 | 642 |
| 652 @override | 643 @override |
| 653 bool _equals(VariableConstantExpression other) { | 644 bool _equals(VariableConstantExpression other) { |
| 654 return element == other.element; | 645 return element == other.element; |
| 655 } | 646 } |
| 656 } | 647 } |
| 657 | 648 |
| 658 /// Reference to a top-level or static function. | 649 /// Reference to a top-level or static function. |
| 659 class FunctionConstantExpression extends ConstantExpression { | 650 class FunctionConstantExpression extends ConstantExpression { |
| 660 final FunctionElement element; | 651 final FunctionElement element; |
| 661 | 652 |
| 662 FunctionConstantExpression(this.element); | 653 FunctionConstantExpression(this.element); |
| 663 | 654 |
| 664 ConstantExpressionKind get kind => ConstantExpressionKind.FUNCTION; | 655 ConstantExpressionKind get kind => ConstantExpressionKind.FUNCTION; |
| 665 | 656 |
| 666 accept(ConstantExpressionVisitor visitor, [context]) { | 657 accept(ConstantExpressionVisitor visitor, [context]) { |
| 667 return visitor.visitFunction(this, context); | 658 return visitor.visitFunction(this, context); |
| 668 } | 659 } |
| 669 | 660 |
| 670 @override | 661 @override |
| 671 ConstantValue evaluate(Environment environment, | 662 ConstantValue evaluate( |
| 672 ConstantSystem constantSystem) { | 663 Environment environment, ConstantSystem constantSystem) { |
| 673 return new FunctionConstantValue(element); | 664 return new FunctionConstantValue(element); |
| 674 } | 665 } |
| 675 | 666 |
| 676 @override | 667 @override |
| 677 int _computeHashCode() => 13 * element.hashCode; | 668 int _computeHashCode() => 13 * element.hashCode; |
| 678 | 669 |
| 679 @override | 670 @override |
| 680 bool _equals(FunctionConstantExpression other) { | 671 bool _equals(FunctionConstantExpression other) { |
| 681 return element == other.element; | 672 return element == other.element; |
| 682 } | 673 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 695 assert(PRECEDENCE_MAP[operator.kind] != null); | 686 assert(PRECEDENCE_MAP[operator.kind] != null); |
| 696 } | 687 } |
| 697 | 688 |
| 698 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY; | 689 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY; |
| 699 | 690 |
| 700 accept(ConstantExpressionVisitor visitor, [context]) { | 691 accept(ConstantExpressionVisitor visitor, [context]) { |
| 701 return visitor.visitBinary(this, context); | 692 return visitor.visitBinary(this, context); |
| 702 } | 693 } |
| 703 | 694 |
| 704 @override | 695 @override |
| 705 ConstantValue evaluate(Environment environment, | 696 ConstantValue evaluate( |
| 706 ConstantSystem constantSystem) { | 697 Environment environment, ConstantSystem constantSystem) { |
| 707 return constantSystem.lookupBinary(operator).fold( | 698 return constantSystem.lookupBinary(operator).fold( |
| 708 left.evaluate(environment, constantSystem), | 699 left.evaluate(environment, constantSystem), |
| 709 right.evaluate(environment, constantSystem)); | 700 right.evaluate(environment, constantSystem)); |
| 710 } | 701 } |
| 711 | 702 |
| 712 ConstantExpression apply(NormalizedArguments arguments) { | 703 ConstantExpression apply(NormalizedArguments arguments) { |
| 713 return new BinaryConstantExpression( | 704 return new BinaryConstantExpression( |
| 714 left.apply(arguments), | 705 left.apply(arguments), operator, right.apply(arguments)); |
| 715 operator, | |
| 716 right.apply(arguments)); | |
| 717 } | 706 } |
| 718 | 707 |
| 719 DartType getKnownType(CoreTypes coreTypes) { | 708 DartType getKnownType(CoreTypes coreTypes) { |
| 720 DartType knownLeftType = left.getKnownType(coreTypes); | 709 DartType knownLeftType = left.getKnownType(coreTypes); |
| 721 DartType knownRightType = right.getKnownType(coreTypes); | 710 DartType knownRightType = right.getKnownType(coreTypes); |
| 722 switch (operator.kind) { | 711 switch (operator.kind) { |
| 723 case BinaryOperatorKind.EQ: | 712 case BinaryOperatorKind.EQ: |
| 724 case BinaryOperatorKind.NOT_EQ: | 713 case BinaryOperatorKind.NOT_EQ: |
| 725 case BinaryOperatorKind.LOGICAL_AND: | 714 case BinaryOperatorKind.LOGICAL_AND: |
| 726 case BinaryOperatorKind.LOGICAL_OR: | 715 case BinaryOperatorKind.LOGICAL_OR: |
| 727 case BinaryOperatorKind.GT: | 716 case BinaryOperatorKind.GT: |
| 728 case BinaryOperatorKind.LT: | 717 case BinaryOperatorKind.LT: |
| 729 case BinaryOperatorKind.GTEQ: | 718 case BinaryOperatorKind.GTEQ: |
| 730 case BinaryOperatorKind.LTEQ: | 719 case BinaryOperatorKind.LTEQ: |
| 731 return coreTypes.boolType; | 720 return coreTypes.boolType; |
| 732 case BinaryOperatorKind.ADD: | 721 case BinaryOperatorKind.ADD: |
| 733 if (knownLeftType == coreTypes.stringType) { | 722 if (knownLeftType == coreTypes.stringType) { |
| 734 assert(knownRightType == coreTypes.stringType); | 723 assert(knownRightType == coreTypes.stringType); |
| 735 return coreTypes.stringType; | 724 return coreTypes.stringType; |
| 736 } else if (knownLeftType == coreTypes.intType && | 725 } else if (knownLeftType == coreTypes.intType && |
| 737 knownRightType == coreTypes.intType) { | 726 knownRightType == coreTypes.intType) { |
| 738 return coreTypes.intType; | 727 return coreTypes.intType; |
| 739 } | 728 } |
| 740 assert(knownLeftType == coreTypes.doubleType || | 729 assert(knownLeftType == coreTypes.doubleType || |
| 741 knownRightType == coreTypes.doubleType); | 730 knownRightType == coreTypes.doubleType); |
| 742 return coreTypes.doubleType; | 731 return coreTypes.doubleType; |
| 743 case BinaryOperatorKind.SUB: | 732 case BinaryOperatorKind.SUB: |
| 744 case BinaryOperatorKind.MUL: | 733 case BinaryOperatorKind.MUL: |
| 745 case BinaryOperatorKind.MOD: | 734 case BinaryOperatorKind.MOD: |
| 746 if (knownLeftType == coreTypes.intType && | 735 if (knownLeftType == coreTypes.intType && |
| 747 knownRightType == coreTypes.intType) { | 736 knownRightType == coreTypes.intType) { |
| 748 return coreTypes.intType; | 737 return coreTypes.intType; |
| 749 } | 738 } |
| 750 assert(knownLeftType == coreTypes.doubleType || | 739 assert(knownLeftType == coreTypes.doubleType || |
| 751 knownRightType == coreTypes.doubleType); | 740 knownRightType == coreTypes.doubleType); |
| 752 return coreTypes.doubleType; | 741 return coreTypes.doubleType; |
| 753 case BinaryOperatorKind.DIV: | 742 case BinaryOperatorKind.DIV: |
| 754 return coreTypes.doubleType; | 743 return coreTypes.doubleType; |
| 755 case BinaryOperatorKind.IDIV: | 744 case BinaryOperatorKind.IDIV: |
| 756 return coreTypes.intType; | 745 return coreTypes.intType; |
| 757 case BinaryOperatorKind.AND: | 746 case BinaryOperatorKind.AND: |
| 758 case BinaryOperatorKind.OR: | 747 case BinaryOperatorKind.OR: |
| 759 case BinaryOperatorKind.XOR: | 748 case BinaryOperatorKind.XOR: |
| 760 case BinaryOperatorKind.SHR: | 749 case BinaryOperatorKind.SHR: |
| 761 case BinaryOperatorKind.SHL: | 750 case BinaryOperatorKind.SHL: |
| 762 return coreTypes.intType; | 751 return coreTypes.intType; |
| 763 case BinaryOperatorKind.IF_NULL: | 752 case BinaryOperatorKind.IF_NULL: |
| 764 case BinaryOperatorKind.INDEX: | 753 case BinaryOperatorKind.INDEX: |
| 765 throw new UnsupportedError( | 754 throw new UnsupportedError( |
| 766 'Unexpected constant binary operator: $operator'); | 755 'Unexpected constant binary operator: $operator'); |
| 767 } | 756 } |
| 768 } | 757 } |
| 769 | 758 |
| 770 | |
| 771 int get precedence => PRECEDENCE_MAP[operator.kind]; | 759 int get precedence => PRECEDENCE_MAP[operator.kind]; |
| 772 | 760 |
| 773 @override | 761 @override |
| 774 int _computeHashCode() { | 762 int _computeHashCode() { |
| 775 return 13 * operator.hashCode + | 763 return 13 * operator.hashCode + 17 * left.hashCode + 19 * right.hashCode; |
| 776 17 * left.hashCode + | |
| 777 19 * right.hashCode; | |
| 778 } | 764 } |
| 779 | 765 |
| 780 @override | 766 @override |
| 781 bool _equals(BinaryConstantExpression other) { | 767 bool _equals(BinaryConstantExpression other) { |
| 782 return operator == other.operator && | 768 return operator == other.operator && |
| 783 left == other.left && | 769 left == other.left && |
| 784 right == other.right; | 770 right == other.right; |
| 785 } | 771 } |
| 786 | 772 |
| 787 static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const { | 773 static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const { |
| 788 BinaryOperatorKind.EQ: 6, | 774 BinaryOperatorKind.EQ: 6, |
| 789 BinaryOperatorKind.NOT_EQ: 6, | 775 BinaryOperatorKind.NOT_EQ: 6, |
| 790 BinaryOperatorKind.LOGICAL_AND: 5, | 776 BinaryOperatorKind.LOGICAL_AND: 5, |
| 791 BinaryOperatorKind.LOGICAL_OR: 4, | 777 BinaryOperatorKind.LOGICAL_OR: 4, |
| 792 BinaryOperatorKind.XOR: 9, | 778 BinaryOperatorKind.XOR: 9, |
| 793 BinaryOperatorKind.AND: 10, | 779 BinaryOperatorKind.AND: 10, |
| 794 BinaryOperatorKind.OR: 8, | 780 BinaryOperatorKind.OR: 8, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 815 | 801 |
| 816 IdenticalConstantExpression(this.left, this.right); | 802 IdenticalConstantExpression(this.left, this.right); |
| 817 | 803 |
| 818 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL; | 804 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL; |
| 819 | 805 |
| 820 accept(ConstantExpressionVisitor visitor, [context]) { | 806 accept(ConstantExpressionVisitor visitor, [context]) { |
| 821 return visitor.visitIdentical(this, context); | 807 return visitor.visitIdentical(this, context); |
| 822 } | 808 } |
| 823 | 809 |
| 824 @override | 810 @override |
| 825 ConstantValue evaluate(Environment environment, | 811 ConstantValue evaluate( |
| 826 ConstantSystem constantSystem) { | 812 Environment environment, ConstantSystem constantSystem) { |
| 827 return constantSystem.identity.fold( | 813 return constantSystem.identity.fold( |
| 828 left.evaluate(environment, constantSystem), | 814 left.evaluate(environment, constantSystem), |
| 829 right.evaluate(environment, constantSystem)); | 815 right.evaluate(environment, constantSystem)); |
| 830 } | 816 } |
| 831 | 817 |
| 832 ConstantExpression apply(NormalizedArguments arguments) { | 818 ConstantExpression apply(NormalizedArguments arguments) { |
| 833 return new IdenticalConstantExpression( | 819 return new IdenticalConstantExpression( |
| 834 left.apply(arguments), | 820 left.apply(arguments), right.apply(arguments)); |
| 835 right.apply(arguments)); | |
| 836 } | 821 } |
| 837 | 822 |
| 838 int get precedence => 15; | 823 int get precedence => 15; |
| 839 | 824 |
| 840 @override | 825 @override |
| 841 int _computeHashCode() { | 826 int _computeHashCode() { |
| 842 return 17 * left.hashCode + | 827 return 17 * left.hashCode + 19 * right.hashCode; |
| 843 19 * right.hashCode; | |
| 844 } | 828 } |
| 845 | 829 |
| 846 @override | 830 @override |
| 847 bool _equals(IdenticalConstantExpression other) { | 831 bool _equals(IdenticalConstantExpression other) { |
| 848 return left == other.left && | 832 return left == other.left && right == other.right; |
| 849 right == other.right; | |
| 850 } | 833 } |
| 851 | 834 |
| 852 @override | 835 @override |
| 853 DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; | 836 DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; |
| 854 } | 837 } |
| 855 | 838 |
| 856 /// A unary constant expression like `-a`. | 839 /// A unary constant expression like `-a`. |
| 857 class UnaryConstantExpression extends ConstantExpression { | 840 class UnaryConstantExpression extends ConstantExpression { |
| 858 final UnaryOperator operator; | 841 final UnaryOperator operator; |
| 859 final ConstantExpression expression; | 842 final ConstantExpression expression; |
| 860 | 843 |
| 861 UnaryConstantExpression(this.operator, this.expression) { | 844 UnaryConstantExpression(this.operator, this.expression) { |
| 862 assert(PRECEDENCE_MAP[operator.kind] != null); | 845 assert(PRECEDENCE_MAP[operator.kind] != null); |
| 863 } | 846 } |
| 864 | 847 |
| 865 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY; | 848 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY; |
| 866 | 849 |
| 867 accept(ConstantExpressionVisitor visitor, [context]) { | 850 accept(ConstantExpressionVisitor visitor, [context]) { |
| 868 return visitor.visitUnary(this, context); | 851 return visitor.visitUnary(this, context); |
| 869 } | 852 } |
| 870 | 853 |
| 871 @override | 854 @override |
| 872 ConstantValue evaluate(Environment environment, | 855 ConstantValue evaluate( |
| 873 ConstantSystem constantSystem) { | 856 Environment environment, ConstantSystem constantSystem) { |
| 874 return constantSystem.lookupUnary(operator).fold( | 857 return constantSystem |
| 875 expression.evaluate(environment, constantSystem)); | 858 .lookupUnary(operator) |
| 859 .fold(expression.evaluate(environment, constantSystem)); |
| 876 } | 860 } |
| 877 | 861 |
| 878 ConstantExpression apply(NormalizedArguments arguments) { | 862 ConstantExpression apply(NormalizedArguments arguments) { |
| 879 return new UnaryConstantExpression( | 863 return new UnaryConstantExpression(operator, expression.apply(arguments)); |
| 880 operator, | |
| 881 expression.apply(arguments)); | |
| 882 } | 864 } |
| 883 | 865 |
| 884 int get precedence => PRECEDENCE_MAP[operator.kind]; | 866 int get precedence => PRECEDENCE_MAP[operator.kind]; |
| 885 | 867 |
| 886 @override | 868 @override |
| 887 int _computeHashCode() { | 869 int _computeHashCode() { |
| 888 return 13 * operator.hashCode + | 870 return 13 * operator.hashCode + 17 * expression.hashCode; |
| 889 17 * expression.hashCode; | |
| 890 } | 871 } |
| 891 | 872 |
| 892 @override | 873 @override |
| 893 bool _equals(UnaryConstantExpression other) { | 874 bool _equals(UnaryConstantExpression other) { |
| 894 return operator == other.operator && | 875 return operator == other.operator && expression == other.expression; |
| 895 expression == other.expression; | |
| 896 } | 876 } |
| 897 | 877 |
| 898 @override | 878 @override |
| 899 DartType getKnownType(CoreTypes coreTypes) { | 879 DartType getKnownType(CoreTypes coreTypes) { |
| 900 return expression.getKnownType(coreTypes); | 880 return expression.getKnownType(coreTypes); |
| 901 } | 881 } |
| 902 | 882 |
| 903 static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const { | 883 static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const { |
| 904 UnaryOperatorKind.NOT: 14, | 884 UnaryOperatorKind.NOT: 14, |
| 905 UnaryOperatorKind.COMPLEMENT: 14, | 885 UnaryOperatorKind.COMPLEMENT: 14, |
| 906 UnaryOperatorKind.NEGATE: 14, | 886 UnaryOperatorKind.NEGATE: 14, |
| 907 }; | 887 }; |
| 908 } | 888 } |
| 909 | 889 |
| 910 | |
| 911 /// A string length constant expression like `a.length`. | 890 /// A string length constant expression like `a.length`. |
| 912 class StringLengthConstantExpression extends ConstantExpression { | 891 class StringLengthConstantExpression extends ConstantExpression { |
| 913 final ConstantExpression expression; | 892 final ConstantExpression expression; |
| 914 | 893 |
| 915 StringLengthConstantExpression(this.expression); | 894 StringLengthConstantExpression(this.expression); |
| 916 | 895 |
| 917 ConstantExpressionKind get kind => ConstantExpressionKind.STRING_LENGTH; | 896 ConstantExpressionKind get kind => ConstantExpressionKind.STRING_LENGTH; |
| 918 | 897 |
| 919 accept(ConstantExpressionVisitor visitor, [context]) { | 898 accept(ConstantExpressionVisitor visitor, [context]) { |
| 920 return visitor.visitStringLength(this, context); | 899 return visitor.visitStringLength(this, context); |
| 921 } | 900 } |
| 922 | 901 |
| 923 @override | 902 @override |
| 924 ConstantValue evaluate(Environment environment, | 903 ConstantValue evaluate( |
| 925 ConstantSystem constantSystem) { | 904 Environment environment, ConstantSystem constantSystem) { |
| 926 ConstantValue value = expression.evaluate(environment, constantSystem); | 905 ConstantValue value = expression.evaluate(environment, constantSystem); |
| 927 if (value.isString) { | 906 if (value.isString) { |
| 928 StringConstantValue stringValue = value; | 907 StringConstantValue stringValue = value; |
| 929 return constantSystem.createInt(stringValue.primitiveValue.length); | 908 return constantSystem.createInt(stringValue.primitiveValue.length); |
| 930 } | 909 } |
| 931 return new NonConstantValue(); | 910 return new NonConstantValue(); |
| 932 } | 911 } |
| 933 | 912 |
| 934 ConstantExpression apply(NormalizedArguments arguments) { | 913 ConstantExpression apply(NormalizedArguments arguments) { |
| 935 return new StringLengthConstantExpression(expression.apply(arguments)); | 914 return new StringLengthConstantExpression(expression.apply(arguments)); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 950 @override | 929 @override |
| 951 DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; | 930 DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; |
| 952 } | 931 } |
| 953 | 932 |
| 954 /// A constant conditional expression like `a ? b : c`. | 933 /// A constant conditional expression like `a ? b : c`. |
| 955 class ConditionalConstantExpression extends ConstantExpression { | 934 class ConditionalConstantExpression extends ConstantExpression { |
| 956 final ConstantExpression condition; | 935 final ConstantExpression condition; |
| 957 final ConstantExpression trueExp; | 936 final ConstantExpression trueExp; |
| 958 final ConstantExpression falseExp; | 937 final ConstantExpression falseExp; |
| 959 | 938 |
| 960 ConditionalConstantExpression(this.condition, | 939 ConditionalConstantExpression(this.condition, this.trueExp, this.falseExp); |
| 961 this.trueExp, | |
| 962 this.falseExp); | |
| 963 | 940 |
| 964 ConstantExpressionKind get kind => ConstantExpressionKind.CONDITIONAL; | 941 ConstantExpressionKind get kind => ConstantExpressionKind.CONDITIONAL; |
| 965 | 942 |
| 966 accept(ConstantExpressionVisitor visitor, [context]) { | 943 accept(ConstantExpressionVisitor visitor, [context]) { |
| 967 return visitor.visitConditional(this, context); | 944 return visitor.visitConditional(this, context); |
| 968 } | 945 } |
| 969 | 946 |
| 970 ConstantExpression apply(NormalizedArguments arguments) { | 947 ConstantExpression apply(NormalizedArguments arguments) { |
| 971 return new ConditionalConstantExpression( | 948 return new ConditionalConstantExpression(condition.apply(arguments), |
| 972 condition.apply(arguments), | 949 trueExp.apply(arguments), falseExp.apply(arguments)); |
| 973 trueExp.apply(arguments), | |
| 974 falseExp.apply(arguments)); | |
| 975 } | 950 } |
| 976 | 951 |
| 977 int get precedence => 3; | 952 int get precedence => 3; |
| 978 | 953 |
| 979 @override | 954 @override |
| 980 int _computeHashCode() { | 955 int _computeHashCode() { |
| 981 return 13 * condition.hashCode + | 956 return 13 * condition.hashCode + |
| 982 17 * trueExp.hashCode + | 957 17 * trueExp.hashCode + |
| 983 19 * falseExp.hashCode; | 958 19 * falseExp.hashCode; |
| 984 } | 959 } |
| 985 | 960 |
| 986 @override | 961 @override |
| 987 bool _equals(ConditionalConstantExpression other) { | 962 bool _equals(ConditionalConstantExpression other) { |
| 988 return condition == other.condition && | 963 return condition == other.condition && |
| 989 trueExp == other.trueExp && | 964 trueExp == other.trueExp && |
| 990 falseExp == other.falseExp; | 965 falseExp == other.falseExp; |
| 991 } | 966 } |
| 992 | 967 |
| 993 @override | 968 @override |
| 994 ConstantValue evaluate(Environment environment, | 969 ConstantValue evaluate( |
| 995 ConstantSystem constantSystem) { | 970 Environment environment, ConstantSystem constantSystem) { |
| 996 ConstantValue conditionValue = | 971 ConstantValue conditionValue = |
| 997 condition.evaluate(environment, constantSystem); | 972 condition.evaluate(environment, constantSystem); |
| 998 ConstantValue trueValue = | 973 ConstantValue trueValue = trueExp.evaluate(environment, constantSystem); |
| 999 trueExp.evaluate(environment, constantSystem); | 974 ConstantValue falseValue = falseExp.evaluate(environment, constantSystem); |
| 1000 ConstantValue falseValue = | |
| 1001 falseExp.evaluate(environment, constantSystem); | |
| 1002 if (conditionValue.isTrue) { | 975 if (conditionValue.isTrue) { |
| 1003 return trueValue; | 976 return trueValue; |
| 1004 } else if (conditionValue.isFalse) { | 977 } else if (conditionValue.isFalse) { |
| 1005 return falseValue; | 978 return falseValue; |
| 1006 } else { | 979 } else { |
| 1007 return new NonConstantValue(); | 980 return new NonConstantValue(); |
| 1008 } | 981 } |
| 1009 } | 982 } |
| 1010 | 983 |
| 1011 @override | 984 @override |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1037 return arguments.getPositionalArgument(index); | 1010 return arguments.getPositionalArgument(index); |
| 1038 } | 1011 } |
| 1039 | 1012 |
| 1040 @override | 1013 @override |
| 1041 int _computeHashCode() => 13 * index.hashCode; | 1014 int _computeHashCode() => 13 * index.hashCode; |
| 1042 | 1015 |
| 1043 @override | 1016 @override |
| 1044 bool _equals(PositionalArgumentReference other) => index == other.index; | 1017 bool _equals(PositionalArgumentReference other) => index == other.index; |
| 1045 | 1018 |
| 1046 @override | 1019 @override |
| 1047 ConstantValue evaluate(Environment environment, | 1020 ConstantValue evaluate( |
| 1048 ConstantSystem constantSystem) { | 1021 Environment environment, ConstantSystem constantSystem) { |
| 1049 throw new UnsupportedError('PositionalArgumentReference.evaluate'); | 1022 throw new UnsupportedError('PositionalArgumentReference.evaluate'); |
| 1050 } | 1023 } |
| 1051 } | 1024 } |
| 1052 | 1025 |
| 1053 /// A reference to a named parameter. | 1026 /// A reference to a named parameter. |
| 1054 class NamedArgumentReference extends ConstantExpression { | 1027 class NamedArgumentReference extends ConstantExpression { |
| 1055 final String name; | 1028 final String name; |
| 1056 | 1029 |
| 1057 NamedArgumentReference(this.name); | 1030 NamedArgumentReference(this.name); |
| 1058 | 1031 |
| 1059 ConstantExpressionKind get kind { | 1032 ConstantExpressionKind get kind { |
| 1060 return ConstantExpressionKind.NAMED_REFERENCE; | 1033 return ConstantExpressionKind.NAMED_REFERENCE; |
| 1061 } | 1034 } |
| 1062 | 1035 |
| 1063 accept(ConstantExpressionVisitor visitor, [context]) { | 1036 accept(ConstantExpressionVisitor visitor, [context]) { |
| 1064 return visitor.visitNamed(this, context); | 1037 return visitor.visitNamed(this, context); |
| 1065 } | 1038 } |
| 1066 | 1039 |
| 1067 ConstantExpression apply(NormalizedArguments arguments) { | 1040 ConstantExpression apply(NormalizedArguments arguments) { |
| 1068 return arguments.getNamedArgument(name); | 1041 return arguments.getNamedArgument(name); |
| 1069 } | 1042 } |
| 1070 | 1043 |
| 1071 @override | 1044 @override |
| 1072 int _computeHashCode() => 13 * name.hashCode; | 1045 int _computeHashCode() => 13 * name.hashCode; |
| 1073 | 1046 |
| 1074 @override | 1047 @override |
| 1075 bool _equals(NamedArgumentReference other) => name == other.name; | 1048 bool _equals(NamedArgumentReference other) => name == other.name; |
| 1076 | 1049 |
| 1077 @override | 1050 @override |
| 1078 ConstantValue evaluate(Environment environment, | 1051 ConstantValue evaluate( |
| 1079 ConstantSystem constantSystem) { | 1052 Environment environment, ConstantSystem constantSystem) { |
| 1080 throw new UnsupportedError('NamedArgumentReference.evaluate'); | 1053 throw new UnsupportedError('NamedArgumentReference.evaluate'); |
| 1081 } | 1054 } |
| 1082 } | 1055 } |
| 1083 | 1056 |
| 1084 abstract class FromEnvironmentConstantExpression extends ConstantExpression { | 1057 abstract class FromEnvironmentConstantExpression extends ConstantExpression { |
| 1085 final ConstantExpression name; | 1058 final ConstantExpression name; |
| 1086 final ConstantExpression defaultValue; | 1059 final ConstantExpression defaultValue; |
| 1087 | 1060 |
| 1088 FromEnvironmentConstantExpression(this.name, this.defaultValue); | 1061 FromEnvironmentConstantExpression(this.name, this.defaultValue); |
| 1089 | 1062 |
| 1090 @override | 1063 @override |
| 1091 int _computeHashCode() { | 1064 int _computeHashCode() { |
| 1092 return 13 * name.hashCode + | 1065 return 13 * name.hashCode + 17 * defaultValue.hashCode; |
| 1093 17 * defaultValue.hashCode; | |
| 1094 } | 1066 } |
| 1095 | 1067 |
| 1096 @override | 1068 @override |
| 1097 bool _equals(FromEnvironmentConstantExpression other) { | 1069 bool _equals(FromEnvironmentConstantExpression other) { |
| 1098 return name == other.name && | 1070 return name == other.name && defaultValue == other.defaultValue; |
| 1099 defaultValue == other.defaultValue; | |
| 1100 } | 1071 } |
| 1101 } | 1072 } |
| 1102 | 1073 |
| 1103 /// A `const bool.fromEnvironment` constant. | 1074 /// A `const bool.fromEnvironment` constant. |
| 1104 class BoolFromEnvironmentConstantExpression | 1075 class BoolFromEnvironmentConstantExpression |
| 1105 extends FromEnvironmentConstantExpression { | 1076 extends FromEnvironmentConstantExpression { |
| 1106 | |
| 1107 BoolFromEnvironmentConstantExpression( | 1077 BoolFromEnvironmentConstantExpression( |
| 1108 ConstantExpression name, | 1078 ConstantExpression name, ConstantExpression defaultValue) |
| 1109 ConstantExpression defaultValue) | |
| 1110 : super(name, defaultValue); | 1079 : super(name, defaultValue); |
| 1111 | 1080 |
| 1112 ConstantExpressionKind get kind { | 1081 ConstantExpressionKind get kind { |
| 1113 return ConstantExpressionKind.BOOL_FROM_ENVIRONMENT; | 1082 return ConstantExpressionKind.BOOL_FROM_ENVIRONMENT; |
| 1114 } | 1083 } |
| 1115 | 1084 |
| 1116 accept(ConstantExpressionVisitor visitor, [context]) { | 1085 accept(ConstantExpressionVisitor visitor, [context]) { |
| 1117 return visitor.visitBoolFromEnvironment(this, context); | 1086 return visitor.visitBoolFromEnvironment(this, context); |
| 1118 } | 1087 } |
| 1119 | 1088 |
| 1120 @override | 1089 @override |
| 1121 ConstantValue evaluate(Environment environment, | 1090 ConstantValue evaluate( |
| 1122 ConstantSystem constantSystem) { | 1091 Environment environment, ConstantSystem constantSystem) { |
| 1123 ConstantValue nameConstantValue = | 1092 ConstantValue nameConstantValue = |
| 1124 name.evaluate(environment, constantSystem); | 1093 name.evaluate(environment, constantSystem); |
| 1125 ConstantValue defaultConstantValue; | 1094 ConstantValue defaultConstantValue; |
| 1126 if (defaultValue != null) { | 1095 if (defaultValue != null) { |
| 1127 defaultConstantValue = | 1096 defaultConstantValue = defaultValue.evaluate(environment, constantSystem); |
| 1128 defaultValue.evaluate(environment, constantSystem); | |
| 1129 } else { | 1097 } else { |
| 1130 defaultConstantValue = constantSystem.createBool(false); | 1098 defaultConstantValue = constantSystem.createBool(false); |
| 1131 } | 1099 } |
| 1132 if (!nameConstantValue.isString) { | 1100 if (!nameConstantValue.isString) { |
| 1133 return new NonConstantValue(); | 1101 return new NonConstantValue(); |
| 1134 } | 1102 } |
| 1135 StringConstantValue nameStringConstantValue = nameConstantValue; | 1103 StringConstantValue nameStringConstantValue = nameConstantValue; |
| 1136 String text = environment.readFromEnvironment( | 1104 String text = environment.readFromEnvironment( |
| 1137 nameStringConstantValue.primitiveValue.slowToString()); | 1105 nameStringConstantValue.primitiveValue.slowToString()); |
| 1138 if (text == 'true') { | 1106 if (text == 'true') { |
| 1139 return constantSystem.createBool(true); | 1107 return constantSystem.createBool(true); |
| 1140 } else if (text == 'false') { | 1108 } else if (text == 'false') { |
| 1141 return constantSystem.createBool(false); | 1109 return constantSystem.createBool(false); |
| 1142 } else { | 1110 } else { |
| 1143 return defaultConstantValue; | 1111 return defaultConstantValue; |
| 1144 } | 1112 } |
| 1145 } | 1113 } |
| 1146 | 1114 |
| 1147 ConstantExpression apply(NormalizedArguments arguments) { | 1115 ConstantExpression apply(NormalizedArguments arguments) { |
| 1148 return new BoolFromEnvironmentConstantExpression( | 1116 return new BoolFromEnvironmentConstantExpression(name.apply(arguments), |
| 1149 name.apply(arguments), | |
| 1150 defaultValue != null ? defaultValue.apply(arguments) : null); | 1117 defaultValue != null ? defaultValue.apply(arguments) : null); |
| 1151 } | 1118 } |
| 1152 | 1119 |
| 1153 @override | 1120 @override |
| 1154 DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; | 1121 DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; |
| 1155 } | 1122 } |
| 1156 | 1123 |
| 1157 /// A `const int.fromEnvironment` constant. | 1124 /// A `const int.fromEnvironment` constant. |
| 1158 class IntFromEnvironmentConstantExpression | 1125 class IntFromEnvironmentConstantExpression |
| 1159 extends FromEnvironmentConstantExpression { | 1126 extends FromEnvironmentConstantExpression { |
| 1160 | |
| 1161 IntFromEnvironmentConstantExpression( | 1127 IntFromEnvironmentConstantExpression( |
| 1162 ConstantExpression name, | 1128 ConstantExpression name, ConstantExpression defaultValue) |
| 1163 ConstantExpression defaultValue) | |
| 1164 : super(name, defaultValue); | 1129 : super(name, defaultValue); |
| 1165 | 1130 |
| 1166 ConstantExpressionKind get kind { | 1131 ConstantExpressionKind get kind { |
| 1167 return ConstantExpressionKind.INT_FROM_ENVIRONMENT; | 1132 return ConstantExpressionKind.INT_FROM_ENVIRONMENT; |
| 1168 } | 1133 } |
| 1169 | 1134 |
| 1170 accept(ConstantExpressionVisitor visitor, [context]) { | 1135 accept(ConstantExpressionVisitor visitor, [context]) { |
| 1171 return visitor.visitIntFromEnvironment(this, context); | 1136 return visitor.visitIntFromEnvironment(this, context); |
| 1172 } | 1137 } |
| 1173 | 1138 |
| 1174 @override | 1139 @override |
| 1175 ConstantValue evaluate(Environment environment, | 1140 ConstantValue evaluate( |
| 1176 ConstantSystem constantSystem) { | 1141 Environment environment, ConstantSystem constantSystem) { |
| 1177 ConstantValue nameConstantValue = | 1142 ConstantValue nameConstantValue = |
| 1178 name.evaluate(environment, constantSystem); | 1143 name.evaluate(environment, constantSystem); |
| 1179 ConstantValue defaultConstantValue; | 1144 ConstantValue defaultConstantValue; |
| 1180 if (defaultValue != null) { | 1145 if (defaultValue != null) { |
| 1181 defaultConstantValue = | 1146 defaultConstantValue = defaultValue.evaluate(environment, constantSystem); |
| 1182 defaultValue.evaluate(environment, constantSystem); | |
| 1183 } else { | 1147 } else { |
| 1184 defaultConstantValue = constantSystem.createNull(); | 1148 defaultConstantValue = constantSystem.createNull(); |
| 1185 } | 1149 } |
| 1186 if (!nameConstantValue.isString) { | 1150 if (!nameConstantValue.isString) { |
| 1187 return new NonConstantValue(); | 1151 return new NonConstantValue(); |
| 1188 } | 1152 } |
| 1189 StringConstantValue nameStringConstantValue = nameConstantValue; | 1153 StringConstantValue nameStringConstantValue = nameConstantValue; |
| 1190 String text = environment.readFromEnvironment( | 1154 String text = environment.readFromEnvironment( |
| 1191 nameStringConstantValue.primitiveValue.slowToString()); | 1155 nameStringConstantValue.primitiveValue.slowToString()); |
| 1192 int value; | 1156 int value; |
| 1193 if (text != null) { | 1157 if (text != null) { |
| 1194 value = int.parse(text, onError: (_) => null); | 1158 value = int.parse(text, onError: (_) => null); |
| 1195 } | 1159 } |
| 1196 if (value == null) { | 1160 if (value == null) { |
| 1197 return defaultConstantValue; | 1161 return defaultConstantValue; |
| 1198 } else { | 1162 } else { |
| 1199 return constantSystem.createInt(value); | 1163 return constantSystem.createInt(value); |
| 1200 } | 1164 } |
| 1201 } | 1165 } |
| 1202 | 1166 |
| 1203 ConstantExpression apply(NormalizedArguments arguments) { | 1167 ConstantExpression apply(NormalizedArguments arguments) { |
| 1204 return new IntFromEnvironmentConstantExpression( | 1168 return new IntFromEnvironmentConstantExpression(name.apply(arguments), |
| 1205 name.apply(arguments), | |
| 1206 defaultValue != null ? defaultValue.apply(arguments) : null); | 1169 defaultValue != null ? defaultValue.apply(arguments) : null); |
| 1207 } | 1170 } |
| 1208 | 1171 |
| 1209 @override | 1172 @override |
| 1210 DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; | 1173 DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; |
| 1211 } | 1174 } |
| 1212 | 1175 |
| 1213 /// A `const String.fromEnvironment` constant. | 1176 /// A `const String.fromEnvironment` constant. |
| 1214 class StringFromEnvironmentConstantExpression | 1177 class StringFromEnvironmentConstantExpression |
| 1215 extends FromEnvironmentConstantExpression { | 1178 extends FromEnvironmentConstantExpression { |
| 1216 | |
| 1217 StringFromEnvironmentConstantExpression( | 1179 StringFromEnvironmentConstantExpression( |
| 1218 ConstantExpression name, | 1180 ConstantExpression name, ConstantExpression defaultValue) |
| 1219 ConstantExpression defaultValue) | |
| 1220 : super(name, defaultValue); | 1181 : super(name, defaultValue); |
| 1221 | 1182 |
| 1222 ConstantExpressionKind get kind { | 1183 ConstantExpressionKind get kind { |
| 1223 return ConstantExpressionKind.STRING_FROM_ENVIRONMENT; | 1184 return ConstantExpressionKind.STRING_FROM_ENVIRONMENT; |
| 1224 } | 1185 } |
| 1225 | 1186 |
| 1226 accept(ConstantExpressionVisitor visitor, [context]) { | 1187 accept(ConstantExpressionVisitor visitor, [context]) { |
| 1227 return visitor.visitStringFromEnvironment(this, context); | 1188 return visitor.visitStringFromEnvironment(this, context); |
| 1228 } | 1189 } |
| 1229 | 1190 |
| 1230 @override | 1191 @override |
| 1231 ConstantValue evaluate(Environment environment, | 1192 ConstantValue evaluate( |
| 1232 ConstantSystem constantSystem) { | 1193 Environment environment, ConstantSystem constantSystem) { |
| 1233 ConstantValue nameConstantValue = | 1194 ConstantValue nameConstantValue = |
| 1234 name.evaluate(environment, constantSystem); | 1195 name.evaluate(environment, constantSystem); |
| 1235 ConstantValue defaultConstantValue; | 1196 ConstantValue defaultConstantValue; |
| 1236 if (defaultValue != null) { | 1197 if (defaultValue != null) { |
| 1237 defaultConstantValue = | 1198 defaultConstantValue = defaultValue.evaluate(environment, constantSystem); |
| 1238 defaultValue.evaluate(environment, constantSystem); | |
| 1239 } else { | 1199 } else { |
| 1240 defaultConstantValue = constantSystem.createNull(); | 1200 defaultConstantValue = constantSystem.createNull(); |
| 1241 } | 1201 } |
| 1242 if (!nameConstantValue.isString) { | 1202 if (!nameConstantValue.isString) { |
| 1243 return new NonConstantValue(); | 1203 return new NonConstantValue(); |
| 1244 } | 1204 } |
| 1245 StringConstantValue nameStringConstantValue = nameConstantValue; | 1205 StringConstantValue nameStringConstantValue = nameConstantValue; |
| 1246 String text = environment.readFromEnvironment( | 1206 String text = environment.readFromEnvironment( |
| 1247 nameStringConstantValue.primitiveValue.slowToString()); | 1207 nameStringConstantValue.primitiveValue.slowToString()); |
| 1248 if (text == null) { | 1208 if (text == null) { |
| 1249 return defaultConstantValue; | 1209 return defaultConstantValue; |
| 1250 } else { | 1210 } else { |
| 1251 return constantSystem.createString(new DartString.literal(text)); | 1211 return constantSystem.createString(new DartString.literal(text)); |
| 1252 } | 1212 } |
| 1253 } | 1213 } |
| 1254 | 1214 |
| 1255 ConstantExpression apply(NormalizedArguments arguments) { | 1215 ConstantExpression apply(NormalizedArguments arguments) { |
| 1256 return new StringFromEnvironmentConstantExpression( | 1216 return new StringFromEnvironmentConstantExpression(name.apply(arguments), |
| 1257 name.apply(arguments), | |
| 1258 defaultValue != null ? defaultValue.apply(arguments) : null); | 1217 defaultValue != null ? defaultValue.apply(arguments) : null); |
| 1259 } | 1218 } |
| 1260 | 1219 |
| 1261 @override | 1220 @override |
| 1262 DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType; | 1221 DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType; |
| 1263 } | 1222 } |
| 1264 | 1223 |
| 1265 /// A constant expression referenced with a deferred prefix. | 1224 /// A constant expression referenced with a deferred prefix. |
| 1266 /// For example `lib.C`. | 1225 /// For example `lib.C`. |
| 1267 class DeferredConstantExpression extends ConstantExpression { | 1226 class DeferredConstantExpression extends ConstantExpression { |
| 1268 final ConstantExpression expression; | 1227 final ConstantExpression expression; |
| 1269 final PrefixElement prefix; | 1228 final PrefixElement prefix; |
| 1270 | 1229 |
| 1271 DeferredConstantExpression(this.expression, this.prefix); | 1230 DeferredConstantExpression(this.expression, this.prefix); |
| 1272 | 1231 |
| 1273 ConstantExpressionKind get kind => ConstantExpressionKind.DEFERRED; | 1232 ConstantExpressionKind get kind => ConstantExpressionKind.DEFERRED; |
| 1274 | 1233 |
| 1275 @override | 1234 @override |
| 1276 ConstantValue evaluate(Environment environment, | 1235 ConstantValue evaluate( |
| 1277 ConstantSystem constantSystem) { | 1236 Environment environment, ConstantSystem constantSystem) { |
| 1278 return expression.evaluate(environment, constantSystem); | 1237 return expression.evaluate(environment, constantSystem); |
| 1279 } | 1238 } |
| 1280 | 1239 |
| 1281 @override | 1240 @override |
| 1282 int _computeHashCode() { | 1241 int _computeHashCode() { |
| 1283 return 13 * expression.hashCode; | 1242 return 13 * expression.hashCode; |
| 1284 } | 1243 } |
| 1285 | 1244 |
| 1286 ConstantExpression apply(NormalizedArguments arguments) { | 1245 ConstantExpression apply(NormalizedArguments arguments) { |
| 1287 return new DeferredConstantExpression( | 1246 return new DeferredConstantExpression(expression.apply(arguments), prefix); |
| 1288 expression.apply(arguments), prefix); | |
| 1289 } | 1247 } |
| 1290 | 1248 |
| 1291 @override | 1249 @override |
| 1292 bool _equals(DeferredConstantExpression other) { | 1250 bool _equals(DeferredConstantExpression other) { |
| 1293 return expression == other.expression; | 1251 return expression == other.expression; |
| 1294 } | 1252 } |
| 1295 | 1253 |
| 1296 @override | 1254 @override |
| 1297 accept(ConstantExpressionVisitor visitor, [context]) { | 1255 accept(ConstantExpressionVisitor visitor, [context]) { |
| 1298 return visitor.visitDeferred(this, context); | 1256 return visitor.visitDeferred(this, context); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1317 R visitConcatenate(ConcatenateConstantExpression exp, A context); | 1275 R visitConcatenate(ConcatenateConstantExpression exp, A context); |
| 1318 R visitSymbol(SymbolConstantExpression exp, A context); | 1276 R visitSymbol(SymbolConstantExpression exp, A context); |
| 1319 R visitType(TypeConstantExpression exp, A context); | 1277 R visitType(TypeConstantExpression exp, A context); |
| 1320 R visitVariable(VariableConstantExpression exp, A context); | 1278 R visitVariable(VariableConstantExpression exp, A context); |
| 1321 R visitFunction(FunctionConstantExpression exp, A context); | 1279 R visitFunction(FunctionConstantExpression exp, A context); |
| 1322 R visitBinary(BinaryConstantExpression exp, A context); | 1280 R visitBinary(BinaryConstantExpression exp, A context); |
| 1323 R visitIdentical(IdenticalConstantExpression exp, A context); | 1281 R visitIdentical(IdenticalConstantExpression exp, A context); |
| 1324 R visitUnary(UnaryConstantExpression exp, A context); | 1282 R visitUnary(UnaryConstantExpression exp, A context); |
| 1325 R visitStringLength(StringLengthConstantExpression exp, A context); | 1283 R visitStringLength(StringLengthConstantExpression exp, A context); |
| 1326 R visitConditional(ConditionalConstantExpression exp, A context); | 1284 R visitConditional(ConditionalConstantExpression exp, A context); |
| 1327 R visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp, | 1285 R visitBoolFromEnvironment( |
| 1328 A context); | 1286 BoolFromEnvironmentConstantExpression exp, A context); |
| 1329 R visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp, | 1287 R visitIntFromEnvironment( |
| 1330 A context); | 1288 IntFromEnvironmentConstantExpression exp, A context); |
| 1331 R visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, | 1289 R visitStringFromEnvironment( |
| 1332 A context); | 1290 StringFromEnvironmentConstantExpression exp, A context); |
| 1333 R visitDeferred(DeferredConstantExpression exp, A context); | 1291 R visitDeferred(DeferredConstantExpression exp, A context); |
| 1334 | 1292 |
| 1335 R visitPositional(PositionalArgumentReference exp, A context); | 1293 R visitPositional(PositionalArgumentReference exp, A context); |
| 1336 R visitNamed(NamedArgumentReference exp, A context); | 1294 R visitNamed(NamedArgumentReference exp, A context); |
| 1337 } | 1295 } |
| 1338 | 1296 |
| 1339 class ConstExpPrinter extends ConstantExpressionVisitor { | 1297 class ConstExpPrinter extends ConstantExpressionVisitor { |
| 1340 final StringBuffer sb = new StringBuffer(); | 1298 final StringBuffer sb = new StringBuffer(); |
| 1341 | 1299 |
| 1342 void write(ConstantExpression parent, | 1300 void write(ConstantExpression parent, ConstantExpression child, |
| 1343 ConstantExpression child, | 1301 {bool leftAssociative: true}) { |
| 1344 {bool leftAssociative: true}) { | |
| 1345 if (child.precedence < parent.precedence || | 1302 if (child.precedence < parent.precedence || |
| 1346 !leftAssociative && child.precedence == parent.precedence) { | 1303 !leftAssociative && child.precedence == parent.precedence) { |
| 1347 sb.write('('); | 1304 sb.write('('); |
| 1348 child.accept(this); | 1305 child.accept(this); |
| 1349 sb.write(')'); | 1306 sb.write(')'); |
| 1350 } else { | 1307 } else { |
| 1351 child.accept(this); | 1308 child.accept(this); |
| 1352 } | 1309 } |
| 1353 } | 1310 } |
| 1354 | 1311 |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1471 for (ConstantExpression expression in exp.expressions) { | 1428 for (ConstantExpression expression in exp.expressions) { |
| 1472 if (expression.kind == ConstantExpressionKind.STRING) { | 1429 if (expression.kind == ConstantExpressionKind.STRING) { |
| 1473 StringConstantExpression string = expression; | 1430 StringConstantExpression string = expression; |
| 1474 // TODO(johnniwinther): Ensure correct escaping. | 1431 // TODO(johnniwinther): Ensure correct escaping. |
| 1475 sb.write('${string.primitiveValue}'); | 1432 sb.write('${string.primitiveValue}'); |
| 1476 } else { | 1433 } else { |
| 1477 sb.write(r"${"); | 1434 sb.write(r"${"); |
| 1478 visit(expression); | 1435 visit(expression); |
| 1479 sb.write("}"); | 1436 sb.write("}"); |
| 1480 } | 1437 } |
| 1481 | |
| 1482 } | 1438 } |
| 1483 sb.write('"'); | 1439 sb.write('"'); |
| 1484 } | 1440 } |
| 1485 | 1441 |
| 1486 @override | 1442 @override |
| 1487 void visitSymbol(SymbolConstantExpression exp, [_]) { | 1443 void visitSymbol(SymbolConstantExpression exp, [_]) { |
| 1488 sb.write('#'); | 1444 sb.write('#'); |
| 1489 sb.write(exp.name); | 1445 sb.write(exp.name); |
| 1490 } | 1446 } |
| 1491 | 1447 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1565 | 1521 |
| 1566 @override | 1522 @override |
| 1567 void visitDeferred(DeferredConstantExpression exp, context) { | 1523 void visitDeferred(DeferredConstantExpression exp, context) { |
| 1568 sb.write(exp.prefix.name); | 1524 sb.write(exp.prefix.name); |
| 1569 sb.write('.'); | 1525 sb.write('.'); |
| 1570 write(exp, exp.expression); | 1526 write(exp, exp.expression); |
| 1571 } | 1527 } |
| 1572 | 1528 |
| 1573 @override | 1529 @override |
| 1574 void visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp, | 1530 void visitBoolFromEnvironment(BoolFromEnvironmentConstantExpression exp, |
| 1575 [_]) { | 1531 [_]) { |
| 1576 sb.write('const bool.fromEnvironment('); | 1532 sb.write('const bool.fromEnvironment('); |
| 1577 visit(exp.name); | 1533 visit(exp.name); |
| 1578 if (exp.defaultValue != null) { | 1534 if (exp.defaultValue != null) { |
| 1579 sb.write(', defaultValue: '); | 1535 sb.write(', defaultValue: '); |
| 1580 visit(exp.defaultValue); | 1536 visit(exp.defaultValue); |
| 1581 } | 1537 } |
| 1582 sb.write(')'); | 1538 sb.write(')'); |
| 1583 } | 1539 } |
| 1584 | 1540 |
| 1585 @override | 1541 @override |
| 1586 void visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp, [_]) { | 1542 void visitIntFromEnvironment(IntFromEnvironmentConstantExpression exp, [_]) { |
| 1587 sb.write('const int.fromEnvironment('); | 1543 sb.write('const int.fromEnvironment('); |
| 1588 visit(exp.name); | 1544 visit(exp.name); |
| 1589 if (exp.defaultValue != null) { | 1545 if (exp.defaultValue != null) { |
| 1590 sb.write(', defaultValue: '); | 1546 sb.write(', defaultValue: '); |
| 1591 visit(exp.defaultValue); | 1547 visit(exp.defaultValue); |
| 1592 } | 1548 } |
| 1593 sb.write(')'); | 1549 sb.write(')'); |
| 1594 } | 1550 } |
| 1595 | 1551 |
| 1596 @override | 1552 @override |
| 1597 void visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, | 1553 void visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, |
| 1598 [_]) { | 1554 [_]) { |
| 1599 sb.write('const String.fromEnvironment('); | 1555 sb.write('const String.fromEnvironment('); |
| 1600 visit(exp.name); | 1556 visit(exp.name); |
| 1601 if (exp.defaultValue != null) { | 1557 if (exp.defaultValue != null) { |
| 1602 sb.write(', defaultValue: '); | 1558 sb.write(', defaultValue: '); |
| 1603 visit(exp.defaultValue); | 1559 visit(exp.defaultValue); |
| 1604 } | 1560 } |
| 1605 sb.write(')'); | 1561 sb.write(')'); |
| 1606 } | 1562 } |
| 1607 | 1563 |
| 1608 String toString() => sb.toString(); | 1564 String toString() => sb.toString(); |
| 1609 } | 1565 } |
| OLD | NEW |