Skip to content

Commit 4166003

Browse files
committed
SlevomatCodingStandard.TypeHints.ParameterTypeHint: callable is not valid type for property promotion
1 parent 0ae2e35 commit 4166003

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

SlevomatCodingStandard/Sniffs/TypeHints/ParameterTypeHintSniff.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PHP_CodeSniffer\Files\File;
66
use PHP_CodeSniffer\Sniffs\Sniff;
7+
use PHP_CodeSniffer\Util\Tokens;
78
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
89
use PHPStan\PhpDocParser\Ast\PhpDoc\TypelessParamTagValueNode;
910
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
@@ -44,11 +45,13 @@
4445
use function sprintf;
4546
use function strtolower;
4647
use const T_BITWISE_AND;
48+
use const T_COMMA;
4749
use const T_DOC_COMMENT_CLOSE_TAG;
4850
use const T_DOC_COMMENT_OPEN_TAG;
4951
use const T_DOC_COMMENT_STAR;
5052
use const T_ELLIPSIS;
5153
use const T_FUNCTION;
54+
use const T_OPEN_PARENTHESIS;
5255
use const T_VARIABLE;
5356

5457
class ParameterTypeHintSniff implements Sniff
@@ -162,7 +165,30 @@ private function checkTypeHints(
162165
})
163166
);
164167

168+
$tokens = $phpcsFile->getTokens();
169+
170+
$isConstructor = FunctionHelper::isMethod($phpcsFile, $functionPointer)
171+
&& strtolower(FunctionHelper::getName($phpcsFile, $functionPointer)) === '__construct';
172+
165173
foreach ($parametersWithoutTypeHint as $parameterName) {
174+
$isPropertyPromotion = false;
175+
176+
if ($isConstructor) {
177+
$parameterPointer = TokenHelper::findNextContent(
178+
$phpcsFile,
179+
T_VARIABLE,
180+
$parameterName,
181+
$tokens[$functionPointer]['parenthesis_opener'],
182+
$tokens[$functionPointer]['parenthesis_closer']
183+
);
184+
185+
$pointerBeforeParameter = TokenHelper::findPrevious($phpcsFile, [T_COMMA, T_OPEN_PARENTHESIS], $parameterPointer - 1);
186+
187+
$visibilityPointer = TokenHelper::findNextEffective($phpcsFile, $pointerBeforeParameter + 1);
188+
189+
$isPropertyPromotion = in_array($tokens[$visibilityPointer]['code'], Tokens::$scopeModifiers, true);
190+
}
191+
166192
if (
167193
!array_key_exists($parameterName, $parametersAnnotations)
168194
|| $parametersAnnotations[$parameterName]->getValue() instanceof TypelessParamTagValueNode
@@ -313,6 +339,10 @@ private function checkTypeHints(
313339
continue;
314340
}
315341

342+
if ($isPropertyPromotion && $typeHint === 'callable') {
343+
continue 2;
344+
}
345+
316346
if (!TypeHintHelper::isValidTypeHint(
317347
$typeHint,
318348
$this->enableObjectTypeHint,

tests/Sniffs/TypeHints/data/parameterTypeHintNoErrors.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,7 +331,9 @@ public function __construct(
331331
/** @var array<int, string> */
332332
public array $promoted,
333333
/** @phpstan-var array<int, string> */
334-
public array $promoted2
334+
public array $promoted2,
335+
/** @var callable */
336+
private $callable,
335337
)
336338
{
337339

0 commit comments

Comments
 (0)