/** * @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; }
/** * {@inheritdoc} */ public function resolveVariableType(Node $node) { if ($node instanceof Node\Param) { if ($node->type instanceof Node\Name) { $this->table->setSymbol($node->name, $node->type->toString()); } } }
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(); } }
/** * {@inheritdoc} */ public function resolveVariableType(Node $node) { if ($node instanceof Node\Expr\PropertyFetch) { // $this->someProperty if ($node->var instanceof Node\Expr\Variable && $node->var->name === 'this') { $node->setAttribute('guessedType', $this->table->lookUpClassProperty($node->name)->type()); } // $x->someProperty } }
/** * @inheritDoc */ public function resolveVariableType(Node $node) { // $this->call() if ($node instanceof Node\Expr\MethodCall && property_exists($node->var, 'name') && null === $node->getAttribute('guessedType', null)) { if ('container' == $node->var->name && $this->isController($this->table->lookUp('this')->type())) { $context = self::CONTAINER; } else { $context = $this->table->lookUp($node->var->name)->type(); } $type = $this->getType($context, $node->name, $node); if (null !== $type) { $node->setAttribute('guessedType', $type); } } // $x = $this->call() if ($node instanceof Node\Expr\Assign && $node->var instanceof Node\Expr\Variable && $node->expr instanceof Node\Expr\MethodCall && property_exists($node->expr->var, 'name') && null === $node->getAttribute('guessedType', null)) { if ('container' == $node->expr->var->name && $this->isController($this->table->lookUp('this')->type())) { $context = self::CONTAINER; } else { $context = $this->table->lookUp($node->expr->var->name)->type(); } $type = $this->getType($context, $node->expr->name, $node->expr); if (null !== $type) { $node->var->setAttribute('guessedType', $type); $this->table->setSymbol($node->var->name, $type); } } }
/** * {@inheritdoc} */ public function resolveVariableType(Node $node) { if ($node instanceof Node\Expr\Assign) { // $x = ... if ($node->var instanceof Node\Expr\Variable) { // skips variable names like ${$node->nodeName} if (!is_string($node->var->name)) { return; } // $x = new X(); if ($node->expr instanceof Node\Expr\New_) { if ($node->expr->class instanceof Node\Name) { $type = $node->expr->class->toString(); $this->table->setSymbol($node->var->name, $type); $node->var->setAttribute('guessedType', $type); } } // $x = $y; if ($node->expr instanceof Node\Expr\Variable) { $type = $this->table->lookUp($node->expr->name)->type(); $node->var->setAttribute('guessedType', $type); $this->table->setSymbol($node->var->name, $type); } // $x = $this->x if ($node->expr instanceof Node\Expr\PropertyFetch) { $type = $this->table->lookUpClassProperty($node->expr->name)->type(); $node->var->setAttribute('guessedType', $type); $this->table->setSymbol($node->var->name, $type); } } } }
/** * {@inheritdoc} */ public function resolveVariableType(Node $node) { if ($node instanceof Node\Expr\Assign) { // $this->x = ... // excluding $this->$x = ... if ($node->var instanceof Node\Expr\PropertyFetch) { // $stub[$key]->x = ... ; if not tested a php notice will occur // @TODO change to be able to use all types of properties like $x->x = 10 if ($node->var->var instanceof Node\Expr\ArrayDimFetch) { return; } // @TODO change to be able to use all types of properties like $x->x = 10 if ($node->var->var->name !== 'this' || !is_string($node->var->name)) { return; } // $this->x = new X(); if ($node->expr instanceof Node\Expr\New_) { if ($node->expr->class instanceof Node\Name) { $type = $node->expr->class->toString(); $node->var->setAttribute('guessedType', $type); $this->table->setClassProperty($node->var->name, $type); } } // $this->x = $y; if ($node->expr instanceof Node\Expr\Variable) { $type = $this->table->lookUp($node->expr->name)->type(); $node->var->setAttribute('guessedType', $type); $this->table->setClassProperty($node->var->name, $type); } // $this->x = $this->y; if ($node->expr instanceof Node\Expr\PropertyFetch) { $type = $this->table->lookUpClassProperty($node->expr->name)->type(); $node->var->setAttribute('guessedType', $type); $this->table->setClassProperty($node->var->name, $type); } } } }
/** * {@inheritdoc} */ public function resolveVariableType(Node $node) { if ($node instanceof Node\Expr\Variable) { $node->setAttribute('guessedType', $this->table->lookUp($node->name)->type()); } }
public function testSetClassPropertyThrowsException() { $this->setExpectedException('Exception', 'Illegal State there is no class scope above'); $table = new SymbolTable(); $table->setClassProperty('property', 'type'); }