mirror of
https://github.com/phabelio/PHP-Parser.git
synced 2024-11-30 04:29:15 +01:00
Support keywords in namespaced names
This commit is contained in:
parent
a98350581c
commit
3aadc15e2e
@ -15,6 +15,7 @@ class Lexer
|
||||
|
||||
protected $tokenMap;
|
||||
protected $dropTokens;
|
||||
protected $identifierTokens;
|
||||
|
||||
private $attributeStartLineUsed;
|
||||
private $attributeEndLineUsed;
|
||||
@ -37,6 +38,7 @@ class Lexer
|
||||
// Create Map from internal tokens to PhpParser tokens.
|
||||
$this->defineCompatibilityTokens();
|
||||
$this->tokenMap = $this->createTokenMap();
|
||||
$this->identifierTokens = $this->createIdentifierTokenMap();
|
||||
|
||||
// map of tokens to drop while lexing (the map is only used for isset lookup,
|
||||
// that's why the value is simply set to 1; the value is never actually used.)
|
||||
@ -170,14 +172,13 @@ class Lexer
|
||||
|
||||
// Emulate PHP 8 T_NAME_* tokens, by combining sequences of T_NS_SEPARATOR and T_STRING
|
||||
// into a single token.
|
||||
// TODO: Also handle reserved keywords in namespaced names.
|
||||
if (\is_array($token)
|
||||
&& ($token[0] === \T_NS_SEPARATOR || $token[0] === \T_STRING || $token[0] === \T_NAMESPACE)) {
|
||||
&& ($token[0] === \T_NS_SEPARATOR || isset($this->identifierTokens[$token[0]]))) {
|
||||
$lastWasSeparator = $token[0] === \T_NS_SEPARATOR;
|
||||
$text = $token[1];
|
||||
for ($j = $i + 1; isset($this->tokens[$j]); $j++) {
|
||||
if ($lastWasSeparator) {
|
||||
if ($this->tokens[$j][0] !== \T_STRING) {
|
||||
if (!isset($this->identifierTokens[$this->tokens[$j][0]])) {
|
||||
break;
|
||||
}
|
||||
$lastWasSeparator = false;
|
||||
@ -488,4 +489,19 @@ class Lexer
|
||||
|
||||
return $tokenMap;
|
||||
}
|
||||
|
||||
private function createIdentifierTokenMap(): array {
|
||||
// Based on semi_reserved production.
|
||||
return array_fill_keys([
|
||||
\T_STRING,
|
||||
\T_INCLUDE, \T_INCLUDE_ONCE, \T_EVAL, \T_REQUIRE, \T_REQUIRE_ONCE, \T_LOGICAL_OR, \T_LOGICAL_XOR, \T_LOGICAL_AND,
|
||||
\T_INSTANCEOF, \T_NEW, \T_CLONE, \T_EXIT, \T_IF, \T_ELSEIF, \T_ELSE, \T_ENDIF, \T_ECHO, \T_DO, \T_WHILE,
|
||||
\T_ENDWHILE, \T_FOR, \T_ENDFOR, \T_FOREACH, \T_ENDFOREACH, \T_DECLARE, \T_ENDDECLARE, \T_AS, \T_TRY, \T_CATCH,
|
||||
\T_FINALLY, \T_THROW, \T_USE, \T_INSTEADOF, \T_GLOBAL, \T_VAR, \T_UNSET, \T_ISSET, \T_EMPTY, \T_CONTINUE, \T_GOTO,
|
||||
\T_FUNCTION, \T_CONST, \T_RETURN, \T_PRINT, \T_YIELD, \T_LIST, \T_SWITCH, \T_ENDSWITCH, \T_CASE, \T_DEFAULT,
|
||||
\T_BREAK, \T_ARRAY, \T_CALLABLE, \T_EXTENDS, \T_IMPLEMENTS, \T_NAMESPACE, \T_TRAIT, \T_INTERFACE, \T_CLASS,
|
||||
\T_CLASS_C, \T_TRAIT_C, \T_FUNC_C, \T_METHOD_C, \T_LINE, \T_FILE, \T_DIR, \T_NS_C, \T_HALT_COMPILER, \T_FN,
|
||||
\T_MATCH,
|
||||
], true);
|
||||
}
|
||||
}
|
||||
|
@ -227,6 +227,18 @@ class LexerTest extends \PHPUnit\Framework\TestCase
|
||||
[Tokens::T_NS_SEPARATOR, '\\', [], []],
|
||||
]
|
||||
],
|
||||
// tests PHP 8 T_NAME_* emulation with reserved keywords
|
||||
[
|
||||
'<?php fn\use \fn\use namespace\fn\use fn\use\\',
|
||||
['usedAttributes' => []],
|
||||
[
|
||||
[Tokens::T_NAME_QUALIFIED, 'fn\use', [], []],
|
||||
[Tokens::T_NAME_FULLY_QUALIFIED, '\fn\use', [], []],
|
||||
[Tokens::T_NAME_RELATIVE, 'namespace\fn\use', [], []],
|
||||
[Tokens::T_NAME_QUALIFIED, 'fn\use', [], []],
|
||||
[Tokens::T_NS_SEPARATOR, '\\', [], []],
|
||||
]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
45
test/code/parser/expr/keywordsInNamespacedName.test
Normal file
45
test/code/parser/expr/keywordsInNamespacedName.test
Normal file
@ -0,0 +1,45 @@
|
||||
Keywords in namespaced name
|
||||
-----
|
||||
<?php
|
||||
fn\use();
|
||||
\fn\use();
|
||||
namespace\fn\use();
|
||||
-----
|
||||
array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: fn
|
||||
1: use
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name_FullyQualified(
|
||||
parts: array(
|
||||
0: fn
|
||||
1: use
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name_Relative(
|
||||
parts: array(
|
||||
0: fn
|
||||
1: use
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
Loading…
Reference in New Issue
Block a user