Skip to content

Commit

Permalink
TypeAlternationTransformer - fix for multiple function parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
kubawerlos committed Jul 30, 2021
1 parent 5ad0853 commit d684396
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 36 deletions.
55 changes: 19 additions & 36 deletions src/Tokenizer/Transformer/TypeAlternationTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,70 +53,53 @@ public function process(Tokens $tokens, Token $token, $index)
return;
}

$prevIndex = $tokens->getPrevMeaningfulToken($index);

if (!$tokens[$prevIndex]->isGivenKind([T_STRING, CT::T_ARRAY_TYPEHINT])) {
return;
}

do {
$prevIndex = $tokens->getPrevMeaningfulToken($prevIndex);

if (null === $prevIndex) {
return;
}

if (!$tokens[$prevIndex]->isGivenKind([T_NS_SEPARATOR, T_STRING])) {
break;
}
} while (true);
$prevIndex = $tokens->getTokenNotOfKindsSibling($index, -1, [T_NS_SEPARATOR, T_STRING, CT::T_ARRAY_TYPEHINT, T_WHITESPACE, T_COMMENT, T_DOC_COMMENT]);

/** @var Token $prevToken */
$prevToken = $tokens[$prevIndex];

if ($prevToken->isGivenKind([
CT::T_TYPE_COLON, // `:` is part of a function return type `foo(): A`
CT::T_TYPE_ALTERNATION, // `|` is part of a union (chain) `X | Y`
T_STATIC, T_VAR, T_PUBLIC, T_PROTECTED, T_PRIVATE, // `var $a;`, `private $a` or `public static $a`
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`
T_STATIC, T_VAR, T_PUBLIC, T_PROTECTED, T_PRIVATE, // `var X|Y $a;`, `private X|Y $a` or `public static X|Y $a`
])) {
$this->replaceToken($tokens, $index);

return;
}

if (!$prevToken->equals('(')) {
if (!$prevToken->equalsAny(['(', ','])) {
return;
}

$prevPrevTokenIndex = $tokens->getPrevMeaningfulToken($prevIndex);

/** @var Token $prePrevToken */
$prePrevToken = $tokens[$prevPrevTokenIndex];

if ($prePrevToken->isGivenKind([
T_CATCH, // `|` is part of catch `catch(X |`
T_FUNCTION, // `|` is part of an anonymous function variable `static function (X|Y`
])) {
if ($tokens[$prevPrevTokenIndex]->isGivenKind([T_CATCH])) {
$this->replaceToken($tokens, $index);

return;
}

if (\PHP_VERSION_ID >= 70400 && $prePrevToken->isGivenKind(T_FN)) {
$this->replaceToken($tokens, $index); // `|` is part of an array function variable `fn(int|null`
$functionKinds = [[T_FUNCTION]];

if (\defined('T_FN')) {
$functionKinds[] = [T_FN];
}

$functionIndex = $tokens->getPrevTokenOfKind($prevIndex, $functionKinds);

if (null === $functionIndex) {
return;
}

if (
$prePrevToken->isGivenKind(T_STRING)
&& $tokens[$tokens->getPrevMeaningfulToken($prevPrevTokenIndex)]->isGivenKind(T_FUNCTION)
) {
// `|` is part of function variable `function Foo (X|Y`
$this->replaceToken($tokens, $index);
$braceOpenIndex = $tokens->getNextTokenOfKind($functionIndex, ['(']);
$braceCloseIndex = $tokens->findBlockEnd(Tokens::BLOCK_TYPE_PARENTHESIS_BRACE, $braceOpenIndex);

if ($braceCloseIndex < $index) {
return;
}

$this->replaceToken($tokens, $index);
}

/**
Expand Down
34 changes: 34 additions & 0 deletions tests/Tokenizer/Transformer/TypeAlternationTransformerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,13 @@ public function provideProcessCases()
echo "aaa" | "bbb";
echo F_OK | F_ERR;
echo foo(F_OK | F_ERR);
foo($A||$b);
foo($A|$b);
// try {} catch (ExceptionType1 | ExceptionType2) {}
$a = function(){};
$x = ($y|$z);
function foo(){}
$a = $b|$c;
',
],
];
Expand Down Expand Up @@ -250,5 +256,33 @@ class Foo {
8 => CT::T_TYPE_ALTERNATION,
],
];

yield 'multiple function parameters' => [
'<?php function foo(A|B $x, C|D $y, E|F $z) {};',
[
6 => CT::T_TYPE_ALTERNATION,
13 => CT::T_TYPE_ALTERNATION,
20 => CT::T_TYPE_ALTERNATION,
],
];

yield 'function calls and function definitions' => [
'<?php
f1(CONST_A|CONST_B);
function f2(A|B $x, C|D $y, E|F $z) {};
f3(CONST_A|CONST_B);
function f4(A|B $x, C|D $y, E|F $z) {};
f5(CONST_A|CONST_B);
$x = ($y|$z);
',
[
15 => CT::T_TYPE_ALTERNATION,
22 => CT::T_TYPE_ALTERNATION,
29 => CT::T_TYPE_ALTERNATION,
52 => CT::T_TYPE_ALTERNATION,
59 => CT::T_TYPE_ALTERNATION,
66 => CT::T_TYPE_ALTERNATION,
],
];
}
}

0 comments on commit d684396

Please sign in to comment.