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 |