Skip to content

Commit ca242a0

Browse files
authored
Fix nullable constructor promotion detection (#321)
1 parent c019db0 commit ca242a0

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

Tests/VariableAnalysisSniff/VariableAnalysisTest.php

+2
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ public function testClassWithMembersWarnings()
194194
115,
195195
116,
196196
174,
197+
202,
198+
203,
197199
];
198200
$this->assertSame($expectedWarnings, $lines);
199201
}

Tests/VariableAnalysisSniff/fixtures/ClassWithMembersFixture.php

+27
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,30 @@ public function getMessage(): string {
195195
return $this->message;
196196
}
197197
}
198+
199+
class ClassWithNullableConstructorPromotion {
200+
public function __construct(
201+
public ?string $name = 'Brent',
202+
$unused, // Unused variable $unused
203+
?string $unused2, // Unused variable $unused2
204+
public ?string $role,
205+
private ?string $role2,
206+
protected ?string $role3,
207+
public $nickname,
208+
private $nickname2,
209+
protected $nickname3
210+
) {
211+
}
212+
}
213+
214+
class ClassWithReadonlyNullableConstructorPromotion {
215+
public function __construct(
216+
private readonly ?string $message,
217+
private readonly $name,
218+
public readonly ?bool $key
219+
) {}
220+
221+
public function getMessage(): string {
222+
return $this->message;
223+
}
224+
}

VariableAnalysis/Lib/Helpers.php

+9
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,15 @@ public static function isConstructorPromotion(File $phpcsFile, $stackPtr)
15611561
return false;
15621562
}
15631563
$prev2Token = $tokens[$prev2Index];
1564+
// If the token that might be a visibility keyword is a nullable typehint,
1565+
// ignore it and move back one token further eg: `public ?boolean $foobar`.
1566+
if ($prev2Token['code'] === 'PHPCS_T_NULLABLE') {
1567+
$prev2Index = $phpcsFile->findPrevious(Tokens::$emptyTokens, ($prev2Index - 1), $functionIndex, true);
1568+
if (! is_int($prev2Index)) {
1569+
return false;
1570+
}
1571+
}
1572+
$prev2Token = $tokens[$prev2Index];
15641573
if (in_array($prev2Token['code'], Tokens::$scopeModifiers, true)) {
15651574
return true;
15661575
}

0 commit comments

Comments
 (0)