/** * @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 testSetClassProperty() { $table = new SymbolTable(); $classScope = $this->prophesize('SensioLabs\\DeprecationDetector\\TypeGuessing\\SymbolTable\\TableScope'); $classScope->scope()->willReturn('CLASS_LIKE_SCOPE'); $classScope->setSymbol(new Symbol('property', 'type'))->shouldBeCalled(); $methodScope = $this->prophesize('SensioLabs\\DeprecationDetector\\TypeGuessing\\SymbolTable\\TableScope'); $methodScope->scope()->willReturn('CLASS_METHOD_SCOPE'); $table->enterScope($classScope->reveal()); $table->enterScope($methodScope->reveal()); $table->setClassProperty('property', 'type'); }
public function enterNode(Node $node) { if ($node instanceof Node\Stmt\ClassLike) { $this->table->enterScope(new TableScope(TableScope::CLASS_LIKE_SCOPE)); $this->table->setSymbol('this', $node->namespacedName->toString()); } if ($node instanceof Node\Stmt\ClassMethod) { $this->table->enterScope(new TableScope(TableScope::CLASS_METHOD_SCOPE)); } if ($node instanceof Node\Stmt\Function_) { $this->table->enterScope(new TableScope(TableScope::FUNCTION_SCOPE)); } $this->resolver->resolveVariableType($node); return; }