Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.10.x' into 1.11.x
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Apr 12, 2024
2 parents 70fb8fc + f71da02 commit 5c3a711
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 26 deletions.
44 changes: 22 additions & 22 deletions src/Rules/FunctionCallParametersCheck.php
Expand Up @@ -27,6 +27,7 @@
use function array_fill;
use function array_key_exists;
use function count;
use function implode;
use function is_string;
use function max;
use function sprintf;
Expand Down Expand Up @@ -278,7 +279,6 @@ public function check(

if ($this->checkArgumentTypes) {
$parameterType = TypeUtils::resolveLateResolvableTypes($parameter->getType());
$parameterDescription = sprintf('%s$%s', $parameter->isVariadic() ? '...' : '', $parameter->getName());

if (
!$parameter->passedByReference()->createsNewVariable()
Expand All @@ -290,11 +290,7 @@ public function check(
$verbosityLevel = VerbosityLevel::getRecommendedLevelByType($parameterType, $argumentValueType);
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[6],
$argumentName === null ? sprintf(
'#%d %s',
$i + 1,
$parameterDescription,
) : $parameterDescription,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
$parameterType->describe($verbosityLevel),
$argumentValueType->describe($verbosityLevel),
))
Expand All @@ -313,11 +309,7 @@ public function check(
) {
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[13],
$argumentName === null ? sprintf(
'#%d %s',
$i + 1,
$parameterDescription,
) : $parameterDescription,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
))->identifier('argument.unresolvableType')->line($argumentLine)->build();
}

Expand All @@ -329,11 +321,7 @@ public function check(
) {
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[6],
$argumentName === null ? sprintf(
'#%d %s',
$i + 1,
$parameterDescription,
) : $parameterDescription,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
'bindable closure',
'static closure',
))
Expand All @@ -351,10 +339,9 @@ public function check(
}

if ($this->nullsafeCheck->containsNullSafe($argumentValue)) {
$parameterDescription = sprintf('%s$%s', $parameter->isVariadic() ? '...' : '', $parameter->getName());
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[8],
$argumentName === null ? sprintf('#%d %s', $i + 1, $parameterDescription) : $parameterDescription,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
))
->identifier('argument.byRef')
->line($argumentLine)
Expand All @@ -381,10 +368,9 @@ public function check(
$propertyDescription = sprintf('readonly property %s::$%s', $propertyReflection->getDeclaringClass()->getDisplayName(), $propertyReflection->getName());
}

$parameterDescription = sprintf('%s$%s', $parameter->isVariadic() ? '...' : '', $parameter->getName());
$errors[] = RuleErrorBuilder::message(sprintf(
'Parameter %s is passed by reference so it does not accept %s.',
$argumentName === null ? sprintf('#%d %s', $i + 1, $parameterDescription) : $parameterDescription,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
$propertyDescription,
))->identifier('argument.byRef')->line($argumentLine)->build();
}
Expand All @@ -397,10 +383,9 @@ public function check(
continue;
}

$parameterDescription = sprintf('%s$%s', $parameter->isVariadic() ? '...' : '', $parameter->getName());
$errors[] = RuleErrorBuilder::message(sprintf(
$messages[8],
$argumentName === null ? sprintf('#%d %s', $i + 1, $parameterDescription) : $parameterDescription,
$this->describeParameter($parameter, $argumentName === null ? $i + 1 : null),
))->identifier('argument.byRef')->line($argumentLine)->build();
}

Expand Down Expand Up @@ -600,4 +585,19 @@ private function processArguments(
return [$errors, $newArguments];
}

private function describeParameter(ParameterReflection $parameter, ?int $position): string
{
$parts = [];
if ($position !== null) {
$parts[] = '#' . $position;
}

$name = $parameter->getName();
if ($name !== '') {
$parts[] = ($parameter->isVariadic() ? '...$' : '$') . $name;
}

return implode(' ', $parts);
}

}
4 changes: 2 additions & 2 deletions tests/PHPStan/Levels/data/callableVariance-5.json
@@ -1,6 +1,6 @@
[
{
"message": "Parameter #1 $ of callable callable(Levels\\CallableVariance\\B): void expects Levels\\CallableVariance\\B, Levels\\CallableVariance\\A given.",
"message": "Parameter #1 of callable callable(Levels\\CallableVariance\\B): void expects Levels\\CallableVariance\\B, Levels\\CallableVariance\\A given.",
"line": 14,
"ignorable": true
},
Expand Down Expand Up @@ -39,4 +39,4 @@
"line": 85,
"ignorable": true
}
]
]
14 changes: 12 additions & 2 deletions tests/PHPStan/Rules/Functions/CallCallablesRuleTest.php
Expand Up @@ -190,7 +190,7 @@ public function dataBug3566(): array
true,
[
[
'Parameter #1 $ of closure expects int, TMemberType given.',
'Parameter #1 of closure expects int, TMemberType given.',
29,
],
],
Expand Down Expand Up @@ -280,7 +280,7 @@ public function testBug6485(): void
{
$this->analyse([__DIR__ . '/data/bug-6485.php'], [
[
'Parameter #1 $ of closure expects never, TBlockType of Bug6485\Block given.',
'Parameter #1 of closure expects never, TBlockType of Bug6485\Block given.',
33,
],
]);
Expand All @@ -306,4 +306,14 @@ public function testBug9614(): void
$this->analyse([__DIR__ . '/data/bug-9614.php'], []);
}

public function testBug10814(): void
{
$this->analyse([__DIR__ . '/data/bug-10814.php'], [
[
'Parameter #1 of closure expects DateTime, DateTimeImmutable given.',
10,
],
]);
}

}
12 changes: 12 additions & 0 deletions tests/PHPStan/Rules/Functions/data/bug-10814.php
@@ -0,0 +1,12 @@
<?php declare(strict_types = 1);

namespace Bug10814;

class HelloWorld
{
/** @param \Closure(\DateTime): void $fx */
public function foo($fx): void
{
$fx(new \DateTimeImmutable());
}
}

0 comments on commit 5c3a711

Please sign in to comment.