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