| 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 'common.dart'; | 7 import 'common.dart'; |
| 8 import 'common/resolution.dart' show Resolution; | 8 import 'common/resolution.dart' show Resolution; |
| 9 import 'common/tasks.dart' show CompilerTask, Measurer; | 9 import 'common/tasks.dart' show CompilerTask, Measurer; |
| 10 import 'compiler.dart' show Compiler; | 10 import 'compiler.dart' show Compiler; |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 : this.isEvaluatingConstant = isConst; | 407 : this.isEvaluatingConstant = isConst; |
| 408 | 408 |
| 409 ConstantSystem get constantSystem => handler.constantSystem; | 409 ConstantSystem get constantSystem => handler.constantSystem; |
| 410 Resolution get resolution => compiler.resolution; | 410 Resolution get resolution => compiler.resolution; |
| 411 CoreTypes get coreTypes => compiler.coreTypes; | 411 CoreTypes get coreTypes => compiler.coreTypes; |
| 412 DiagnosticReporter get reporter => compiler.reporter; | 412 DiagnosticReporter get reporter => compiler.reporter; |
| 413 | 413 |
| 414 AstConstant evaluate(Node node) { | 414 AstConstant evaluate(Node node) { |
| 415 // TODO(johnniwinther): should there be a visitErrorNode? | 415 // TODO(johnniwinther): should there be a visitErrorNode? |
| 416 if (node is ErrorNode) return new ErroneousAstConstant(context, node); | 416 if (node is ErrorNode) return new ErroneousAstConstant(context, node); |
| 417 AstConstant result = node.accept(this); | 417 return node.accept(this); |
| 418 assert(invariant(node, !isEvaluatingConstant || result != null, | |
| 419 message: "No AstConstant computed for the node.")); | |
| 420 return result; | |
| 421 } | 418 } |
| 422 | 419 |
| 423 AstConstant evaluateConstant(Node node) { | 420 AstConstant evaluateConstant(Node node) { |
| 424 bool oldIsEvaluatingConstant = isEvaluatingConstant; | 421 bool oldIsEvaluatingConstant = isEvaluatingConstant; |
| 425 isEvaluatingConstant = true; | 422 isEvaluatingConstant = true; |
| 426 AstConstant result = node.accept(this); | 423 AstConstant result = node.accept(this); |
| 427 isEvaluatingConstant = oldIsEvaluatingConstant; | 424 isEvaluatingConstant = oldIsEvaluatingConstant; |
| 428 assert(invariant(node, result != null, | 425 assert(result != null); |
| 429 message: "No AstConstant computed for the node.")); | |
| 430 return result; | 426 return result; |
| 431 } | 427 } |
| 432 | 428 |
| 433 AstConstant visitNode(Node node) { | 429 AstConstant visitNode(Node node) { |
| 434 return signalNotCompileTimeConstant(node); | 430 return signalNotCompileTimeConstant(node); |
| 435 } | 431 } |
| 436 | 432 |
| 437 AstConstant visitLiteralBool(LiteralBool node) { | 433 AstConstant visitLiteralBool(LiteralBool node) { |
| 438 return new AstConstant( | 434 return new AstConstant( |
| 439 context, | 435 context, |
| (...skipping 18 matching lines...) Expand all Loading... |
| 458 AstConstant visitLiteralList(LiteralList node) { | 454 AstConstant visitLiteralList(LiteralList node) { |
| 459 if (!node.isConst) { | 455 if (!node.isConst) { |
| 460 return signalNotCompileTimeConstant(node); | 456 return signalNotCompileTimeConstant(node); |
| 461 } | 457 } |
| 462 List<ConstantExpression> argumentExpressions = <ConstantExpression>[]; | 458 List<ConstantExpression> argumentExpressions = <ConstantExpression>[]; |
| 463 List<ConstantValue> argumentValues = <ConstantValue>[]; | 459 List<ConstantValue> argumentValues = <ConstantValue>[]; |
| 464 for (Link<Node> link = node.elements.nodes; | 460 for (Link<Node> link = node.elements.nodes; |
| 465 !link.isEmpty; | 461 !link.isEmpty; |
| 466 link = link.tail) { | 462 link = link.tail) { |
| 467 AstConstant argument = evaluateConstant(link.head); | 463 AstConstant argument = evaluateConstant(link.head); |
| 468 if (argument == null || argument.isError) { | 464 if (argument == null) { |
| 469 return argument; | 465 return null; |
| 470 } | 466 } |
| 471 argumentExpressions.add(argument.expression); | 467 argumentExpressions.add(argument.expression); |
| 472 argumentValues.add(argument.value); | 468 argumentValues.add(argument.value); |
| 473 } | 469 } |
| 474 DartType type = elements.getType(node); | 470 DartType type = elements.getType(node); |
| 475 return new AstConstant( | 471 return new AstConstant( |
| 476 context, | 472 context, |
| 477 node, | 473 node, |
| 478 new ListConstantExpression(type, argumentExpressions), | 474 new ListConstantExpression(type, argumentExpressions), |
| 479 constantSystem.createList(type, argumentValues)); | 475 constantSystem.createList(type, argumentValues)); |
| 480 } | 476 } |
| 481 | 477 |
| 482 AstConstant visitLiteralMap(LiteralMap node) { | 478 AstConstant visitLiteralMap(LiteralMap node) { |
| 483 if (!node.isConst) { | 479 if (!node.isConst) { |
| 484 return signalNotCompileTimeConstant(node); | 480 return signalNotCompileTimeConstant(node); |
| 485 } | 481 } |
| 486 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; | 482 List<ConstantExpression> keyExpressions = <ConstantExpression>[]; |
| 487 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; | 483 List<ConstantExpression> valueExpressions = <ConstantExpression>[]; |
| 488 List<ConstantValue> keyValues = <ConstantValue>[]; | 484 List<ConstantValue> keyValues = <ConstantValue>[]; |
| 489 Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{}; | 485 Map<ConstantValue, ConstantValue> map = <ConstantValue, ConstantValue>{}; |
| 490 for (Link<Node> link = node.entries.nodes; | 486 for (Link<Node> link = node.entries.nodes; |
| 491 !link.isEmpty; | 487 !link.isEmpty; |
| 492 link = link.tail) { | 488 link = link.tail) { |
| 493 LiteralMapEntry entry = link.head; | 489 LiteralMapEntry entry = link.head; |
| 494 AstConstant key = evaluateConstant(entry.key); | 490 AstConstant key = evaluateConstant(entry.key); |
| 495 if (key == null || key.isError) { | 491 if (key == null) { |
| 496 return key; | 492 return null; |
| 497 } | 493 } |
| 498 AstConstant value = evaluateConstant(entry.value); | 494 AstConstant value = evaluateConstant(entry.value); |
| 499 if (value == null || value.isError) { | 495 if (value == null) { |
| 500 return value; | 496 return null; |
| 501 } | 497 } |
| 502 if (!map.containsKey(key.value)) { | 498 if (!map.containsKey(key.value)) { |
| 503 keyValues.add(key.value); | 499 keyValues.add(key.value); |
| 504 } else { | 500 } else { |
| 505 reporter.reportWarningMessage( | 501 reporter.reportWarningMessage( |
| 506 entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); | 502 entry.key, MessageKind.EQUAL_MAP_ENTRY_KEY); |
| 507 } | 503 } |
| 508 keyExpressions.add(key.expression); | 504 keyExpressions.add(key.expression); |
| 509 valueExpressions.add(value.expression); | 505 valueExpressions.add(value.expression); |
| 510 map[key.value] = value.value; | 506 map[key.value] = value.value; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 527 return new AstConstant( | 523 return new AstConstant( |
| 528 context, | 524 context, |
| 529 node, | 525 node, |
| 530 new StringConstantExpression(node.dartString.slowToString()), | 526 new StringConstantExpression(node.dartString.slowToString()), |
| 531 constantSystem.createString(node.dartString)); | 527 constantSystem.createString(node.dartString)); |
| 532 } | 528 } |
| 533 | 529 |
| 534 AstConstant visitStringJuxtaposition(StringJuxtaposition node) { | 530 AstConstant visitStringJuxtaposition(StringJuxtaposition node) { |
| 535 AstConstant left = evaluate(node.first); | 531 AstConstant left = evaluate(node.first); |
| 536 AstConstant right = evaluate(node.second); | 532 AstConstant right = evaluate(node.second); |
| 537 if (left == null || left.isError) { | 533 if (left == null || right == null) return null; |
| 538 return left; | |
| 539 } | |
| 540 if (right == null || right.isError) { | |
| 541 return right; | |
| 542 } | |
| 543 StringConstantValue leftValue = left.value; | 534 StringConstantValue leftValue = left.value; |
| 544 StringConstantValue rightValue = right.value; | 535 StringConstantValue rightValue = right.value; |
| 545 return new AstConstant( | 536 return new AstConstant( |
| 546 context, | 537 context, |
| 547 node, | 538 node, |
| 548 new ConcatenateConstantExpression([left.expression, right.expression]), | 539 new ConcatenateConstantExpression([left.expression, right.expression]), |
| 549 constantSystem.createString(new DartString.concat( | 540 constantSystem.createString(new DartString.concat( |
| 550 leftValue.primitiveValue, rightValue.primitiveValue))); | 541 leftValue.primitiveValue, rightValue.primitiveValue))); |
| 551 } | 542 } |
| 552 | 543 |
| 553 AstConstant visitStringInterpolation(StringInterpolation node) { | 544 AstConstant visitStringInterpolation(StringInterpolation node) { |
| 554 List<ConstantExpression> subexpressions = <ConstantExpression>[]; | 545 List<ConstantExpression> subexpressions = <ConstantExpression>[]; |
| 555 AstConstant initialString = evaluate(node.string); | 546 AstConstant initialString = evaluate(node.string); |
| 556 if (initialString == null || initialString.isError) { | 547 if (initialString == null) { |
| 557 return initialString; | 548 return null; |
| 558 } | 549 } |
| 559 subexpressions.add(initialString.expression); | 550 subexpressions.add(initialString.expression); |
| 560 StringConstantValue initialStringValue = initialString.value; | 551 StringConstantValue initialStringValue = initialString.value; |
| 561 DartString accumulator = initialStringValue.primitiveValue; | 552 DartString accumulator = initialStringValue.primitiveValue; |
| 562 for (StringInterpolationPart part in node.parts) { | 553 for (StringInterpolationPart part in node.parts) { |
| 563 AstConstant subexpression = evaluate(part.expression); | 554 AstConstant subexpression = evaluate(part.expression); |
| 564 if (subexpression == null || subexpression.isError) { | 555 if (subexpression == null) { |
| 565 return subexpression; | 556 return null; |
| 566 } | 557 } |
| 567 subexpressions.add(subexpression.expression); | 558 subexpressions.add(subexpression.expression); |
| 568 ConstantValue expression = subexpression.value; | 559 ConstantValue expression = subexpression.value; |
| 569 DartString expressionString; | 560 DartString expressionString; |
| 570 if (expression.isNum || expression.isBool || expression.isNull) { | 561 if (expression.isNum || expression.isBool || expression.isNull) { |
| 571 PrimitiveConstantValue primitive = expression; | 562 PrimitiveConstantValue primitive = expression; |
| 572 expressionString = | 563 expressionString = |
| 573 new DartString.literal(primitive.primitiveValue.toString()); | 564 new DartString.literal(primitive.primitiveValue.toString()); |
| 574 } else if (expression.isString) { | 565 } else if (expression.isString) { |
| 575 PrimitiveConstantValue primitive = expression; | 566 PrimitiveConstantValue primitive = expression; |
| 576 expressionString = primitive.primitiveValue; | 567 expressionString = primitive.primitiveValue; |
| 577 } else { | 568 } else { |
| 578 // TODO(johnniwinther): Specialize message to indicated that the problem | 569 // TODO(johnniwinther): Specialize message to indicated that the problem |
| 579 // is not constness but the types of the const expressions. | 570 // is not constness but the types of the const expressions. |
| 580 return signalNotCompileTimeConstant(part.expression); | 571 return signalNotCompileTimeConstant(part.expression); |
| 581 } | 572 } |
| 582 accumulator = new DartString.concat(accumulator, expressionString); | 573 accumulator = new DartString.concat(accumulator, expressionString); |
| 583 AstConstant partString = evaluate(part.string); | 574 AstConstant partString = evaluate(part.string); |
| 584 if (partString == null) return null; | 575 if (partString == null) return null; |
| 585 subexpressions.add(partString.expression); | 576 subexpressions.add(partString.expression); |
| 586 StringConstantValue partStringValue = partString.value; | 577 StringConstantValue partStringValue = partString.value; |
| 587 accumulator = | 578 accumulator = |
| 588 new DartString.concat(accumulator, partStringValue.primitiveValue); | 579 new DartString.concat(accumulator, partStringValue.primitiveValue); |
| 589 } | 580 } |
| 581 ; |
| 590 return new AstConstant( | 582 return new AstConstant( |
| 591 context, | 583 context, |
| 592 node, | 584 node, |
| 593 new ConcatenateConstantExpression(subexpressions), | 585 new ConcatenateConstantExpression(subexpressions), |
| 594 constantSystem.createString(accumulator)); | 586 constantSystem.createString(accumulator)); |
| 595 } | 587 } |
| 596 | 588 |
| 597 AstConstant visitLiteralSymbol(LiteralSymbol node) { | 589 AstConstant visitLiteralSymbol(LiteralSymbol node) { |
| 598 InterfaceType type = coreTypes.symbolType; | 590 InterfaceType type = coreTypes.symbolType; |
| 599 String text = node.slowNameString; | 591 String text = node.slowNameString; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 send, | 718 send, |
| 727 new IdenticalConstantExpression( | 719 new IdenticalConstantExpression( |
| 728 left.expression, right.expression), | 720 left.expression, right.expression), |
| 729 result); | 721 result); |
| 730 } | 722 } |
| 731 } | 723 } |
| 732 return signalNotCompileTimeConstant(send); | 724 return signalNotCompileTimeConstant(send); |
| 733 } else if (send.isPrefix) { | 725 } else if (send.isPrefix) { |
| 734 assert(send.isOperator); | 726 assert(send.isOperator); |
| 735 AstConstant receiverConstant = evaluate(send.receiver); | 727 AstConstant receiverConstant = evaluate(send.receiver); |
| 736 if (receiverConstant == null || receiverConstant.isError) { | 728 if (receiverConstant == null) { |
| 737 return receiverConstant; | 729 return null; |
| 738 } | 730 } |
| 739 Operator node = send.selector; | 731 Operator node = send.selector; |
| 740 UnaryOperator operator = UnaryOperator.parse(node.source); | 732 UnaryOperator operator = UnaryOperator.parse(node.source); |
| 741 UnaryOperation operation = constantSystem.lookupUnary(operator); | 733 UnaryOperation operation = constantSystem.lookupUnary(operator); |
| 742 if (operation == null) { | 734 if (operation == null) { |
| 743 reporter.internalError(send.selector, "Unexpected operator."); | 735 reporter.internalError(send.selector, "Unexpected operator."); |
| 744 } | 736 } |
| 745 ConstantValue folded = operation.fold(receiverConstant.value); | 737 ConstantValue folded = operation.fold(receiverConstant.value); |
| 746 if (folded == null) { | 738 if (folded == null) { |
| 747 return signalNotCompileTimeConstant(send); | 739 return signalNotCompileTimeConstant(send); |
| 748 } | 740 } |
| 749 return new AstConstant( | 741 return new AstConstant( |
| 750 context, | 742 context, |
| 751 send, | 743 send, |
| 752 new UnaryConstantExpression(operator, receiverConstant.expression), | 744 new UnaryConstantExpression(operator, receiverConstant.expression), |
| 753 folded); | 745 folded); |
| 754 } else if (send.isOperator && !send.isPostfix) { | 746 } else if (send.isOperator && !send.isPostfix) { |
| 755 assert(send.argumentCount() == 1); | 747 assert(send.argumentCount() == 1); |
| 756 AstConstant left = evaluate(send.receiver); | 748 AstConstant left = evaluate(send.receiver); |
| 757 AstConstant right = evaluate(send.argumentsNode.nodes.head); | 749 AstConstant right = evaluate(send.argumentsNode.nodes.head); |
| 758 if (left == null || left.isError) { | 750 if (left == null || right == null) { |
| 759 return left; | 751 return null; |
| 760 } | |
| 761 if (right == null || right.isError) { | |
| 762 return right; | |
| 763 } | 752 } |
| 764 ConstantValue leftValue = left.value; | 753 ConstantValue leftValue = left.value; |
| 765 ConstantValue rightValue = right.value; | 754 ConstantValue rightValue = right.value; |
| 766 Operator node = send.selector.asOperator(); | 755 Operator node = send.selector.asOperator(); |
| 767 BinaryOperator operator = BinaryOperator.parse(node.source); | 756 BinaryOperator operator = BinaryOperator.parse(node.source); |
| 768 ConstantValue folded = null; | 757 ConstantValue folded = null; |
| 769 // operator is null when `node=="is"` | 758 // operator is null when `node=="is"` |
| 770 if (operator != null) { | 759 if (operator != null) { |
| 771 switch (operator.kind) { | 760 switch (operator.kind) { |
| 772 case BinaryOperatorKind.EQ: | 761 case BinaryOperatorKind.EQ: |
| (...skipping 27 matching lines...) Expand all Loading... |
| 800 send, | 789 send, |
| 801 new BinaryConstantExpression( | 790 new BinaryConstantExpression( |
| 802 left.expression, operator, right.expression), | 791 left.expression, operator, right.expression), |
| 803 folded); | 792 folded); |
| 804 } | 793 } |
| 805 return signalNotCompileTimeConstant(send); | 794 return signalNotCompileTimeConstant(send); |
| 806 } | 795 } |
| 807 | 796 |
| 808 AstConstant visitConditional(Conditional node) { | 797 AstConstant visitConditional(Conditional node) { |
| 809 AstConstant condition = evaluate(node.condition); | 798 AstConstant condition = evaluate(node.condition); |
| 810 if (condition == null || condition.isError) { | 799 if (condition == null) { |
| 811 return condition; | 800 return null; |
| 812 } else if (!condition.value.isBool) { | 801 } else if (!condition.value.isBool) { |
| 813 DartType conditionType = condition.value.getType(coreTypes); | 802 DartType conditionType = condition.value.getType(coreTypes); |
| 814 if (isEvaluatingConstant) { | 803 if (isEvaluatingConstant) { |
| 815 reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE, | 804 reporter.reportErrorMessage(node.condition, MessageKind.NOT_ASSIGNABLE, |
| 816 {'fromType': conditionType, 'toType': coreTypes.boolType}); | 805 {'fromType': conditionType, 'toType': coreTypes.boolType}); |
| 817 return new ErroneousAstConstant(context, node); | 806 return new ErroneousAstConstant(context, node); |
| 818 } | 807 } |
| 819 return null; | 808 return null; |
| 820 } | 809 } |
| 821 AstConstant thenExpression = evaluate(node.thenExpression); | 810 AstConstant thenExpression = evaluate(node.thenExpression); |
| 822 AstConstant elseExpression = evaluate(node.elseExpression); | 811 AstConstant elseExpression = evaluate(node.elseExpression); |
| 823 if (thenExpression == null || thenExpression.isError) { | 812 if (thenExpression == null || elseExpression == null) { |
| 824 return thenExpression; | 813 return null; |
| 825 } | |
| 826 if (elseExpression == null || elseExpression.isError) { | |
| 827 return elseExpression; | |
| 828 } | 814 } |
| 829 BoolConstantValue boolCondition = condition.value; | 815 BoolConstantValue boolCondition = condition.value; |
| 830 return new AstConstant( | 816 return new AstConstant( |
| 831 context, | 817 context, |
| 832 node, | 818 node, |
| 833 new ConditionalConstantExpression(condition.expression, | 819 new ConditionalConstantExpression(condition.expression, |
| 834 thenExpression.expression, elseExpression.expression), | 820 thenExpression.expression, elseExpression.expression), |
| 835 boolCondition.primitiveValue | 821 boolCondition.primitiveValue |
| 836 ? thenExpression.value | 822 ? thenExpression.value |
| 837 : elseExpression.value); | 823 : elseExpression.value); |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 985 Node node, | 971 Node node, |
| 986 InterfaceType type, | 972 InterfaceType type, |
| 987 ConstructorElement constructor, | 973 ConstructorElement constructor, |
| 988 CallStructure callStructure, | 974 CallStructure callStructure, |
| 989 List<AstConstant> normalizedArguments, | 975 List<AstConstant> normalizedArguments, |
| 990 List<AstConstant> concreteArguments) { | 976 List<AstConstant> concreteArguments) { |
| 991 var firstArgument = normalizedArguments[0].value; | 977 var firstArgument = normalizedArguments[0].value; |
| 992 ConstantValue defaultValue = normalizedArguments[1].value; | 978 ConstantValue defaultValue = normalizedArguments[1].value; |
| 993 | 979 |
| 994 if (firstArgument.isNull) { | 980 if (firstArgument.isNull) { |
| 995 return reportNotCompileTimeConstant( | 981 reporter.reportErrorMessage( |
| 996 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); | 982 normalizedArguments[0].node, MessageKind.NULL_NOT_ALLOWED); |
| 983 return null; |
| 997 } | 984 } |
| 998 | 985 |
| 999 if (!firstArgument.isString) { | 986 if (!firstArgument.isString) { |
| 1000 DartType type = defaultValue.getType(coreTypes); | 987 DartType type = defaultValue.getType(coreTypes); |
| 1001 return reportNotCompileTimeConstant( | 988 reporter.reportErrorMessage( |
| 1002 normalizedArguments[0].node, | 989 normalizedArguments[0].node, |
| 1003 MessageKind.NOT_ASSIGNABLE, | 990 MessageKind.NOT_ASSIGNABLE, |
| 1004 {'fromType': type, 'toType': coreTypes.stringType}); | 991 {'fromType': type, 'toType': coreTypes.stringType}); |
| 992 return null; |
| 1005 } | 993 } |
| 1006 | 994 |
| 1007 if (constructor.isIntFromEnvironmentConstructor && | 995 if (constructor.isIntFromEnvironmentConstructor && |
| 1008 !(defaultValue.isNull || defaultValue.isInt)) { | 996 !(defaultValue.isNull || defaultValue.isInt)) { |
| 1009 DartType type = defaultValue.getType(coreTypes); | 997 DartType type = defaultValue.getType(coreTypes); |
| 1010 return reportNotCompileTimeConstant( | 998 reporter.reportErrorMessage( |
| 1011 normalizedArguments[1].node, | 999 normalizedArguments[1].node, |
| 1012 MessageKind.NOT_ASSIGNABLE, | 1000 MessageKind.NOT_ASSIGNABLE, |
| 1013 {'fromType': type, 'toType': coreTypes.intType}); | 1001 {'fromType': type, 'toType': coreTypes.intType}); |
| 1002 return null; |
| 1014 } | 1003 } |
| 1015 | 1004 |
| 1016 if (constructor.isBoolFromEnvironmentConstructor && | 1005 if (constructor.isBoolFromEnvironmentConstructor && |
| 1017 !(defaultValue.isNull || defaultValue.isBool)) { | 1006 !(defaultValue.isNull || defaultValue.isBool)) { |
| 1018 DartType type = defaultValue.getType(coreTypes); | 1007 DartType type = defaultValue.getType(coreTypes); |
| 1019 return reportNotCompileTimeConstant( | 1008 reporter.reportErrorMessage( |
| 1020 normalizedArguments[1].node, | 1009 normalizedArguments[1].node, |
| 1021 MessageKind.NOT_ASSIGNABLE, | 1010 MessageKind.NOT_ASSIGNABLE, |
| 1022 {'fromType': type, 'toType': coreTypes.boolType}); | 1011 {'fromType': type, 'toType': coreTypes.boolType}); |
| 1012 return null; |
| 1023 } | 1013 } |
| 1024 | 1014 |
| 1025 if (constructor.isStringFromEnvironmentConstructor && | 1015 if (constructor.isStringFromEnvironmentConstructor && |
| 1026 !(defaultValue.isNull || defaultValue.isString)) { | 1016 !(defaultValue.isNull || defaultValue.isString)) { |
| 1027 DartType type = defaultValue.getType(coreTypes); | 1017 DartType type = defaultValue.getType(coreTypes); |
| 1028 return reportNotCompileTimeConstant( | 1018 reporter.reportErrorMessage( |
| 1029 normalizedArguments[1].node, | 1019 normalizedArguments[1].node, |
| 1030 MessageKind.NOT_ASSIGNABLE, | 1020 MessageKind.NOT_ASSIGNABLE, |
| 1031 {'fromType': type, 'toType': coreTypes.stringType}); | 1021 {'fromType': type, 'toType': coreTypes.stringType}); |
| 1022 return null; |
| 1032 } | 1023 } |
| 1033 | 1024 |
| 1034 String name = firstArgument.primitiveValue.slowToString(); | 1025 String name = firstArgument.primitiveValue.slowToString(); |
| 1035 String value = compiler.fromEnvironment(name); | 1026 String value = compiler.fromEnvironment(name); |
| 1036 | 1027 |
| 1037 AstConstant createEvaluatedConstant(ConstantValue value) { | 1028 AstConstant createEvaluatedConstant(ConstantValue value) { |
| 1038 ConstantExpression expression; | 1029 ConstantExpression expression; |
| 1039 ConstantExpression name = concreteArguments[0].expression; | 1030 ConstantExpression name = concreteArguments[0].expression; |
| 1040 ConstantExpression defaultValue; | 1031 ConstantExpression defaultValue; |
| 1041 if (concreteArguments.length > 1) { | 1032 if (concreteArguments.length > 1) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 ConstructorEvaluator evaluator = | 1096 ConstructorEvaluator evaluator = |
| 1106 new ConstructorEvaluator(constructedType, target, handler, compiler); | 1097 new ConstructorEvaluator(constructedType, target, handler, compiler); |
| 1107 evaluator.evaluateConstructorFieldValues(normalizedArguments); | 1098 evaluator.evaluateConstructorFieldValues(normalizedArguments); |
| 1108 Map<FieldElement, AstConstant> fieldConstants = | 1099 Map<FieldElement, AstConstant> fieldConstants = |
| 1109 evaluator.buildFieldConstants(target.enclosingClass); | 1100 evaluator.buildFieldConstants(target.enclosingClass); |
| 1110 Map<FieldElement, ConstantValue> fieldValues = | 1101 Map<FieldElement, ConstantValue> fieldValues = |
| 1111 <FieldElement, ConstantValue>{}; | 1102 <FieldElement, ConstantValue>{}; |
| 1112 fieldConstants.forEach((FieldElement field, AstConstant astConstant) { | 1103 fieldConstants.forEach((FieldElement field, AstConstant astConstant) { |
| 1113 fieldValues[field] = astConstant.value; | 1104 fieldValues[field] = astConstant.value; |
| 1114 }); | 1105 }); |
| 1115 for (AstConstant fieldValue in fieldConstants.values) { | |
| 1116 if (fieldValue.isError) { | |
| 1117 return fieldValue; | |
| 1118 } | |
| 1119 } | |
| 1120 return new AstConstant( | 1106 return new AstConstant( |
| 1121 context, | 1107 context, |
| 1122 node, | 1108 node, |
| 1123 new ConstructedConstantExpression(type, constructor, callStructure, | 1109 new ConstructedConstantExpression(type, constructor, callStructure, |
| 1124 concreteArguments.map((e) => e.expression).toList()), | 1110 concreteArguments.map((e) => e.expression).toList()), |
| 1125 new ConstructedConstantValue(constructedType, fieldValues)); | 1111 new ConstructedConstantValue(constructedType, fieldValues)); |
| 1126 } | 1112 } |
| 1127 | 1113 |
| 1128 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { | 1114 AstConstant visitParenthesizedExpression(ParenthesizedExpression node) { |
| 1129 return node.expression.accept(this); | 1115 return node.expression.accept(this); |
| 1130 } | 1116 } |
| 1131 | 1117 |
| 1132 AstConstant reportNotCompileTimeConstant(Node node, MessageKind message, | 1118 AstConstant signalNotCompileTimeConstant(Node node, |
| 1133 [Map arguments = const {}]) { | 1119 {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT}) { |
| 1134 reporter.reportErrorMessage(node, message, arguments); | 1120 if (isEvaluatingConstant) { |
| 1135 return new AstConstant(context, node, new ErroneousConstantExpression(), | 1121 reporter.reportErrorMessage(node, message); |
| 1136 new NullConstantValue()); | |
| 1137 } | |
| 1138 | 1122 |
| 1139 AstConstant signalNotCompileTimeConstant(Node node, | 1123 return new AstConstant(context, node, new ErroneousConstantExpression(), |
| 1140 {MessageKind message: MessageKind.NOT_A_COMPILE_TIME_CONSTANT, | 1124 new NullConstantValue()); |
| 1141 Map arguments: const {}}) { | |
| 1142 if (isEvaluatingConstant) { | |
| 1143 return reportNotCompileTimeConstant(node, message, arguments); | |
| 1144 } | 1125 } |
| 1145 // Else we don't need to do anything. The final handler is only | 1126 // Else we don't need to do anything. The final handler is only |
| 1146 // optimistically trying to compile constants. So it is normal that we | 1127 // optimistically trying to compile constants. So it is normal that we |
| 1147 // sometimes see non-compile time constants. | 1128 // sometimes see non-compile time constants. |
| 1148 // Simply return [:null:] which is used to propagate a failing | 1129 // Simply return [:null:] which is used to propagate a failing |
| 1149 // compile-time compilation. | 1130 // compile-time compilation. |
| 1150 return null; | 1131 return null; |
| 1151 } | 1132 } |
| 1152 } | 1133 } |
| 1153 | 1134 |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1384 | 1365 |
| 1385 factory AstConstant.fromDefaultValue(VariableElement element, | 1366 factory AstConstant.fromDefaultValue(VariableElement element, |
| 1386 ConstantExpression constant, ConstantValue value) { | 1367 ConstantExpression constant, ConstantValue value) { |
| 1387 return new AstConstant( | 1368 return new AstConstant( |
| 1388 element, | 1369 element, |
| 1389 element.initializer != null ? element.initializer : element.node, | 1370 element.initializer != null ? element.initializer : element.node, |
| 1390 constant, | 1371 constant, |
| 1391 value); | 1372 value); |
| 1392 } | 1373 } |
| 1393 | 1374 |
| 1394 bool get isError => expression.kind == ConstantExpressionKind.ERRONEOUS; | |
| 1395 | |
| 1396 String toString() => expression.toString(); | 1375 String toString() => expression.toString(); |
| 1397 } | 1376 } |
| 1398 | 1377 |
| 1399 /// A synthetic constant used to recover from errors. | 1378 /// A synthetic constant used to recover from errors. |
| 1400 class ErroneousAstConstant extends AstConstant { | 1379 class ErroneousAstConstant extends AstConstant { |
| 1401 ErroneousAstConstant(Element element, Node node) | 1380 ErroneousAstConstant(Element element, Node node) |
| 1402 : super( | 1381 : super( |
| 1403 element, | 1382 element, |
| 1404 node, | 1383 node, |
| 1405 // TODO(johnniwinther): Return a [NonConstantValue] instead. | 1384 // TODO(johnniwinther): Return a [NonConstantValue] instead. |
| 1406 new ErroneousConstantExpression(), | 1385 new ErroneousConstantExpression(), |
| 1407 new NullConstantValue()); | 1386 new NullConstantValue()); |
| 1408 } | 1387 } |
| 1409 | 1388 |
| 1410 class _CompilerEnvironment implements Environment { | 1389 class _CompilerEnvironment implements Environment { |
| 1411 final Compiler compiler; | 1390 final Compiler compiler; |
| 1412 | 1391 |
| 1413 _CompilerEnvironment(this.compiler); | 1392 _CompilerEnvironment(this.compiler); |
| 1414 | 1393 |
| 1415 @override | 1394 @override |
| 1416 String readFromEnvironment(String name) { | 1395 String readFromEnvironment(String name) { |
| 1417 return compiler.fromEnvironment(name); | 1396 return compiler.fromEnvironment(name); |
| 1418 } | 1397 } |
| 1419 } | 1398 } |
| OLD | NEW |