/** * Add hooks to the queue and update the node stack when we enter a node. * * If we are entering a class, function or method, we push it to the location * stack. This is just so that we know whether we are in the file scope or not, * so that hooks in the main file scope can be added to the file. * * We also check function calls to see if there are any actions or hooks. If * there are, they are added to the file's hooks if in the global scope, or if * we are in a function/method, they are added to the queue. They will be * assigned to the function by leaveNode(). We also check for any other function * calls and treat them similarly, so that we can export a list of functions * used by each element. * * Finally, we pick up any docblocks for nodes that usually aren't documentable, * so they can be assigned to the hooks to which they may belong. * * @param \PHPParser_Node $node */ public function enterNode(\PHPParser_Node $node) { parent::enterNode($node); switch ($node->getType()) { // Add classes, functions, and methods to the current location stack case 'Stmt_Class': case 'Stmt_Function': case 'Stmt_ClassMethod': array_push($this->location, $node); break; // Parse out hook definitions and function calls and add them to the queue. // Parse out hook definitions and function calls and add them to the queue. case 'Expr_FuncCall': $function = new Function_Call_Reflector($node, $this->context); // Add the call to the list of functions used in this scope. $this->getLocation()->uses['functions'][] = $function; if ($this->isFilter($node)) { if ($this->last_doc && !$node->getDocComment()) { $node->setAttribute('comments', array($this->last_doc)); $this->last_doc = null; } $hook = new Hook_Reflector($node, $this->context); // Add it to the list of hooks used in this scope. $this->getLocation()->uses['hooks'][] = $hook; } break; // Parse out method calls, so we can export where methods are used. // Parse out method calls, so we can export where methods are used. case 'Expr_MethodCall': $method = new Method_Call_Reflector($node, $this->context); // Add it to the list of methods used in this scope. $this->getLocation()->uses['methods'][] = $method; break; // Parse out method calls, so we can export where methods are used. // Parse out method calls, so we can export where methods are used. case 'Expr_StaticCall': $method = new Static_Method_Call_Reflector($node, $this->context); // Add it to the list of methods used in this scope. $this->getLocation()->uses['methods'][] = $method; break; // Parse out `new Class()` calls as uses of Class::__construct(). // Parse out `new Class()` calls as uses of Class::__construct(). case 'Expr_New': $method = new \WP_Parser\Method_Call_Reflector($node, $this->context); // Add it to the list of methods used in this scope. $this->getLocation()->uses['methods'][] = $method; break; } // Pick up DocBlock from non-documentable elements so that it can be assigned // to the next hook if necessary. We don't do this for name nodes, since even // though they aren't documentable, they still carry the docblock from their // corresponding class/constant/function/etc. that they are the name of. If // we don't ignore them, we'll end up picking up docblocks that are already // associated with a named element, and so aren't really from a non- // documentable element after all. if (!$this->isNodeDocumentable($node) && 'Name' !== $node->getType() && ($docblock = $node->getDocComment())) { $this->last_doc = $docblock; } }