| 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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 } | 415 } |
| 416 } | 416 } |
| 417 return value; | 417 return value; |
| 418 } | 418 } |
| 419 | 419 |
| 420 DartObjectImpl evaluateConstructorCall( | 420 DartObjectImpl evaluateConstructorCall( |
| 421 AstNode node, | 421 AstNode node, |
| 422 List<Expression> arguments, | 422 List<Expression> arguments, |
| 423 ConstructorElement constructor, | 423 ConstructorElement constructor, |
| 424 ConstantVisitor constantVisitor, | 424 ConstantVisitor constantVisitor, |
| 425 ErrorReporter errorReporter) { | 425 ErrorReporter errorReporter, |
| 426 {ConstructorElement originalConstructor, |
| 427 List<DartObjectImpl> originalArguments, |
| 428 Map<String, DartObjectImpl> originalNamedArguments}) { |
| 426 if (!getConstructorImpl(constructor).isCycleFree) { | 429 if (!getConstructorImpl(constructor).isCycleFree) { |
| 427 // It's not safe to evaluate this constructor, so bail out. | 430 // It's not safe to evaluate this constructor, so bail out. |
| 428 // TODO(paulberry): ensure that a reasonable error message is produced | 431 // TODO(paulberry): ensure that a reasonable error message is produced |
| 429 // in this case, as well as other cases involving constant expression | 432 // in this case, as well as other cases involving constant expression |
| 430 // circularities (e.g. "compile-time constant expression depends on | 433 // circularities (e.g. "compile-time constant expression depends on |
| 431 // itself") | 434 // itself") |
| 432 return new DartObjectImpl.validWithUnknownValue(constructor.returnType); | 435 return new DartObjectImpl.validWithUnknownValue(constructor.returnType); |
| 433 } | 436 } |
| 434 int argumentCount = arguments.length; | 437 int argumentCount = arguments.length; |
| 435 List<DartObjectImpl> argumentValues = | 438 List<DartObjectImpl> argumentValues = |
| 436 new List<DartObjectImpl>(argumentCount); | 439 new List<DartObjectImpl>(argumentCount); |
| 440 List<DartObjectImpl> positionalArguments = <DartObjectImpl>[]; |
| 437 List<Expression> argumentNodes = new List<Expression>(argumentCount); | 441 List<Expression> argumentNodes = new List<Expression>(argumentCount); |
| 438 HashMap<String, DartObjectImpl> namedArgumentValues = | 442 HashMap<String, DartObjectImpl> namedArgumentValues = |
| 439 new HashMap<String, DartObjectImpl>(); | 443 new HashMap<String, DartObjectImpl>(); |
| 440 HashMap<String, NamedExpression> namedArgumentNodes = | 444 HashMap<String, NamedExpression> namedArgumentNodes = |
| 441 new HashMap<String, NamedExpression>(); | 445 new HashMap<String, NamedExpression>(); |
| 442 for (int i = 0; i < argumentCount; i++) { | 446 for (int i = 0; i < argumentCount; i++) { |
| 443 Expression argument = arguments[i]; | 447 Expression argument = arguments[i]; |
| 444 if (argument is NamedExpression) { | 448 if (argument is NamedExpression) { |
| 445 String name = argument.name.label.name; | 449 String name = argument.name.label.name; |
| 446 namedArgumentValues[name] = | 450 namedArgumentValues[name] = |
| 447 constantVisitor._valueOf(argument.expression); | 451 constantVisitor._valueOf(argument.expression); |
| 448 namedArgumentNodes[name] = argument; | 452 namedArgumentNodes[name] = argument; |
| 449 argumentValues[i] = typeProvider.nullObject; | 453 argumentValues[i] = typeProvider.nullObject; |
| 450 } else { | 454 } else { |
| 451 argumentValues[i] = constantVisitor._valueOf(argument); | 455 var argumentValue = constantVisitor._valueOf(argument); |
| 456 argumentValues[i] = argumentValue; |
| 457 positionalArguments.add(argumentValue); |
| 452 argumentNodes[i] = argument; | 458 argumentNodes[i] = argument; |
| 453 } | 459 } |
| 454 } | 460 } |
| 461 if (originalConstructor == null) { |
| 462 originalConstructor = constructor; |
| 463 originalArguments = positionalArguments; |
| 464 originalNamedArguments = namedArgumentValues; |
| 465 } |
| 455 constructor = followConstantRedirectionChain(constructor); | 466 constructor = followConstantRedirectionChain(constructor); |
| 456 InterfaceType definingClass = constructor.returnType as InterfaceType; | 467 InterfaceType definingClass = constructor.returnType as InterfaceType; |
| 457 if (constructor.isFactory) { | 468 if (constructor.isFactory) { |
| 458 // We couldn't find a non-factory constructor. | 469 // We couldn't find a non-factory constructor. |
| 459 // See if it's because we reached an external const factory constructor | 470 // See if it's because we reached an external const factory constructor |
| 460 // that we can emulate. | 471 // that we can emulate. |
| 461 if (constructor.name == "fromEnvironment") { | 472 if (constructor.name == "fromEnvironment") { |
| 462 if (!checkFromEnvironmentArguments( | 473 if (!checkFromEnvironmentArguments( |
| 463 arguments, argumentValues, namedArgumentValues, definingClass)) { | 474 arguments, argumentValues, namedArgumentValues, definingClass)) { |
| 464 errorReporter.reportErrorForNode( | 475 errorReporter.reportErrorForNode( |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 } else if (initializer is RedirectingConstructorInvocation) { | 713 } else if (initializer is RedirectingConstructorInvocation) { |
| 703 // This is a redirecting constructor, so just evaluate the constructor | 714 // This is a redirecting constructor, so just evaluate the constructor |
| 704 // it redirects to. | 715 // it redirects to. |
| 705 ConstructorElement constructor = initializer.staticElement; | 716 ConstructorElement constructor = initializer.staticElement; |
| 706 if (constructor != null && constructor.isConst) { | 717 if (constructor != null && constructor.isConst) { |
| 707 return evaluateConstructorCall( | 718 return evaluateConstructorCall( |
| 708 node, | 719 node, |
| 709 initializer.argumentList.arguments, | 720 initializer.argumentList.arguments, |
| 710 constructor, | 721 constructor, |
| 711 initializerVisitor, | 722 initializerVisitor, |
| 712 errorReporter); | 723 errorReporter, |
| 724 originalConstructor: originalConstructor, |
| 725 originalArguments: originalArguments, |
| 726 originalNamedArguments: originalNamedArguments); |
| 713 } | 727 } |
| 714 } | 728 } |
| 715 } | 729 } |
| 716 // Evaluate explicit or implicit call to super(). | 730 // Evaluate explicit or implicit call to super(). |
| 717 InterfaceType superclass = definingClass.superclass; | 731 InterfaceType superclass = definingClass.superclass; |
| 718 if (superclass != null && !superclass.isObject) { | 732 if (superclass != null && !superclass.isObject) { |
| 719 ConstructorElement superConstructor = | 733 ConstructorElement superConstructor = |
| 720 superclass.lookUpConstructor(superName, constructor.library); | 734 superclass.lookUpConstructor(superName, constructor.library); |
| 721 if (superConstructor != null) { | 735 if (superConstructor != null) { |
| 722 if (superArguments == null) { | 736 if (superArguments == null) { |
| 723 superArguments = astFactory.nodeList/*<Expression>*/(null); | 737 superArguments = astFactory.nodeList/*<Expression>*/(null); |
| 724 } | 738 } |
| 725 | 739 |
| 726 evaluateSuperConstructorCall(node, fieldMap, superConstructor, | 740 evaluateSuperConstructorCall(node, fieldMap, superConstructor, |
| 727 superArguments, initializerVisitor, errorReporter); | 741 superArguments, initializerVisitor, errorReporter); |
| 728 } | 742 } |
| 729 } | 743 } |
| 730 return new DartObjectImpl(definingClass, new GenericState(fieldMap)); | 744 return new DartObjectImpl( |
| 745 definingClass, |
| 746 new GenericState(fieldMap, |
| 747 constructor: originalConstructor, |
| 748 positionalArguments: originalArguments, |
| 749 namedArguments: originalNamedArguments)); |
| 731 } | 750 } |
| 732 | 751 |
| 733 void evaluateSuperConstructorCall( | 752 void evaluateSuperConstructorCall( |
| 734 AstNode node, | 753 AstNode node, |
| 735 HashMap<String, DartObjectImpl> fieldMap, | 754 HashMap<String, DartObjectImpl> fieldMap, |
| 736 ConstructorElement superConstructor, | 755 ConstructorElement superConstructor, |
| 737 List<Expression> superArguments, | 756 List<Expression> superArguments, |
| 738 ConstantVisitor initializerVisitor, | 757 ConstantVisitor initializerVisitor, |
| 739 ErrorReporter errorReporter) { | 758 ErrorReporter errorReporter) { |
| 740 if (superConstructor != null && superConstructor.isConst) { | 759 if (superConstructor != null && superConstructor.isConst) { |
| (...skipping 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2086 } | 2105 } |
| 2087 | 2106 |
| 2088 @override | 2107 @override |
| 2089 String toString() { | 2108 String toString() { |
| 2090 if (value == null) { | 2109 if (value == null) { |
| 2091 return "error"; | 2110 return "error"; |
| 2092 } | 2111 } |
| 2093 return value.toString(); | 2112 return value.toString(); |
| 2094 } | 2113 } |
| 2095 } | 2114 } |
| OLD | NEW |