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/errors.dart' show internalError; | 6 import 'package:front_end/src/fasta/errors.dart' show internalError; |
7 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; | 7 import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart'; |
8 import 'package:front_end/src/fasta/names.dart' show callName; | 8 import 'package:front_end/src/fasta/names.dart' show callName; |
9 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'; | 9 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart'; |
10 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; | 10 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart'
; |
(...skipping 26 matching lines...) Expand all Loading... |
37 SuperMethodInvocation, | 37 SuperMethodInvocation, |
38 SuperPropertyGet, | 38 SuperPropertyGet, |
39 SuperPropertySet, | 39 SuperPropertySet, |
40 TypeParameterType, | 40 TypeParameterType, |
41 VariableDeclaration, | 41 VariableDeclaration, |
42 VoidType; | 42 VoidType; |
43 import 'package:kernel/class_hierarchy.dart'; | 43 import 'package:kernel/class_hierarchy.dart'; |
44 import 'package:kernel/core_types.dart'; | 44 import 'package:kernel/core_types.dart'; |
45 import 'package:kernel/type_algebra.dart'; | 45 import 'package:kernel/type_algebra.dart'; |
46 | 46 |
| 47 bool isOverloadableArithmeticOperator(String name) { |
| 48 return identical(name, '+') || |
| 49 identical(name, '-') || |
| 50 identical(name, '*') || |
| 51 identical(name, '%'); |
| 52 } |
| 53 |
| 54 bool _isUserDefinableOperator(String name) { |
| 55 return identical(name, '<') || |
| 56 identical(name, '>') || |
| 57 identical(name, '<=') || |
| 58 identical(name, '>=') || |
| 59 identical(name, '==') || |
| 60 identical(name, '-') || |
| 61 identical(name, '+') || |
| 62 identical(name, '/') || |
| 63 identical(name, '~/') || |
| 64 identical(name, '*') || |
| 65 identical(name, '%') || |
| 66 identical(name, '|') || |
| 67 identical(name, '^') || |
| 68 identical(name, '&') || |
| 69 identical(name, '<<') || |
| 70 identical(name, '>>') || |
| 71 identical(name, '[]=') || |
| 72 identical(name, '~'); |
| 73 } |
| 74 |
47 /// Keeps track of information about the innermost function or closure being | 75 /// Keeps track of information about the innermost function or closure being |
48 /// inferred. | 76 /// inferred. |
49 class ClosureContext { | 77 class ClosureContext { |
50 final bool isAsync; | 78 final bool isAsync; |
51 | 79 |
52 final bool isGenerator; | 80 final bool isGenerator; |
53 | 81 |
54 final DartType returnContext; | 82 final DartType returnContext; |
55 | 83 |
56 DartType _inferredReturnType; | 84 DartType _inferredReturnType; |
(...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
614 } | 642 } |
615 DartType inferredType; | 643 DartType inferredType; |
616 if (typeNeeded) { | 644 if (typeNeeded) { |
617 inferredType = substitution == null | 645 inferredType = substitution == null |
618 ? returnType | 646 ? returnType |
619 : substitution.substituteType(returnType); | 647 : substitution.substituteType(returnType); |
620 } | 648 } |
621 return inferredType; | 649 return inferredType; |
622 } | 650 } |
623 | 651 |
| 652 /// Performs the core type inference algorithm for method invocations (this |
| 653 /// handles both null-aware and non-null-aware method invocations). |
| 654 DartType inferMethodInvocation( |
| 655 Expression expression, |
| 656 Expression receiver, |
| 657 int fileOffset, |
| 658 MethodInvocation desugaredInvocation, |
| 659 bool isImplicitCall, |
| 660 DartType typeContext, |
| 661 bool typeNeeded, |
| 662 {VariableDeclaration receiverVariable}) { |
| 663 typeNeeded = |
| 664 listener.methodInvocationEnter(expression, typeContext) || typeNeeded; |
| 665 // First infer the receiver so we can look up the method that was invoked. |
| 666 var receiverType = inferExpression(receiver, null, true); |
| 667 receiverVariable?.type = receiverType; |
| 668 bool isOverloadedArithmeticOperator = false; |
| 669 Member interfaceMember = |
| 670 findMethodInvocationMember(receiverType, desugaredInvocation); |
| 671 if (interfaceMember is Procedure) { |
| 672 isOverloadedArithmeticOperator = typeSchemaEnvironment |
| 673 .isOverloadedArithmeticOperatorAndType(interfaceMember, receiverType); |
| 674 } |
| 675 var calleeType = getCalleeFunctionType(interfaceMember, receiverType, |
| 676 desugaredInvocation.name, !isImplicitCall); |
| 677 bool forceArgumentInference = false; |
| 678 if (isDryRun) { |
| 679 if (_isUserDefinableOperator(desugaredInvocation.name.name)) { |
| 680 // If this is an overloadable arithmetic operator, then type inference |
| 681 // might depend on the RHS, so conservatively assume it does. |
| 682 forceArgumentInference = |
| 683 isOverloadableArithmeticOperator(desugaredInvocation.name.name); |
| 684 } else { |
| 685 // If no type arguments were given, then type inference might depend on |
| 686 // the arguments (because the called method might be generic), so |
| 687 // conservatively assume it does. |
| 688 forceArgumentInference = |
| 689 getExplicitTypeArguments(desugaredInvocation.arguments) == null; |
| 690 } |
| 691 } |
| 692 var inferredType = inferInvocation(typeContext, typeNeeded, fileOffset, |
| 693 calleeType, calleeType.returnType, desugaredInvocation.arguments, |
| 694 isOverloadedArithmeticOperator: isOverloadedArithmeticOperator, |
| 695 receiverType: receiverType, |
| 696 forceArgumentInference: forceArgumentInference); |
| 697 listener.methodInvocationExit(expression, inferredType); |
| 698 return inferredType; |
| 699 } |
| 700 |
624 @override | 701 @override |
625 void inferParameterInitializer( | 702 void inferParameterInitializer( |
626 Expression initializer, DartType declaredType) { | 703 Expression initializer, DartType declaredType) { |
627 assert(closureContext == null); | 704 assert(closureContext == null); |
628 inferExpression(initializer, declaredType, false); | 705 inferExpression(initializer, declaredType, false); |
629 } | 706 } |
630 | 707 |
631 /// Performs the core type inference algorithm for property gets (this handles | 708 /// Performs the core type inference algorithm for property gets (this handles |
632 /// both null-aware and non-null-aware property gets). | 709 /// both null-aware and non-null-aware property gets). |
633 DartType inferPropertyGet( | 710 DartType inferPropertyGet( |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
743 void _forEachArgument( | 820 void _forEachArgument( |
744 Arguments arguments, void callback(String name, Expression expression)) { | 821 Arguments arguments, void callback(String name, Expression expression)) { |
745 for (var expression in arguments.positional) { | 822 for (var expression in arguments.positional) { |
746 callback(null, expression); | 823 callback(null, expression); |
747 } | 824 } |
748 for (var namedExpression in arguments.named) { | 825 for (var namedExpression in arguments.named) { |
749 callback(namedExpression.name, namedExpression.value); | 826 callback(namedExpression.name, namedExpression.value); |
750 } | 827 } |
751 } | 828 } |
752 } | 829 } |
OLD | NEW |