mirror of
https://github.com/danog/PHP-Parser.git
synced 2024-12-02 09:17:58 +01:00
Correctly handle ?-> in encapsed strings
Followup upstream change.
This commit is contained in:
parent
c3e20d9970
commit
8505acd151
@ -22,15 +22,35 @@ final class NullsafeTokenEmulator extends TokenEmulator
|
|||||||
// the tokens array on the way
|
// the tokens array on the way
|
||||||
$line = 1;
|
$line = 1;
|
||||||
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
|
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
|
||||||
if (isset($tokens[$i + 1])) {
|
if ($tokens[$i] === '?' && isset($tokens[$i + 1]) && $tokens[$i + 1][0] === \T_OBJECT_OPERATOR) {
|
||||||
if ($tokens[$i] === '?' && $tokens[$i + 1][0] === \T_OBJECT_OPERATOR) {
|
|
||||||
array_splice($tokens, $i, 2, [
|
array_splice($tokens, $i, 2, [
|
||||||
[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line]
|
[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line]
|
||||||
]);
|
]);
|
||||||
$c--;
|
$c--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle ?-> inside encapsed string.
|
||||||
|
if ($tokens[$i][0] === \T_ENCAPSED_AND_WHITESPACE && isset($tokens[$i - 1])
|
||||||
|
&& $tokens[$i - 1][0] === \T_VARIABLE
|
||||||
|
&& preg_match('/^\?->([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/', $tokens[$i][1], $matches)
|
||||||
|
) {
|
||||||
|
$replacement = [
|
||||||
|
[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line],
|
||||||
|
[\T_STRING, $matches[1], $line],
|
||||||
|
];
|
||||||
|
if (\strlen($matches[0]) !== \strlen($tokens[$i][1])) {
|
||||||
|
$replacement[] = [
|
||||||
|
\T_ENCAPSED_AND_WHITESPACE,
|
||||||
|
\substr($tokens[$i][1], \strlen($matches[0])),
|
||||||
|
$line
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
array_splice($tokens, $i, 1, $replacement);
|
||||||
|
$c += \count($replacement) - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (\is_array($tokens[$i])) {
|
if (\is_array($tokens[$i])) {
|
||||||
$line += substr_count($tokens[$i][1], "\n");
|
$line += substr_count($tokens[$i][1], "\n");
|
||||||
}
|
}
|
||||||
|
@ -320,6 +320,22 @@ class EmulativeTest extends LexerTest
|
|||||||
['7.4', 'match', [[Tokens::T_STRING, 'match']]],
|
['7.4', 'match', [[Tokens::T_STRING, 'match']]],
|
||||||
['7.4', 'fn', [[Tokens::T_FN, 'fn']]],
|
['7.4', 'fn', [[Tokens::T_FN, 'fn']]],
|
||||||
['7.3', 'fn', [[Tokens::T_STRING, 'fn']]],
|
['7.3', 'fn', [[Tokens::T_STRING, 'fn']]],
|
||||||
|
// Tested here to skip testLeaveStuffAloneInStrings.
|
||||||
|
['8.0', '"$foo?->bar"', [
|
||||||
|
[ord('"'), '"'],
|
||||||
|
[Tokens::T_VARIABLE, '$foo'],
|
||||||
|
[Tokens::T_NULLSAFE_OBJECT_OPERATOR, '?->'],
|
||||||
|
[Tokens::T_STRING, 'bar'],
|
||||||
|
[ord('"'), '"'],
|
||||||
|
]],
|
||||||
|
['8.0', '"$foo?->bar baz"', [
|
||||||
|
[ord('"'), '"'],
|
||||||
|
[Tokens::T_VARIABLE, '$foo'],
|
||||||
|
[Tokens::T_NULLSAFE_OBJECT_OPERATOR, '?->'],
|
||||||
|
[Tokens::T_STRING, 'bar'],
|
||||||
|
[Tokens::T_ENCAPSED_AND_WHITESPACE, ' baz'],
|
||||||
|
[ord('"'), '"'],
|
||||||
|
]],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,11 +71,13 @@ array(
|
|||||||
4: Stmt_Expression(
|
4: Stmt_Expression(
|
||||||
expr: Scalar_Encapsed(
|
expr: Scalar_Encapsed(
|
||||||
parts: array(
|
parts: array(
|
||||||
0: Expr_Variable(
|
0: Expr_NullsafePropertyFetch(
|
||||||
|
var: Expr_Variable(
|
||||||
name: a
|
name: a
|
||||||
)
|
)
|
||||||
1: Scalar_EncapsedStringPart(
|
name: Identifier(
|
||||||
value: ?->b
|
name: b
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -19,4 +19,4 @@ $a?->b($c)?->d;
|
|||||||
$a?->b($c)();
|
$a?->b($c)();
|
||||||
new $a?->b();
|
new $a?->b();
|
||||||
"{$a?->b}";
|
"{$a?->b}";
|
||||||
"{$a}?->b";
|
"{$a?->b}";
|
Loading…
Reference in New Issue
Block a user