Skip to content

Commit

Permalink
Resolve PHPStan issue with deprecated parameter order in PHP 8.1 and 8.3
Browse files Browse the repository at this point in the history
  • Loading branch information
sayuprc committed Mar 16, 2024
1 parent e7d6c3a commit 79aed74
Show file tree
Hide file tree
Showing 10 changed files with 527 additions and 10 deletions.
10 changes: 10 additions & 0 deletions src/Php/PhpVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ public function deprecatesRequiredParameterAfterOptional(): bool
return $this->versionId >= 80000;
}

public function deprecatesRequiredParameterAfterOptionalNullableAndDefaultNull(): bool
{
return $this->versionId >= 80100;
}

public function deprecatesRequiredParameterAfterOptionalUnionOrMixed(): bool
{
return $this->versionId >= 80300;
}

public function supportsLessOverridenParametersWithVariadic(): bool
{
return $this->versionId >= 80000;
Expand Down
48 changes: 46 additions & 2 deletions src/Rules/FunctionDefinitionCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
use PhpParser\Node\Expr\ConstFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Identifier;
use PhpParser\Node\IntersectionType;
use PhpParser\Node\Name;
use PhpParser\Node\NullableType;
use PhpParser\Node\Param;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Function_;
Expand All @@ -29,10 +33,12 @@
use PHPStan\Type\Type;
use PHPStan\Type\TypeTraverser;
use PHPStan\Type\VerbosityLevel;
use function array_filter;
use function array_keys;
use function array_map;
use function array_merge;
use function count;
use function in_array;
use function is_string;
use function sprintf;

Expand Down Expand Up @@ -366,6 +372,7 @@ private function checkRequiredParameterAfterOptional(array $parameterNodes): arr
/** @var string|null $optionalParameter */
$optionalParameter = null;
$errors = [];
$targetPhpVersion = null;
foreach ($parameterNodes as $parameterNode) {
if (!$parameterNode->var instanceof Variable) {
throw new ShouldNotHappenException();
Expand All @@ -375,7 +382,16 @@ private function checkRequiredParameterAfterOptional(array $parameterNodes): arr
}
$parameterName = $parameterNode->var->name;
if ($optionalParameter !== null && $parameterNode->default === null && !$parameterNode->variadic) {
$errors[] = RuleErrorBuilder::message(sprintf('Deprecated in PHP 8.0: Required parameter $%s follows optional parameter $%s.', $parameterName, $optionalParameter))->line($parameterNode->getStartLine())->build();
$errors[] = RuleErrorBuilder::message(
sprintf(
'Deprecated in PHP %s: Required parameter $%s follows optional parameter $%s.',
$targetPhpVersion ??= '8.0',
$parameterName,
$optionalParameter,
),
)->line($parameterNode->getStartLine())->build();

$targetPhpVersion = null;
continue;
}
if ($parameterNode->default === null) {
Expand All @@ -394,7 +410,35 @@ private function checkRequiredParameterAfterOptional(array $parameterNodes): arr

$constantName = $defaultValue->name->toLowerString();
if ($constantName === 'null') {
continue;
if (!$this->phpVersion->deprecatesRequiredParameterAfterOptionalNullableAndDefaultNull()) {
continue;
}

$parameterNodeType = $parameterNode->type;

if ($parameterNodeType instanceof NullableType) {
$targetPhpVersion = '8.1';
}

if ($this->phpVersion->deprecatesRequiredParameterAfterOptionalUnionOrMixed()) {
$types = [];

if ($parameterNodeType instanceof UnionType) {
$types = $parameterNodeType->types;
} elseif ($parameterNodeType instanceof Identifier) {
$types = [$parameterNodeType];
}

$nullOrMixed = array_filter($types, static fn (Identifier|Name|IntersectionType $type): bool => $type instanceof Identifier && (in_array($type->name, ['null', 'mixed'], true)));

if (0 < count($nullOrMixed)) {
$targetPhpVersion = '8.3';
}
}

if ($targetPhpVersion === null) {
continue;
}
}

$optionalParameter = $parameterName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,16 @@ public function dataRequiredParameterAfterOptional(): array
return [
[
70400,
[],
[
[
"Anonymous function uses native union types but they're supported only on PHP 8.0 and later.",
17,
],
[
"Anonymous function uses native union types but they're supported only on PHP 8.0 and later.",
19,
],
],
],
[
80000,
Expand All @@ -108,6 +117,92 @@ public function dataRequiredParameterAfterOptional(): array
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
11,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
13,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
17,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
21,
],
],
],
[
80100,
[
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
5,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
9,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
11,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
13,
],
[
'Deprecated in PHP 8.1: Required parameter $bar follows optional parameter $foo.',
15,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
17,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
21,
],
],
],
[
80300,
[
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
5,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
9,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
11,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
13,
],
[
'Deprecated in PHP 8.1: Required parameter $bar follows optional parameter $foo.',
15,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
17,
],
[
'Deprecated in PHP 8.3: Required parameter $bar follows optional parameter $foo.',
19,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
21,
],
[
'Deprecated in PHP 8.3: Required parameter $bar follows optional parameter $foo.',
23,
],
],
],
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,16 @@ public function dataRequiredParameterAfterOptional(): array
return [
[
70400,
[],
[
[
"Anonymous function uses native union types but they're supported only on PHP 8.0 and later.",
29,
],
[
"Anonymous function uses native union types but they're supported only on PHP 8.0 and later.",
33,
],
],
],
[
80000,
Expand All @@ -152,6 +161,92 @@ public function dataRequiredParameterAfterOptional(): array
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
17,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
21,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
29,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
37,
],
],
],
[
80100,
[
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
5,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
13,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
17,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
21,
],
[
'Deprecated in PHP 8.1: Required parameter $bar follows optional parameter $foo.',
25,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
29,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
37,
],
],
],
[
80300,
[
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
5,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
13,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
17,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
21,
],
[
'Deprecated in PHP 8.1: Required parameter $bar follows optional parameter $foo.',
25,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
29,
],
[
'Deprecated in PHP 8.3: Required parameter $bar follows optional parameter $foo.',
33,
],
[
'Deprecated in PHP 8.0: Required parameter $bar follows optional parameter $foo.',
37,
],
[
'Deprecated in PHP 8.3: Required parameter $bar follows optional parameter $foo.',
41,
],
],
],
];
Expand Down

0 comments on commit 79aed74

Please sign in to comment.