/** * Different Traits may implement their own copies of the same method name. That's fine at this point. Later we will * use adaptations to reduce duplicates down to a single method for each name. * @param TraitUse $use * @param array $methods * @param array $properties * @throws UnknownTraitException */ private function indexTrait(TraitUse $use, array &$methods, array &$properties) { foreach ($use->traits as $useTrait) { $traitName = strval($useTrait); $trait = $this->index->getTrait($traitName); if (!$trait) { throw new \Guardrail\Exceptions\UnknownTraitException($traitName, $this->file, $use->getLine()); } foreach ($trait->stmts as $stmt) { if ($stmt instanceof Node\Stmt\Property) { foreach ($stmt->props as $prop) { // Make a deep copy of the node $properties[$prop->name] = unserialize(serialize($prop)); } } else { if ($stmt instanceof Node\Stmt\ClassMethod) { // Make a deep copy of the node $methods[$stmt->name][$traitName] = unserialize(serialize($stmt)); } } } } }
function inferPropertyFetch(Node\Expr\PropertyFetch $expr, $inside, $scope) { $class = $this->inferType($inside, $expr->var, $scope); if (!empty($class) && $class[0] != "!") { if (gettype($expr->name) == 'string') { $classDef = $this->index->getClass($class); if ($classDef) { $prop = Util::findProperty($classDef, strval($expr->name), $this->index); if ($prop) { /* $type = $prop->getAttribute("namespacedType") ?: ""; if(!empty($type)) { if($type[0]=='\\') { $type=substr($type,1); } return $type; }*/ } } } } return Scope::MIXED_TYPE; }
function __construct($fileName, $basePath) { parent::__construct($basePath); $this->con = new \PDO("sqlite:{$fileName}"); $this->init(); }
function enterNode(Node $node) { $class = get_class($node); if ($node instanceof Trait_) { return NodeTraverserInterface::DONT_TRAVERSE_CHILDREN; } if ($node instanceof Class_ || $node instanceof Trait_) { array_push($this->classStack, $node); } if ($node instanceof Node\FunctionLike) { // Typecast $this->pushFunctionScope($node); } if ($node instanceof Node\Expr\Assign || $node instanceof Node\Expr\AssignRef) { $this->handleAssignment($node); } if ($node instanceof Node\Stmt\StaticVar) { $this->setScopeExpression($node->name, $node->default); } if ($node instanceof Node\Stmt\Catch_) { $this->setScopeType(strval($node->var), strval($node->type)); } if ($node instanceof Node\Stmt\Global_) { foreach ($node->vars as $var) { if ($var instanceof Node\Expr\Variable && gettype($var->name) == "string") { $this->setScopeType(strval($var->name), Scope::MIXED_TYPE); } } } if ($node instanceof Node\Expr\MethodCall) { if (gettype($node->name) == "string") { $type = $this->typeInferrer->inferType(end($this->classStack) ?: null, $node->var, end($this->scopeStack)); if ($type && $type[0] != "!") { $method = $this->index->getAbstractedMethod($type, $node->name); if ($method) { /** @var FunctionLikeParameter[] $params */ $params = $method->getParameters(); $paramCount = count($params); foreach ($node->args as $index => $arg) { if (isset($params[$index]) && $params[$index]->isReference() || $index >= $paramCount && $paramCount > 0 && $params[$paramCount - 1]->isReference()) { if ($arg->value instanceof Node\Expr\Variable && gettype($arg->value->name) == "string") { $this->setScopeType($arg->value->name, Scope::MIXED_TYPE); } } } } } } } if ($node instanceof Node\Expr\StaticCall) { if ($node->class instanceof Node\Name && gettype($node->name) == "string") { $method = $this->index->getAbstractedMethod(strval($node->class), strval($node->name)); if ($method) { /** @var FunctionLikeParameter[] $params */ $params = $method->getParameters(); $paramCount = count($params); foreach ($node->args as $index => $arg) { if (isset($params[$index]) && $params[$index]->isReference() || $index >= $paramCount && $paramCount > 0 && $params[$paramCount - 1]->isReference()) { if ($arg->value instanceof Node\Expr\Variable && gettype($arg->value->name) == "string") { $this->setScopeType($arg->value->name, Scope::MIXED_TYPE); } } } } } } if ($node instanceof Node\Expr\FuncCall) { if ($node->name instanceof Node\Name) { $function = $this->index->getAbstractedFunction(strval($node->name)); if ($function) { $params = $function->getParameters(); $paramCount = count($params); foreach ($node->args as $index => $arg) { if ($arg->value instanceof Node\Expr\Variable && gettype($arg->value->name) == "string" && (isset($params[$index]) && $params[$index]->isReference() || $index >= $paramCount && $paramCount > 0 && $params[$paramCount - 1]->isReference())) { $this->setScopeType($arg->value->name, Scope::MIXED_TYPE); } } } } } if ($node instanceof Node\Stmt\Foreach_) { if ($node->keyVar instanceof Node\Expr\Variable && gettype($node->keyVar->name) == "string") { $this->setScopeType(strval($node->keyVar->name), Scope::MIXED_TYPE); } if ($node->valueVar instanceof Node\Expr\Variable && gettype($node->valueVar->name) == "string") { $type = $this->typeInferrer->inferType(end($this->classStack) ?: null, $node->expr, end($this->scopeStack)); if (substr($type, -2) == "[]") { $type = substr($type, 0, -2); } else { $type = Scope::MIXED_TYPE; } $this->setScopeType(strval($node->valueVar->name), $type); } else { if ($node->valueVar instanceof Node\Expr\List_) { foreach ($node->valueVar->vars as $var) { if ($var instanceof Node\Expr\Variable && gettype($var->name) == "string") { $this->setScopeType(strval($var->name), Scope::MIXED_TYPE); } } } } } if ($node instanceof Node\Stmt\If_ || $node instanceof Node\Stmt\ElseIf_) { if ($node instanceof Node\Stmt\ElseIf_) { // Pop the previous if's scope array_pop($this->scopeStack); } $this->pushIfScope($node); } if ($node instanceof Node\Stmt\Else_) { // The previous scope was only valid for the if side. array_pop($this->scopeStack); } if (isset($this->checks[$class])) { foreach ($this->checks[$class] as $check) { $check->run($this->file, $node, end($this->classStack) ?: null, end($this->scopeStack) ?: null); } } return null; }
/** * @param Class_ $node * @param $name * @param SymbolTable $symbolTable * @return ClassMethod */ static function findProperty(Class_ $node, $name, SymbolTable $symbolTable) { while ($node) { $properties = \Guardrail\NodeVisitors\Grabber::filterByType($node->stmts, \PhpParser\Node\Stmt\Property::class); /** @var Property[] $propertyList */ foreach ($properties as $props) { /** @var Property $props */ foreach ($props->props as $prop) { if (strcasecmp($prop->name, $name) == 0) { return $prop; } } } if ($node->extends) { $parent = $node->extends->toString(); $node = $symbolTable->getClass($parent); } else { return null; } } return null; }