private void traverseFunction ( Node n , Node parent ) { final Node fnName = n . getFirstChild ( ) ; // NOTE: If a function declaration is the root of a traversal, then we will treat it as a // function expression (since 'parent' is null, even though 'n' actually has a parent node) and // traverse the function name before entering the scope, rather than afterwards. Removing the // null check for 'parent' seems safe, but causes a rare crash when traverseScopeRoots is called // by PeepholeOptimizationsPass on a function that somehow doesn't actually have a parent at all // (presumably because it's already been removed from the AST?) so that doesn't actually work. // This does not actually change anything, though, since rooting a traversal at a function node // causes the function scope to be entered twice (unless using #traverseAtScope, which doesn't // call this method), so that the name node is just always traversed inside the scope anyway. boolean isFunctionDeclaration = parent != null && NodeUtil . isFunctionDeclaration ( n ) ; if ( isFunctionDeclaration ) { // Function declarations are in the scope containing the declaration. traverseBranch ( fnName , n ) ; } curNode = n ; pushScope ( n ) ; if ( ! isFunctionDeclaration ) { // Function expression names are only accessible within the function // scope. traverseBranch ( fnName , n ) ; } final Node args = fnName . getNext ( ) ; final Node body = args . getNext ( ) ; // Args traverseBranch ( args , n ) ; // Body // ES6 "arrow" function may not have a block as a body. traverseBranch ( body , n ) ; popScope ( ) ; }
Traverses a function .