From 3698f4b727ae18831fb3400b6eeab42dc16b1faf Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 1 Aug 2020 22:02:52 +0200 Subject: [PATCH] Add common KeywordEmulator The logic for keyword emulation is always going to be the same. --- .../Lexer/TokenEmulator/FnTokenEmulator.php | 40 +++------------ .../Lexer/TokenEmulator/KeywordEmulator.php | 50 +++++++++++++++++++ .../TokenEmulator/MatchTokenEmulator.php | 38 ++------------ 3 files changed, 61 insertions(+), 67 deletions(-) create mode 100644 lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php diff --git a/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php b/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php index 3b47dac..92f72f2 100644 --- a/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php +++ b/lib/PhpParser/Lexer/TokenEmulator/FnTokenEmulator.php @@ -4,48 +4,20 @@ namespace PhpParser\Lexer\TokenEmulator; use PhpParser\Lexer\Emulative; -final class FnTokenEmulator implements TokenEmulatorInterface +final class FnTokenEmulator extends KeywordEmulator { public function getPhpVersion(): string { return Emulative::PHP_7_4; } - public function isEmulationNeeded(string $code): bool + public function getKeywordString(): string { - return strpos($code, 'fn') !== false; + return 'fn'; } - public function emulate(string $code, array $tokens): array + public function getKeywordToken(): int { - foreach ($tokens as $i => $token) { - if ($token[0] === T_STRING && strtolower($token[1]) === 'fn') { - $previousNonSpaceToken = $this->getPreviousNonSpaceToken($tokens, $i); - if ($previousNonSpaceToken !== null && $previousNonSpaceToken[0] === T_OBJECT_OPERATOR) { - continue; - } - - $tokens[$i][0] = Emulative::T_FN; - } - } - - return $tokens; + return Emulative::T_FN; } - - /** - * @param mixed[] $tokens - * @return mixed[]|null - */ - private function getPreviousNonSpaceToken(array $tokens, int $start) - { - for ($i = $start - 1; $i >= 0; --$i) { - if ($tokens[$i][0] === T_WHITESPACE) { - continue; - } - - return $tokens[$i]; - } - - return null; - } -} +} \ No newline at end of file diff --git a/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php b/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php new file mode 100644 index 0000000..84296aa --- /dev/null +++ b/lib/PhpParser/Lexer/TokenEmulator/KeywordEmulator.php @@ -0,0 +1,50 @@ +getKeywordString()) !== false; + } + + public function emulate(string $code, array $tokens): array + { + $keywordString = $this->getKeywordString(); + foreach ($tokens as $i => $token) { + if ($token[0] === T_STRING && strtolower($token[1]) === $keywordString) { + $previousNonSpaceToken = $this->getPreviousNonSpaceToken($tokens, $i); + if ($previousNonSpaceToken !== null && $previousNonSpaceToken[0] === T_OBJECT_OPERATOR) { + continue; + } + + $tokens[$i][0] = $this->getKeywordToken(); + } + } + + return $tokens; + } + + /** + * @param mixed[] $tokens + * @return mixed[]|null + */ + private function getPreviousNonSpaceToken(array $tokens, int $start) + { + for ($i = $start - 1; $i >= 0; --$i) { + if ($tokens[$i][0] === T_WHITESPACE) { + continue; + } + + return $tokens[$i]; + } + + return null; + } +} diff --git a/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php b/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php index 83c8ed2..a295052 100644 --- a/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php +++ b/lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php @@ -4,48 +4,20 @@ namespace PhpParser\Lexer\TokenEmulator; use PhpParser\Lexer\Emulative; -final class MatchTokenEmulator implements TokenEmulatorInterface +final class MatchTokenEmulator extends KeywordEmulator { public function getPhpVersion(): string { return Emulative::PHP_8_0; } - public function isEmulationNeeded(string $code): bool + public function getKeywordString(): string { - return strpos($code, 'match') !== false; + return 'match'; } - public function emulate(string $code, array $tokens): array + public function getKeywordToken(): int { - foreach ($tokens as $i => $token) { - if ($token[0] === T_STRING && strtolower($token[1]) === 'match') { - $previousNonSpaceToken = $this->getPreviousNonSpaceToken($tokens, $i); - if ($previousNonSpaceToken !== null && $previousNonSpaceToken[0] === T_OBJECT_OPERATOR) { - continue; - } - - $tokens[$i][0] = Emulative::T_MATCH; - } - } - - return $tokens; - } - - /** - * @param mixed[] $tokens - * @return mixed[]|null - */ - private function getPreviousNonSpaceToken(array $tokens, int $start) - { - for ($i = $start - 1; $i >= 0; --$i) { - if ($tokens[$i][0] === T_WHITESPACE) { - continue; - } - - return $tokens[$i]; - } - - return null; + return Emulative::T_MATCH; } }