Skip to content

Commit

Permalink
Refactored FunctionCallParametersCheck::check() parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Oct 2, 2024
1 parent b539c74 commit 710e09c
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 122 deletions.
32 changes: 15 additions & 17 deletions src/Rules/AttributesCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,25 +136,23 @@ public function check(
$scope,
$attributeConstructor->getDeclaringClass()->isBuiltin(),
new New_($attribute->name, $attribute->args, $nodeAttributes),
[
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, at least %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, at least %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, %d-%d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, %d-%d required.',
'Parameter %s of attribute class ' . $attributeClassName . ' constructor expects %s, %s given.',
'', // constructor does not have a return type
'Parameter %s of attribute class ' . $attributeClassName . ' constructor is passed by reference, so it expects variables only',
'Unable to resolve the template type %s in instantiation of attribute class ' . $attributeClassName,
'Missing parameter $%s in call to ' . $attributeClassName . ' constructor.',
'Unknown parameter $%s in call to ' . $attributeClassName . ' constructor.',
'Return type of call to ' . $attributeClassName . ' constructor contains unresolvable type.',
'Parameter %s of attribute class ' . $attributeClassName . ' constructor contains unresolvable type.',
'Attribute class ' . $attributeClassName . ' constructorinvoked with %s, but it\'s not allowed because of @no-named-arguments.',
],
'attribute',
$attributeConstructor->acceptsNamedArguments(),
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, at least %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, at least %d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameter, %d-%d required.',
'Attribute class ' . $attributeClassName . ' constructor invoked with %d parameters, %d-%d required.',
'Parameter %s of attribute class ' . $attributeClassName . ' constructor expects %s, %s given.',
'', // constructor does not have a return type
'Parameter %s of attribute class ' . $attributeClassName . ' constructor is passed by reference, so it expects variables only',
'Unable to resolve the template type %s in instantiation of attribute class ' . $attributeClassName,
'Missing parameter $%s in call to ' . $attributeClassName . ' constructor.',
'Unknown parameter $%s in call to ' . $attributeClassName . ' constructor.',
'Return type of call to ' . $attributeClassName . ' constructor contains unresolvable type.',
'Parameter %s of attribute class ' . $attributeClassName . ' constructor contains unresolvable type.',
'Attribute class ' . $attributeClassName . ' constructorinvoked with %s, but it\'s not allowed because of @no-named-arguments.',
);

foreach ($parameterErrors as $error) {
Expand Down
32 changes: 15 additions & 17 deletions src/Rules/Classes/InstantiationRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,25 +201,23 @@ private function checkClassName(string $class, bool $isName, Node $node, Scope $
$scope,
$constructorReflection->getDeclaringClass()->isBuiltin(),
$node,
[
'Class ' . $classDisplayName . ' constructor invoked with %d parameter, %d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameters, %d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameter, at least %d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameters, at least %d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameter, %d-%d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameters, %d-%d required.',
'Parameter %s of class ' . $classDisplayName . ' constructor expects %s, %s given.',
'', // constructor does not have a return type
'Parameter %s of class ' . $classDisplayName . ' constructor is passed by reference, so it expects variables only',
'Unable to resolve the template type %s in instantiation of class ' . $classDisplayName,
'Missing parameter $%s in call to ' . $classDisplayName . ' constructor.',
'Unknown parameter $%s in call to ' . $classDisplayName . ' constructor.',
'Return type of call to ' . $classDisplayName . ' constructor contains unresolvable type.',
'Parameter %s of class ' . $classDisplayName . ' constructor contains unresolvable type.',
'Class ' . $classDisplayName . ' constructor invoked with %s, but it\'s not allowed because of @no-named-arguments.',
],
'new',
$constructorReflection->acceptsNamedArguments(),
'Class ' . $classDisplayName . ' constructor invoked with %d parameter, %d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameters, %d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameter, at least %d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameters, at least %d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameter, %d-%d required.',
'Class ' . $classDisplayName . ' constructor invoked with %d parameters, %d-%d required.',
'Parameter %s of class ' . $classDisplayName . ' constructor expects %s, %s given.',
'', // constructor does not have a return type
'Parameter %s of class ' . $classDisplayName . ' constructor is passed by reference, so it expects variables only',
'Unable to resolve the template type %s in instantiation of class ' . $classDisplayName,
'Missing parameter $%s in call to ' . $classDisplayName . ' constructor.',
'Unknown parameter $%s in call to ' . $classDisplayName . ' constructor.',
'Return type of call to ' . $classDisplayName . ' constructor contains unresolvable type.',
'Parameter %s of class ' . $classDisplayName . ' constructor contains unresolvable type.',
'Class ' . $classDisplayName . ' constructor invoked with %s, but it\'s not allowed because of @no-named-arguments.',
));
}

Expand Down
48 changes: 30 additions & 18 deletions src/Rules/FunctionCallParametersCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ public function __construct(

/**
* @param Node\Expr\FuncCall|Node\Expr\MethodCall|Node\Expr\StaticCall|Node\Expr\New_ $funcCall
* @param array{0: string, 1: string, 2: string, 3: string, 4: string, 5: string, 6: string, 7: string, 8: string, 9: string, 10: string, 11: string, 12: string, 13?: string, 14?: string} $messages
* @param 'attribute'|'callable'|'method'|'staticMethod'|'function'|'new' $nodeType
* @return list<IdentifierRuleError>
*/
Expand All @@ -62,9 +61,23 @@ public function check(
Scope $scope,
bool $isBuiltin,
$funcCall,
array $messages,
string $nodeType,
TrinaryLogic $acceptsNamedArguments,
string $singleInsufficientParameterMessage,
string $pluralInsufficientParametersMessage,
string $singleInsufficientParameterInVariadicFunctionMessage,
string $pluralInsufficientParametersInVariadicFunctionMessage,
string $singleInsufficientParameterWithOptionalParametersMessage,
string $pluralInsufficientParametersWithOptionalParametersMessage,
string $wrongArgumentTypeMessage,
string $voidReturnTypeUsed,
string $parameterPassedByReferenceMessage,
string $unresolvableTemplateTypeMessage,
string $missingParameterMessage,
string $unknownParameterMessage,
string $unresolvableReturnTypeMessage,
string $unresolvableParameterTypeMessage,
string $namedArgumentMessage,
): array
{
$functionParametersMinCount = 0;
Expand Down Expand Up @@ -204,7 +217,7 @@ public function check(
) {
if ($functionParametersMinCount === $functionParametersMaxCount) {
$errors[] = RuleErrorBuilder::message(sprintf(
$invokedParametersCount === 1 ? $messages[0] : $messages[1],
$invokedParametersCount === 1 ? $singleInsufficientParameterMessage : $pluralInsufficientParametersMessage,
$invokedParametersCount,
$functionParametersMinCount,
))
Expand All @@ -213,7 +226,7 @@ public function check(
->build();
} elseif ($functionParametersMaxCount === -1 && $invokedParametersCount < $functionParametersMinCount) {
$errors[] = RuleErrorBuilder::message(sprintf(
$invokedParametersCount === 1 ? $messages[2] : $messages[3],
$invokedParametersCount === 1 ? $singleInsufficientParameterInVariadicFunctionMessage : $pluralInsufficientParametersInVariadicFunctionMessage,
$invokedParametersCount,
$functionParametersMinCount,
))
Expand All @@ -222,7 +235,7 @@ public function check(
->build();
} elseif ($functionParametersMaxCount !== -1) {
$errors[] = RuleErrorBuilder::message(sprintf(
$invokedParametersCount === 1 ? $messages[4] : $messages[5],
$invokedParametersCount === 1 ? $singleInsufficientParameterWithOptionalParametersMessage : $pluralInsufficientParametersWithOptionalParametersMessage,
$invokedParametersCount,
$functionParametersMinCount,
$functionParametersMaxCount,
Expand All @@ -239,13 +252,13 @@ public function check(
&& !$scope->isInFirstLevelStatement()
&& $scope->getKeepVoidType($funcCall)->isVoid()->yes()
) {
$errors[] = RuleErrorBuilder::message($messages[7])
$errors[] = RuleErrorBuilder::message($voidReturnTypeUsed)
->identifier(sprintf('%s.void', $nodeType))
->line($funcCall->getStartLine())
->build();
}

[$addedErrors, $argumentsWithParameters] = $this->processArguments($parametersAcceptor, $funcCall->getStartLine(), $isBuiltin, $arguments, $hasNamedArguments, $messages[10], $messages[11]);
[$addedErrors, $argumentsWithParameters] = $this->processArguments($parametersAcceptor, $funcCall->getStartLine(), $isBuiltin, $arguments, $hasNamedArguments, $missingParameterMessage, $unknownParameterMessage);
foreach ($addedErrors as $error) {
$errors[] = $error;
}
Expand Down Expand Up @@ -290,17 +303,17 @@ public function check(
}
}

if (!$acceptsNamedArguments->yes() && isset($messages[14])) {
if (!$acceptsNamedArguments->yes()) {
if ($argumentName !== null) {
$errors[] = RuleErrorBuilder::message(sprintf($messages[14], sprintf('named argument $%s', $argumentName)))
$errors[] = RuleErrorBuilder::message(sprintf($namedArgumentMessage, sprintf('named argument $%s', $argumentName)))
->identifier('argument.named')
->line($argumentLine)
->build();
} elseif ($unpack) {
$unpackedArrayType = $scope->getType($argumentValue);
$hasStringKey = $unpackedArrayType->getIterableKeyType()->isString();
if (!$hasStringKey->no()) {
$errors[] = RuleErrorBuilder::message(sprintf($messages[14], sprintf('unpacked array with %s', $hasStringKey->yes() ? 'string key' : 'possibly string key')))
$errors[] = RuleErrorBuilder::message(sprintf($namedArgumentMessage, sprintf('unpacked array with %s', $hasStringKey->yes() ? 'string key' : 'possibly string key')))
->identifier('argument.named')
->line($argumentLine)
->build();
Expand All @@ -317,7 +330,7 @@ public function check(
if (!$accepts->result) {
$verbosityLevel = VerbosityLevel::getRecommendedLevelByType($parameterType, $argumentValueType);
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[6],
$wrongArgumentTypeMessage,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
$parameterType->describe($verbosityLevel),
$argumentValueType->describe($verbosityLevel),
Expand All @@ -331,12 +344,11 @@ public function check(

if (
$originalParameter !== null
&& isset($messages[13])
&& !$this->unresolvableTypeHelper->containsUnresolvableType($originalParameter->getType())
&& $this->unresolvableTypeHelper->containsUnresolvableType($parameterType)
) {
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[13],
$unresolvableParameterTypeMessage,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
))->identifier('argument.unresolvableType')->line($argumentLine)->build();
}
Expand All @@ -348,7 +360,7 @@ public function check(
&& $argumentValue->static
) {
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[6],
$wrongArgumentTypeMessage,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
'bindable closure',
'static closure',
Expand All @@ -368,7 +380,7 @@ public function check(

if ($this->nullsafeCheck->containsNullSafe($argumentValue)) {
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[8],
$parameterPassedByReferenceMessage,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
))
->identifier('argument.byRef')
Expand Down Expand Up @@ -412,7 +424,7 @@ public function check(
}

$errors[] = RuleErrorBuilder::message(sprintf(
$messages[8],
$parameterPassedByReferenceMessage,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
))->identifier('argument.byRef')->line($argumentLine)->build();
}
Expand Down Expand Up @@ -469,7 +481,7 @@ static function (Type $type, callable $traverse) use (&$returnTemplateTypes): Ty
continue;
}

$errors[] = RuleErrorBuilder::message(sprintf($messages[9], $name))
$errors[] = RuleErrorBuilder::message(sprintf($unresolvableTemplateTypeMessage, $name))
->identifier('argument.templateType')
->line($funcCall->getStartLine())
->tip('See: https://phpstan.org/blog/solving-phpstan-error-unable-to-resolve-template-type')
Expand All @@ -481,7 +493,7 @@ static function (Type $type, callable $traverse) use (&$returnTemplateTypes): Ty
!$this->unresolvableTypeHelper->containsUnresolvableType($originalParametersAcceptor->getReturnType())
&& $this->unresolvableTypeHelper->containsUnresolvableType($parametersAcceptor->getReturnType())
) {
$errors[] = RuleErrorBuilder::message($messages[12])
$errors[] = RuleErrorBuilder::message($unresolvableReturnTypeMessage)
->identifier(sprintf('%s.unresolvableReturnType', $nodeType))
->line($funcCall->getStartLine())
->build();
Expand Down
32 changes: 15 additions & 17 deletions src/Rules/Functions/CallCallablesRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,25 +118,23 @@ public function processNode(
$scope,
false,
$node,
[
ucfirst($callableDescription) . ' invoked with %d parameter, %d required.',
ucfirst($callableDescription) . ' invoked with %d parameters, %d required.',
ucfirst($callableDescription) . ' invoked with %d parameter, at least %d required.',
ucfirst($callableDescription) . ' invoked with %d parameters, at least %d required.',
ucfirst($callableDescription) . ' invoked with %d parameter, %d-%d required.',
ucfirst($callableDescription) . ' invoked with %d parameters, %d-%d required.',
'Parameter %s of ' . $callableDescription . ' expects %s, %s given.',
'Result of ' . $callableDescription . ' (void) is used.',
'Parameter %s of ' . $callableDescription . ' is passed by reference, so it expects variables only.',
'Unable to resolve the template type %s in call to ' . $callableDescription,
'Missing parameter $%s in call to ' . $callableDescription . '.',
'Unknown parameter $%s in call to ' . $callableDescription . '.',
'Return type of call to ' . $callableDescription . ' contains unresolvable type.',
'Parameter %s of ' . $callableDescription . ' contains unresolvable type.',
ucfirst($callableDescription) . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.',
],
'callable',
$acceptsNamedArguments,
ucfirst($callableDescription) . ' invoked with %d parameter, %d required.',
ucfirst($callableDescription) . ' invoked with %d parameters, %d required.',
ucfirst($callableDescription) . ' invoked with %d parameter, at least %d required.',
ucfirst($callableDescription) . ' invoked with %d parameters, at least %d required.',
ucfirst($callableDescription) . ' invoked with %d parameter, %d-%d required.',
ucfirst($callableDescription) . ' invoked with %d parameters, %d-%d required.',
'Parameter %s of ' . $callableDescription . ' expects %s, %s given.',
'Result of ' . $callableDescription . ' (void) is used.',
'Parameter %s of ' . $callableDescription . ' is passed by reference, so it expects variables only.',
'Unable to resolve the template type %s in call to ' . $callableDescription,
'Missing parameter $%s in call to ' . $callableDescription . '.',
'Unknown parameter $%s in call to ' . $callableDescription . '.',
'Return type of call to ' . $callableDescription . ' contains unresolvable type.',
'Parameter %s of ' . $callableDescription . ' contains unresolvable type.',
ucfirst($callableDescription) . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.',
),
);
}
Expand Down
32 changes: 15 additions & 17 deletions src/Rules/Functions/CallToFunctionParametersRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,23 @@ public function processNode(Node $node, Scope $scope): array
$scope,
$function->isBuiltin(),
$node,
[
'Function ' . $functionName . ' invoked with %d parameter, %d required.',
'Function ' . $functionName . ' invoked with %d parameters, %d required.',
'Function ' . $functionName . ' invoked with %d parameter, at least %d required.',
'Function ' . $functionName . ' invoked with %d parameters, at least %d required.',
'Function ' . $functionName . ' invoked with %d parameter, %d-%d required.',
'Function ' . $functionName . ' invoked with %d parameters, %d-%d required.',
'Parameter %s of function ' . $functionName . ' expects %s, %s given.',
'Result of function ' . $functionName . ' (void) is used.',
'Parameter %s of function ' . $functionName . ' is passed by reference, so it expects variables only.',
'Unable to resolve the template type %s in call to function ' . $functionName,
'Missing parameter $%s in call to function ' . $functionName . '.',
'Unknown parameter $%s in call to function ' . $functionName . '.',
'Return type of call to function ' . $functionName . ' contains unresolvable type.',
'Parameter %s of function ' . $functionName . ' contains unresolvable type.',
'Function ' . $functionName . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.',
],
'function',
$function->acceptsNamedArguments(),
'Function ' . $functionName . ' invoked with %d parameter, %d required.',
'Function ' . $functionName . ' invoked with %d parameters, %d required.',
'Function ' . $functionName . ' invoked with %d parameter, at least %d required.',
'Function ' . $functionName . ' invoked with %d parameters, at least %d required.',
'Function ' . $functionName . ' invoked with %d parameter, %d-%d required.',
'Function ' . $functionName . ' invoked with %d parameters, %d-%d required.',
'Parameter %s of function ' . $functionName . ' expects %s, %s given.',
'Result of function ' . $functionName . ' (void) is used.',
'Parameter %s of function ' . $functionName . ' is passed by reference, so it expects variables only.',
'Unable to resolve the template type %s in call to function ' . $functionName,
'Missing parameter $%s in call to function ' . $functionName . '.',
'Unknown parameter $%s in call to function ' . $functionName . '.',
'Return type of call to function ' . $functionName . ' contains unresolvable type.',
'Parameter %s of function ' . $functionName . ' contains unresolvable type.',
'Function ' . $functionName . ' invoked with %s, but it\'s not allowed because of @no-named-arguments.',
);
}

Expand Down
Loading

0 comments on commit 710e09c

Please sign in to comment.