/** * @param Node\Stmt\Class_ $node * * @return Node\Stmt\Class_ */ public function resolveConstructor(Node\Stmt\Class_ $node) { foreach ($node->stmts as $key => $stmt) { if ($stmt instanceof Node\Stmt\ClassMethod && $stmt->name === '__construct') { // this will make problems we need an layer above which chains the variable resolvers // because we need may need more than this resolver // skip constructor if is abstract if ($stmt->isAbstract()) { return $node; } // change recursivly the nodes $subTraverser = new NodeTraverser(); foreach ($this->visitors as $visitor) { $subTraverser->addVisitor($visitor); } // the table switches to a method scope // $x = ... will be treated normal // $this->x = ... will be stored in the above class scope and is available afterwards $this->table->enterScope(new TableScope(TableScope::CLASS_METHOD_SCOPE)); $subTraverser->traverse($stmt->params); $nodes = $subTraverser->traverse($stmt->stmts); $this->table->leaveScope(); //override the old statement $stmt->stmts = $nodes; // override the classmethod statement in class $node->stmts[$key] = $stmt; // return the changed node to override it return $node; } } // no constructor defined return $node; }
public function leaveNode(Node $node) { if ($node instanceof Node\Stmt\Class_ || $node instanceof Node\Stmt\Interface_ || $node instanceof Node\Stmt\Trait_) { $this->table->leaveScope(); } if ($node instanceof Node\Stmt\ClassMethod || $node instanceof Node\Stmt\Function_) { $this->table->leaveScope(); } }
public function testEnterLeaveAndCurrentScope() { $table = new SymbolTable(); $this->assertEquals(TableScope::GLOBAL_SCOPE, $table->currentScope()->scope()); $classScope = $this->prophesize('SensioLabs\\DeprecationDetector\\TypeGuessing\\SymbolTable\\TableScope'); $classScope->scope()->willReturn(TableScope::CLASS_LIKE_SCOPE); $classScope = $classScope->reveal(); $table->enterScope($classScope); $this->assertSame($classScope, $table->currentScope()); $table->leaveScope(); $this->assertEquals(TableScope::GLOBAL_SCOPE, $table->currentScope()->scope()); }