private void addNode ( Node n ) { Node target = null ; Node fn = null ; String name = null ; switch ( n . getToken ( ) ) { // handles assignment cases like: // a = function() {} // a = b = c = function() {} case ASSIGN : if ( ! n . getFirstChild ( ) . isQualifiedName ( ) ) { compiler . report ( JSError . make ( n , INJECTED_FUNCTION_ON_NON_QNAME ) ) ; return ; } name = n . getFirstChild ( ) . getQualifiedName ( ) ; // last node of chained assignment. fn = n ; while ( fn . isAssign ( ) ) { fn = fn . getLastChild ( ) ; } target = n . getParent ( ) ; break ; // handles function case: // function fnName() {} case FUNCTION : name = NodeUtil . getName ( n ) ; fn = n ; target = n ; if ( n . getParent ( ) . isAssign ( ) && n . getParent ( ) . getJSDocInfo ( ) . isNgInject ( ) ) { // This is a function assigned into a symbol, e.g. a regular function // declaration in a goog.module or goog.scope. // Skip in this traversal, it is handled when visiting the assign. return ; } break ; // handles var declaration cases like: // var a = function() {} // var a = b = function() {} case VAR : case LET : case CONST : name = n . getFirstChild ( ) . getString ( ) ; // looks for a function node. fn = getDeclarationRValue ( n ) ; target = n ; break ; // handles class method case: // class clName(){ // constructor(){} // someMethod(){} <=== // } case MEMBER_FUNCTION_DEF : Node parent = n . getParent ( ) ; if ( parent . isClassMembers ( ) ) { Node classNode = parent . getParent ( ) ; String midPart = n . isStaticMember ( ) ? "." : ".prototype." ; name = NodeUtil . getName ( classNode ) + midPart + n . getString ( ) ; if ( NodeUtil . isEs6ConstructorMemberFunctionDef ( n ) ) { name = NodeUtil . getName ( classNode ) ; } fn = n . getFirstChild ( ) ; if ( classNode . getParent ( ) . isAssign ( ) || classNode . getParent ( ) . isName ( ) ) { target = classNode . getGrandparent ( ) ; } else { target = classNode ; } } break ; default : break ; } if ( fn == null || ! fn . isFunction ( ) ) { compiler . report ( JSError . make ( n , INJECT_NON_FUNCTION_ERROR ) ) ; return ; } // report an error if the function declaration did not take place in a block or global scope if ( ! target . getParent ( ) . isScript ( ) && ! target . getParent ( ) . isBlock ( ) && ! target . getParent ( ) . isModuleBody ( ) ) { compiler . report ( JSError . make ( n , INJECT_IN_NON_GLOBAL_OR_BLOCK_ERROR ) ) ; return ; } // checks that name is present, which must always be the case unless the // compiler allowed a syntax error or a dangling anonymous function // expression. checkNotNull ( name ) ; // registers the node. injectables . add ( new NodeContext ( name , n , fn , target ) ) ; }
Add node to the list of injectables .