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 |