533547ae4825d8f24558fcfdfca87837c978ff46
[yaffs-website] / vendor / nikic / php-parser / test / PhpParser / Lexer / EmulativeTest.php
1 <?php declare(strict_types=1);
2
3 namespace PhpParser\Lexer;
4
5 use PhpParser\ErrorHandler;
6 use PhpParser\LexerTest;
7 use PhpParser\Parser\Tokens;
8
9 require_once __DIR__ . '/../LexerTest.php';
10
11 class EmulativeTest extends LexerTest
12 {
13     protected function getLexer(array $options = []) {
14         return new Emulative($options);
15     }
16
17     /**
18      * @dataProvider provideTestReplaceKeywords
19      */
20     public function testReplaceKeywords($keyword, $expectedToken) {
21         $lexer = $this->getLexer();
22         $lexer->startLexing('<?php ' . $keyword);
23
24         $this->assertSame($expectedToken, $lexer->getNextToken());
25         $this->assertSame(0, $lexer->getNextToken());
26     }
27
28     /**
29      * @dataProvider provideTestReplaceKeywords
30      */
31     public function testNoReplaceKeywordsAfterObjectOperator($keyword) {
32         $lexer = $this->getLexer();
33         $lexer->startLexing('<?php ->' . $keyword);
34
35         $this->assertSame(Tokens::T_OBJECT_OPERATOR, $lexer->getNextToken());
36         $this->assertSame(Tokens::T_STRING, $lexer->getNextToken());
37         $this->assertSame(0, $lexer->getNextToken());
38     }
39
40     public function provideTestReplaceKeywords() {
41         return [
42             // PHP 5.5
43             ['finally',       Tokens::T_FINALLY],
44             ['yield',         Tokens::T_YIELD],
45
46             // PHP 5.4
47             ['callable',      Tokens::T_CALLABLE],
48             ['insteadof',     Tokens::T_INSTEADOF],
49             ['trait',         Tokens::T_TRAIT],
50             ['__TRAIT__',     Tokens::T_TRAIT_C],
51
52             // PHP 5.3
53             ['__DIR__',       Tokens::T_DIR],
54             ['goto',          Tokens::T_GOTO],
55             ['namespace',     Tokens::T_NAMESPACE],
56             ['__NAMESPACE__', Tokens::T_NS_C],
57         ];
58     }
59
60     /**
61      * @dataProvider provideTestLexNewFeatures
62      */
63     public function testLexNewFeatures($code, array $expectedTokens) {
64         $lexer = $this->getLexer();
65         $lexer->startLexing('<?php ' . $code);
66
67         $tokens = [];
68         while (0 !== $token = $lexer->getNextToken($text)) {
69             $tokens[] = [$token, $text];
70         }
71         $this->assertSame($expectedTokens, $tokens);
72     }
73
74     /**
75      * @dataProvider provideTestLexNewFeatures
76      */
77     public function testLeaveStuffAloneInStrings($code) {
78         $stringifiedToken = '"' . addcslashes($code, '"\\') . '"';
79
80         $lexer = $this->getLexer();
81         $lexer->startLexing('<?php ' . $stringifiedToken);
82
83         $this->assertSame(Tokens::T_CONSTANT_ENCAPSED_STRING, $lexer->getNextToken($text));
84         $this->assertSame($stringifiedToken, $text);
85         $this->assertSame(0, $lexer->getNextToken());
86     }
87
88     /**
89      * @dataProvider provideTestLexNewFeatures
90      */
91     public function testErrorAfterEmulation($code) {
92         $errorHandler = new ErrorHandler\Collecting;
93         $lexer = $this->getLexer([]);
94         $lexer->startLexing('<?php ' . $code . "\0", $errorHandler);
95
96         $errors = $errorHandler->getErrors();
97         $this->assertCount(1, $errors);
98
99         $error = $errors[0];
100         $this->assertSame('Unexpected null byte', $error->getRawMessage());
101
102         $attrs = $error->getAttributes();
103         $expPos = strlen('<?php ' . $code);
104         $expLine = 1 + substr_count('<?php ' . $code, "\n");
105         $this->assertSame($expPos, $attrs['startFilePos']);
106         $this->assertSame($expPos, $attrs['endFilePos']);
107         $this->assertSame($expLine, $attrs['startLine']);
108         $this->assertSame($expLine, $attrs['endLine']);
109     }
110
111     public function provideTestLexNewFeatures() {
112         return [
113             ['yield from', [
114                 [Tokens::T_YIELD_FROM, 'yield from'],
115             ]],
116             ["yield\r\nfrom", [
117                 [Tokens::T_YIELD_FROM, "yield\r\nfrom"],
118             ]],
119             ['...', [
120                 [Tokens::T_ELLIPSIS, '...'],
121             ]],
122             ['**', [
123                 [Tokens::T_POW, '**'],
124             ]],
125             ['**=', [
126                 [Tokens::T_POW_EQUAL, '**='],
127             ]],
128             ['??', [
129                 [Tokens::T_COALESCE, '??'],
130             ]],
131             ['<=>', [
132                 [Tokens::T_SPACESHIP, '<=>'],
133             ]],
134             ['0b1010110', [
135                 [Tokens::T_LNUMBER, '0b1010110'],
136             ]],
137             ['0b1011010101001010110101010010101011010101010101101011001110111100', [
138                 [Tokens::T_DNUMBER, '0b1011010101001010110101010010101011010101010101101011001110111100'],
139             ]],
140             ['\\', [
141                 [Tokens::T_NS_SEPARATOR, '\\'],
142             ]],
143             ["<<<'NOWDOC'\nNOWDOC;\n", [
144                 [Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"],
145                 [Tokens::T_END_HEREDOC, 'NOWDOC'],
146                 [ord(';'), ';'],
147             ]],
148             ["<<<'NOWDOC'\nFoobar\nNOWDOC;\n", [
149                 [Tokens::T_START_HEREDOC, "<<<'NOWDOC'\n"],
150                 [Tokens::T_ENCAPSED_AND_WHITESPACE, "Foobar\n"],
151                 [Tokens::T_END_HEREDOC, 'NOWDOC'],
152                 [ord(';'), ';'],
153             ]],
154
155             // Flexible heredoc/nowdoc
156             ["<<<LABEL\nLABEL,", [
157                 [Tokens::T_START_HEREDOC, "<<<LABEL\n"],
158                 [Tokens::T_END_HEREDOC, "LABEL"],
159                 [ord(','), ','],
160             ]],
161             ["<<<LABEL\n    LABEL,", [
162                 [Tokens::T_START_HEREDOC, "<<<LABEL\n"],
163                 [Tokens::T_END_HEREDOC, "    LABEL"],
164                 [ord(','), ','],
165             ]],
166             ["<<<LABEL\n    Foo\n  LABEL;", [
167                 [Tokens::T_START_HEREDOC, "<<<LABEL\n"],
168                 [Tokens::T_ENCAPSED_AND_WHITESPACE, "    Foo\n"],
169                 [Tokens::T_END_HEREDOC, "  LABEL"],
170                 [ord(';'), ';'],
171             ]],
172             ["<<<A\n A,<<<A\n A,", [
173                 [Tokens::T_START_HEREDOC, "<<<A\n"],
174                 [Tokens::T_END_HEREDOC, " A"],
175                 [ord(','), ','],
176                 [Tokens::T_START_HEREDOC, "<<<A\n"],
177                 [Tokens::T_END_HEREDOC, " A"],
178                 [ord(','), ','],
179             ]],
180             ["<<<LABEL\nLABELNOPE\nLABEL\n", [
181                 [Tokens::T_START_HEREDOC, "<<<LABEL\n"],
182                 [Tokens::T_ENCAPSED_AND_WHITESPACE, "LABELNOPE\n"],
183                 [Tokens::T_END_HEREDOC, "LABEL"],
184             ]],
185             // Interpretation changed
186             ["<<<LABEL\n    LABEL\nLABEL\n", [
187                 [Tokens::T_START_HEREDOC, "<<<LABEL\n"],
188                 [Tokens::T_END_HEREDOC, "    LABEL"],
189                 [Tokens::T_STRING, "LABEL"],
190             ]],
191         ];
192     }
193 }