| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dart2js.compile_time_constant_evaluator; | 5 library dart2js.compile_time_constant_evaluator; |
| 6 | 6 |
| 7 import 'constant_system_dart.dart'; | 7 import 'constant_system_dart.dart'; |
| 8 import 'constants/constant_system.dart'; | 8 import 'constants/constant_system.dart'; |
| 9 import 'constants/expressions.dart'; | 9 import 'constants/expressions.dart'; |
| 10 import 'constants/values.dart'; | 10 import 'constants/values.dart'; |
| 11 import 'dart_types.dart'; | 11 import 'dart_types.dart'; |
| 12 import 'dart2jslib.dart' show Compiler, CompilerTask, MessageKind, invariant; | 12 import 'dart2jslib.dart' show Compiler, CompilerTask, MessageKind, invariant; |
| 13 import 'elements/elements.dart'; | 13 import 'elements/elements.dart'; |
| 14 import 'elements/modelx.dart' show FunctionElementX; | 14 import 'elements/modelx.dart' show FunctionElementX; |
| 15 import 'resolution/resolution.dart'; | 15 import 'resolution/resolution.dart'; |
| 16 import 'resolution/operators.dart'; |
| 16 import 'tree/tree.dart'; | 17 import 'tree/tree.dart'; |
| 17 import 'util/util.dart' show Link; | 18 import 'util/util.dart' show Link; |
| 18 import 'universe/universe.dart' show CallStructure; | 19 import 'universe/universe.dart' show CallStructure; |
| 19 | 20 |
| 20 /// A [ConstantEnvironment] provides access for constants compiled for variable | 21 /// A [ConstantEnvironment] provides access for constants compiled for variable |
| 21 /// initializers. | 22 /// initializers. |
| 22 abstract class ConstantEnvironment { | 23 abstract class ConstantEnvironment { |
| 23 /// Returns the constant for the initializer of [element]. | 24 /// Returns the constant for the initializer of [element]. |
| 24 ConstantExpression getConstantForVariable(VariableElement element); | 25 ConstantExpression getConstantForVariable(VariableElement element); |
| 25 } | 26 } |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 && send.argumentCount() == 2) { | 549 && send.argumentCount() == 2) { |
| 549 AstConstant left = evaluate(send.argumentsNode.nodes.head); | 550 AstConstant left = evaluate(send.argumentsNode.nodes.head); |
| 550 AstConstant right = evaluate(send.argumentsNode.nodes.tail.head); | 551 AstConstant right = evaluate(send.argumentsNode.nodes.tail.head); |
| 551 if (left == null || right == null) { | 552 if (left == null || right == null) { |
| 552 return null; | 553 return null; |
| 553 } | 554 } |
| 554 ConstantValue result = | 555 ConstantValue result = |
| 555 constantSystem.identity.fold(left.value, right.value); | 556 constantSystem.identity.fold(left.value, right.value); |
| 556 if (result != null) { | 557 if (result != null) { |
| 557 return new AstConstant( | 558 return new AstConstant( |
| 558 context, send, new BinaryConstantExpression(result, | 559 context, send, new IdenticalConstantExpression(result, |
| 559 left.expression, 'identical', right.expression)); | 560 left.expression, right.expression)); |
| 560 } | 561 } |
| 561 } | 562 } |
| 562 return signalNotCompileTimeConstant(send); | 563 return signalNotCompileTimeConstant(send); |
| 563 } else if (send.isPrefix) { | 564 } else if (send.isPrefix) { |
| 564 assert(send.isOperator); | 565 assert(send.isOperator); |
| 565 AstConstant receiverConstant = evaluate(send.receiver); | 566 AstConstant receiverConstant = evaluate(send.receiver); |
| 566 if (receiverConstant == null) { | 567 if (receiverConstant == null) { |
| 567 return null; | 568 return null; |
| 568 } | 569 } |
| 569 Operator op = send.selector; | 570 Operator node = send.selector; |
| 570 UnaryOperation operation = constantSystem.lookupUnary(op.source); | 571 UnaryOperator operator = UnaryOperator.parse(node.source); |
| 572 UnaryOperation operation = constantSystem.lookupUnary(operator); |
| 571 if (operation == null) { | 573 if (operation == null) { |
| 572 compiler.internalError(op, "Unexpected operator."); | 574 compiler.internalError(send.selector, "Unexpected operator."); |
| 573 } | 575 } |
| 574 ConstantValue folded = operation.fold(receiverConstant.value); | 576 ConstantValue folded = operation.fold(receiverConstant.value); |
| 575 if (folded == null) { | 577 if (folded == null) { |
| 576 return signalNotCompileTimeConstant(send); | 578 return signalNotCompileTimeConstant(send); |
| 577 } | 579 } |
| 578 return new AstConstant( | 580 return new AstConstant( |
| 579 context, send, new UnaryConstantExpression(folded, | 581 context, send, new UnaryConstantExpression(folded, |
| 580 op.source, receiverConstant.expression)); | 582 operator, receiverConstant.expression)); |
| 581 } else if (send.isOperator && !send.isPostfix) { | 583 } else if (send.isOperator && !send.isPostfix) { |
| 582 assert(send.argumentCount() == 1); | 584 assert(send.argumentCount() == 1); |
| 583 AstConstant left = evaluate(send.receiver); | 585 AstConstant left = evaluate(send.receiver); |
| 584 AstConstant right = evaluate(send.argumentsNode.nodes.head); | 586 AstConstant right = evaluate(send.argumentsNode.nodes.head); |
| 585 if (left == null || right == null) { | 587 if (left == null || right == null) { |
| 586 return null; | 588 return null; |
| 587 } | 589 } |
| 588 ConstantValue leftValue = left.value; | 590 ConstantValue leftValue = left.value; |
| 589 ConstantValue rightValue = right.value; | 591 ConstantValue rightValue = right.value; |
| 590 Operator op = send.selector.asOperator(); | 592 Operator node = send.selector.asOperator(); |
| 593 BinaryOperator operator = BinaryOperator.parse(node.source); |
| 591 ConstantValue folded = null; | 594 ConstantValue folded = null; |
| 592 switch (op.source) { | 595 switch (operator.kind) { |
| 593 case "==": | 596 case BinaryOperatorKind.EQ: |
| 594 if (leftValue.isPrimitive && rightValue.isPrimitive) { | 597 if (leftValue.isPrimitive && rightValue.isPrimitive) { |
| 595 folded = constantSystem.equal.fold(leftValue, rightValue); | 598 folded = constantSystem.equal.fold(leftValue, rightValue); |
| 596 } | 599 } |
| 597 break; | 600 break; |
| 598 case "!=": | 601 case BinaryOperatorKind.NOT_EQ: |
| 599 if (leftValue.isPrimitive && rightValue.isPrimitive) { | 602 if (leftValue.isPrimitive && rightValue.isPrimitive) { |
| 600 BoolConstantValue areEquals = | 603 BoolConstantValue areEquals = |
| 601 constantSystem.equal.fold(leftValue, rightValue); | 604 constantSystem.equal.fold(leftValue, rightValue); |
| 602 if (areEquals == null) { | 605 if (areEquals == null) { |
| 603 folded = null; | 606 folded = null; |
| 604 } else { | 607 } else { |
| 605 folded = areEquals.negate(); | 608 folded = areEquals.negate(); |
| 606 } | 609 } |
| 607 } | 610 } |
| 608 break; | 611 break; |
| 609 default: | 612 default: |
| 610 BinaryOperation operation = constantSystem.lookupBinary(op.source); | 613 BinaryOperation operation = constantSystem.lookupBinary(operator); |
| 611 if (operation != null) { | 614 if (operation != null) { |
| 612 folded = operation.fold(leftValue, rightValue); | 615 folded = operation.fold(leftValue, rightValue); |
| 613 } | 616 } |
| 614 } | 617 } |
| 615 if (folded == null) { | 618 if (folded == null) { |
| 616 return signalNotCompileTimeConstant(send); | 619 return signalNotCompileTimeConstant(send); |
| 617 } | 620 } |
| 618 return new AstConstant( | 621 return new AstConstant( |
| 619 context, send, new BinaryConstantExpression(folded, | 622 context, send, new BinaryConstantExpression(folded, |
| 620 left.expression, op.source, right.expression)); | 623 left.expression, operator, right.expression)); |
| 621 } | 624 } |
| 622 return signalNotCompileTimeConstant(send); | 625 return signalNotCompileTimeConstant(send); |
| 623 } | 626 } |
| 624 | 627 |
| 625 AstConstant visitConditional(Conditional node) { | 628 AstConstant visitConditional(Conditional node) { |
| 626 AstConstant condition = evaluate(node.condition); | 629 AstConstant condition = evaluate(node.condition); |
| 627 if (condition == null) { | 630 if (condition == null) { |
| 628 return null; | 631 return null; |
| 629 } else if (!condition.value.isBool) { | 632 } else if (!condition.value.isBool) { |
| 630 DartType conditionType = condition.value.getType(compiler.coreTypes); | 633 DartType conditionType = condition.value.getType(compiler.coreTypes); |
| (...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1132 ConstantValue get value => expression.value; | 1135 ConstantValue get value => expression.value; |
| 1133 | 1136 |
| 1134 String toString() => expression.toString(); | 1137 String toString() => expression.toString(); |
| 1135 } | 1138 } |
| 1136 | 1139 |
| 1137 /// A synthetic constant used to recover from errors. | 1140 /// A synthetic constant used to recover from errors. |
| 1138 class ErroneousAstConstant extends AstConstant { | 1141 class ErroneousAstConstant extends AstConstant { |
| 1139 ErroneousAstConstant(Element element, Node node) | 1142 ErroneousAstConstant(Element element, Node node) |
| 1140 : super(element, node, new ErroneousConstantExpression()); | 1143 : super(element, node, new ErroneousConstantExpression()); |
| 1141 } | 1144 } |
| OLD | NEW |