private void visitReturn ( NodeTraversal t , Node n ) { Node enclosingFunction = t . getEnclosingFunction ( ) ; if ( enclosingFunction . isGeneratorFunction ( ) && ! n . hasChildren ( ) ) { // Allow "return;" in a generator function, even if it's not the declared return type. // e.g. Don't warn for a generator function with JSDoc "@return {!Generator<number>}" and // a "return;" in the fn body, even though "undefined" does not match "number". return ; } JSType jsType = getJSType ( enclosingFunction ) ; if ( jsType . isFunctionType ( ) ) { FunctionType functionType = jsType . toMaybeFunctionType ( ) ; JSType returnType = functionType . getReturnType ( ) ; // if no return type is specified, undefined must be returned // (it's a void function) if ( returnType == null ) { returnType = getNativeType ( VOID_TYPE ) ; } else if ( enclosingFunction . isGeneratorFunction ( ) ) { // Unwrap the template variable from a generator function's declared return type. // e.g. if returnType is "Generator<string>", make it just "string". returnType = JsIterables . getElementType ( returnType , typeRegistry ) ; if ( enclosingFunction . isAsyncGeneratorFunction ( ) ) { // Can return x|IThenable<x> in an AsyncGenerator<x>, no await needed. Note that we must // first wrap the type in IThenable as createAsyncReturnableType will map a non-IThenable // to `?`. returnType = Promises . createAsyncReturnableType ( typeRegistry , Promises . wrapInIThenable ( typeRegistry , returnType ) ) ; } } else if ( enclosingFunction . isAsyncFunction ( ) ) { // e.g. `!Promise<string>` => `string|!IThenable<string>` // We transform the expected return type rather than the actual return type so that the // extual return type is always reported to the user. This was felt to be clearer. returnType = Promises . createAsyncReturnableType ( typeRegistry , returnType ) ; } else if ( returnType . isVoidType ( ) && functionType . isConstructor ( ) ) { // Allow constructors to use empty returns for flow control. if ( ! n . hasChildren ( ) ) { return ; } // Allow constructors to return its own instance type returnType = functionType . getInstanceType ( ) ; } // fetching the returned value's type Node valueNode = n . getFirstChild ( ) ; JSType actualReturnType ; if ( valueNode == null ) { actualReturnType = getNativeType ( VOID_TYPE ) ; valueNode = n ; } else { actualReturnType = getJSType ( valueNode ) ; } // verifying validator . expectCanAssignTo ( valueNode , actualReturnType , returnType , "inconsistent return type" ) ; } }
Visits a RETURN node .