public function testScopeChanges() { $function = new \PHPParser_Node_Stmt_Function('foo', array('stmts' => $functionBlock = new BlockNode(array(new \PHPParser_Node_Expr_Assign(new \PHPParser_Node_Expr_Variable('foo'), $closure = new \PHPParser_Node_Expr_Closure(array('stmts' => $closureBlock = new BlockNode(array())))))))); $callback = $this->getMock('Scrutinizer\\PhpAnalyzer\\PhpParser\\Traversal\\CallbackInterface'); $functionScope = $closureScope = null; $t = new NodeTraversal($callback); $callback->expects($this->atLeastOnce())->method('shouldTraverse')->will($this->returnValue(true)); $self = $this; $callback->expects($this->atLeastOnce())->method('visit')->will($this->returnCallback(function (NodeTraversal $t, \PHPParser_Node $node, \PHPParser_Node $parent = null) use(&$functionScope, &$closureScope, $function, $closure, $self) { if (null === $parent) { $functionScope = $t->getScope(); $self->assertSame(1, $t->getScopeDepth()); $self->assertSame($function, $t->getScopeRoot()); } if ($parent instanceof \PHPParser_Node_Expr_Closure) { $closureScope = $t->getScope(); $self->assertSame(2, $t->getScopeDepth()); $self->assertSame($closure, $t->getScopeRoot()); } })); $t->traverse($function); $this->assertInstanceOf('Scrutinizer\\PhpAnalyzer\\PhpParser\\Scope\\Scope', $functionScope); $this->assertInstanceOf('Scrutinizer\\PhpAnalyzer\\PhpParser\\Scope\\Scope', $closureScope); $this->assertNotSame($functionScope, $closureScope); }
public function enterScope(NodeTraversal $t) { $node = $t->getScopeRoot(); $function = null; if ($node instanceof \PHPParser_Node_Stmt_Function) { $function = $this->typeRegistry->getFunction($node->name); if (null !== $function) { $this->parser->setCurrentClassName(null); $this->parser->setImportedNamespaces($this->importedNamespaces = $function->getImportedNamespaces()); } } else { if ($node instanceof \PHPParser_Node_Stmt_ClassMethod) { $objType = $t->getScope()->getTypeOfThis()->toMaybeObjectType(); if (null !== $objType) { /** @var $objType MethodContainer */ $this->parser->setCurrentClassName($objType->getName()); $this->parser->setImportedNamespaces($this->importedNamespaces = $objType->getImportedNamespaces()); $function = $objType->getMethod($node->name); } } } if (null !== $function) { if (null !== ($returnType = $function->getReturnType())) { $this->verifyReturnType($returnType, $node); } foreach ($function->getParameters() as $param) { /** @var $param Parameter */ if (null !== ($paramType = $param->getPhpType())) { $this->verifyParamType($paramType, $node, $param->getName()); } } } return true; }
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 enterScope(NodeTraversal $t) { $node = $t->getScopeRoot(); $function = null; if ($node instanceof \PHPParser_Node_Stmt_ClassMethod) { $function = $t->getScope()->getTypeOfThis()->getMethod($node->name)->getMethod(); } else { if ($node instanceof \PHPParser_Node_Stmt_Function) { $function = $this->typeRegistry->getFunctionByNode($node); } } if (null !== $function) { $this->inferTypesForFunction($function); } }
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(); }
/** * Returns the originating function, or method. * * @param NodeTraversal $t * * @return AbstractFunction|null */ private function getSource(NodeTraversal $t) { $root = $t->getScopeRoot(); if ($root instanceof \PHPParser_Node_Stmt_Function) { return $this->typeRegistry->getFunctionByNode($root); } else { if ($root instanceof \PHPParser_Node_Stmt_ClassMethod) { // If the originating object was not part of this packages' dependencies, or we // have not scanned it for some other reason, we have to bail out here. if (null === ($thisObject = $t->getScope()->getTypeOfThis()->toMaybeObjectType())) { return null; } // This could be the case if the same class has been defined more than once. // We had such cases for example when people add fixtures for code generation to their // packages, and do not ensure that class names are unique. if (null === ($classMethod = $thisObject->getMethod($root->name))) { return null; } return $classMethod->getMethod(); } } return null; }