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;
 }