public function enterScope(NodeTraversal $t) { $scope = $t->getScope(); $cfg = $t->getControlFlowGraph(); $this->liveness = new LiveVariablesAnalysis($cfg, $scope); $this->liveness->analyze(); $this->tryRemoveDeadAssignments($t, $cfg); }
public function enterScope(NodeTraversal $t) { $cfg = $t->getControlFlowGraph(); $scope = $t->getScope(); $mayBeAnalysis = new MayBeReachingUseAnalysis($cfg, $scope); $mayBeAnalysis->analyze(); $mustBeAnalysis = new MustBeReachingDefAnalysis($cfg, $scope); $mustBeAnalysis->setLogger($this->logger); $mustBeAnalysis->analyze(); }
public function enterScope(NodeTraversal $traversal) { $typeInference = new TypeInference($traversal->getControlFlowGraph(), $this->reverseInterpreter, $this->functionInterpreter, $this->methodInterpreter, $this->commentParser, $traversal->getScope(), $this->registry, $this->logger); try { $typeInference->analyze(); } catch (MaxIterationsExceededException $ex) { $scopeRoot = $traversal->getScopeRoot(); $this->logger->warning($ex->getMessage() . ' - Scope-Root: ' . get_class($scopeRoot) . ' on line ' . $scopeRoot->getLine() . ' in ' . $this->file->getName()); } }
public function shouldTraverse(NodeTraversal $t, \PHPParser_Node $node, \PHPParser_Node $parent = null) { $graphNode = $t->getControlFlowGraph()->getNode($node); if (null !== $graphNode && GraphReachability::UNREACHABLE === $graphNode->getAttribute(GraphReachability::ATTR_REACHABILITY)) { // Only report error when there are some line number informations. // There are synthetic nodes with no line number informations, nodes // introduced by other passes (although not likely since this pass should // be executed early) or some PHPParser bug. if (-1 !== $node->getLine()) { $this->file->addComment($node->getLine(), Comment::warning('usage.unreachable_code', '``%unreachable_code%`` is not reachable.', array('unreachable_code' => $this->prettyPrinter->prettyPrint(array($node))))); // From now on, we are going to assume the user fixed the error and not // give more warnings related to code sections reachable from this node. $r = new GraphReachability($t->getControlFlowGraph()); $r->recompute($node); // Saves time by not traversing children. return false; } } return true; }
public function enterScope(NodeTraversal $t) { $root = $t->getScopeRoot(); if (!$root instanceof \PHPParser_Node_Stmt_ClassMethod) { return; } if ($root->name !== $this->method) { return; } $container = $root->getAttribute('parent')->getAttribute('parent'); $className = implode("\\", $container->namespacedName->parts); if ($this->class !== substr($className, -1 * strlen($this->class))) { return; } $this->cfg = $t->getControlFlowGraph(); }
public function enterScope(NodeTraversal $t) { $scope = $t->getScope(); $root = $scope->getRootNode(); if (!$root instanceof \PHPParser_Node_Stmt_Function && !$root instanceof \PHPParser_Node_Stmt_ClassMethod) { return; } // Bail out on abstract methods. if ($root instanceof \PHPParser_Node_Stmt_ClassMethod && ($root->type & \PHPParser_Node_Stmt_Class::MODIFIER_ABSTRACT) !== 0) { return; } // Bail out on methods defined on interfaces. if ($root instanceof \PHPParser_Node_Stmt_ClassMethod && $root->getAttribute('parent')->getAttribute('parent') instanceof \PHPParser_Node_Stmt_Interface) { return; } // Bail out on built-in functions marked by the @jms-builtin annotation. // For these, we will solely infer types from doc comments. if (false !== strpos($root->getDocComment(), '@jms-builtin')) { return; } // Same as above, but for methods of classes marked with @jms-builtin. if ($root instanceof \PHPParser_Node_Stmt_ClassMethod) { $maybeClass = $root->getAttribute('parent')->getAttribute('parent'); if ($maybeClass instanceof \PHPParser_Node_Stmt_Class && false !== strpos($maybeClass->getDocComment(), '@jms-builtin')) { return; } } $cfg = $t->getControlFlowGraph(); $builder = new UnionTypeBuilder($this->typeRegistry); foreach ($cfg->getNode(null)->getInEdges() as $edge) { $sourceNode = $edge->getSource()->getAstNode(); if (!$sourceNode instanceof \PHPParser_Node_Stmt_Return) { $builder->addAlternate($this->typeRegistry->getNativeType('null')); continue; } // If there is no type information available, we cannot make any // assumptions for this function/method. if (!($type = $sourceNode->getAttribute('type'))) { return; } $builder->addAlternate($type); } $type = $builder->build(); if ($type->isUnknownType()) { return; } $function = $this->typeRegistry->getFunctionByNode($root); if ($function instanceof GlobalFunction) { if ($this->hasTypeChanged($type, $function->getReturnType())) { $this->repeatedPass->repeat(); } $function->setReturnType($type); } else { if ($function instanceof ContainerMethodInterface) { $method = $function->getMethod(); if ($this->hasTypeChanged($type, $method->getReturnType())) { $this->repeatedPass->repeat(); } $method->setReturnType($type); } } }