1: <?php declare(strict_types=1);
2:
3: namespace PhpParser\Lexer\TokenEmulator;
4:
5: use PhpParser\PhpVersion;
6: use PhpParser\Token;
7:
8: final class AttributeEmulator extends TokenEmulator {
9: public function getPhpVersion(): PhpVersion {
10: return PhpVersion::fromComponents(8, 0);
11: }
12:
13: public function isEmulationNeeded(string $code): bool {
14: return strpos($code, '#[') !== false;
15: }
16:
17: public function emulate(string $code, array $tokens): array {
18: // We need to manually iterate and manage a count because we'll change
19: // the tokens array on the way.
20: for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
21: $token = $tokens[$i];
22: if ($token->text === '#' && isset($tokens[$i + 1]) && $tokens[$i + 1]->text === '[') {
23: array_splice($tokens, $i, 2, [
24: new Token(\T_ATTRIBUTE, '#[', $token->line, $token->pos),
25: ]);
26: $c--;
27: continue;
28: }
29: }
30:
31: return $tokens;
32: }
33:
34: public function reverseEmulate(string $code, array $tokens): array {
35: // TODO
36: return $tokens;
37: }
38:
39: public function preprocessCode(string $code, array &$patches): string {
40: $pos = 0;
41: while (false !== $pos = strpos($code, '#[', $pos)) {
42: // Replace #[ with %[
43: $code[$pos] = '%';
44: $patches[] = [$pos, 'replace', '#'];
45: $pos += 2;
46: }
47: return $code;
48: }
49: }
50: