Inheritance: extends PhpParser\Node
 /**
  * @param \PhpParser\Node\FunctionLike $function
  * @param \PHPStan\Analyser\Scope $scope
  * @param string $parameterMessage
  * @param string $returnMessage
  * @return string[]
  */
 public function checkFunction(FunctionLike $function, Scope $scope, string $parameterMessage, string $returnMessage) : array
 {
     if ($function instanceof ClassMethod && $scope->getClass() !== null) {
         return $this->checkParametersAcceptor($this->broker->getClass($scope->getClass())->getMethod($function->name), $parameterMessage, $returnMessage);
     }
     if ($function instanceof Function_) {
         $functionName = $function->name;
         if (isset($function->namespacedName)) {
             $functionName = $function->namespacedName;
         }
         return $this->checkParametersAcceptor($this->broker->getFunction(new Name($functionName)), $parameterMessage, $returnMessage);
     }
     $errors = [];
     foreach ($function->getParams() as $param) {
         $class = (string) $param->type;
         if ($class && !in_array($class, self::VALID_TYPEHINTS, true) && !$this->broker->hasClass($class)) {
             $errors[] = sprintf($parameterMessage, $param->name, $class);
         }
     }
     $returnType = (string) $function->getReturnType();
     if ($returnType && !in_array($returnType, self::VALID_TYPEHINTS, true) && !$this->broker->hasClass($returnType)) {
         $errors[] = sprintf($returnMessage, $returnType);
     }
     return $errors;
 }
Esempio n. 2
0
 /**
  * @param FunctionLike $function
  *
  * @return string[]
  */
 private function getByRefParameters(FunctionLike $function) : array
 {
     $byRefParams = [];
     foreach ($function->getParams() as $param) {
         if ($param->byRef) {
             $byRefParams[] = $param->name;
         }
     }
     return $byRefParams;
 }
Esempio n. 3
0
 /**
  * @param FunctionLike $node A PHP-Parser Node function-like object to resolve return types of
  *
  * @return array A array of the return types, or empty array if no return comment exists
  */
 public static function parseNode(FunctionLike $node)
 {
     /** @var Comment[] $returnComments */
     $returnComments = self::filterComments($node->getAttribute("comments", []));
     if (empty($returnComments)) {
         return [];
         // TODO: void? mixed? Maybe verify that comments tag exists?
     }
     /** @var DocBlock\Tag $lastReturnKeyword If multiple "@return" tags, only the last one in last DocBlock used. */
     $lastReturnKeyword = last((new DocBlock(last($returnComments)->getReformattedText()))->getTagsByName("return"));
     // Everything after the tag (after the appending space), is tag content.
     return self::parse(DocTypeNormaliser::sanitise($lastReturnKeyword->getContent()));
 }
Esempio n. 4
0
 /**
  * @param FunctionLike $node A PHP-Parser Node function-like object to resolve param types of
  *
  * @return array A array of the param arguments and types (if possible), or empty array if no arguments accepted
  */
 public static function parseNode(FunctionLike $node)
 {
     /** @var Comment[] $paramComments */
     $paramComments = self::filterComments($node->getAttribute("comments", []));
     if (empty($paramComments)) {
         return [];
     }
     $posCount = 0;
     // Used for positional @param tags e.g. without $varName
     $params = array_unique(array_map(function (DocBlock\Tag $param) use(&$posCount) {
         $param = DocTypeNormaliser::sanitise($param->getContent());
         $param = self::parse($param, $posCount++);
         // Below code can be used to selectively increment posCount - remove ++ above
         // $posCount = ($param["name"]{0} === "#") ? $posCount + 1 : $posCount;
         return $param;
     }, array_flatten(array_map(function (Comment $comment) {
         return (new DocBlock($comment->getReformattedText()))->getTagsByName("param");
     }, $paramComments))), SORT_REGULAR);
     // ["$var" => ["pos" => 0, "name" => "$var", "type" => ["bool", "\Class"]]]
     // ["#1" => ["pos" => 1, "name" => "#1", "type" => ["bool", "\Class"]]]
     return array_combine(array_map(function ($param) {
         return $param["name"];
     }, $params), $params);
 }
 function pushFunctionScope(Node\FunctionLike $func)
 {
     $isStatic = true;
     if ($func instanceof Node\Stmt\ClassMethod) {
         $isStatic = $func->isStatic();
     }
     $scope = new Scope($isStatic);
     foreach ($func->getParams() as $param) {
         $scope->setVarType(strval($param->name), strval($param->type));
     }
     if ($func instanceof Node\Expr\Closure) {
         $oldScope = end($this->scopeStack);
         foreach ($func->uses as $variable) {
             $type = $oldScope->getVarType($variable->var);
             if ($type == Scope::UNDEFINED) {
                 $type = Scope::MIXED_TYPE;
             }
             $scope->setVarType($variable->var, $type);
         }
     }
     array_push($this->scopeStack, $scope);
 }
 /**
  * {@inheritDoc}
  */
 public function returnsReference()
 {
     return $this->functionLikeNode->returnsByRef();
 }