Skip to content

Commit

Permalink
feat: add support for typed constants in AlphabeticallyOrderedConstan…
Browse files Browse the repository at this point in the history
…tsSniff
  • Loading branch information
David Kurka committed Mar 7, 2024
1 parent be52c85 commit 79579b7
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 12 deletions.
66 changes: 58 additions & 8 deletions src/Cdn77/Sniffs/Ordering/AlphabeticallyOrderedConstantsSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@
use const T_WHITESPACE;

/**
* @phpstan-type NameWithValueShape array{
* @phpstan-type TypeNameValueShape array{
* type: TypeShape|null,
* name: NameShape,
* value: ValueShape
* }
* @phpstan-type TypeShape array{
* content: string,
* ptr: int
* }
* @phpstan-type NameShape array{
* content: string,
* lowercaseContent: string,
Expand Down Expand Up @@ -89,7 +94,7 @@ public function process(File $phpcsFile, mixed $stackPtr): void
}
}

/** @param list<NameWithValueShape> $namesWithValues */
/** @param list<TypeNameValueShape> $namesWithValues */
private function fix(File $file, array $namesWithValues): void
{
$fixer = $file->fixer;
Expand All @@ -104,9 +109,19 @@ private function fix(File $file, array $namesWithValues): void
foreach ($namesWithValues as $key => $nameWithValue) {
$sortedNameAndValueToken = $sortedNameAndValueTokens[$key];

$typePointer = $nameWithValue['type']['ptr'] ?? null;
$namePointer = $nameWithValue['name']['ptr'];
FixerHelper::removeBetweenIncluding($file, $namePointer, $namePointer);
$fixer->addContent($namePointer, $sortedNameAndValueToken['name']['content']);
FixerHelper::removeBetweenIncluding($file, $typePointer ?? $namePointer, $namePointer);
$fixer->addContent(
$typePointer ?? $namePointer,
$sortedNameAndValueToken['type'] === null ?
$sortedNameAndValueToken['name']['content']
: sprintf(
'%s %s',
$sortedNameAndValueToken['type']['content'],
$sortedNameAndValueToken['name']['content'],
),
);

$value = $nameWithValue['value'];
FixerHelper::removeBetweenIncluding($file, $value['startPtr'], $value['endPtr']);
Expand All @@ -116,7 +131,7 @@ private function fix(File $file, array $namesWithValues): void
$fixer->endChangeset();
}

/** @return array<string, list<NameWithValueShape>> */
/** @return array<string, list<TypeNameValueShape>> */
private function findConstantNamesWithValuesByVisibility(File $phpcsFile): array
{
$constantNamesWithValues = [];
Expand All @@ -128,7 +143,8 @@ private function findConstantNamesWithValuesByVisibility(File $phpcsFile): array
}

$visibility = $this->getVisibility($phpcsFile, $stackPtr);
$constantName = $this->findConstantName($phpcsFile, $stackPtr);
$type = $this->findType($phpcsFile, $stackPtr);
$constantName = $this->findConstantName($phpcsFile, $type['ptr'] ?? $stackPtr);

if ($constantName === null) {
continue;
Expand All @@ -147,6 +163,7 @@ private function findConstantNamesWithValuesByVisibility(File $phpcsFile): array
}

$constantNamesWithValues[$visibility][] = [
'type' => $type,
'name' => $constantName,
'value' => $value,
];
Expand All @@ -170,13 +187,46 @@ private function getVisibility(File $phpcsFile, int $constStackPtr): string
: 'public';
}

/** @phpstan-return TypeShape|null */
private function findType(File $phpcsFile, int $constStackPtr): array|null
{
$tokens = $phpcsFile->getTokens();
$possibleTypeTokenPointer = $phpcsFile->findNext(
types: Tokens::$emptyTokens,
start: $constStackPtr + 1,
exclude: true,
local: true,
);

if ($possibleTypeTokenPointer === false || $tokens[$possibleTypeTokenPointer]['code'] !== T_STRING) {
return null;
}

$possibleTypeToken = $tokens[$possibleTypeTokenPointer];
$afterPossibleTypeTokenPointer = $phpcsFile->findNext(
types: Tokens::$emptyTokens,
start: $possibleTypeTokenPointer + 1,
exclude: true,
local: true,
);

if ($afterPossibleTypeTokenPointer === false || $tokens[$afterPossibleTypeTokenPointer]['code'] !== T_STRING) {
return null;
}

return [
'content' => $possibleTypeToken['content'],
'ptr' => $possibleTypeTokenPointer,
];
}

/** @phpstan-return NameShape|null */
private function findConstantName(File $phpcsFile, int $constStackPtr): array|null
private function findConstantName(File $phpcsFile, int $constOrTypeStackPtr): array|null
{
$tokens = $phpcsFile->getTokens();
$constantNameTokenPointer = $phpcsFile->findNext(
types: Tokens::$emptyTokens,
start: $constStackPtr + 1,
start: $constOrTypeStackPtr + 1,
exclude: true,
local: true,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ final class TestClass
public const C = 'c' . PHP_EOL;
public const D = [123, 'test'];

protected const E = 'e';
protected const F = 'f';
protected const string E = 'e';
protected const int F = 123;
protected const G = 'g';
protected const Ha = 'h';
protected const HB = 'h';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ final class TestClass
public const D = [123, 'test'];
public const B = 'b';

protected const E = 'e';
protected const G = 'g';
protected const F = 'f';
protected const string E = 'e';
protected const int F = 123;
protected const HB = 'h';
protected const Ha = 'h';

Expand Down

0 comments on commit 79579b7

Please sign in to comment.