Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(69)

Side by Side Diff: pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Issue 2950923002: Add type inference for null-aware method invocations. (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart ('k') | pkg/front_end/test/fasta/kompile.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698