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