src/Pahout.php
private function traverse(string $file, Node $node)
    {
        Logger::getInstance()->debug('Traverse: '.\ast\get_kind_name($node->kind));

        foreach ($this->tools as $tool) {
            Logger::getInstance()->debug('Entrypoint check: '.get_class($tool));
            if ($tool::ENTRY_POINT !== $node->kind) {
                continue;
            }

            Logger::getInstance()->debug('Run: '.get_class($tool));
            $hints = $tool->run($file, $node);
            $hints = array_filter($hints, function ($hint) {
                foreach ($this->annotations as $annotation) {
                    if (!($annotation instanceof Annotation\Rebel)) {
                        continue;
                    }
                    if ($annotation->isAffected($hint)) {
                        Logger::getInstance()->debug('Annotation effecting to hint: line='.$hint->lineno);
                        return false;
                    }
                }
                Logger::getInstance()->debug('Detected hints: line='.$hint->lineno);
                return true;
            });

            if (count($hints) === 0) {
                continue;
            }
            array_push($this->hints, ...$hints);
        }

        foreach ($node->children as $type => $child) {
            if ($child instanceof Node) {
                $this->traverse($file, $child);
            }
        }
    }
private function traverse(string $file, Node $node)
    {
        Logger::getInstance()->debug('Traverse: '.\ast\get_kind_name($node->kind));

        foreach ($this->tools as $tool) {
            Logger::getInstance()->debug('Entrypoint check: '.get_class($tool));
            if ($tool::ENTRY_POINT !== $node->kind) {
                continue;
            }

            Logger::getInstance()->debug('Run: '.get_class($tool));
            $hints = $tool->run($file, $node);
            $hints = array_filter($hints, function ($hint) {
                foreach ($this->annotations as $annotation) {
                    if (!($annotation instanceof Annotation\Rebel)) {
                        continue;
                    }
                    if ($annotation->isAffected($hint)) {
                        Logger::getInstance()->debug('Annotation effecting to hint: line='.$hint->lineno);
                        return false;
                    }
                }
                Logger::getInstance()->debug('Detected hints: line='.$hint->lineno);
                return true;
            });

            if (count($hints) === 0) {
                continue;
            }
            array_push($this->hints, ...$hints);
        }

        foreach ($node->children as $type => $child) {
            if ($child instanceof Node) {
                $this->traverse($file, $child);
            }
        }
    }
private function traverse ( string $ file , Node $ node ) { Logger :: getInstance ( ) -> debug ( 'Traverse: ' . \ ast \ get_kind_name ( $ node -> kind ) ) ; foreach ( $ this -> tools as $ tool ) { Logger :: getInstance ( ) -> debug ( 'Entrypoint check: ' . get_class ( $ tool ) ) ; if ( $ tool :: ENTRY_POINT !== $ node -> kind ) { continue ; } Logger :: getInstance ( ) -> debug ( 'Run: ' . get_class ( $ tool ) ) ; $ hints = $ tool -> run ( $ file , $ node ) ; $ hints = array_filter ( $ hints , function ( $ hint ) { foreach ( $ this -> annotations as $ annotation ) { if ( ! ( $ annotation instanceof Annotation \ Rebel ) ) { continue ; } if ( $ annotation -> isAffected ( $ hint ) ) { Logger :: getInstance ( ) -> debug ( 'Annotation effecting to hint: line=' . $ hint -> lineno ) ; return false ; } } Logger :: getInstance ( ) -> debug ( 'Detected hints: line=' . $ hint -> lineno ) ; return true ; } ) ; if ( count ( $ hints ) === 0 ) { continue ; } array_push ( $ this -> hints , ... $ hints ) ; } foreach ( $ node -> children as $ type => $ child ) { if ( $ child instanceof Node ) { $ this -> traverse ( $ file , $ child ) ; } } }
Traverse AST nodes with DFS and check the entrypoint of tools.

Each time it compares the kind of Node with the entry point of tools.
If it matches, it will perform an detection by the tool.
Do this process recursively until the children is not a Node.

@param string $file File name to be analyzed.
@param Node   $node AST node to be analyzed.
@return void

@suppress PhanUndeclaredConstant
Traverse AST nodes with DFS and check the entrypoint of tools .