private void updateTypeOfArguments ( Node n , FunctionType fnType ) { checkState ( NodeUtil . isInvocation ( n ) , n ) ; Iterator < Node > parameters = fnType . getParameters ( ) . iterator ( ) ; if ( n . isTaggedTemplateLit ( ) ) { // Skip the first parameter because it corresponds to a constructed array of the template lit // subs, not an actual AST node, so there's nothing to update. if ( ! parameters . hasNext ( ) ) { // TypeCheck will warn if there is no first parameter. Just bail out here. return ; } parameters . next ( ) ; } Iterator < Node > arguments = NodeUtil . getInvocationArgsAsIterable ( n ) . iterator ( ) ; Node iParameter ; Node iArgument ; // Note: if there are too many or too few arguments, TypeCheck will warn. while ( parameters . hasNext ( ) && arguments . hasNext ( ) ) { iArgument = arguments . next ( ) ; JSType iArgumentType = getJSType ( iArgument ) ; iParameter = parameters . next ( ) ; JSType iParameterType = getJSType ( iParameter ) ; inferPropertyTypesToMatchConstraint ( iArgumentType , iParameterType ) ; // If the parameter to the call is a function expression, propagate the // function signature from the call site to the function node. // Filter out non-function types (such as null and undefined) as // we only care about FUNCTION subtypes here. FunctionType restrictedParameter = null ; if ( iParameterType . isUnionType ( ) ) { UnionType union = iParameterType . toMaybeUnionType ( ) ; for ( JSType alternative : union . getAlternates ( ) ) { if ( alternative . isFunctionType ( ) ) { // There is only one function type per union. restrictedParameter = alternative . toMaybeFunctionType ( ) ; break ; } } } else { restrictedParameter = iParameterType . toMaybeFunctionType ( ) ; } if ( restrictedParameter != null && iArgument . isFunction ( ) && iArgumentType . isFunctionType ( ) ) { FunctionType argFnType = iArgumentType . toMaybeFunctionType ( ) ; JSDocInfo argJsdoc = iArgument . getJSDocInfo ( ) ; // Treat the parameter & return types of the function as 'declared' if the function has // JSDoc with type annotations, or a parameter has inline JSDoc. // Note that this does not distinguish between cases where all parameters have JSDoc vs // only one parameter has JSDoc. boolean declared = ( argJsdoc != null && argJsdoc . containsDeclaration ( ) ) || NodeUtil . functionHasInlineJsdocs ( iArgument ) ; iArgument . setJSType ( matchFunction ( restrictedParameter , argFnType , declared ) ) ; } } }
Performs a limited back - inference on function arguments based on the expected parameter types .