|
@@ -21,8 +21,19 @@ namespace PhpCsFixer\Tokenizer;
|
|
|
*/
|
|
|
abstract class AbstractTypeTransformer extends AbstractTransformer
|
|
|
{
|
|
|
+ private const TYPE_END_TOKENS = [')', [T_CALLABLE], [T_NS_SEPARATOR], [T_STRING], [CT::T_ARRAY_TYPEHINT]];
|
|
|
+
|
|
|
+ private const TYPE_TOKENS = [
|
|
|
+ '|', '&', '(',
|
|
|
+ ...self::TYPE_END_TOKENS,
|
|
|
+ [CT::T_TYPE_ALTERNATION], [CT::T_TYPE_INTERSECTION], // some siblings may already be transformed
|
|
|
+ [T_WHITESPACE], [T_COMMENT], [T_DOC_COMMENT], // technically these can be inside of type tokens array
|
|
|
+ ];
|
|
|
+
|
|
|
+ abstract protected function replaceToken(Tokens $tokens, int $index): void;
|
|
|
+
|
|
|
/**
|
|
|
- * @param array{0: int, 1?: string}|string $originalToken
|
|
|
+ * @param array{0: int, 1: string}|string $originalToken
|
|
|
*/
|
|
|
protected function doProcess(Tokens $tokens, int $index, $originalToken): void
|
|
|
{
|
|
@@ -30,67 +41,27 @@ abstract class AbstractTypeTransformer extends AbstractTransformer
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- $prevIndex = $this->getPreviousTokenCandidate($tokens, $index);
|
|
|
-
|
|
|
- /** @var Token $prevToken */
|
|
|
- $prevToken = $tokens[$prevIndex];
|
|
|
-
|
|
|
- if ($prevToken->isGivenKind([
|
|
|
- CT::T_TYPE_COLON, // `:` is part of a function return type `foo(): X|Y`
|
|
|
- CT::T_TYPE_ALTERNATION, // `|` is part of a union (chain) `X|Y`
|
|
|
- CT::T_TYPE_INTERSECTION,
|
|
|
- T_STATIC, T_VAR, T_PUBLIC, T_PROTECTED, T_PRIVATE, // `var X|Y $a;`, `private X|Y $a` or `public static X|Y $a`
|
|
|
- CT::T_CONSTRUCTOR_PROPERTY_PROMOTION_PRIVATE, CT::T_CONSTRUCTOR_PROPERTY_PROMOTION_PROTECTED, CT::T_CONSTRUCTOR_PROPERTY_PROMOTION_PUBLIC, // promoted properties
|
|
|
- ])) {
|
|
|
- $this->replaceToken($tokens, $index);
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (\defined('T_READONLY') && $prevToken->isGivenKind(T_READONLY)) { // @TODO: drop condition when PHP 8.1+ is required
|
|
|
- $this->replaceToken($tokens, $index);
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (!$prevToken->equalsAny(['(', ','])) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- $prevPrevTokenIndex = $tokens->getPrevMeaningfulToken($prevIndex);
|
|
|
-
|
|
|
- if ($tokens[$prevPrevTokenIndex]->isGivenKind(T_CATCH)) {
|
|
|
- $this->replaceToken($tokens, $index);
|
|
|
-
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- $functionKinds = [[T_FUNCTION], [T_FN]];
|
|
|
- $functionIndex = $tokens->getPrevTokenOfKind($prevIndex, $functionKinds);
|
|
|
-
|
|
|
- if (null === $functionIndex) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- $braceOpenIndex = $tokens->getNextTokenOfKind($functionIndex, ['(']);
|
|
|
- $braceCloseIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $braceOpenIndex);
|
|
|
-
|
|
|
- if ($braceCloseIndex < $index) {
|
|
|
+ if (!$this->isPartOfType($tokens, $index)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
$this->replaceToken($tokens, $index);
|
|
|
}
|
|
|
|
|
|
- abstract protected function replaceToken(Tokens $tokens, int $index): void;
|
|
|
-
|
|
|
- private function getPreviousTokenCandidate(Tokens $tokens, int $index): int
|
|
|
+ private function isPartOfType(Tokens $tokens, int $index): bool
|
|
|
{
|
|
|
- $candidateIndex = $tokens->getTokenNotOfKindsSibling($index, -1, [T_CALLABLE, T_NS_SEPARATOR, T_STRING, CT::T_ARRAY_TYPEHINT, T_WHITESPACE, T_COMMENT, T_DOC_COMMENT]);
|
|
|
+ // for parameter there will be variable after type
|
|
|
+ $variableIndex = $tokens->getTokenNotOfKindSibling($index, 1, self::TYPE_TOKENS);
|
|
|
+ if ($tokens[$variableIndex]->isGivenKind(T_VARIABLE)) {
|
|
|
+ return $tokens[$tokens->getPrevMeaningfulToken($variableIndex)]->equalsAny(self::TYPE_END_TOKENS);
|
|
|
+ }
|
|
|
+
|
|
|
+ // return types and non-capturing catches
|
|
|
+ $typeColonIndex = $tokens->getTokenNotOfKindSibling($index, -1, self::TYPE_TOKENS);
|
|
|
+ if ($tokens[$typeColonIndex]->isGivenKind([T_CATCH, CT::T_TYPE_COLON])) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- return $tokens[$candidateIndex]->isGivenKind(CT::T_ATTRIBUTE_CLOSE)
|
|
|
- ? $this->getPreviousTokenCandidate($tokens, $tokens->getPrevTokenOfKind($index, [[T_ATTRIBUTE]]))
|
|
|
- : $candidateIndex
|
|
|
- ;
|
|
|
+ return false;
|
|
|
}
|
|
|
}
|