-
-
Notifications
You must be signed in to change notification settings - Fork 182
/
Copy pathLongTypeHintsSniff.php
101 lines (82 loc) · 3.02 KB
/
LongTypeHintsSniff.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<?php declare(strict_types = 1);
namespace SlevomatCodingStandard\Sniffs\TypeHints;
use SlevomatCodingStandard\Helpers\AnnotationHelper;
use SlevomatCodingStandard\Helpers\DocCommentHelper;
use SlevomatCodingStandard\Helpers\FunctionHelper;
use SlevomatCodingStandard\Helpers\PropertyHelper;
use SlevomatCodingStandard\Helpers\TokenHelper;
class LongTypeHintsSniff implements \PHP_CodeSniffer\Sniffs\Sniff
{
public const CODE_USED_LONG_TYPE_HINT = 'UsedLongTypeHint';
/**
* @return mixed[]
*/
public function register(): array
{
return [
T_FUNCTION,
T_VARIABLE,
];
}
/**
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
* @param \PHP_CodeSniffer\Files\File $phpcsFile
* @param int $pointer
*/
public function process(\PHP_CodeSniffer\Files\File $phpcsFile, $pointer): void
{
$tokens = $phpcsFile->getTokens();
if ($tokens[$pointer]['code'] === T_FUNCTION) {
$allAnnotations = ['@param' => FunctionHelper::getParametersAnnotations($phpcsFile, $pointer)];
$return = FunctionHelper::findReturnAnnotation($phpcsFile, $pointer);
if ($return !== null) {
$allAnnotations['@return'] = [$return];
}
} else {
if (!PropertyHelper::isProperty($phpcsFile, $pointer)) {
return;
}
$allAnnotations = ['@var' => AnnotationHelper::getAnnotationsByName($phpcsFile, $pointer, '@var')];
}
foreach ($allAnnotations as $annotationName => $annotations) {
foreach ($annotations as $annotation) {
if ($annotation->getContent() === null) {
continue;
}
$types = preg_split('~\\s+~', $annotation->getContent())[0];
foreach (explode('|', $types) as $type) {
$type = strtolower(trim($type, '[]'));
$suggestType = null;
if ($type === 'integer') {
$suggestType = 'int';
} elseif ($type === 'boolean') {
$suggestType = 'bool';
}
if ($suggestType !== null) {
$fix = $phpcsFile->addFixableError(sprintf(
'Expected "%s" but found "%s" in %s annotation.',
$suggestType,
$type,
$annotationName
), $pointer, self::CODE_USED_LONG_TYPE_HINT);
if ($fix) {
/** @var int $docCommentOpenPointer */
$docCommentOpenPointer = DocCommentHelper::findDocCommentOpenToken($phpcsFile, $pointer);
$docCommentClosePointer = $tokens[$docCommentOpenPointer]['comment_closer'];
$phpcsFile->fixer->beginChangeset();
for ($i = $docCommentOpenPointer; $i <= $docCommentClosePointer; $i++) {
$phpcsFile->fixer->replaceToken($i, '');
}
$docComment = TokenHelper::getContent($phpcsFile, $docCommentOpenPointer, $docCommentClosePointer);
$fixedDocComment = preg_replace_callback('~((?:@(?:var|param|return)\\s+)|\|)' . preg_quote($type, '~') . '(\\s|\||\[)~', function (array $matches) use ($suggestType): string {
return $matches[1] . $suggestType . $matches[2];
}, $docComment);
$phpcsFile->fixer->addContent($docCommentOpenPointer, $fixedDocComment);
$phpcsFile->fixer->endChangeset();
}
}
}
}
}
}
}