Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: pkg/compiler/lib/src/constants/expressions.dart

Issue 1559233002: WIP: Compute constant expressions in resolution. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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';
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 int _hashCode; 66 int _hashCode;
67 67
68 ConstantExpressionKind get kind; 68 ConstantExpressionKind get kind;
69 69
70 // TODO(johnniwinther): Unify precedence handled between constants, front-end 70 // TODO(johnniwinther): Unify precedence handled between constants, front-end
71 // and back-end. 71 // and back-end.
72 int get precedence => 16; 72 int get precedence => 16;
73 73
74 accept(ConstantExpressionVisitor visitor, [context]); 74 accept(ConstantExpressionVisitor visitor, [context]);
75 75
76 /// `true` if this is an erroneous constant expression.
77 bool get isErroneous => false;
78
76 /// Substitute free variables using arguments. 79 /// Substitute free variables using arguments.
77 ConstantExpression apply(NormalizedArguments arguments) => this; 80 ConstantExpression apply(NormalizedArguments arguments) => this;
78 81
79 /// Compute the [ConstantValue] for this expression using the [environment] 82 /// Compute the [ConstantValue] for this expression using the [environment]
80 /// and the [constantSystem]. 83 /// and the [constantSystem].
81 ConstantValue evaluate(Environment environment, 84 ConstantValue evaluate(Environment environment,
82 ConstantSystem constantSystem); 85 ConstantSystem constantSystem);
83 86
84 /// Returns the type of this constant expression, if it is independent of the 87 /// Returns the type of this constant expression, if it is independent of the
85 /// environment values. 88 /// environment values.
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 ConstantSystem constantSystem) { 133 ConstantSystem constantSystem) {
131 // TODO(johnniwinther): Use non-constant values for errors. 134 // TODO(johnniwinther): Use non-constant values for errors.
132 return new NonConstantValue(); 135 return new NonConstantValue();
133 } 136 }
134 137
135 @override 138 @override
136 int _computeHashCode() => 13; 139 int _computeHashCode() => 13;
137 140
138 @override 141 @override
139 bool _equals(ErroneousConstantExpression other) => true; 142 bool _equals(ErroneousConstantExpression other) => true;
143
144 @override
145 bool get isErroneous => true;
140 } 146 }
141 147
142 // TODO(johnniwinther): Avoid the need for this class. 148 // TODO(johnniwinther): Avoid the need for this class.
143 class SyntheticConstantExpression extends ConstantExpression { 149 class SyntheticConstantExpression extends ConstantExpression {
144 final SyntheticConstantValue value; 150 final SyntheticConstantValue value;
145 151
146 SyntheticConstantExpression(this.value); 152 SyntheticConstantExpression(this.value);
147 153
148 @override 154 @override
149 ConstantValue evaluate(Environment environment, 155 ConstantValue evaluate(Environment environment,
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
380 386
381 ConstantExpressionKind get kind => ConstantExpressionKind.MAP; 387 ConstantExpressionKind get kind => ConstantExpressionKind.MAP;
382 388
383 accept(ConstantExpressionVisitor visitor, [context]) { 389 accept(ConstantExpressionVisitor visitor, [context]) {
384 return visitor.visitMap(this, context); 390 return visitor.visitMap(this, context);
385 } 391 }
386 392
387 @override 393 @override
388 ConstantValue evaluate(Environment environment, 394 ConstantValue evaluate(Environment environment,
389 ConstantSystem constantSystem) { 395 ConstantSystem constantSystem) {
390 return constantSystem.createMap(environment.compiler, 396 /*return constantSystem.createMap(environment.compiler,
391 type, 397 type,
392 keys.map((k) => k.evaluate(environment, constantSystem)).toList(), 398 keys.map((k) => k.evaluate(environment, constantSystem)).toList(),
393 values.map((v) => v.evaluate(environment, constantSystem)).toList()); 399 values.map((v) => v.evaluate(environment, constantSystem)).toList());*/
400 Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{};
401
402 for (int i = 0; i < keys.length; i++) {
403 ConstantValue key = keys[i].evaluate(environment, constantSystem);
404 if (!key.isConstant) {
405 return new NonConstantValue();
406 }
407 ConstantValue value = values[i].evaluate(environment, constantSystem);
408 if (!value.isConstant) {
409 return new NonConstantValue();
410 }
411 if (map.containsKey(key)) {
412 environment.reportWarning(keys[i], MessageKind.EQUAL_MAP_ENTRY_KEY, {});
413 }
414 map[key] = value;
415 }
416 return constantSystem.createMap(
417 environment.compiler, type, map.keys.toList(), map.values.toList());
394 } 418 }
395 419
396 ConstantExpression apply(NormalizedArguments arguments) { 420 ConstantExpression apply(NormalizedArguments arguments) {
397 return new MapConstantExpression( 421 return new MapConstantExpression(
398 type, 422 type,
399 keys.map((k) => k.apply(arguments)).toList(), 423 keys.map((k) => k.apply(arguments)).toList(),
400 values.map((v) => v.apply(arguments)).toList()); 424 values.map((v) => v.apply(arguments)).toList());
401 } 425 }
402 426
403 @override 427 @override
(...skipping 27 matching lines...) Expand all
431 final CallStructure callStructure; 455 final CallStructure callStructure;
432 final List<ConstantExpression> arguments; 456 final List<ConstantExpression> arguments;
433 457
434 ConstructedConstantExpression( 458 ConstructedConstantExpression(
435 this.type, 459 this.type,
436 this.target, 460 this.target,
437 this.callStructure, 461 this.callStructure,
438 this.arguments) { 462 this.arguments) {
439 assert(type.element == target.enclosingClass); 463 assert(type.element == target.enclosingClass);
440 assert(!arguments.contains(null)); 464 assert(!arguments.contains(null));
465 assert(invariant(NO_LOCATION_SPANNABLE, target.isConst,
466 message: "Referenced constructor $target is not constant."));
441 } 467 }
442 468
443 ConstantExpressionKind get kind => ConstantExpressionKind.CONSTRUCTED; 469 ConstantExpressionKind get kind => ConstantExpressionKind.CONSTRUCTED;
444 470
445 accept(ConstantExpressionVisitor visitor, [context]) { 471 accept(ConstantExpressionVisitor visitor, [context]) {
446 return visitor.visitConstructed(this, context); 472 return visitor.visitConstructed(this, context);
447 } 473 }
448 474
449 Map<FieldElement, ConstantExpression> computeInstanceFields() { 475 Map<FieldElement, ConstantExpression> computeInstanceFields() {
476 assert(invariant(target, target.constantConstructor != null,
477 message: "Constant constructor has not been computed for $target."));
450 return target.constantConstructor.computeInstanceFields( 478 return target.constantConstructor.computeInstanceFields(
451 arguments, callStructure); 479 arguments, callStructure);
452 } 480 }
453 481
454 InterfaceType computeInstanceType() { 482 InterfaceType computeInstanceType() {
455 return target.constantConstructor.computeInstanceType(type); 483 return target.constantConstructor.computeInstanceType(type);
456 } 484 }
457 485
458 ConstructedConstantExpression apply(NormalizedArguments arguments) { 486 ConstructedConstantExpression apply(NormalizedArguments arguments) {
459 return new ConstructedConstantExpression( 487 return new ConstructedConstantExpression(
460 type, target, callStructure, 488 type, target, callStructure,
461 this.arguments.map((a) => a.apply(arguments)).toList()); 489 this.arguments.map((a) => a.apply(arguments)).toList());
462 } 490 }
463 491
464 @override 492 @override
465 ConstantValue evaluate(Environment environment, 493 ConstantValue evaluate(Environment environment,
466 ConstantSystem constantSystem) { 494 ConstantSystem constantSystem) {
467 Map<FieldElement, ConstantValue> fieldValues = 495 return environment.evaluateConstructor(target, () {
468 <FieldElement, ConstantValue>{}; 496 Map<FieldElement, ConstantExpression> fieldMap =
469 computeInstanceFields().forEach( 497 computeInstanceFields();
470 (FieldElement field, ConstantExpression constant) { 498 if (fieldMap == null) {
471 fieldValues[field] = constant.evaluate(environment, constantSystem); 499 // An erroneous constant constructor was encountered in the super-chain.
500 return new NonConstantValue();
501 }
502 bool isValidAsConstant = true;
503 Map<FieldElement, ConstantValue> fieldValues =
504 <FieldElement, ConstantValue>{};
505 fieldMap.forEach((FieldElement field, ConstantExpression constant) {
506 ConstantValue value = constant.evaluate(environment, constantSystem);
507 assert(invariant(CURRENT_ELEMENT_SPANNABLE, value != null,
508 message: "No value computed for ${constant.getText()}."));
509 if (value.isConstant) {
510 fieldValues[field] = value;
511 } else {
512 isValidAsConstant = false;
513 }
514 });
515 if (isValidAsConstant) {
516 return new ConstructedConstantValue(computeInstanceType(), fieldValues);
517 } else {
518 return new NonConstantValue();
519 }
472 }); 520 });
473 return new ConstructedConstantValue(computeInstanceType(), fieldValues);
474 } 521 }
475 522
476 @override 523 @override
477 int _computeHashCode() { 524 int _computeHashCode() {
478 int hashCode = 525 int hashCode =
479 13 * type.hashCode + 526 13 * type.hashCode +
480 17 * target.hashCode + 527 17 * target.hashCode +
481 19 * callStructure.hashCode; 528 19 * callStructure.hashCode;
482 for (ConstantExpression value in arguments) { 529 for (ConstantExpression value in arguments) {
483 hashCode ^= 23 * value.hashCode; 530 hashCode ^= 23 * value.hashCode;
(...skipping 26 matching lines...) Expand all
510 } 557 }
511 558
512 ConstantExpression apply(NormalizedArguments arguments) { 559 ConstantExpression apply(NormalizedArguments arguments) {
513 return new ConcatenateConstantExpression( 560 return new ConcatenateConstantExpression(
514 expressions.map((a) => a.apply(arguments)).toList()); 561 expressions.map((a) => a.apply(arguments)).toList());
515 } 562 }
516 563
517 @override 564 @override
518 ConstantValue evaluate(Environment environment, 565 ConstantValue evaluate(Environment environment,
519 ConstantSystem constantSystem) { 566 ConstantSystem constantSystem) {
567 bool isValidAsConstant = true;
520 DartString accumulator; 568 DartString accumulator;
521 for (ConstantExpression expression in expressions) { 569 for (ConstantExpression expression in expressions) {
522 ConstantValue value = expression.evaluate(environment, constantSystem); 570 ConstantValue value = expression.evaluate(environment, constantSystem);
523 DartString valueString; 571 DartString valueString;
524 if (value.isNum || value.isBool) { 572 if (!value.isConstant) {
573 isValidAsConstant = false;
574 continue;
575 } else if (value.isNum || value.isBool) {
525 PrimitiveConstantValue primitive = value; 576 PrimitiveConstantValue primitive = value;
526 valueString = 577 valueString =
527 new DartString.literal(primitive.primitiveValue.toString()); 578 new DartString.literal(primitive.primitiveValue.toString());
528 } else if (value.isString) { 579 } else if (value.isString) {
529 PrimitiveConstantValue primitive = value; 580 PrimitiveConstantValue primitive = value;
530 valueString = primitive.primitiveValue; 581 valueString = primitive.primitiveValue;
531 } else { 582 } else {
532 // TODO(johnniwinther): Specialize message to indicated that the problem 583 // TODO(johnniwinther): Specialize message to indicated that the problem
533 // is not constness but the types of the const expressions. 584 // is not constness but the types of the const expressions.
534 return new NonConstantValue(); 585 environment.reportError(
586 expression,
587 MessageKind.INVALID_CONSTANT_INTERPOLATION_TYPE,
588 {'constant': expression,
589 'type': value.getType(environment.coreTypes)});
590 isValidAsConstant = false;
591 continue;
535 } 592 }
536 if (accumulator == null) { 593 if (accumulator == null) {
537 accumulator = valueString; 594 accumulator = valueString;
538 } else { 595 } else {
539 accumulator = new DartString.concat(accumulator, valueString); 596 accumulator = new DartString.concat(accumulator, valueString);
540 } 597 }
541 } 598 }
542 return constantSystem.createString(accumulator); 599 if (isValidAsConstant) {
600 return constantSystem.createString(accumulator);
601 }
602 return new NonConstantValue();
543 } 603 }
544 604
545 @override 605 @override
546 int _computeHashCode() { 606 int _computeHashCode() {
547 int hashCode = 17 * expressions.length; 607 int hashCode = 17 * expressions.length;
548 for (ConstantExpression value in expressions) { 608 for (ConstantExpression value in expressions) {
549 hashCode ^= 19 * value.hashCode; 609 hashCode ^= 19 * value.hashCode;
550 } 610 }
551 return hashCode; 611 return hashCode;
552 } 612 }
(...skipping 27 matching lines...) Expand all
580 int _computeHashCode() => 13 * name.hashCode; 640 int _computeHashCode() => 13 * name.hashCode;
581 641
582 @override 642 @override
583 bool _equals(SymbolConstantExpression other) { 643 bool _equals(SymbolConstantExpression other) {
584 return name == other.name; 644 return name == other.name;
585 } 645 }
586 646
587 @override 647 @override
588 ConstantValue evaluate(Environment environment, 648 ConstantValue evaluate(Environment environment,
589 ConstantSystem constantSystem) { 649 ConstantSystem constantSystem) {
590 // TODO(johnniwinther): Implement this. 650 return constantSystem.createSymbol(environment.compiler, name);
591 throw new UnsupportedError('SymbolConstantExpression.evaluate');
592 } 651 }
593 652
594 @override 653 @override
595 DartType getKnownType(CoreTypes coreTypes) => coreTypes.symbolType; 654 DartType getKnownType(CoreTypes coreTypes) => coreTypes.symbolType;
596 } 655 }
597 656
598 /// Type literal. 657 /// Type literal.
599 class TypeConstantExpression extends ConstantExpression { 658 class TypeConstantExpression extends ConstantExpression {
600 /// Either [DynamicType] or a raw [GenericType]. 659 /// Either [DynamicType] or a raw [GenericType].
601 final DartType type; 660 final DartType type;
(...skipping 23 matching lines...) Expand all
625 } 684 }
626 685
627 @override 686 @override
628 DartType getKnownType(CoreTypes coreTypes) => coreTypes.typeType; 687 DartType getKnownType(CoreTypes coreTypes) => coreTypes.typeType;
629 } 688 }
630 689
631 /// Reference to a constant local, top-level, or static variable. 690 /// Reference to a constant local, top-level, or static variable.
632 class VariableConstantExpression extends ConstantExpression { 691 class VariableConstantExpression extends ConstantExpression {
633 final VariableElement element; 692 final VariableElement element;
634 693
635 VariableConstantExpression(this.element); 694 VariableConstantExpression(this.element) {
695 /*assert(invariant(NO_LOCATION_SPANNABLE, element.isConst,
696 message: "Referenced variable $element is not constant."));*/
697 }
636 698
637 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE; 699 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE;
638 700
639 accept(ConstantExpressionVisitor visitor, [context]) { 701 accept(ConstantExpressionVisitor visitor, [context]) {
640 return visitor.visitVariable(this, context); 702 return visitor.visitVariable(this, context);
641 } 703 }
642 704
643 @override 705 @override
644 ConstantValue evaluate(Environment environment, 706 ConstantValue evaluate(Environment environment,
645 ConstantSystem constantSystem) { 707 ConstantSystem constantSystem) {
646 return element.constant.evaluate(environment, constantSystem); 708 return environment.evaluateVariable(element, () {
709 return element.constant.evaluate(environment, constantSystem);
710 });
647 } 711 }
648 712
649 @override 713 @override
650 int _computeHashCode() => 13 * element.hashCode; 714 int _computeHashCode() => 13 * element.hashCode;
651 715
652 @override 716 @override
653 bool _equals(VariableConstantExpression other) { 717 bool _equals(VariableConstantExpression other) {
654 return element == other.element; 718 return element == other.element;
655 } 719 }
656 } 720 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 761
698 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY; 762 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY;
699 763
700 accept(ConstantExpressionVisitor visitor, [context]) { 764 accept(ConstantExpressionVisitor visitor, [context]) {
701 return visitor.visitBinary(this, context); 765 return visitor.visitBinary(this, context);
702 } 766 }
703 767
704 @override 768 @override
705 ConstantValue evaluate(Environment environment, 769 ConstantValue evaluate(Environment environment,
706 ConstantSystem constantSystem) { 770 ConstantSystem constantSystem) {
707 return constantSystem.lookupBinary(operator).fold( 771 ConstantValue leftValue = left.evaluate(environment, constantSystem);
708 left.evaluate(environment, constantSystem), 772 ConstantValue rightValue = right.evaluate(environment, constantSystem);
709 right.evaluate(environment, constantSystem)); 773 if (!leftValue.isConstant ||
774 !rightValue.isConstant) {
775 return new NonConstantValue();
776 }
777 ConstantExpressionChecker checker =
778 new ConstantExpressionChecker(environment);
779 bool isValid = checker.checkBinaryExpression(
780 this,
781 checker.createInfo(left, leftValue),
782 operator,
783 checker.createInfo(right, rightValue));
784
785 BinaryOperation operation = constantSystem.lookupBinary(operator);
786 assert(invariant(NO_LOCATION_SPANNABLE, operation != null,
787 message: "No binary operation for $operator."));
788 ConstantValue value = operation.fold(leftValue, rightValue);
789 if (value != null) {
790 return value;
791 }
792 assert(!isValid);
793 return new NonConstantValue();
710 } 794 }
711 795
712 ConstantExpression apply(NormalizedArguments arguments) { 796 ConstantExpression apply(NormalizedArguments arguments) {
713 return new BinaryConstantExpression( 797 return new BinaryConstantExpression(
714 left.apply(arguments), 798 left.apply(arguments),
715 operator, 799 operator,
716 right.apply(arguments)); 800 right.apply(arguments));
717 } 801 }
718 802
719 DartType getKnownType(CoreTypes coreTypes) { 803 DartType getKnownType(CoreTypes coreTypes) {
720 DartType knownLeftType = left.getKnownType(coreTypes); 804 DartType knownLeftType = left.getKnownType(coreTypes);
721 DartType knownRightType = right.getKnownType(coreTypes); 805 DartType knownRightType = right.getKnownType(coreTypes);
722 switch (operator.kind) { 806 switch (operator.kind) {
723 case BinaryOperatorKind.EQ: 807 case BinaryOperatorKind.EQ:
724 case BinaryOperatorKind.NOT_EQ: 808 case BinaryOperatorKind.NOT_EQ:
725 case BinaryOperatorKind.LOGICAL_AND: 809 case BinaryOperatorKind.LOGICAL_AND:
726 case BinaryOperatorKind.LOGICAL_OR: 810 case BinaryOperatorKind.LOGICAL_OR:
727 case BinaryOperatorKind.GT: 811 case BinaryOperatorKind.GT:
728 case BinaryOperatorKind.LT: 812 case BinaryOperatorKind.LT:
729 case BinaryOperatorKind.GTEQ: 813 case BinaryOperatorKind.GTEQ:
730 case BinaryOperatorKind.LTEQ: 814 case BinaryOperatorKind.LTEQ:
731 return coreTypes.boolType; 815 return coreTypes.boolType;
732 case BinaryOperatorKind.ADD: 816 case BinaryOperatorKind.ADD:
733 if (knownLeftType == coreTypes.stringType) { 817 if (knownLeftType == coreTypes.stringType &&
734 assert(knownRightType == coreTypes.stringType); 818 knownRightType == coreTypes.stringType) {
735 return coreTypes.stringType; 819 return coreTypes.stringType;
736 } else if (knownLeftType == coreTypes.intType && 820 } else if (knownLeftType == coreTypes.intType &&
737 knownRightType == coreTypes.intType) { 821 knownRightType == coreTypes.intType) {
738 return coreTypes.intType; 822 return coreTypes.intType;
823 } else if ((knownLeftType == coreTypes.intType ||
824 knownLeftType == coreTypes.doubleType) &&
825 (knownRightType == coreTypes.intType ||
826 knownRightType == coreTypes.doubleType)) {
827 return coreTypes.doubleType;
739 } 828 }
740 assert(knownLeftType == coreTypes.doubleType || 829 return null;
741 knownRightType == coreTypes.doubleType);
742 return coreTypes.doubleType;
743 case BinaryOperatorKind.SUB: 830 case BinaryOperatorKind.SUB:
744 case BinaryOperatorKind.MUL: 831 case BinaryOperatorKind.MUL:
745 case BinaryOperatorKind.MOD: 832 case BinaryOperatorKind.MOD:
746 if (knownLeftType == coreTypes.intType && 833 if (knownLeftType == coreTypes.intType &&
747 knownRightType == coreTypes.intType) { 834 knownRightType == coreTypes.intType) {
748 return coreTypes.intType; 835 return coreTypes.intType;
836 } else if ((knownLeftType == coreTypes.intType ||
837 knownLeftType == coreTypes.doubleType) &&
838 (knownRightType == coreTypes.intType ||
839 knownRightType == coreTypes.doubleType)) {
840 return coreTypes.doubleType;
749 } 841 }
750 assert(knownLeftType == coreTypes.doubleType || 842 return null;
751 knownRightType == coreTypes.doubleType);
752 return coreTypes.doubleType;
753 case BinaryOperatorKind.DIV: 843 case BinaryOperatorKind.DIV:
754 return coreTypes.doubleType; 844 return coreTypes.doubleType;
755 case BinaryOperatorKind.IDIV: 845 case BinaryOperatorKind.IDIV:
756 return coreTypes.intType; 846 return coreTypes.intType;
757 case BinaryOperatorKind.AND: 847 case BinaryOperatorKind.AND:
758 case BinaryOperatorKind.OR: 848 case BinaryOperatorKind.OR:
759 case BinaryOperatorKind.XOR: 849 case BinaryOperatorKind.XOR:
760 case BinaryOperatorKind.SHR: 850 case BinaryOperatorKind.SHR:
761 case BinaryOperatorKind.SHL: 851 case BinaryOperatorKind.SHL:
762 return coreTypes.intType; 852 return coreTypes.intType;
763 case BinaryOperatorKind.IF_NULL: 853 case BinaryOperatorKind.IF_NULL:
764 case BinaryOperatorKind.INDEX: 854 case BinaryOperatorKind.INDEX:
765 throw new UnsupportedError( 855 throw new UnsupportedError(
766 'Unexpected constant binary operator: $operator'); 856 'Unexpected constant binary operator: $operator');
767 } 857 }
768 } 858 }
769 859
770
771 int get precedence => PRECEDENCE_MAP[operator.kind]; 860 int get precedence => PRECEDENCE_MAP[operator.kind];
772 861
773 @override 862 @override
774 int _computeHashCode() { 863 int _computeHashCode() {
775 return 13 * operator.hashCode + 864 return 13 * operator.hashCode +
776 17 * left.hashCode + 865 17 * left.hashCode +
777 19 * right.hashCode; 866 19 * right.hashCode;
778 } 867 }
779 868
780 @override 869 @override
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 905
817 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL; 906 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL;
818 907
819 accept(ConstantExpressionVisitor visitor, [context]) { 908 accept(ConstantExpressionVisitor visitor, [context]) {
820 return visitor.visitIdentical(this, context); 909 return visitor.visitIdentical(this, context);
821 } 910 }
822 911
823 @override 912 @override
824 ConstantValue evaluate(Environment environment, 913 ConstantValue evaluate(Environment environment,
825 ConstantSystem constantSystem) { 914 ConstantSystem constantSystem) {
826 return constantSystem.identity.fold( 915 ConstantValue leftValue = left.evaluate(environment, constantSystem);
827 left.evaluate(environment, constantSystem), 916 ConstantValue rightValue = right.evaluate(environment, constantSystem);
828 right.evaluate(environment, constantSystem)); 917 if (leftValue.isConstant && rightValue.isConstant) {
918 return constantSystem.identity.fold(leftValue, rightValue);
919 }
920 return new NonConstantValue();
829 } 921 }
830 922
831 ConstantExpression apply(NormalizedArguments arguments) { 923 ConstantExpression apply(NormalizedArguments arguments) {
832 return new IdenticalConstantExpression( 924 return new IdenticalConstantExpression(
833 left.apply(arguments), 925 left.apply(arguments),
834 right.apply(arguments)); 926 right.apply(arguments));
835 } 927 }
836 928
837 int get precedence => 15; 929 int get precedence => 15;
838 930
(...skipping 24 matching lines...) Expand all
863 955
864 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY; 956 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY;
865 957
866 accept(ConstantExpressionVisitor visitor, [context]) { 958 accept(ConstantExpressionVisitor visitor, [context]) {
867 return visitor.visitUnary(this, context); 959 return visitor.visitUnary(this, context);
868 } 960 }
869 961
870 @override 962 @override
871 ConstantValue evaluate(Environment environment, 963 ConstantValue evaluate(Environment environment,
872 ConstantSystem constantSystem) { 964 ConstantSystem constantSystem) {
873 return constantSystem.lookupUnary(operator).fold( 965 ConstantValue expressionValue =
874 expression.evaluate(environment, constantSystem)); 966 expression.evaluate(environment, constantSystem);
967 ConstantExpressionChecker checker =
968 new ConstantExpressionChecker(environment);
969 bool isValidAsConstant = checker.checkUnary(
970 operator, checker.createInfo(expression, expressionValue));
971 if (isValidAsConstant) {
972 return constantSystem.lookupUnary(operator).fold(expressionValue);
973 }
974 return new NonConstantValue();
875 } 975 }
876 976
877 ConstantExpression apply(NormalizedArguments arguments) { 977 ConstantExpression apply(NormalizedArguments arguments) {
878 return new UnaryConstantExpression( 978 return new UnaryConstantExpression(
879 operator, 979 operator,
880 expression.apply(arguments)); 980 expression.apply(arguments));
881 } 981 }
882 982
883 int get precedence => PRECEDENCE_MAP[operator.kind]; 983 int get precedence => PRECEDENCE_MAP[operator.kind];
884 984
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 1091
992 @override 1092 @override
993 ConstantValue evaluate(Environment environment, 1093 ConstantValue evaluate(Environment environment,
994 ConstantSystem constantSystem) { 1094 ConstantSystem constantSystem) {
995 ConstantValue conditionValue = 1095 ConstantValue conditionValue =
996 condition.evaluate(environment, constantSystem); 1096 condition.evaluate(environment, constantSystem);
997 ConstantValue trueValue = 1097 ConstantValue trueValue =
998 trueExp.evaluate(environment, constantSystem); 1098 trueExp.evaluate(environment, constantSystem);
999 ConstantValue falseValue = 1099 ConstantValue falseValue =
1000 falseExp.evaluate(environment, constantSystem); 1100 falseExp.evaluate(environment, constantSystem);
1001 if (conditionValue.isTrue) { 1101 ConstantExpressionChecker checker =
1102 new ConstantExpressionChecker(environment);
1103 bool isValidAsConstant = checker.checkConditional(
1104 checker.createInfo(condition, conditionValue));
1105 if (!isValidAsConstant) {
1106 return new NonConstantValue();
1107 } else if (conditionValue.isTrue) {
1002 return trueValue; 1108 return trueValue;
1003 } else if (conditionValue.isFalse) { 1109 } else {
1110 assert(conditionValue.isFalse);
1004 return falseValue; 1111 return falseValue;
1005 } else {
1006 return new NonConstantValue();
1007 } 1112 }
1008 } 1113 }
1009 1114
1010 @override 1115 @override
1011 DartType getKnownType(CoreTypes coreTypes) { 1116 DartType getKnownType(CoreTypes coreTypes) {
1012 DartType trueType = trueExp.getKnownType(coreTypes); 1117 DartType trueType = trueExp.getKnownType(coreTypes);
1013 DartType falseType = falseExp.getKnownType(coreTypes); 1118 DartType falseType = falseExp.getKnownType(coreTypes);
1014 if (trueType == falseType) { 1119 if (trueType == falseType) {
1015 return trueType; 1120 return trueType;
1016 } 1121 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 ConstantSystem constantSystem) { 1226 ConstantSystem constantSystem) {
1122 ConstantValue nameConstantValue = 1227 ConstantValue nameConstantValue =
1123 name.evaluate(environment, constantSystem); 1228 name.evaluate(environment, constantSystem);
1124 ConstantValue defaultConstantValue; 1229 ConstantValue defaultConstantValue;
1125 if (defaultValue != null) { 1230 if (defaultValue != null) {
1126 defaultConstantValue = 1231 defaultConstantValue =
1127 defaultValue.evaluate(environment, constantSystem); 1232 defaultValue.evaluate(environment, constantSystem);
1128 } else { 1233 } else {
1129 defaultConstantValue = constantSystem.createBool(false); 1234 defaultConstantValue = constantSystem.createBool(false);
1130 } 1235 }
1131 if (!nameConstantValue.isString) { 1236 ConstantExpressionChecker checker =
1237 new ConstantExpressionChecker(environment);
1238 bool isValidAsConstant = checker.checkBoolFromEnvironment(
1239 checker.createInfo(name, nameConstantValue),
1240 checker.createInfo(defaultValue, defaultConstantValue));
1241 if (!isValidAsConstant) {
1132 return new NonConstantValue(); 1242 return new NonConstantValue();
1133 } 1243 }
1134 StringConstantValue nameStringConstantValue = nameConstantValue; 1244 StringConstantValue nameStringConstantValue = nameConstantValue;
1135 String text = environment.readFromEnvironment( 1245 String text = environment.readFromEnvironment(
1136 nameStringConstantValue.primitiveValue.slowToString()); 1246 nameStringConstantValue.primitiveValue.slowToString());
1137 if (text == 'true') { 1247 if (text == 'true') {
1138 return constantSystem.createBool(true); 1248 return constantSystem.createBool(true);
1139 } else if (text == 'false') { 1249 } else if (text == 'false') {
1140 return constantSystem.createBool(false); 1250 return constantSystem.createBool(false);
1141 } else { 1251 } else {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 ConstantSystem constantSystem) { 1285 ConstantSystem constantSystem) {
1176 ConstantValue nameConstantValue = 1286 ConstantValue nameConstantValue =
1177 name.evaluate(environment, constantSystem); 1287 name.evaluate(environment, constantSystem);
1178 ConstantValue defaultConstantValue; 1288 ConstantValue defaultConstantValue;
1179 if (defaultValue != null) { 1289 if (defaultValue != null) {
1180 defaultConstantValue = 1290 defaultConstantValue =
1181 defaultValue.evaluate(environment, constantSystem); 1291 defaultValue.evaluate(environment, constantSystem);
1182 } else { 1292 } else {
1183 defaultConstantValue = constantSystem.createNull(); 1293 defaultConstantValue = constantSystem.createNull();
1184 } 1294 }
1185 if (!nameConstantValue.isString) { 1295 ConstantExpressionChecker checker =
1296 new ConstantExpressionChecker(environment);
1297 bool isValidAsConstant = checker.checkIntFromEnvironment(
1298 checker.createInfo(name, nameConstantValue),
1299 checker.createInfo(defaultValue, defaultConstantValue));
1300 if (!isValidAsConstant) {
1186 return new NonConstantValue(); 1301 return new NonConstantValue();
1187 } 1302 }
1188 StringConstantValue nameStringConstantValue = nameConstantValue; 1303 StringConstantValue nameStringConstantValue = nameConstantValue;
1189 String text = environment.readFromEnvironment( 1304 String text = environment.readFromEnvironment(
1190 nameStringConstantValue.primitiveValue.slowToString()); 1305 nameStringConstantValue.primitiveValue.slowToString());
1191 int value; 1306 int value;
1192 if (text != null) { 1307 if (text != null) {
1193 value = int.parse(text, onError: (_) => null); 1308 value = int.parse(text, onError: (_) => null);
1194 } 1309 }
1195 if (value == null) { 1310 if (value == null) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1231 ConstantSystem constantSystem) { 1346 ConstantSystem constantSystem) {
1232 ConstantValue nameConstantValue = 1347 ConstantValue nameConstantValue =
1233 name.evaluate(environment, constantSystem); 1348 name.evaluate(environment, constantSystem);
1234 ConstantValue defaultConstantValue; 1349 ConstantValue defaultConstantValue;
1235 if (defaultValue != null) { 1350 if (defaultValue != null) {
1236 defaultConstantValue = 1351 defaultConstantValue =
1237 defaultValue.evaluate(environment, constantSystem); 1352 defaultValue.evaluate(environment, constantSystem);
1238 } else { 1353 } else {
1239 defaultConstantValue = constantSystem.createNull(); 1354 defaultConstantValue = constantSystem.createNull();
1240 } 1355 }
1241 if (!nameConstantValue.isString) { 1356 ConstantExpressionChecker checker =
1357 new ConstantExpressionChecker(environment);
1358 bool isValidAsConstant = checker.checkStringFromEnvironment(
1359 checker.createInfo(name, nameConstantValue),
1360 checker.createInfo(defaultValue, defaultConstantValue));
1361 if (!isValidAsConstant) {
1242 return new NonConstantValue(); 1362 return new NonConstantValue();
1243 } 1363 }
1244 StringConstantValue nameStringConstantValue = nameConstantValue; 1364 StringConstantValue nameStringConstantValue = nameConstantValue;
1245 String text = environment.readFromEnvironment( 1365 String text = environment.readFromEnvironment(
1246 nameStringConstantValue.primitiveValue.slowToString()); 1366 nameStringConstantValue.primitiveValue.slowToString());
1247 if (text == null) { 1367 if (text == null) {
1248 return defaultConstantValue; 1368 return defaultConstantValue;
1249 } else { 1369 } else {
1250 return constantSystem.createString(new DartString.literal(text)); 1370 return constantSystem.createString(new DartString.literal(text));
1251 } 1371 }
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1598 sb.write('const String.fromEnvironment('); 1718 sb.write('const String.fromEnvironment(');
1599 visit(exp.name); 1719 visit(exp.name);
1600 if (exp.defaultValue != null) { 1720 if (exp.defaultValue != null) {
1601 sb.write(', defaultValue: '); 1721 sb.write(', defaultValue: ');
1602 visit(exp.defaultValue); 1722 visit(exp.defaultValue);
1603 } 1723 }
1604 sb.write(')'); 1724 sb.write(')');
1605 } 1725 }
1606 1726
1607 String toString() => sb.toString(); 1727 String toString() => sb.toString();
1608 } 1728 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/constants/evaluation.dart ('k') | pkg/compiler/lib/src/constants/values.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698