/** * @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; }
/** * @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; }
/** * {@inheritDoc} */ public function getParameters() { if (!isset($this->parameters)) { $parameters = []; foreach ($this->functionLikeNode->getParams() as $parameterIndex => $parameterNode) { $reflectionParameter = new ReflectionParameter($this->getName(), $parameterNode->name, $parameterNode, $parameterIndex, $this); $parameters[] = $reflectionParameter; } $this->parameters = $parameters; } return $this->parameters; }
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); }