[ticket/17512] Refactor PHP Sniffer coding standard logic

PHPBB-17512
This commit is contained in:
rxu 2025-05-15 16:50:51 +07:00
parent b3ff1d7e34
commit 7a4b3f52ae
No known key found for this signature in database
GPG key ID: 8117904FEDEFDD17

View file

@ -22,52 +22,60 @@ use PHP_CodeSniffer\Sniffs\Sniff;
class UnionTypesCheckSniff implements Sniff class UnionTypesCheckSniff implements Sniff
{ {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function register() public function register()
{ {
return [ return [
T_TYPE_UNION, T_FUNCTION,
T_NULLABLE, T_CLASS,
]; ];
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function process(File $phpcsFile, $stackPtr) public function process(File $phpcsFile, $stackPtr)
{ {
$tokens = $phpcsFile->getTokens(); $tokens = $phpcsFile->getTokens();
// Check if nullable type shortcut syntax ('?typehint') is used if ($tokens[$stackPtr]['type'] === 'T_FUNCTION')
if ($tokens[$stackPtr]['type'] === 'T_NULLABLE')
{ {
$type = $tokens[$stackPtr + 1]['content']; $method_params = $phpcsFile->getMethodParameters($stackPtr);
$error = 'Nullable shortcut syntax must not be used. Use union type instead: %2$s|null; found %1$s%2$s'; $method_params_array = array_column($method_params, 'type_hint', 'token');
$data = [trim($tokens[$stackPtr]['content']), $type]; foreach ($method_params_array as $stack_pointer => $type_hint)
$phpcsFile->addError($error, $stackPtr, 'ShortNullableSyntax', $data);
}
// Get the entry before the 1st '|' and all entries after it untill the end of union type declaration
if ($tokens[$stackPtr]['type'] === 'T_TYPE_UNION' && $tokens[$stackPtr - 2]['type'] !== 'T_TYPE_UNION')
{
// Get all the types within the union type declaration
$types_array = [];
for ($i = $stackPtr - 2; $i++;)
{ {
if (in_array($tokens[$i]['type'], ['T_TYPE_UNION', 'T_STRING', 'T_NULL'])) $this->check_union_type($phpcsFile, $stack_pointer, $type_hint);
{
if ($tokens[$i]['type'] != 'T_TYPE_UNION')
{
$types_array[] = $tokens[$i]['content'];
}
}
else
{
break;
}
} }
$method_properties = $phpcsFile->getMethodProperties($stackPtr);
$this->check_union_type($phpcsFile, $stackPtr, $method_properties['return_type']);
}
else if ($tokens[$stackPtr]['type'] === 'T_CLASS')
{
$class_member_pointer = $phpcsFile->findNext(T_VARIABLE, $stackPtr);
$first_method_pointer = $phpcsFile->findNext(T_FUNCTION, $stackPtr);
do
{
$properties = $phpcsFile->getMemberProperties($class_member_pointer);
$this->check_union_type($phpcsFile, $class_member_pointer, $properties['type']);
$class_member_pointer = $phpcsFile->findNext(T_VARIABLE, $class_member_pointer + 1);
}
while($class_member_pointer !== false && ($class_member_pointer < $first_method_pointer));
}
}
public function check_union_type(File $phpcsFile, $stack_pointer, $type_hint)
{
if (!strpos($type_hint, '|') && $type_hint[0] == '?') // Check nullable shortcut syntax
{
$type = substr($type_hint, 1);
$error = 'Nullable shortcut syntax must not be used. Use union type instead: %1$s|null; found %2$s';
$data = [$type, $type_hint];
$phpcsFile->addError($error, $stack_pointer, 'ShortNullableSyntax', $data);
}
else if (($types_array = explode('|', $type_hint)) > 1) // Check union type layout
{
$types_array_sorted = $types_array_null_less = $types_array; $types_array_sorted = $types_array_null_less = $types_array;
// Check 'null' to be the last element // Check 'null' to be the last element
@ -76,7 +84,7 @@ class UnionTypesCheckSniff implements Sniff
{ {
$error = 'The "null" type hint must be the last of the union type elements; found %s'; $error = 'The "null" type hint must be the last of the union type elements; found %s';
$data = [implode('|', $types_array)]; $data = [implode('|', $types_array)];
$phpcsFile->addError($error, $stackPtr, 'NullAlwaysLast', $data); $phpcsFile->addError($error, $stack_pointer, 'NullAlwaysLast', $data);
} }
// Check types excepting 'null' to follow alphabetical order // Check types excepting 'null' to follow alphabetical order
@ -89,8 +97,8 @@ class UnionTypesCheckSniff implements Sniff
{ {
$error = 'Union type elements must be sorted alphabetically excepting the "null" type hint must be the last if any; found %s'; $error = 'Union type elements must be sorted alphabetically excepting the "null" type hint must be the last if any; found %s';
$data = [implode('|', $types_array)]; $data = [implode('|', $types_array)];
$phpcsFile->addError($error, $stackPtr, 'AlphabeticalSort', $data); $phpcsFile->addError($error, $stack_pointer, 'AlphabeticalSort', $data);
} }
} }
} }
} }