Phan\Analysis::shouldVisit PHP Method

shouldVisit() public static method

Possible Premature Optimization. We can trim a bunch of calls to nodes that we'll never analyze during parsing, pre-order analysis or post-order analysis.
public static shouldVisit ( ast\Node $node ) : boolean
$node ast\Node A node we'd like to determine if we should visit
return boolean True if the given node should be visited or false if it should be skipped entirely
    public static function shouldVisit(Node $node)
    {
        // When doing dead code detection, we need to go
        // super deep
        if (Config::get()->dead_code_detection || Config::get()->should_visit_all_nodes) {
            return true;
        }
        switch ($node->kind) {
            case \ast\AST_ARRAY_ELEM:
            case \ast\AST_ASSIGN_OP:
            case \ast\AST_BREAK:
            case \ast\AST_CAST:
            case \ast\AST_CLONE:
            case \ast\AST_CLOSURE_USES:
            case \ast\AST_CLOSURE_VAR:
            case \ast\AST_COALESCE:
            case \ast\AST_CONST_ELEM:
            case \ast\AST_CONTINUE:
            case \ast\AST_EMPTY:
            case \ast\AST_EXIT:
            case \ast\AST_INCLUDE_OR_EVAL:
            case \ast\AST_ISSET:
            case \ast\AST_MAGIC_CONST:
            case \ast\AST_NAME:
            case \ast\AST_NAME_LIST:
            case \ast\AST_PARAM:
            case \ast\AST_PARAM_LIST:
            case \ast\AST_POST_INC:
            case \ast\AST_PRE_INC:
            case \ast\AST_STATIC_PROP:
            case \ast\AST_TYPE:
            case \ast\AST_UNARY_OP:
            case \ast\AST_UNSET:
            case \ast\AST_YIELD:
                return false;
        }
        return true;
    }

Usage Example

示例#1
0
 /**
  * For 'closed context' items (classes, methods, functions,
  * closures), we analyze children in the parent context, but
  * then return the parent context itself unmodified by the
  * children.
  *
  *           │
  *           ▼
  *        ┌──●────┐
  *        │       │
  *        ●──●──● │
  *           ┌────┘
  *           ●
  *           │
  *           ▼
  *
  * @param Node $node
  * An AST node we'd like to determine the UnionType
  * for
  *
  * @return Context
  * The updated context after visiting the node
  */
 public function visitClosedContext(Node $node) : Context
 {
     // Make a copy of the internal context so that we don't
     // leak any changes within the closed context to the
     // outer scope
     $context = clone $this->context->withLineNumberStart($node->lineno ?? 0);
     // Visit the given node populating the code base
     // with anything we learn and get a new context
     // indicating the state of the world within the
     // given node
     $context = (new PreOrderAnalysisVisitor($this->code_base, $context))($node);
     assert(!empty($context), 'Context cannot be null');
     // We collect all child context so that the
     // PostOrderAnalysisVisitor can optionally operate on
     // them
     $child_context_list = [];
     $child_context = $context;
     // With a context that is inside of the node passed
     // to this method, we analyze all children of the
     // node.
     foreach ($node->children ?? [] as $child_node) {
         // Skip any non Node children.
         if (!$child_node instanceof Node) {
             continue;
         }
         if (!Analysis::shouldVisit($child_node)) {
             $child_context->withLineNumberStart($child_node->lineno ?? 0);
             continue;
         }
         // Step into each child node and get an
         // updated context for the node
         $child_context = (new BlockAnalysisVisitor($this->code_base, $child_context, $node, $this->depth + 1))($child_node);
         $child_context_list[] = $child_context;
     }
     // For if statements, we need to merge the contexts
     // of all child context into a single scope based
     // on any possible branching structure
     $context = (new ContextMergeVisitor($this->code_base, $context, $child_context_list))($node);
     // Now that we know all about our context (like what
     // 'self' means), we can analyze statements like
     // assignments and method calls.
     $context = (new PostOrderAnalysisVisitor($this->code_base, $context->withLineNumberStart($node->lineno ?? 0), $this->parent_node))($node);
     // Return the initial context as we exit
     return $this->context;
 }