@@ -121,6 +121,20 @@ abstract class FixBuilder extends GeneralizingAstVisitor<DartType>
121121 _assignedVariables.capturedAnywhere);
122122 }
123123
124+ @override
125+ DartType visitArgumentList (ArgumentList node) {
126+ for (var argument in node.arguments) {
127+ Expression expression;
128+ if (argument is NamedExpression ) {
129+ expression = argument.expression;
130+ } else {
131+ expression = argument;
132+ }
133+ visitSubexpression (expression, UnknownInferredType .instance);
134+ }
135+ return null ;
136+ }
137+
124138 @override
125139 DartType visitAssignmentExpression (AssignmentExpression node) {
126140 var operatorType = node.operator .type;
@@ -378,6 +392,44 @@ abstract class FixBuilder extends GeneralizingAstVisitor<DartType>
378392 .withNullability (NullabilitySuffix .none);
379393 }
380394
395+ @override
396+ DartType visitMethodInvocation (MethodInvocation node) {
397+ var target = node.realTarget;
398+ var callee = node.methodName.staticElement;
399+ bool isNullAware = node.isNullAware;
400+ DartType targetType;
401+ if (target != null ) {
402+ if (callee is ExecutableElement && callee.isStatic) {
403+ target.accept (this );
404+ } else {
405+ targetType = visitSubexpression (
406+ target,
407+ isNullAware || isDeclaredOnObject (node.methodName.name)
408+ ? typeProvider.dynamicType
409+ : typeProvider.objectType);
410+ }
411+ }
412+ if (callee == null ) {
413+ // Dynamic dispatch. The return type is `dynamic`.
414+ node.typeArguments? .accept (this );
415+ node.argumentList.accept (this );
416+ return typeProvider.dynamicType;
417+ }
418+ var calleeType = _computeMigratedType (callee, targetType: targetType);
419+ var expressionType = _handleInvocationArguments (
420+ node,
421+ node.argumentList.arguments,
422+ node.typeArguments,
423+ node.typeArgumentTypes,
424+ calleeType as FunctionType ,
425+ null ,
426+ invokeType: node.staticInvokeType);
427+ if (isNullAware) {
428+ expressionType = _typeSystem.makeNullable (expressionType as TypeImpl );
429+ }
430+ return expressionType;
431+ }
432+
381433 @override
382434 DartType visitNode (AstNode node) {
383435 // Every node type needs its own visit method.
@@ -665,6 +717,51 @@ abstract class FixBuilder extends GeneralizingAstVisitor<DartType>
665717 return combinedType;
666718 }
667719
720+ DartType _handleInvocationArguments (
721+ AstNode node,
722+ Iterable <AstNode > arguments,
723+ TypeArgumentList typeArguments,
724+ List <DartType > typeArgumentTypes,
725+ FunctionType calleeType,
726+ List <TypeParameterElement > constructorTypeParameters,
727+ {DartType invokeType}) {
728+ var typeFormals = constructorTypeParameters ?? calleeType.typeFormals;
729+ if (typeFormals.isNotEmpty) {
730+ throw UnimplementedError ('TODO(paulberry): Invocation of generic method' );
731+ }
732+ int i = 0 ;
733+ var namedParameterTypes = < String , DartType > {};
734+ var positionalParameterTypes = < DartType > [];
735+ for (var parameter in calleeType.parameters) {
736+ if (parameter.isNamed) {
737+ namedParameterTypes[parameter.name] = parameter.type;
738+ } else {
739+ positionalParameterTypes.add (parameter.type);
740+ }
741+ }
742+ for (var argument in arguments) {
743+ String name;
744+ Expression expression;
745+ if (argument is NamedExpression ) {
746+ name = argument.name.label.name;
747+ expression = argument.expression;
748+ } else {
749+ expression = argument as Expression ;
750+ }
751+ DartType parameterType;
752+ if (name != null ) {
753+ parameterType = namedParameterTypes[name];
754+ assert (parameterType != null , 'Missing type for named parameter' );
755+ } else {
756+ assert (i < positionalParameterTypes.length,
757+ 'Missing positional parameter at $i ' );
758+ parameterType = positionalParameterTypes[i++ ];
759+ }
760+ visitSubexpression (expression, parameterType);
761+ }
762+ return calleeType.returnType;
763+ }
764+
668765 DartType _handlePropertyAccess (Expression node, Expression target,
669766 SimpleIdentifier propertyName, bool isNullAware) {
670767 var staticElement = propertyName.staticElement;
0 commit comments