Skip to content

Commit 8080bb3

Browse files
committed
UnusedPrivateElementsSniff: Fixed missing reports for write-only properties with FQN native typehints
1 parent 2999540 commit 8080bb3

File tree

3 files changed

+31
-25
lines changed

3 files changed

+31
-25
lines changed

SlevomatCodingStandard/Sniffs/Classes/UnusedPrivateElementsSniff.php

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use SlevomatCodingStandard\Helpers\SuppressHelper;
1414
use SlevomatCodingStandard\Helpers\TokenHelper;
1515
use function array_keys;
16+
use function array_merge;
1617
use function array_reverse;
1718
use function count;
1819
use function in_array;
@@ -455,7 +456,7 @@ private function getProperties(File $phpcsFile, int $classTokenPointer): array
455456
break;
456457
}
457458

458-
$visibilityModifierTokenPointer = $this->findVisibilityModifierTokenPointer($phpcsFile, $tokens, $propertyTokenPointer);
459+
$visibilityModifierTokenPointer = $this->findVisibilityPointer($phpcsFile, $propertyTokenPointer);
459460
if ($visibilityModifierTokenPointer === null || $tokens[$visibilityModifierTokenPointer]['code'] !== T_PRIVATE) {
460461
$findPropertiesStartTokenPointer = $propertyTokenPointer + 1;
461462
continue;
@@ -526,7 +527,7 @@ private function getMethods(File $phpcsFile, int $classTokenPointer): array
526527
break;
527528
}
528529

529-
$visibilityModifierTokenPointer = $this->findVisibilityModifierTokenPointer($phpcsFile, $tokens, $methodTokenPointer);
530+
$visibilityModifierTokenPointer = $this->findVisibilityPointer($phpcsFile, $methodTokenPointer);
530531
if ($visibilityModifierTokenPointer === null || $tokens[$visibilityModifierTokenPointer]['code'] !== T_PRIVATE) {
531532
$findMethodsStartTokenPointer = $methodTokenPointer + 1;
532533
continue;
@@ -592,7 +593,7 @@ private function getConstants(File $phpcsFile, int $classTokenPointer): array
592593
break;
593594
}
594595

595-
$visibilityModifierTokenPointer = $this->findVisibilityModifierTokenPointer($phpcsFile, $tokens, $constantTokenPointer);
596+
$visibilityModifierTokenPointer = $this->findVisibilityPointer($phpcsFile, $constantTokenPointer);
596597
if ($visibilityModifierTokenPointer === null || $tokens[$visibilityModifierTokenPointer]['code'] !== T_PRIVATE) {
597598
$findConstantsStartTokenPointer = $constantTokenPointer + 1;
598599
continue;
@@ -608,33 +609,34 @@ private function getConstants(File $phpcsFile, int $classTokenPointer): array
608609
return $reportedConstants;
609610
}
610611

611-
/**
612-
* @param File $phpcsFile
613-
* @param array<int, array<string, array<int, int|string>|int|string>> $tokens
614-
* @param int $methodTokenPointer
615-
* @return int|null
616-
*/
617-
private function findVisibilityModifierTokenPointer(File $phpcsFile, array $tokens, int $methodTokenPointer): ?int
612+
private function findVisibilityPointer(File $phpcsFile, int $pointer): ?int
618613
{
619-
/** @var int $visibilityModifiedTokenPointer */
620-
$visibilityModifiedTokenPointer = TokenHelper::findPreviousEffective($phpcsFile, $methodTokenPointer - 1);
621-
$visibilityModifiedToken = $tokens[$visibilityModifiedTokenPointer];
622-
if (in_array($visibilityModifiedToken['code'], [T_PUBLIC, T_PROTECTED, T_PRIVATE], true)) {
623-
return $visibilityModifiedTokenPointer;
624-
}
614+
$tokens = $phpcsFile->getTokens();
615+
616+
$visibilityPointer = TokenHelper::findPreviousEffective($phpcsFile, $pointer - 1);
625617

626-
if (in_array($visibilityModifiedToken['code'], [T_SELF, T_STRING], true)) {
627-
$mightBeNullableTokenPointer = TokenHelper::findPreviousEffective($phpcsFile, $visibilityModifiedTokenPointer - 1);
628-
$mightBeNullableToken = $tokens[$mightBeNullableTokenPointer];
629-
if ($mightBeNullableToken['code'] === T_NULLABLE) {
630-
$visibilityModifiedTokenPointer = $mightBeNullableTokenPointer;
618+
if (in_array($tokens[$visibilityPointer]['code'], [T_SELF, T_STRING], true)) {
619+
$visibilityPointer = TokenHelper::findPreviousExcluding(
620+
$phpcsFile,
621+
array_merge(TokenHelper::$nameTokenCodes, TokenHelper::$ineffectiveTokenCodes),
622+
$visibilityPointer - 1
623+
);
624+
625+
if ($tokens[$visibilityPointer]['code'] === T_NULLABLE) {
626+
$visibilityPointer = TokenHelper::findPreviousEffective($phpcsFile, $visibilityPointer - 1);
631627
}
628+
}
632629

633-
return $this->findVisibilityModifierTokenPointer($phpcsFile, $tokens, $visibilityModifiedTokenPointer);
630+
if (in_array($tokens[$visibilityPointer]['code'], [T_ABSTRACT, T_STATIC], true)) {
631+
$visibilityPointer = TokenHelper::findPreviousExcluding(
632+
$phpcsFile,
633+
array_merge([T_ABSTRACT, T_STATIC], TokenHelper::$ineffectiveTokenCodes),
634+
$visibilityPointer - 1
635+
);
634636
}
635637

636-
if (in_array($visibilityModifiedToken['code'], [T_ABSTRACT, T_STATIC], true)) {
637-
return $this->findVisibilityModifierTokenPointer($phpcsFile, $tokens, $visibilityModifiedTokenPointer);
638+
if (in_array($tokens[$visibilityPointer]['code'], [T_PUBLIC, T_PROTECTED, T_PRIVATE], true)) {
639+
return $visibilityPointer;
638640
}
639641

640642
return null;

tests/Sniffs/Classes/UnusedPrivateElementsSniffTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,12 @@ public function testClassWithTypedProperties(): void
235235
{
236236
$resultFile = self::checkFile(__DIR__ . '/data/classWithTypedProperties.php');
237237

238-
self::assertNoSniffError($resultFile, 6);
238+
self::assertSame(4, $resultFile->getErrorCount());
239+
239240
self::assertSniffError($resultFile, 7, UnusedPrivateElementsSniff::CODE_WRITE_ONLY_PROPERTY);
240241
self::assertSniffError($resultFile, 8, UnusedPrivateElementsSniff::CODE_WRITE_ONLY_PROPERTY);
241242
self::assertSniffError($resultFile, 9, UnusedPrivateElementsSniff::CODE_WRITE_ONLY_PROPERTY);
243+
self::assertSniffError($resultFile, 10, UnusedPrivateElementsSniff::CODE_WRITE_ONLY_PROPERTY);
242244
}
243245

244246
}

tests/Sniffs/Classes/data/classWithTypedProperties.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@ class ClassWithTypedProperties
66
private self $self;
77
private ?self $empty;
88
private ClassWithTypedProperties $static;
9+
private \ClassWithTypedProperties $static2;
910
private int $int;
1011

1112
public function __construct()
1213
{
1314
$this->self = $this;
1415
$this->empty = null;
1516
$this->static = $this;
17+
$this->static2 = $this;
1618
$this->int = 0;
1719
}
1820

0 commit comments

Comments
 (0)