Skip to content

Commit 24667fa

Browse files
maryokukulich
authored andcommitted
SlevomatCodingStandard.TypeHints.ClassConstantTypeHint: fixing only private constants
1 parent 43ab100 commit 24667fa

File tree

5 files changed

+69
-1
lines changed

5 files changed

+69
-1
lines changed

SlevomatCodingStandard/Sniffs/TypeHints/ClassConstantTypeHintSniff.php

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use function array_key_exists;
1414
use function count;
1515
use function sprintf;
16+
use const T_CLOSE_CURLY_BRACKET;
1617
use const T_CONST;
1718
use const T_CONSTANT_ENCAPSED_STRING;
1819
use const T_DNUMBER;
@@ -22,7 +23,10 @@
2223
use const T_LNUMBER;
2324
use const T_MINUS;
2425
use const T_NULL;
26+
use const T_OPEN_CURLY_BRACKET;
2527
use const T_OPEN_SHORT_ARRAY;
28+
use const T_PRIVATE;
29+
use const T_SEMICOLON;
2630
use const T_START_HEREDOC;
2731
use const T_START_NOWDOC;
2832
use const T_TRUE;
@@ -34,8 +38,14 @@ class ClassConstantTypeHintSniff implements Sniff
3438
public const CODE_USELESS_DOC_COMMENT = 'UselessDocComment';
3539
public const CODE_USELESS_VAR_ANNOTATION = 'UselessVarAnnotation';
3640

41+
private const YES = 'yes';
42+
private const NO = 'no';
43+
private const PRIVATE = 'private';
44+
3745
public ?bool $enableNativeTypeHint = null;
3846

47+
public string $fixableNativeTypeHint = self::YES;
48+
3949
/** @var array<int|string, string> */
4050
private static array $tokenToTypeHintMapping = [
4151
T_FALSE => 'false',
@@ -113,7 +123,14 @@ private function checkNativeTypeHint(File $phpcsFile, int $constantPointer): voi
113123
self::CODE_MISSING_NATIVE_TYPE_HINT,
114124
];
115125

116-
if ($typeHint === null) {
126+
if (
127+
$typeHint === null
128+
|| $this->fixableNativeTypeHint === self::NO
129+
|| (
130+
$this->fixableNativeTypeHint === self::PRIVATE
131+
&& !$this->isConstantPrivate($phpcsFile, $constantPointer)
132+
)
133+
) {
117134
$phpcsFile->addError(...$errorParameters);
118135
return;
119136
}
@@ -193,4 +210,16 @@ private function getConstantNamePointer(File $phpcsFile, int $constantPointer):
193210
return TokenHelper::findPreviousEffective($phpcsFile, $equalPointer - 1);
194211
}
195212

213+
private function isConstantPrivate(File $phpcsFile, int $constantPointer): bool
214+
{
215+
$tokens = $phpcsFile->getTokens();
216+
$previousPointer = TokenHelper::findPrevious(
217+
$phpcsFile,
218+
[T_PRIVATE, T_OPEN_CURLY_BRACKET, T_CLOSE_CURLY_BRACKET, T_SEMICOLON],
219+
$constantPointer - 1,
220+
);
221+
222+
return $previousPointer !== null && $tokens[$previousPointer]['code'] === T_PRIVATE;
223+
}
224+
196225
}

doc/type-hints.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
Sniff provides the following settings:
99

1010
* `enableNativeTypeHint`: enforces native typehint. It's on by default if you're on PHP 8.3+
11+
* `fixableNativeTypeHint`: (default: `yes`) allows fixing native type hints. Use `no` to disable fixing, or `private` to fix only private constants (safer for inheritance/interface compatibility).
1112

1213
#### SlevomatCodingStandard.TypeHints.DeclareStrictTypes 🔧
1314

tests/Sniffs/TypeHints/ClassConstantTypeHintSniffTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,22 @@ public function testNativeTypeHintErrors(): void
4343
self::assertAllFixedInFile($report);
4444
}
4545

46+
public function testNativeTypeHintPrivateErrors(): void
47+
{
48+
$report = self::checkFile(__DIR__ . '/data/classConstantTypeHintNativePrivateErrors.php', [
49+
'enableNativeTypeHint' => true,
50+
'fixableNativeTypeHint' => 'private',
51+
]);
52+
53+
self::assertSame(4, $report->getErrorCount());
54+
55+
foreach (range(6, 9) as $line) {
56+
self::assertSniffError($report, $line, ClassConstantTypeHintSniff::CODE_MISSING_NATIVE_TYPE_HINT);
57+
}
58+
59+
self::assertAllFixedInFile($report);
60+
}
61+
4662
public function testUselessDocCommentNoErrors(): void
4763
{
4864
$report = self::checkFile(__DIR__ . '/data/classConstantTypeHintUselessDocCommentNoErrors.php', [
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php // lint >= 8.3
2+
3+
class Whatever
4+
{
5+
6+
const C_IMPLICIT_PUBLIC = 'implicit_public';
7+
public const C_EXPLICIT_PUBLIC = 'explicit_public';
8+
protected const C_PROTECTED = 'protected';
9+
private const string C_PRIVATE = 'private';
10+
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php // lint >= 8.3
2+
3+
class Whatever
4+
{
5+
6+
const C_IMPLICIT_PUBLIC = 'implicit_public';
7+
public const C_EXPLICIT_PUBLIC = 'explicit_public';
8+
protected const C_PROTECTED = 'protected';
9+
private const C_PRIVATE = 'private';
10+
11+
}

0 commit comments

Comments
 (0)