OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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.md file. | 3 // BSD-style license that can be found in the LICENSE.md file. |
4 | 4 |
5 import 'package:front_end/src/base/instrumentation.dart'; | 5 import 'package:front_end/src/base/instrumentation.dart'; |
6 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; | 6 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; |
7 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'; | 7 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'; |
8 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; | 8 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; |
9 import 'package:front_end/src/fasta/type_inference/type_promotion.dart'; | 9 import 'package:front_end/src/fasta/type_inference/type_promotion.dart'; |
10 import 'package:front_end/src/fasta/type_inference/type_schema.dart'; | 10 import 'package:front_end/src/fasta/type_inference/type_schema.dart'; |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 int offset, | 540 int offset, |
541 Expression receiver, | 541 Expression receiver, |
542 Name methodName, | 542 Name methodName, |
543 List<DartType> explicitTypeArguments, | 543 List<DartType> explicitTypeArguments, |
544 void forEachArgument(void callback(String name, Expression expression)), | 544 void forEachArgument(void callback(String name, Expression expression)), |
545 void setInferredTypeArguments(List<DartType> types), | 545 void setInferredTypeArguments(List<DartType> types), |
546 void setInterfaceTarget(Procedure procedure)) { | 546 void setInterfaceTarget(Procedure procedure)) { |
547 typeNeeded = listener.methodInvocationEnter(typeContext) || typeNeeded; | 547 typeNeeded = listener.methodInvocationEnter(typeContext) || typeNeeded; |
548 // First infer the receiver so we can look up the method that was invoked. | 548 // First infer the receiver so we can look up the method that was invoked. |
549 var receiverType = inferExpression(receiver, null, true); | 549 var receiverType = inferExpression(receiver, null, true); |
550 // TODO(paulberry): can we share some of the code below with | |
551 // inferConstructorInvocation? | |
552 bool isOverloadedArithmeticOperator = false; | 550 bool isOverloadedArithmeticOperator = false; |
553 Member interfaceMember; | 551 Member interfaceMember; |
554 if (receiverType is InterfaceType) { | 552 if (receiverType is InterfaceType) { |
555 interfaceMember = | 553 interfaceMember = |
556 classHierarchy.getInterfaceMember(receiverType.classNode, methodName); | 554 classHierarchy.getInterfaceMember(receiverType.classNode, methodName); |
557 if (interfaceMember is Procedure) { | 555 if (interfaceMember is Procedure) { |
558 setInterfaceTarget(interfaceMember); | 556 setInterfaceTarget(interfaceMember); |
559 isOverloadedArithmeticOperator = typeSchemaEnvironment | 557 isOverloadedArithmeticOperator = typeSchemaEnvironment |
560 .isOverloadedArithmeticOperator(interfaceMember); | 558 .isOverloadedArithmeticOperator(interfaceMember); |
561 } | 559 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 /// [getterType] is the type of the field being referenced, or the return type | 609 /// [getterType] is the type of the field being referenced, or the return type |
612 /// of the getter. | 610 /// of the getter. |
613 DartType inferStaticGet( | 611 DartType inferStaticGet( |
614 DartType typeContext, bool typeNeeded, DartType getterType) { | 612 DartType typeContext, bool typeNeeded, DartType getterType) { |
615 typeNeeded = listener.staticGetEnter(typeContext) || typeNeeded; | 613 typeNeeded = listener.staticGetEnter(typeContext) || typeNeeded; |
616 var inferredType = typeNeeded ? getterType : null; | 614 var inferredType = typeNeeded ? getterType : null; |
617 listener.staticGetExit(inferredType); | 615 listener.staticGetExit(inferredType); |
618 return inferredType; | 616 return inferredType; |
619 } | 617 } |
620 | 618 |
| 619 /// Performs the core type inference algorithm for method invocations. |
| 620 /// |
| 621 /// [typeContext], [typeNeeded], and the return value behave as described in |
| 622 /// [inferExpression]. |
| 623 /// |
| 624 /// [offset] is the location of the method invocation in the source file. |
| 625 /// [receiver] is the object whose method is being invoked, and [methodName] |
| 626 /// is the name of the method. [explicitTypeArguments] is the set of type |
| 627 /// arguments explicitly provided, or `null` if no type arguments were |
| 628 /// provided. [forEachArgument] is a callback which can be used to iterate |
| 629 /// through all invocation arguments (both named and positional). |
| 630 /// [setInferredTypeArguments] is a callback which can be used to record the |
| 631 /// inferred type arguments. [setInterfaceTarget] is a callback which can be |
| 632 /// used to record the method being invoked. |
| 633 DartType inferStaticInvocation( |
| 634 DartType typeContext, |
| 635 bool typeNeeded, |
| 636 int offset, |
| 637 Procedure target, |
| 638 Name methodName, |
| 639 List<DartType> explicitTypeArguments, |
| 640 void forEachArgument(void callback(String name, Expression expression)), |
| 641 void setInferredTypeArguments(List<DartType> types)) { |
| 642 typeNeeded = listener.staticInvocationEnter(typeContext) || typeNeeded; |
| 643 var calleeType = target.function.functionType; |
| 644 var inferredType = _inferInvocation( |
| 645 typeContext, |
| 646 typeNeeded, |
| 647 offset, |
| 648 calleeType, |
| 649 calleeType.returnType, |
| 650 explicitTypeArguments, |
| 651 forEachArgument, |
| 652 setInferredTypeArguments); |
| 653 listener.staticInvocationExit(inferredType); |
| 654 return inferredType; |
| 655 } |
| 656 |
621 /// Performs the core type inference algorithm for string concatenations. | 657 /// Performs the core type inference algorithm for string concatenations. |
622 /// | 658 /// |
623 /// [typeContext], [typeNeeded], and the return value behave as described in | 659 /// [typeContext], [typeNeeded], and the return value behave as described in |
624 /// [inferExpression]. | 660 /// [inferExpression]. |
625 DartType inferStringConcatenation( | 661 DartType inferStringConcatenation( |
626 DartType typeContext, bool typeNeeded, Iterable<Expression> expressions) { | 662 DartType typeContext, bool typeNeeded, Iterable<Expression> expressions) { |
627 typeNeeded = listener.stringConcatenationEnter(typeContext) || typeNeeded; | 663 typeNeeded = listener.stringConcatenationEnter(typeContext) || typeNeeded; |
628 for (Expression expression in expressions) { | 664 for (Expression expression in expressions) { |
629 inferExpression(expression, null, false); | 665 inferExpression(expression, null, false); |
630 } | 666 } |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 typeSchemaEnvironment.inferGenericFunctionOrType(returnType, | 818 typeSchemaEnvironment.inferGenericFunctionOrType(returnType, |
783 calleeTypeParameters, null, null, typeContext, inferredTypes); | 819 calleeTypeParameters, null, null, typeContext, inferredTypes); |
784 substitution = | 820 substitution = |
785 Substitution.fromPairs(calleeTypeParameters, inferredTypes); | 821 Substitution.fromPairs(calleeTypeParameters, inferredTypes); |
786 formalTypes = []; | 822 formalTypes = []; |
787 actualTypes = []; | 823 actualTypes = []; |
788 } else if (explicitTypeArguments != null && | 824 } else if (explicitTypeArguments != null && |
789 calleeTypeParameters.length == explicitTypeArguments.length) { | 825 calleeTypeParameters.length == explicitTypeArguments.length) { |
790 substitution = | 826 substitution = |
791 Substitution.fromPairs(calleeTypeParameters, explicitTypeArguments); | 827 Substitution.fromPairs(calleeTypeParameters, explicitTypeArguments); |
| 828 } else if (calleeTypeParameters.length != 0) { |
| 829 substitution = Substitution.fromPairs( |
| 830 calleeTypeParameters, |
| 831 new List<DartType>.filled( |
| 832 calleeTypeParameters.length, const DynamicType())); |
792 } | 833 } |
793 int i = 0; | 834 int i = 0; |
794 forEachArgument((name, expression) { | 835 forEachArgument((name, expression) { |
795 DartType formalType = name != null | 836 DartType formalType = name != null |
796 ? _getNamedParameterType(calleeType, name) | 837 ? _getNamedParameterType(calleeType, name) |
797 : _getPositionalParameterType(calleeType, i++); | 838 : _getPositionalParameterType(calleeType, i++); |
798 DartType inferredFormalType = substitution != null | 839 DartType inferredFormalType = substitution != null |
799 ? substitution.substituteType(formalType) | 840 ? substitution.substituteType(formalType) |
800 : formalType; | 841 : formalType; |
801 var expressionType = inferExpression(expression, inferredFormalType, | 842 var expressionType = inferExpression(expression, inferredFormalType, |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 /// statement returning the given [type]. | 904 /// statement returning the given [type]. |
864 void updateInferredReturnType(TypeInferrerImpl inferrer, DartType type) { | 905 void updateInferredReturnType(TypeInferrerImpl inferrer, DartType type) { |
865 if (_inferredReturnType == null) { | 906 if (_inferredReturnType == null) { |
866 _inferredReturnType = type; | 907 _inferredReturnType = type; |
867 } else { | 908 } else { |
868 _inferredReturnType = inferrer.typeSchemaEnvironment | 909 _inferredReturnType = inferrer.typeSchemaEnvironment |
869 .getLeastUpperBound(_inferredReturnType, type); | 910 .getLeastUpperBound(_inferredReturnType, type); |
870 } | 911 } |
871 } | 912 } |
872 } | 913 } |
OLD | NEW |