private function checkParametersAcceptor(ParametersAcceptor $parametersAcceptor, string $parameterMessage, string $returnMessage) : array { $errors = []; foreach ($parametersAcceptor->getParameters() as $parameter) { $type = $parameter->getType(); if ($type->getClass() !== null && !$this->broker->hasClass($type->getClass())) { $errors[] = sprintf($parameterMessage, $parameter->getName(), $type->getClass()); } elseif ($type instanceof ArrayType) { $nestedItemType = $type->getNestedItemType(); if ($nestedItemType->getItemType()->getClass() !== null && !$this->broker->hasClass($nestedItemType->getItemType()->getClass())) { $errors[] = sprintf($parameterMessage, $parameter->getName(), $type->describe()); } } } $returnType = $parametersAcceptor->getReturnType(); if ($returnType->getClass() !== null && !$this->broker->hasClass($returnType->getClass())) { $errors[] = sprintf($returnMessage, $returnType->getClass()); } elseif ($returnType instanceof ArrayType) { $nestedItemType = $returnType->getNestedItemType(); if ($nestedItemType->getItemType()->getClass() !== null && !$this->broker->hasClass($nestedItemType->getItemType()->getClass())) { $errors[] = sprintf($returnMessage, $returnType->describe()); } } return $errors; }
/** * @param \PHPStan\Reflection\ParametersAcceptor $function * @param \PhpParser\Node\Expr\FuncCall|\PhpParser\Node\Expr\MethodCall|\PhpParser\Node\Expr\StaticCall $funcCall * @param string[] $messages Six message templates * @return string[] */ public function check(ParametersAcceptor $function, $funcCall, array $messages) : array { if ($function instanceof FunctionReflection && $function->getName() === 'implode') { $functionParametersMinCount = 1; $functionParametersMaxCount = 2; } else { $functionParametersMinCount = 0; $functionParametersMaxCount = 0; foreach ($function->getParameters() as $parameter) { if (!$parameter->isOptional()) { $functionParametersMinCount++; } $functionParametersMaxCount++; } if ($function->isVariadic()) { $functionParametersMaxCount = -1; } } $invokedParametersCount = count($funcCall->args); foreach ($funcCall->args as $arg) { if ($arg->unpack) { $invokedParametersCount = max($functionParametersMinCount, $functionParametersMaxCount); break; } } if ($invokedParametersCount < $functionParametersMinCount || $invokedParametersCount > $functionParametersMaxCount) { if ($functionParametersMinCount === $functionParametersMaxCount) { return [sprintf($invokedParametersCount === 1 ? $messages[0] : $messages[1], $invokedParametersCount, $functionParametersMinCount)]; } elseif ($functionParametersMaxCount === -1 && $invokedParametersCount < $functionParametersMinCount) { return [sprintf($invokedParametersCount === 1 ? $messages[2] : $messages[3], $invokedParametersCount, $functionParametersMinCount)]; } elseif ($functionParametersMaxCount !== -1) { return [sprintf($invokedParametersCount === 1 ? $messages[4] : $messages[5], $invokedParametersCount, $functionParametersMinCount, $functionParametersMaxCount)]; } } return []; }
public function enterFunction(ParametersAcceptor $functionReflection) : self { $variableTypes = $this->getVariableTypes(); foreach ($functionReflection->getParameters() as $parameter) { $variableTypes[$parameter->getName()] = $parameter->getType(); } return new self($this->broker, $this->printer, $this->getFile(), $this->getAnalysedContextFile(), $this->isDeclareStrictTypes(), $this->getClass(), $functionReflection, $this->getNamespace(), $variableTypes); }