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 '../dart2jslib.dart' show assertDebugMode; | 7 import '../constants/constant_system.dart'; |
| 8 import '../dart2jslib.dart' show assertDebugMode, Compiler; |
8 import '../dart_types.dart'; | 9 import '../dart_types.dart'; |
9 import '../elements/elements.dart' show | 10 import '../elements/elements.dart' show |
10 ConstructorElement, | 11 ConstructorElement, |
11 Element, | 12 Element, |
12 FieldElement, | 13 FieldElement, |
13 FunctionElement, | 14 FunctionElement, |
14 VariableElement; | 15 VariableElement; |
15 import '../resolution/operators.dart'; | 16 import '../resolution/operators.dart'; |
| 17 import '../tree/tree.dart' show DartString; |
16 import '../universe/universe.dart' show CallStructure; | 18 import '../universe/universe.dart' show CallStructure; |
17 import 'values.dart'; | 19 import 'values.dart'; |
18 | 20 |
19 enum ConstantExpressionKind { | 21 enum ConstantExpressionKind { |
20 BINARY, | 22 BINARY, |
21 BOOL, | 23 BOOL, |
22 BOOL_FROM_ENVIRONMENT, | 24 BOOL_FROM_ENVIRONMENT, |
23 CONCATENATE, | 25 CONCATENATE, |
24 CONDITIONAL, | 26 CONDITIONAL, |
25 CONSTRUCTED, | 27 CONSTRUCTED, |
(...skipping 10 matching lines...) Expand all Loading... |
36 STRING_FROM_ENVIRONMENT, | 38 STRING_FROM_ENVIRONMENT, |
37 SYMBOL, | 39 SYMBOL, |
38 TYPE, | 40 TYPE, |
39 UNARY, | 41 UNARY, |
40 VARIABLE, | 42 VARIABLE, |
41 | 43 |
42 POSITIONAL_REFERENCE, | 44 POSITIONAL_REFERENCE, |
43 NAMED_REFERENCE, | 45 NAMED_REFERENCE, |
44 } | 46 } |
45 | 47 |
| 48 /// Environment used for evaluating constant expressions. |
| 49 abstract class Environment { |
| 50 // TODO(johnniwinther): Replace this with [CoreTypes] and maybe [Backend]. |
| 51 Compiler get compiler; |
| 52 |
| 53 /// Read environments string passed in using the '-Dname=value' option. |
| 54 String readFromEnvironment(String name); |
| 55 } |
| 56 |
46 /// The normalized arguments passed to a const constructor computed from the | 57 /// The normalized arguments passed to a const constructor computed from the |
47 /// actual [arguments] and the [defaultValues] of the called construrctor. | 58 /// actual [arguments] and the [defaultValues] of the called construrctor. |
48 class Arguments { | 59 class Arguments { |
49 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues; | 60 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues; |
50 final CallStructure callStructure; | 61 final CallStructure callStructure; |
51 final List<ConstantExpression> arguments; | 62 final List<ConstantExpression> arguments; |
52 | 63 |
53 Arguments(this.defaultValues, this.callStructure, this.arguments); | 64 Arguments(this.defaultValues, this.callStructure, this.arguments); |
54 | 65 |
55 /// Returns the normalized named argument [name]. | 66 /// Returns the normalized named argument [name]. |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 | 254 |
244 // TODO(johnniwinther): Unify precedence handled between constants, front-end | 255 // TODO(johnniwinther): Unify precedence handled between constants, front-end |
245 // and back-end. | 256 // and back-end. |
246 int get precedence => 16; | 257 int get precedence => 16; |
247 | 258 |
248 accept(ConstantExpressionVisitor visitor, [context]); | 259 accept(ConstantExpressionVisitor visitor, [context]); |
249 | 260 |
250 /// Substitute free variables using arguments. | 261 /// Substitute free variables using arguments. |
251 ConstantExpression apply(Arguments arguments) => this; | 262 ConstantExpression apply(Arguments arguments) => this; |
252 | 263 |
| 264 /// Compute the [ConstantValue] for this expression using the [environment] |
| 265 /// and the [constantSystem]. |
| 266 ConstantValue evaluate(Environment environment, |
| 267 ConstantSystem constantSystem); |
| 268 |
253 String getText() { | 269 String getText() { |
254 ConstExpPrinter printer = new ConstExpPrinter(); | 270 ConstExpPrinter printer = new ConstExpPrinter(); |
255 accept(printer); | 271 accept(printer); |
256 return printer.toString(); | 272 return printer.toString(); |
257 } | 273 } |
258 | 274 |
259 int _computeHashCode(); | 275 int _computeHashCode(); |
260 | 276 |
261 int get hashCode { | 277 int get hashCode { |
262 if (_hashCode == null) { | 278 if (_hashCode == null) { |
(...skipping 23 matching lines...) Expand all Loading... |
286 class ErroneousConstantExpression extends ConstantExpression { | 302 class ErroneousConstantExpression extends ConstantExpression { |
287 final PrimitiveConstantValue value = new NullConstantValue(); | 303 final PrimitiveConstantValue value = new NullConstantValue(); |
288 | 304 |
289 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS; | 305 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS; |
290 | 306 |
291 accept(ConstantExpressionVisitor visitor, [context]) { | 307 accept(ConstantExpressionVisitor visitor, [context]) { |
292 // Do nothing. This is an error. | 308 // Do nothing. This is an error. |
293 } | 309 } |
294 | 310 |
295 @override | 311 @override |
| 312 ConstantValue evaluate(Environment environment, |
| 313 ConstantSystem constantSystem) { |
| 314 // TODO(johnniwinther): Use non-constant values for errors. |
| 315 return value; |
| 316 } |
| 317 |
| 318 @override |
296 int _computeHashCode() => 13; | 319 int _computeHashCode() => 13; |
297 | 320 |
298 @override | 321 @override |
299 bool _equals(ErroneousConstantExpression other) => true; | 322 bool _equals(ErroneousConstantExpression other) => true; |
300 } | 323 } |
301 | 324 |
302 /// A boolean, int, double, string, or null constant. | 325 /// A boolean, int, double, string, or null constant. |
303 abstract class PrimitiveConstantExpression extends ConstantExpression { | 326 abstract class PrimitiveConstantExpression extends ConstantExpression { |
304 final PrimitiveConstantValue value; | 327 final PrimitiveConstantValue value; |
305 | 328 |
(...skipping 10 matching lines...) Expand all Loading... |
316 BoolConstantExpression(this.primitiveValue, | 339 BoolConstantExpression(this.primitiveValue, |
317 PrimitiveConstantValue value) : super(value); | 340 PrimitiveConstantValue value) : super(value); |
318 | 341 |
319 ConstantExpressionKind get kind => ConstantExpressionKind.BOOL; | 342 ConstantExpressionKind get kind => ConstantExpressionKind.BOOL; |
320 | 343 |
321 accept(ConstantExpressionVisitor visitor, [context]) { | 344 accept(ConstantExpressionVisitor visitor, [context]) { |
322 return visitor.visitBool(this, context); | 345 return visitor.visitBool(this, context); |
323 } | 346 } |
324 | 347 |
325 @override | 348 @override |
| 349 ConstantValue evaluate(Environment environment, |
| 350 ConstantSystem constantSystem) { |
| 351 return constantSystem.createBool(primitiveValue); |
| 352 } |
| 353 |
| 354 @override |
326 int _computeHashCode() => 13 * primitiveValue.hashCode; | 355 int _computeHashCode() => 13 * primitiveValue.hashCode; |
327 | 356 |
328 @override | 357 @override |
329 bool _equals(BoolConstantExpression other) { | 358 bool _equals(BoolConstantExpression other) { |
330 return primitiveValue == other.primitiveValue; | 359 return primitiveValue == other.primitiveValue; |
331 } | 360 } |
332 } | 361 } |
333 | 362 |
334 /// Integer literal constant. | 363 /// Integer literal constant. |
335 class IntConstantExpression extends PrimitiveConstantExpression { | 364 class IntConstantExpression extends PrimitiveConstantExpression { |
336 final int primitiveValue; | 365 final int primitiveValue; |
337 | 366 |
338 IntConstantExpression(this.primitiveValue, | 367 IntConstantExpression(this.primitiveValue, |
339 PrimitiveConstantValue value) : super(value); | 368 PrimitiveConstantValue value) : super(value); |
340 | 369 |
341 ConstantExpressionKind get kind => ConstantExpressionKind.INT; | 370 ConstantExpressionKind get kind => ConstantExpressionKind.INT; |
342 | 371 |
343 accept(ConstantExpressionVisitor visitor, [context]) { | 372 accept(ConstantExpressionVisitor visitor, [context]) { |
344 return visitor.visitInt(this, context); | 373 return visitor.visitInt(this, context); |
345 } | 374 } |
346 | 375 |
347 @override | 376 @override |
| 377 ConstantValue evaluate(Environment environment, |
| 378 ConstantSystem constantSystem) { |
| 379 return constantSystem.createInt(primitiveValue); |
| 380 } |
| 381 |
| 382 @override |
348 int _computeHashCode() => 17 * primitiveValue.hashCode; | 383 int _computeHashCode() => 17 * primitiveValue.hashCode; |
349 | 384 |
350 @override | 385 @override |
351 bool _equals(IntConstantExpression other) { | 386 bool _equals(IntConstantExpression other) { |
352 return primitiveValue == other.primitiveValue; | 387 return primitiveValue == other.primitiveValue; |
353 } | 388 } |
354 } | 389 } |
355 | 390 |
356 /// Double literal constant. | 391 /// Double literal constant. |
357 class DoubleConstantExpression extends PrimitiveConstantExpression { | 392 class DoubleConstantExpression extends PrimitiveConstantExpression { |
358 final double primitiveValue; | 393 final double primitiveValue; |
359 | 394 |
360 DoubleConstantExpression(this.primitiveValue, | 395 DoubleConstantExpression(this.primitiveValue, |
361 PrimitiveConstantValue value) : super(value); | 396 PrimitiveConstantValue value) : super(value); |
362 | 397 |
363 ConstantExpressionKind get kind => ConstantExpressionKind.DOUBLE; | 398 ConstantExpressionKind get kind => ConstantExpressionKind.DOUBLE; |
364 | 399 |
365 accept(ConstantExpressionVisitor visitor, [context]) { | 400 accept(ConstantExpressionVisitor visitor, [context]) { |
366 return visitor.visitDouble(this, context); | 401 return visitor.visitDouble(this, context); |
367 } | 402 } |
368 | 403 |
369 @override | 404 @override |
| 405 ConstantValue evaluate(Environment environment, |
| 406 ConstantSystem constantSystem) { |
| 407 return constantSystem.createDouble(primitiveValue); |
| 408 } |
| 409 |
| 410 @override |
370 int _computeHashCode() => 19 * primitiveValue.hashCode; | 411 int _computeHashCode() => 19 * primitiveValue.hashCode; |
371 | 412 |
372 @override | 413 @override |
373 bool _equals(DoubleConstantExpression other) { | 414 bool _equals(DoubleConstantExpression other) { |
374 return primitiveValue == other.primitiveValue; | 415 return primitiveValue == other.primitiveValue; |
375 } | 416 } |
376 } | 417 } |
377 | 418 |
378 /// String literal constant. | 419 /// String literal constant. |
379 class StringConstantExpression extends PrimitiveConstantExpression { | 420 class StringConstantExpression extends PrimitiveConstantExpression { |
380 final String primitiveValue; | 421 final String primitiveValue; |
381 | 422 |
382 StringConstantExpression(this.primitiveValue, | 423 StringConstantExpression(this.primitiveValue, |
383 PrimitiveConstantValue value) : super(value); | 424 PrimitiveConstantValue value) : super(value); |
384 | 425 |
385 ConstantExpressionKind get kind => ConstantExpressionKind.STRING; | 426 ConstantExpressionKind get kind => ConstantExpressionKind.STRING; |
386 | 427 |
387 accept(ConstantExpressionVisitor visitor, [context]) { | 428 accept(ConstantExpressionVisitor visitor, [context]) { |
388 return visitor.visitString(this, context); | 429 return visitor.visitString(this, context); |
389 } | 430 } |
390 | 431 |
391 @override | 432 @override |
| 433 ConstantValue evaluate(Environment environment, |
| 434 ConstantSystem constantSystem) { |
| 435 return constantSystem.createString(new DartString.literal(primitiveValue)); |
| 436 } |
| 437 |
| 438 @override |
392 int _computeHashCode() => 23 * primitiveValue.hashCode; | 439 int _computeHashCode() => 23 * primitiveValue.hashCode; |
393 | 440 |
394 @override | 441 @override |
395 bool _equals(StringConstantExpression other) { | 442 bool _equals(StringConstantExpression other) { |
396 return primitiveValue == other.primitiveValue; | 443 return primitiveValue == other.primitiveValue; |
397 } | 444 } |
398 } | 445 } |
399 | 446 |
400 /// Null literal constant. | 447 /// Null literal constant. |
401 class NullConstantExpression extends PrimitiveConstantExpression { | 448 class NullConstantExpression extends PrimitiveConstantExpression { |
402 NullConstantExpression(PrimitiveConstantValue value) : super(value); | 449 NullConstantExpression(PrimitiveConstantValue value) : super(value); |
403 | 450 |
404 ConstantExpressionKind get kind => ConstantExpressionKind.NULL; | 451 ConstantExpressionKind get kind => ConstantExpressionKind.NULL; |
405 | 452 |
406 accept(ConstantExpressionVisitor visitor, [context]) { | 453 accept(ConstantExpressionVisitor visitor, [context]) { |
407 return visitor.visitNull(this, context); | 454 return visitor.visitNull(this, context); |
408 } | 455 } |
409 | 456 |
| 457 @override |
| 458 ConstantValue evaluate(Environment environment, |
| 459 ConstantSystem constantSystem) { |
| 460 return constantSystem.createNull(); |
| 461 } |
| 462 |
410 get primitiveValue => null; | 463 get primitiveValue => null; |
411 | 464 |
412 @override | 465 @override |
413 int _computeHashCode() => 29; | 466 int _computeHashCode() => 29; |
414 | 467 |
415 @override | 468 @override |
416 bool _equals(NullConstantExpression other) => true; | 469 bool _equals(NullConstantExpression other) => true; |
417 } | 470 } |
418 | 471 |
419 /// Literal list constant. | 472 /// Literal list constant. |
420 class ListConstantExpression extends ConstantExpression { | 473 class ListConstantExpression extends ConstantExpression { |
421 final ListConstantValue value; | 474 final ListConstantValue value; |
422 final InterfaceType type; | 475 final InterfaceType type; |
423 final List<ConstantExpression> values; | 476 final List<ConstantExpression> values; |
424 | 477 |
425 ListConstantExpression(this.value, this.type, this.values); | 478 ListConstantExpression(this.value, this.type, this.values); |
426 | 479 |
427 ConstantExpressionKind get kind => ConstantExpressionKind.LIST; | 480 ConstantExpressionKind get kind => ConstantExpressionKind.LIST; |
428 | 481 |
429 accept(ConstantExpressionVisitor visitor, [context]) { | 482 accept(ConstantExpressionVisitor visitor, [context]) { |
430 return visitor.visitList(this, context); | 483 return visitor.visitList(this, context); |
431 } | 484 } |
432 | 485 |
433 @override | 486 @override |
| 487 ConstantValue evaluate(Environment environment, |
| 488 ConstantSystem constantSystem) { |
| 489 return constantSystem.createList(type, |
| 490 values.map((v) => v.evaluate(environment, constantSystem)).toList()); |
| 491 } |
| 492 |
434 ConstantExpression apply(Arguments arguments) { | 493 ConstantExpression apply(Arguments arguments) { |
435 return new ListConstantExpression(null, type, | 494 return new ListConstantExpression(null, type, |
436 values.map((v) => v.apply(arguments)).toList()); | 495 values.map((v) => v.apply(arguments)).toList()); |
437 } | 496 } |
438 | 497 |
| 498 @override |
439 int _computeHashCode() { | 499 int _computeHashCode() { |
440 int hashCode = 13 * type.hashCode + 17 * values.length; | 500 int hashCode = 13 * type.hashCode + 17 * values.length; |
441 for (ConstantExpression value in values) { | 501 for (ConstantExpression value in values) { |
442 hashCode ^= 19 * value.hashCode; | 502 hashCode ^= 19 * value.hashCode; |
443 } | 503 } |
444 return hashCode; | 504 return hashCode; |
445 } | 505 } |
446 | 506 |
447 @override | 507 @override |
448 bool _equals(ListConstantExpression other) { | 508 bool _equals(ListConstantExpression other) { |
(...skipping 15 matching lines...) Expand all Loading... |
464 | 524 |
465 MapConstantExpression(this.value, this.type, this.keys, this.values); | 525 MapConstantExpression(this.value, this.type, this.keys, this.values); |
466 | 526 |
467 ConstantExpressionKind get kind => ConstantExpressionKind.MAP; | 527 ConstantExpressionKind get kind => ConstantExpressionKind.MAP; |
468 | 528 |
469 accept(ConstantExpressionVisitor visitor, [context]) { | 529 accept(ConstantExpressionVisitor visitor, [context]) { |
470 return visitor.visitMap(this, context); | 530 return visitor.visitMap(this, context); |
471 } | 531 } |
472 | 532 |
473 @override | 533 @override |
| 534 ConstantValue evaluate(Environment environment, |
| 535 ConstantSystem constantSystem) { |
| 536 return constantSystem.createMap(environment.compiler, |
| 537 type, |
| 538 keys.map((k) => k.evaluate(environment, constantSystem)).toList(), |
| 539 values.map((v) => v.evaluate(environment, constantSystem)).toList()); |
| 540 } |
| 541 |
474 ConstantExpression apply(Arguments arguments) { | 542 ConstantExpression apply(Arguments arguments) { |
475 return new MapConstantExpression(null, type, | 543 return new MapConstantExpression(null, type, |
476 keys.map((k) => k.apply(arguments)).toList(), | 544 keys.map((k) => k.apply(arguments)).toList(), |
477 values.map((v) => v.apply(arguments)).toList()); | 545 values.map((v) => v.apply(arguments)).toList()); |
478 } | 546 } |
479 | 547 |
| 548 @override |
480 int _computeHashCode() { | 549 int _computeHashCode() { |
481 int hashCode = 13 * type.hashCode + 17 * values.length; | 550 int hashCode = 13 * type.hashCode + 17 * values.length; |
482 for (ConstantExpression value in values) { | 551 for (ConstantExpression value in values) { |
483 hashCode ^= 19 * value.hashCode; | 552 hashCode ^= 19 * value.hashCode; |
484 } | 553 } |
485 return hashCode; | 554 return hashCode; |
486 } | 555 } |
487 | 556 |
488 @override | 557 @override |
489 bool _equals(MapConstantExpression other) { | 558 bool _equals(MapConstantExpression other) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 InterfaceType computeInstanceType() { | 598 InterfaceType computeInstanceType() { |
530 return target.constantConstructor.computeInstanceType(type); | 599 return target.constantConstructor.computeInstanceType(type); |
531 } | 600 } |
532 | 601 |
533 ConstructedConstantExpression apply(Arguments arguments) { | 602 ConstructedConstantExpression apply(Arguments arguments) { |
534 return new ConstructedConstantExpression(null, | 603 return new ConstructedConstantExpression(null, |
535 type, target, callStructure, | 604 type, target, callStructure, |
536 this.arguments.map((a) => a.apply(arguments)).toList()); | 605 this.arguments.map((a) => a.apply(arguments)).toList()); |
537 } | 606 } |
538 | 607 |
| 608 @override |
| 609 ConstantValue evaluate(Environment environment, |
| 610 ConstantSystem constantSystem) { |
| 611 Map<FieldElement, ConstantValue> fieldValues = |
| 612 <FieldElement, ConstantValue>{}; |
| 613 computeInstanceFields().forEach( |
| 614 (FieldElement field, ConstantExpression constant) { |
| 615 fieldValues[field] = constant.evaluate(environment, constantSystem); |
| 616 }); |
| 617 return new ConstructedConstantValue(computeInstanceType(), fieldValues); |
| 618 } |
| 619 |
| 620 @override |
539 int _computeHashCode() { | 621 int _computeHashCode() { |
540 int hashCode = | 622 int hashCode = |
541 13 * type.hashCode + | 623 13 * type.hashCode + |
542 17 * target.hashCode + | 624 17 * target.hashCode + |
543 19 * callStructure.hashCode; | 625 19 * callStructure.hashCode; |
544 for (ConstantExpression value in arguments) { | 626 for (ConstantExpression value in arguments) { |
545 hashCode ^= 23 * value.hashCode; | 627 hashCode ^= 23 * value.hashCode; |
546 } | 628 } |
547 return hashCode; | 629 return hashCode; |
548 } | 630 } |
(...skipping 22 matching lines...) Expand all Loading... |
571 accept(ConstantExpressionVisitor visitor, [context]) { | 653 accept(ConstantExpressionVisitor visitor, [context]) { |
572 return visitor.visitConcatenate(this, context); | 654 return visitor.visitConcatenate(this, context); |
573 } | 655 } |
574 | 656 |
575 ConstantExpression apply(Arguments arguments) { | 657 ConstantExpression apply(Arguments arguments) { |
576 return new ConcatenateConstantExpression(null, | 658 return new ConcatenateConstantExpression(null, |
577 expressions.map((a) => a.apply(arguments)).toList()); | 659 expressions.map((a) => a.apply(arguments)).toList()); |
578 } | 660 } |
579 | 661 |
580 @override | 662 @override |
| 663 ConstantValue evaluate(Environment environment, |
| 664 ConstantSystem constantSystem) { |
| 665 DartString accumulator; |
| 666 for (ConstantExpression expression in expressions) { |
| 667 ConstantValue value = expression.evaluate(environment, constantSystem); |
| 668 DartString valueString; |
| 669 if (value.isNum || value.isBool) { |
| 670 PrimitiveConstantValue primitive = value; |
| 671 valueString = |
| 672 new DartString.literal(primitive.primitiveValue.toString()); |
| 673 } else if (value.isString) { |
| 674 PrimitiveConstantValue primitive = value; |
| 675 valueString = primitive.primitiveValue; |
| 676 } else { |
| 677 // TODO(johnniwinther): Specialize message to indicated that the problem |
| 678 // is not constness but the types of the const expressions. |
| 679 return new NonConstantValue(); |
| 680 } |
| 681 if (accumulator == null) { |
| 682 accumulator = valueString; |
| 683 } else { |
| 684 accumulator = new DartString.concat(accumulator, valueString); |
| 685 } |
| 686 } |
| 687 return constantSystem.createString(accumulator); |
| 688 } |
| 689 |
| 690 @override |
581 int _computeHashCode() { | 691 int _computeHashCode() { |
582 int hashCode = 17 * expressions.length; | 692 int hashCode = 17 * expressions.length; |
583 for (ConstantExpression value in expressions) { | 693 for (ConstantExpression value in expressions) { |
584 hashCode ^= 19 * value.hashCode; | 694 hashCode ^= 19 * value.hashCode; |
585 } | 695 } |
586 return hashCode; | 696 return hashCode; |
587 } | 697 } |
588 | 698 |
589 @override | 699 @override |
590 bool _equals(ConcatenateConstantExpression other) { | 700 bool _equals(ConcatenateConstantExpression other) { |
(...skipping 18 matching lines...) Expand all Loading... |
609 return visitor.visitSymbol(this, context); | 719 return visitor.visitSymbol(this, context); |
610 } | 720 } |
611 | 721 |
612 @override | 722 @override |
613 int _computeHashCode() => 13 * name.hashCode; | 723 int _computeHashCode() => 13 * name.hashCode; |
614 | 724 |
615 @override | 725 @override |
616 bool _equals(SymbolConstantExpression other) { | 726 bool _equals(SymbolConstantExpression other) { |
617 return name == other.name; | 727 return name == other.name; |
618 } | 728 } |
| 729 |
| 730 @override |
| 731 ConstantValue evaluate(Environment environment, |
| 732 ConstantSystem constantSystem) { |
| 733 // TODO(johnniwinther): Implement this. |
| 734 throw new UnsupportedError('SymbolConstantExpression.evaluate'); |
| 735 } |
619 } | 736 } |
620 | 737 |
621 /// Type literal. | 738 /// Type literal. |
622 class TypeConstantExpression extends ConstantExpression { | 739 class TypeConstantExpression extends ConstantExpression { |
623 final TypeConstantValue value; | 740 final TypeConstantValue value; |
624 /// Either [DynamicType] or a raw [GenericType]. | 741 /// Either [DynamicType] or a raw [GenericType]. |
625 final DartType type; | 742 final DartType type; |
626 | 743 |
627 TypeConstantExpression(this.value, this.type) { | 744 TypeConstantExpression(this.value, this.type) { |
628 assert(type is GenericType || type is DynamicType); | 745 assert(type is GenericType || type is DynamicType); |
629 } | 746 } |
630 | 747 |
631 ConstantExpressionKind get kind => ConstantExpressionKind.TYPE; | 748 ConstantExpressionKind get kind => ConstantExpressionKind.TYPE; |
632 | 749 |
633 accept(ConstantExpressionVisitor visitor, [context]) { | 750 accept(ConstantExpressionVisitor visitor, [context]) { |
634 return visitor.visitType(this, context); | 751 return visitor.visitType(this, context); |
635 } | 752 } |
636 | 753 |
637 @override | 754 @override |
| 755 ConstantValue evaluate(Environment environment, |
| 756 ConstantSystem constantSystem) { |
| 757 return constantSystem.createType(environment.compiler, type); |
| 758 } |
| 759 |
| 760 @override |
638 int _computeHashCode() => 13 * type.hashCode; | 761 int _computeHashCode() => 13 * type.hashCode; |
639 | 762 |
640 @override | 763 @override |
641 bool _equals(TypeConstantExpression other) { | 764 bool _equals(TypeConstantExpression other) { |
642 return type == other.type; | 765 return type == other.type; |
643 } | 766 } |
644 } | 767 } |
645 | 768 |
646 /// Reference to a constant local, top-level, or static variable. | 769 /// Reference to a constant local, top-level, or static variable. |
647 class VariableConstantExpression extends ConstantExpression { | 770 class VariableConstantExpression extends ConstantExpression { |
648 final ConstantValue value; | 771 final ConstantValue value; |
649 final VariableElement element; | 772 final VariableElement element; |
650 | 773 |
651 VariableConstantExpression(this.value, this.element); | 774 VariableConstantExpression(this.value, this.element); |
652 | 775 |
653 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE; | 776 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE; |
654 | 777 |
655 accept(ConstantExpressionVisitor visitor, [context]) { | 778 accept(ConstantExpressionVisitor visitor, [context]) { |
656 return visitor.visitVariable(this, context); | 779 return visitor.visitVariable(this, context); |
657 } | 780 } |
658 | 781 |
659 @override | 782 @override |
| 783 ConstantValue evaluate(Environment environment, |
| 784 ConstantSystem constantSystem) { |
| 785 return element.constant.evaluate(environment, constantSystem); |
| 786 } |
| 787 |
| 788 @override |
660 int _computeHashCode() => 13 * element.hashCode; | 789 int _computeHashCode() => 13 * element.hashCode; |
661 | 790 |
662 @override | 791 @override |
663 bool _equals(VariableConstantExpression other) { | 792 bool _equals(VariableConstantExpression other) { |
664 return element == other.element; | 793 return element == other.element; |
665 } | 794 } |
666 } | 795 } |
667 | 796 |
668 /// Reference to a top-level or static function. | 797 /// Reference to a top-level or static function. |
669 class FunctionConstantExpression extends ConstantExpression { | 798 class FunctionConstantExpression extends ConstantExpression { |
670 final FunctionConstantValue value; | 799 final FunctionConstantValue value; |
671 final FunctionElement element; | 800 final FunctionElement element; |
672 | 801 |
673 FunctionConstantExpression(this.value, this.element); | 802 FunctionConstantExpression(this.value, this.element); |
674 | 803 |
675 ConstantExpressionKind get kind => ConstantExpressionKind.FUNCTION; | 804 ConstantExpressionKind get kind => ConstantExpressionKind.FUNCTION; |
676 | 805 |
677 accept(ConstantExpressionVisitor visitor, [context]) { | 806 accept(ConstantExpressionVisitor visitor, [context]) { |
678 return visitor.visitFunction(this, context); | 807 return visitor.visitFunction(this, context); |
679 } | 808 } |
680 | 809 |
681 @override | 810 @override |
| 811 ConstantValue evaluate(Environment environment, |
| 812 ConstantSystem constantSystem) { |
| 813 return new FunctionConstantValue(element); |
| 814 } |
| 815 |
| 816 @override |
682 int _computeHashCode() => 13 * element.hashCode; | 817 int _computeHashCode() => 13 * element.hashCode; |
683 | 818 |
684 @override | 819 @override |
685 bool _equals(FunctionConstantExpression other) { | 820 bool _equals(FunctionConstantExpression other) { |
686 return element == other.element; | 821 return element == other.element; |
687 } | 822 } |
688 } | 823 } |
689 | 824 |
690 /// A constant binary expression like `a * b`. | 825 /// A constant binary expression like `a * b`. |
691 class BinaryConstantExpression extends ConstantExpression { | 826 class BinaryConstantExpression extends ConstantExpression { |
692 final ConstantValue value; | 827 final ConstantValue value; |
693 final ConstantExpression left; | 828 final ConstantExpression left; |
694 final BinaryOperator operator; | 829 final BinaryOperator operator; |
695 final ConstantExpression right; | 830 final ConstantExpression right; |
696 | 831 |
697 BinaryConstantExpression(this.value, this.left, this.operator, this.right) { | 832 BinaryConstantExpression(this.value, this.left, this.operator, this.right) { |
698 assert(PRECEDENCE_MAP[operator.kind] != null); | 833 assert(PRECEDENCE_MAP[operator.kind] != null); |
699 } | 834 } |
700 | 835 |
701 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY; | 836 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY; |
702 | 837 |
703 accept(ConstantExpressionVisitor visitor, [context]) { | 838 accept(ConstantExpressionVisitor visitor, [context]) { |
704 return visitor.visitBinary(this, context); | 839 return visitor.visitBinary(this, context); |
705 } | 840 } |
706 | 841 |
| 842 @override |
| 843 ConstantValue evaluate(Environment environment, |
| 844 ConstantSystem constantSystem) { |
| 845 return constantSystem.lookupBinary(operator).fold( |
| 846 left.evaluate(environment, constantSystem), |
| 847 right.evaluate(environment, constantSystem)); |
| 848 } |
| 849 |
707 ConstantExpression apply(Arguments arguments) { | 850 ConstantExpression apply(Arguments arguments) { |
708 return new BinaryConstantExpression( | 851 return new BinaryConstantExpression( |
709 value, | 852 value, |
710 left.apply(arguments), | 853 left.apply(arguments), |
711 operator, | 854 operator, |
712 right.apply(arguments)); | 855 right.apply(arguments)); |
713 } | 856 } |
714 | 857 |
715 int get precedence => PRECEDENCE_MAP[operator.kind]; | 858 int get precedence => PRECEDENCE_MAP[operator.kind]; |
716 | 859 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
758 final ConstantExpression right; | 901 final ConstantExpression right; |
759 | 902 |
760 IdenticalConstantExpression(this.value, this.left, this.right); | 903 IdenticalConstantExpression(this.value, this.left, this.right); |
761 | 904 |
762 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL; | 905 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL; |
763 | 906 |
764 accept(ConstantExpressionVisitor visitor, [context]) { | 907 accept(ConstantExpressionVisitor visitor, [context]) { |
765 return visitor.visitIdentical(this, context); | 908 return visitor.visitIdentical(this, context); |
766 } | 909 } |
767 | 910 |
| 911 @override |
| 912 ConstantValue evaluate(Environment environment, |
| 913 ConstantSystem constantSystem) { |
| 914 return constantSystem.identity.fold( |
| 915 left.evaluate(environment, constantSystem), |
| 916 right.evaluate(environment, constantSystem)); |
| 917 } |
| 918 |
768 ConstantExpression apply(Arguments arguments) { | 919 ConstantExpression apply(Arguments arguments) { |
769 return new IdenticalConstantExpression( | 920 return new IdenticalConstantExpression( |
770 value, | 921 value, |
771 left.apply(arguments), | 922 left.apply(arguments), |
772 right.apply(arguments)); | 923 right.apply(arguments)); |
773 } | 924 } |
774 | 925 |
775 int get precedence => 15; | 926 int get precedence => 15; |
776 | 927 |
777 @override | 928 @override |
(...skipping 18 matching lines...) Expand all Loading... |
796 UnaryConstantExpression(this.value, this.operator, this.expression) { | 947 UnaryConstantExpression(this.value, this.operator, this.expression) { |
797 assert(PRECEDENCE_MAP[operator.kind] != null); | 948 assert(PRECEDENCE_MAP[operator.kind] != null); |
798 } | 949 } |
799 | 950 |
800 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY; | 951 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY; |
801 | 952 |
802 accept(ConstantExpressionVisitor visitor, [context]) { | 953 accept(ConstantExpressionVisitor visitor, [context]) { |
803 return visitor.visitUnary(this, context); | 954 return visitor.visitUnary(this, context); |
804 } | 955 } |
805 | 956 |
| 957 @override |
| 958 ConstantValue evaluate(Environment environment, |
| 959 ConstantSystem constantSystem) { |
| 960 return constantSystem.lookupUnary(operator).fold( |
| 961 expression.evaluate(environment, constantSystem)); |
| 962 } |
| 963 |
806 ConstantExpression apply(Arguments arguments) { | 964 ConstantExpression apply(Arguments arguments) { |
807 return new UnaryConstantExpression( | 965 return new UnaryConstantExpression( |
808 value, | 966 value, |
809 operator, | 967 operator, |
810 expression.apply(arguments)); | 968 expression.apply(arguments)); |
811 } | 969 } |
812 | 970 |
813 int get precedence => PRECEDENCE_MAP[operator.kind]; | 971 int get precedence => PRECEDENCE_MAP[operator.kind]; |
814 | 972 |
815 @override | 973 @override |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
865 17 * trueExp.hashCode + | 1023 17 * trueExp.hashCode + |
866 19 * falseExp.hashCode; | 1024 19 * falseExp.hashCode; |
867 } | 1025 } |
868 | 1026 |
869 @override | 1027 @override |
870 bool _equals(ConditionalConstantExpression other) { | 1028 bool _equals(ConditionalConstantExpression other) { |
871 return condition == other.condition && | 1029 return condition == other.condition && |
872 trueExp == other.trueExp && | 1030 trueExp == other.trueExp && |
873 falseExp == other.falseExp; | 1031 falseExp == other.falseExp; |
874 } | 1032 } |
| 1033 |
| 1034 @override |
| 1035 ConstantValue evaluate(Environment environment, |
| 1036 ConstantSystem constantSystem) { |
| 1037 ConstantValue conditionValue = |
| 1038 condition.evaluate(environment, constantSystem); |
| 1039 ConstantValue trueValue = |
| 1040 trueExp.evaluate(environment, constantSystem); |
| 1041 ConstantValue falseValue = |
| 1042 falseExp.evaluate(environment, constantSystem); |
| 1043 if (conditionValue.isTrue) { |
| 1044 return trueValue; |
| 1045 } else if (conditionValue.isFalse) { |
| 1046 return falseValue; |
| 1047 } else { |
| 1048 return new NonConstantValue(); |
| 1049 } |
| 1050 } |
875 } | 1051 } |
876 | 1052 |
877 /// A reference to a position parameter. | 1053 /// A reference to a position parameter. |
878 class PositionalArgumentReference extends ConstantExpression { | 1054 class PositionalArgumentReference extends ConstantExpression { |
879 final int index; | 1055 final int index; |
880 | 1056 |
881 PositionalArgumentReference(this.index); | 1057 PositionalArgumentReference(this.index); |
882 | 1058 |
883 ConstantExpressionKind get kind { | 1059 ConstantExpressionKind get kind { |
884 return ConstantExpressionKind.POSITIONAL_REFERENCE; | 1060 return ConstantExpressionKind.POSITIONAL_REFERENCE; |
885 } | 1061 } |
886 | 1062 |
887 accept(ConstantExpressionVisitor visitor, [context]) { | 1063 accept(ConstantExpressionVisitor visitor, [context]) { |
888 return visitor.visitPositional(this, context); | 1064 return visitor.visitPositional(this, context); |
889 } | 1065 } |
890 | 1066 |
891 ConstantValue get value { | 1067 ConstantValue get value { |
892 throw new UnsupportedError('PositionalArgumentReference.value'); | 1068 throw new UnsupportedError('PositionalArgumentReference.value'); |
893 } | 1069 } |
894 | 1070 |
895 ConstantExpression apply(Arguments arguments) { | 1071 ConstantExpression apply(Arguments arguments) { |
896 return arguments.getPositionalArgument(index); | 1072 return arguments.getPositionalArgument(index); |
897 } | 1073 } |
898 | 1074 |
899 @override | 1075 @override |
900 int _computeHashCode() => 13 * index.hashCode; | 1076 int _computeHashCode() => 13 * index.hashCode; |
901 | 1077 |
902 @override | 1078 @override |
903 bool _equals(PositionalArgumentReference other) => index == other.index; | 1079 bool _equals(PositionalArgumentReference other) => index == other.index; |
| 1080 |
| 1081 @override |
| 1082 ConstantValue evaluate(Environment environment, |
| 1083 ConstantSystem constantSystem) { |
| 1084 throw new UnsupportedError('PositionalArgumentReference.evaluate'); |
| 1085 } |
904 } | 1086 } |
905 | 1087 |
906 /// A reference to a named parameter. | 1088 /// A reference to a named parameter. |
907 class NamedArgumentReference extends ConstantExpression { | 1089 class NamedArgumentReference extends ConstantExpression { |
908 final String name; | 1090 final String name; |
909 | 1091 |
910 NamedArgumentReference(this.name); | 1092 NamedArgumentReference(this.name); |
911 | 1093 |
912 ConstantExpressionKind get kind { | 1094 ConstantExpressionKind get kind { |
913 return ConstantExpressionKind.NAMED_REFERENCE; | 1095 return ConstantExpressionKind.NAMED_REFERENCE; |
914 } | 1096 } |
915 | 1097 |
916 accept(ConstantExpressionVisitor visitor, [context]) { | 1098 accept(ConstantExpressionVisitor visitor, [context]) { |
917 return visitor.visitNamed(this, context); | 1099 return visitor.visitNamed(this, context); |
918 } | 1100 } |
919 | 1101 |
920 ConstantValue get value { | 1102 ConstantValue get value { |
921 throw new UnsupportedError('NamedArgumentReference.value'); | 1103 throw new UnsupportedError('NamedArgumentReference.value'); |
922 } | 1104 } |
923 | 1105 |
924 ConstantExpression apply(Arguments arguments) { | 1106 ConstantExpression apply(Arguments arguments) { |
925 return arguments.getNamedArgument(name); | 1107 return arguments.getNamedArgument(name); |
926 } | 1108 } |
927 | 1109 |
928 @override | 1110 @override |
929 int _computeHashCode() => 13 * name.hashCode; | 1111 int _computeHashCode() => 13 * name.hashCode; |
930 | 1112 |
931 @override | 1113 @override |
932 bool _equals(NamedArgumentReference other) => name == other.name; | 1114 bool _equals(NamedArgumentReference other) => name == other.name; |
| 1115 |
| 1116 @override |
| 1117 ConstantValue evaluate(Environment environment, |
| 1118 ConstantSystem constantSystem) { |
| 1119 throw new UnsupportedError('NamedArgumentReference.evaluate'); |
| 1120 } |
933 } | 1121 } |
934 | 1122 |
935 abstract class FromEnvironmentConstantExpression extends ConstantExpression { | 1123 abstract class FromEnvironmentConstantExpression extends ConstantExpression { |
936 final ConstantValue value; | 1124 final ConstantValue value; |
937 final String name; | 1125 final String name; |
938 final ConstantExpression defaultValue; | 1126 final ConstantExpression defaultValue; |
939 | 1127 |
940 FromEnvironmentConstantExpression(this.value, this.name, this.defaultValue); | 1128 FromEnvironmentConstantExpression(this.value, this.name, this.defaultValue); |
941 | 1129 |
942 @override | 1130 @override |
(...skipping 20 matching lines...) Expand all Loading... |
963 : super(value, name, defaultValue); | 1151 : super(value, name, defaultValue); |
964 | 1152 |
965 ConstantExpressionKind get kind { | 1153 ConstantExpressionKind get kind { |
966 return ConstantExpressionKind.BOOL_FROM_ENVIRONMENT; | 1154 return ConstantExpressionKind.BOOL_FROM_ENVIRONMENT; |
967 } | 1155 } |
968 | 1156 |
969 accept(ConstantExpressionVisitor visitor, [context]) { | 1157 accept(ConstantExpressionVisitor visitor, [context]) { |
970 return visitor.visitBoolFromEnvironment(this, context); | 1158 return visitor.visitBoolFromEnvironment(this, context); |
971 } | 1159 } |
972 | 1160 |
| 1161 @override |
| 1162 ConstantValue evaluate(Environment environment, |
| 1163 ConstantSystem constantSystem) { |
| 1164 String text = environment.readFromEnvironment(name); |
| 1165 if (text == 'true') { |
| 1166 return constantSystem.createBool(true); |
| 1167 } else if (text == 'false') { |
| 1168 return constantSystem.createBool(false); |
| 1169 } else { |
| 1170 return defaultValue.evaluate(environment, constantSystem); |
| 1171 } |
| 1172 } |
| 1173 |
973 ConstantExpression apply(Arguments arguments) { | 1174 ConstantExpression apply(Arguments arguments) { |
974 return new BoolFromEnvironmentConstantExpression( | 1175 return new BoolFromEnvironmentConstantExpression( |
975 null, name, defaultValue.apply(arguments)); | 1176 null, name, defaultValue.apply(arguments)); |
976 } | 1177 } |
977 } | 1178 } |
978 | 1179 |
979 /// A `const int.fromEnvironment` constant. | 1180 /// A `const int.fromEnvironment` constant. |
980 class IntFromEnvironmentConstantExpression | 1181 class IntFromEnvironmentConstantExpression |
981 extends FromEnvironmentConstantExpression { | 1182 extends FromEnvironmentConstantExpression { |
982 | 1183 |
983 IntFromEnvironmentConstantExpression( | 1184 IntFromEnvironmentConstantExpression( |
984 ConstantValue value, | 1185 ConstantValue value, |
985 String name, | 1186 String name, |
986 ConstantExpression defaultValue) | 1187 ConstantExpression defaultValue) |
987 : super(value, name, defaultValue); | 1188 : super(value, name, defaultValue); |
988 | 1189 |
989 ConstantExpressionKind get kind { | 1190 ConstantExpressionKind get kind { |
990 return ConstantExpressionKind.INT_FROM_ENVIRONMENT; | 1191 return ConstantExpressionKind.INT_FROM_ENVIRONMENT; |
991 } | 1192 } |
992 | 1193 |
993 accept(ConstantExpressionVisitor visitor, [context]) { | 1194 accept(ConstantExpressionVisitor visitor, [context]) { |
994 return visitor.visitIntFromEnvironment(this, context); | 1195 return visitor.visitIntFromEnvironment(this, context); |
995 } | 1196 } |
996 | 1197 |
| 1198 @override |
| 1199 ConstantValue evaluate(Environment environment, |
| 1200 ConstantSystem constantSystem) { |
| 1201 int value; |
| 1202 String text = environment.readFromEnvironment(name); |
| 1203 if (text != null) { |
| 1204 value = int.parse(text, onError: (_) => null); |
| 1205 } |
| 1206 if (value == null) { |
| 1207 return defaultValue.evaluate(environment, constantSystem); |
| 1208 } else { |
| 1209 return constantSystem.createInt(value); |
| 1210 } |
| 1211 } |
| 1212 |
997 ConstantExpression apply(Arguments arguments) { | 1213 ConstantExpression apply(Arguments arguments) { |
998 return new IntFromEnvironmentConstantExpression( | 1214 return new IntFromEnvironmentConstantExpression( |
999 null, name, defaultValue.apply(arguments)); | 1215 null, name, defaultValue.apply(arguments)); |
1000 } | 1216 } |
1001 } | 1217 } |
1002 | 1218 |
1003 /// A `const String.fromEnvironment` constant. | 1219 /// A `const String.fromEnvironment` constant. |
1004 class StringFromEnvironmentConstantExpression | 1220 class StringFromEnvironmentConstantExpression |
1005 extends FromEnvironmentConstantExpression { | 1221 extends FromEnvironmentConstantExpression { |
1006 | 1222 |
1007 StringFromEnvironmentConstantExpression( | 1223 StringFromEnvironmentConstantExpression( |
1008 ConstantValue value, | 1224 ConstantValue value, |
1009 String name, | 1225 String name, |
1010 ConstantExpression defaultValue) | 1226 ConstantExpression defaultValue) |
1011 : super(value, name, defaultValue); | 1227 : super(value, name, defaultValue); |
1012 | 1228 |
1013 ConstantExpressionKind get kind { | 1229 ConstantExpressionKind get kind { |
1014 return ConstantExpressionKind.STRING_FROM_ENVIRONMENT; | 1230 return ConstantExpressionKind.STRING_FROM_ENVIRONMENT; |
1015 } | 1231 } |
1016 | 1232 |
1017 accept(ConstantExpressionVisitor visitor, [context]) { | 1233 accept(ConstantExpressionVisitor visitor, [context]) { |
1018 return visitor.visitStringFromEnvironment(this, context); | 1234 return visitor.visitStringFromEnvironment(this, context); |
1019 } | 1235 } |
1020 | 1236 |
| 1237 @override |
| 1238 ConstantValue evaluate(Environment environment, |
| 1239 ConstantSystem constantSystem) { |
| 1240 String text = environment.readFromEnvironment(name); |
| 1241 if (text == null) { |
| 1242 return defaultValue.evaluate(environment, constantSystem); |
| 1243 } else { |
| 1244 return constantSystem.createString(new DartString.literal(text)); |
| 1245 } |
| 1246 } |
1021 | 1247 |
1022 ConstantExpression apply(Arguments arguments) { | 1248 ConstantExpression apply(Arguments arguments) { |
1023 return new StringFromEnvironmentConstantExpression( | 1249 return new StringFromEnvironmentConstantExpression( |
1024 null, name, defaultValue.apply(arguments)); | 1250 null, name, defaultValue.apply(arguments)); |
1025 } | 1251 } |
1026 } | 1252 } |
1027 | 1253 |
1028 abstract class ConstantExpressionVisitor<R, A> { | 1254 abstract class ConstantExpressionVisitor<R, A> { |
1029 const ConstantExpressionVisitor(); | 1255 const ConstantExpressionVisitor(); |
1030 | 1256 |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1293 sb.write(')'); | 1519 sb.write(')'); |
1294 } | 1520 } |
1295 | 1521 |
1296 @override | 1522 @override |
1297 visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, [_]) { | 1523 visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, [_]) { |
1298 sb.write('const String.fromEnvironment("${exp.name}", defaultValue: '); | 1524 sb.write('const String.fromEnvironment("${exp.name}", defaultValue: '); |
1299 visit(exp.defaultValue); | 1525 visit(exp.defaultValue); |
1300 sb.write(')'); | 1526 sb.write(')'); |
1301 } | 1527 } |
1302 } | 1528 } |
OLD | NEW |