| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library analyzer.src.dart.constant.evaluation; | 5 library analyzer.src.dart.constant.evaluation; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/context/declared_variables.dart'; | 9 import 'package:analyzer/context/declared_variables.dart'; |
| 10 import 'package:analyzer/dart/ast/ast.dart'; | 10 import 'package:analyzer/dart/ast/ast.dart'; |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 // Instantiate the constructor with the in-scope type arguments. | 543 // Instantiate the constructor with the in-scope type arguments. |
| 544 definingClass = constantVisitor.evaluateType(definingClass); | 544 definingClass = constantVisitor.evaluateType(definingClass); |
| 545 constructor = ConstructorMember.from(constructorBase, definingClass); | 545 constructor = ConstructorMember.from(constructorBase, definingClass); |
| 546 | 546 |
| 547 typeArgumentMap = new HashMap<String, DartObjectImpl>.fromIterables( | 547 typeArgumentMap = new HashMap<String, DartObjectImpl>.fromIterables( |
| 548 definingClass.typeParameters.map((t) => t.name), | 548 definingClass.typeParameters.map((t) => t.name), |
| 549 definingClass.typeArguments.map(constantVisitor.typeConstant)); | 549 definingClass.typeArguments.map(constantVisitor.typeConstant)); |
| 550 } | 550 } |
| 551 | 551 |
| 552 var fieldMap = new HashMap<String, DartObjectImpl>(); | 552 var fieldMap = new HashMap<String, DartObjectImpl>(); |
| 553 var fieldInitVisitor = new ConstantVisitor(this, errorReporter, | 553 |
| 554 // The errors reported while computing values for field initializers, or |
| 555 // default values for the constructor parameters, cannot be reported |
| 556 // into the current ErrorReporter, because they usually happen in a |
| 557 // different source. But they still should cause a constant evaluation |
| 558 // error for the current node. |
| 559 var externalErrorListener = new RecordingErrorListener(); |
| 560 var externalErrorReporter = |
| 561 new ErrorReporter(externalErrorListener, constructor.source); |
| 562 |
| 563 void reportLocalErrorForRecordedExternalErrors() { |
| 564 ErrorCode errorCode; |
| 565 for (AnalysisError error in externalErrorListener.errors) { |
| 566 if (error.errorCode is CompileTimeErrorCode) { |
| 567 errorCode = CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION; |
| 568 break; |
| 569 } |
| 570 if (error.errorCode is CheckedModeCompileTimeErrorCode) { |
| 571 errorCode = |
| 572 CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION; |
| 573 break; |
| 574 } |
| 575 } |
| 576 if (errorCode != null) { |
| 577 errorReporter.reportErrorForNode(errorCode, node); |
| 578 } |
| 579 } |
| 580 |
| 581 var fieldInitVisitor = new ConstantVisitor(this, externalErrorReporter, |
| 554 lexicalEnvironment: typeArgumentMap); | 582 lexicalEnvironment: typeArgumentMap); |
| 555 // Start with final fields that are initialized at their declaration site. | 583 // Start with final fields that are initialized at their declaration site. |
| 556 List<FieldElement> fields = constructor.enclosingElement.fields; | 584 List<FieldElement> fields = constructor.enclosingElement.fields; |
| 557 for (int i = 0; i < fields.length; i++) { | 585 for (int i = 0; i < fields.length; i++) { |
| 558 FieldElement field = fields[i]; | 586 FieldElement field = fields[i]; |
| 559 if ((field.isFinal || field.isConst) && | 587 if ((field.isFinal || field.isConst) && |
| 560 !field.isStatic && | 588 !field.isStatic && |
| 561 field is ConstFieldElementImpl) { | 589 field is ConstFieldElementImpl) { |
| 562 validator.beforeGetFieldEvaluationResult(field); | 590 validator.beforeGetFieldEvaluationResult(field); |
| 563 | 591 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); | 694 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, node); |
| 667 } | 695 } |
| 668 fieldMap[fieldName] = argumentValue; | 696 fieldMap[fieldName] = argumentValue; |
| 669 } | 697 } |
| 670 } | 698 } |
| 671 String name = baseParameter.name; | 699 String name = baseParameter.name; |
| 672 parameterMap[name] = argumentValue; | 700 parameterMap[name] = argumentValue; |
| 673 } | 701 } |
| 674 } | 702 } |
| 675 ConstantVisitor initializerVisitor = new ConstantVisitor( | 703 ConstantVisitor initializerVisitor = new ConstantVisitor( |
| 676 this, errorReporter, | 704 this, externalErrorReporter, |
| 677 lexicalEnvironment: parameterMap); | 705 lexicalEnvironment: parameterMap); |
| 678 String superName = null; | 706 String superName = null; |
| 679 NodeList<Expression> superArguments = null; | 707 NodeList<Expression> superArguments = null; |
| 680 for (ConstructorInitializer initializer in initializers) { | 708 for (ConstructorInitializer initializer in initializers) { |
| 681 if (initializer is ConstructorFieldInitializer) { | 709 if (initializer is ConstructorFieldInitializer) { |
| 682 Expression initializerExpression = initializer.expression; | 710 Expression initializerExpression = initializer.expression; |
| 683 DartObjectImpl evaluationResult = | 711 DartObjectImpl evaluationResult = |
| 684 initializerExpression.accept(initializerVisitor); | 712 initializerExpression.accept(initializerVisitor); |
| 685 if (evaluationResult != null) { | 713 if (evaluationResult != null) { |
| 686 String fieldName = initializer.fieldName.name; | 714 String fieldName = initializer.fieldName.name; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 705 SimpleIdentifier name = initializer.constructorName; | 733 SimpleIdentifier name = initializer.constructorName; |
| 706 if (name != null) { | 734 if (name != null) { |
| 707 superName = name.name; | 735 superName = name.name; |
| 708 } | 736 } |
| 709 superArguments = initializer.argumentList.arguments; | 737 superArguments = initializer.argumentList.arguments; |
| 710 } else if (initializer is RedirectingConstructorInvocation) { | 738 } else if (initializer is RedirectingConstructorInvocation) { |
| 711 // This is a redirecting constructor, so just evaluate the constructor | 739 // This is a redirecting constructor, so just evaluate the constructor |
| 712 // it redirects to. | 740 // it redirects to. |
| 713 ConstructorElement constructor = initializer.staticElement; | 741 ConstructorElement constructor = initializer.staticElement; |
| 714 if (constructor != null && constructor.isConst) { | 742 if (constructor != null && constructor.isConst) { |
| 715 return evaluateConstructorCall( | 743 DartObjectImpl result = evaluateConstructorCall( |
| 716 node, | 744 node, |
| 717 initializer.argumentList.arguments, | 745 initializer.argumentList.arguments, |
| 718 constructor, | 746 constructor, |
| 719 initializerVisitor, | 747 initializerVisitor, |
| 720 errorReporter, | 748 externalErrorReporter, |
| 721 invocation: invocation); | 749 invocation: invocation); |
| 750 reportLocalErrorForRecordedExternalErrors(); |
| 751 return result; |
| 722 } | 752 } |
| 723 } | 753 } |
| 724 } | 754 } |
| 725 // Evaluate explicit or implicit call to super(). | 755 // Evaluate explicit or implicit call to super(). |
| 726 InterfaceType superclass = definingClass.superclass; | 756 InterfaceType superclass = definingClass.superclass; |
| 727 if (superclass != null && !superclass.isObject) { | 757 if (superclass != null && !superclass.isObject) { |
| 728 ConstructorElement superConstructor = | 758 ConstructorElement superConstructor = |
| 729 superclass.lookUpConstructor(superName, constructor.library); | 759 superclass.lookUpConstructor(superName, constructor.library); |
| 730 if (superConstructor != null) { | 760 if (superConstructor != null) { |
| 731 if (superArguments == null) { | 761 if (superArguments == null) { |
| 732 superArguments = astFactory.nodeList/*<Expression>*/(null); | 762 superArguments = astFactory.nodeList/*<Expression>*/(null); |
| 733 } | 763 } |
| 734 | 764 |
| 735 evaluateSuperConstructorCall(node, fieldMap, superConstructor, | 765 evaluateSuperConstructorCall(node, fieldMap, superConstructor, |
| 736 superArguments, initializerVisitor, errorReporter); | 766 superArguments, initializerVisitor, externalErrorReporter); |
| 737 } | 767 } |
| 738 } | 768 } |
| 769 reportLocalErrorForRecordedExternalErrors(); |
| 739 return new DartObjectImpl( | 770 return new DartObjectImpl( |
| 740 definingClass, new GenericState(fieldMap, invocation: invocation)); | 771 definingClass, new GenericState(fieldMap, invocation: invocation)); |
| 741 } | 772 } |
| 742 | 773 |
| 743 void evaluateSuperConstructorCall( | 774 void evaluateSuperConstructorCall( |
| 744 AstNode node, | 775 AstNode node, |
| 745 HashMap<String, DartObjectImpl> fieldMap, | 776 HashMap<String, DartObjectImpl> fieldMap, |
| 746 ConstructorElement superConstructor, | 777 ConstructorElement superConstructor, |
| 747 List<Expression> superArguments, | 778 List<Expression> superArguments, |
| 748 ConstantVisitor initializerVisitor, | 779 ConstantVisitor initializerVisitor, |
| (...skipping 1347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2096 } | 2127 } |
| 2097 | 2128 |
| 2098 @override | 2129 @override |
| 2099 String toString() { | 2130 String toString() { |
| 2100 if (value == null) { | 2131 if (value == null) { |
| 2101 return "error"; | 2132 return "error"; |
| 2102 } | 2133 } |
| 2103 return value.toString(); | 2134 return value.toString(); |
| 2104 } | 2135 } |
| 2105 } | 2136 } |
| OLD | NEW |