1--TEST--
2Flexible heredoc and nowdoc testing with token_get_all
3--SKIPIF--
4<?php if (!extension_loaded("tokenizer")) print "skip"; ?>
5--FILE--
6<?php
7
8function test(string $code, int $flags)
9{
10    try {
11        $tokens = token_get_all($code, $flags);
12        foreach ($tokens as $token) {
13            if (is_array($token)) {
14                echo "Line {$token[2]}: ", token_name($token[0]), " ('{$token[1]}')\n";
15            }
16        }
17    } catch (ParseError $e) {
18        echo "Parse error: {$e->getMessage()} on line {$e->getLine()}\n";
19    }
20}
21
22$tests = [];
23
24$tests[1] = <<<'OUTER_END'
25<?php <<<INNER_END
26INNER_END;
27OUTER_END;
28
29$tests[2] = <<<'OUTER_END'
30<?php <<<INNER_END
31  INNER_END;
32OUTER_END;
33
34$tests[3] = <<<'OUTER_END'
35<?php <<<'INNER_END'
36INNER_END;
37OUTER_END;
38
39$tests[4] = <<<'OUTER_END'
40<?php <<<'INNER_END'
41  INNER_END;
42OUTER_END;
43
44$tests[5] = <<<'OUTER_END'
45  <?php <<<INNER_END
46  a
47  OUTER_END;
48
49$tests[6] = <<<'OUTER_END'
50<?php <<<INNER_END
51ab
52OUTER_END;
53
54$tests[7] = <<<'OUTER_END'
55<?php <<<INNER_END
56a
57INNER_END;
58OUTER_END;
59
60$tests[8] = <<<CODE
61<?php
62 \t<<<'DOC'
63 \tXXX
64 \tDOC;
65CODE;
66
67$tests[9] = <<<'OUTER_END'
68<?php <<<INNER_END
69ab
70INNER_END;
71OUTER_END;
72
73$tests[10] = <<<'OUTER_END'
74<?php <<<INNER_END
75  ab
76  INNER_END;
77OUTER_END;
78
79$tests[11] = <<<'OUTER_END'
80<?php <<<INNER_END
81abc
82   INNER_END;
83OUTER_END;
84
85$tests[12] = <<<'OUTER_END'
86<?php <<<INNER_END
87
88   INNER_END;
89OUTER_END;
90
91$tests[13] = <<<'OUTER_END'
92<?php <<<'INNER_END'
93ab
94INNER_END;
95OUTER_END;
96
97$tests[14] = <<<'OUTER_END'
98<?php <<<'INNER_END'
99  ab
100  INNER_END;
101OUTER_END;
102
103$tests[15] = <<<'OUTER_END'
104<?php <<<'INNER_END'
105abc
106   INNER_END;
107OUTER_END;
108
109$tests[16] = <<<'OUTER_END'
110<?php <<<'INNER_END'
111
112   INNER_END;
113OUTER_END;
114
115$tests[17] = <<<OUTER_END
116<?php <<<INNER_END
117ab
118ab
119\t
120OUTER_END;
121
122$tests[18] = <<<OUTER_END
123<?php <<<'INNER_END'
124ab
125ab
126\t
127OUTER_END;
128
129echo "Without TOKEN_PARSE:\n";
130foreach ($tests as $i => $test) {
131    echo "\nTest case $i\n\n";
132    test($test, 0);
133}
134
135echo "\nWith TOKEN_PARSE:\n";
136foreach ($tests as $i => $test) {
137    echo "\nTest case $i\n\n";
138    test($test, TOKEN_PARSE);
139}
140
141?>
142--EXPECT--
143Without TOKEN_PARSE:
144
145Test case 1
146
147Line 1: T_OPEN_TAG ('<?php ')
148Line 1: T_START_HEREDOC ('<<<INNER_END
149')
150Line 2: T_END_HEREDOC ('INNER_END')
151
152Test case 2
153
154Line 1: T_OPEN_TAG ('<?php ')
155Line 1: T_START_HEREDOC ('<<<INNER_END
156')
157Line 2: T_END_HEREDOC ('  INNER_END')
158
159Test case 3
160
161Line 1: T_OPEN_TAG ('<?php ')
162Line 1: T_START_HEREDOC ('<<<'INNER_END'
163')
164Line 2: T_END_HEREDOC ('INNER_END')
165
166Test case 4
167
168Line 1: T_OPEN_TAG ('<?php ')
169Line 1: T_START_HEREDOC ('<<<'INNER_END'
170')
171Line 2: T_END_HEREDOC ('  INNER_END')
172
173Test case 5
174
175Line 1: T_OPEN_TAG ('<?php ')
176Line 1: T_START_HEREDOC ('<<<INNER_END
177')
178Line 2: T_ENCAPSED_AND_WHITESPACE ('a')
179
180Test case 6
181
182Line 1: T_OPEN_TAG ('<?php ')
183Line 1: T_START_HEREDOC ('<<<INNER_END
184')
185Line 2: T_ENCAPSED_AND_WHITESPACE ('ab')
186
187Test case 7
188
189Line 1: T_OPEN_TAG ('<?php ')
190Line 1: T_START_HEREDOC ('<<<INNER_END
191')
192Line 2: T_ENCAPSED_AND_WHITESPACE ('a
193')
194Line 3: T_END_HEREDOC ('INNER_END')
195
196Test case 8
197
198Line 1: T_OPEN_TAG ('<?php
199')
200Line 2: T_WHITESPACE (' 	')
201Line 2: T_START_HEREDOC ('<<<'DOC'
202')
203Line 3: T_ENCAPSED_AND_WHITESPACE (' 	XXX
204')
205Line 4: T_END_HEREDOC (' 	DOC')
206
207Test case 9
208
209Line 1: T_OPEN_TAG ('<?php ')
210Line 1: T_START_HEREDOC ('<<<INNER_END
211')
212Line 2: T_ENCAPSED_AND_WHITESPACE ('ab
213')
214Line 3: T_END_HEREDOC ('INNER_END')
215
216Test case 10
217
218Line 1: T_OPEN_TAG ('<?php ')
219Line 1: T_START_HEREDOC ('<<<INNER_END
220')
221Line 2: T_ENCAPSED_AND_WHITESPACE ('  ab
222')
223Line 3: T_END_HEREDOC ('  INNER_END')
224
225Test case 11
226
227Line 1: T_OPEN_TAG ('<?php ')
228Line 1: T_START_HEREDOC ('<<<INNER_END
229')
230Line 2: T_ENCAPSED_AND_WHITESPACE ('abc
231')
232Line 3: T_END_HEREDOC ('   INNER_END')
233
234Test case 12
235
236Line 1: T_OPEN_TAG ('<?php ')
237Line 1: T_START_HEREDOC ('<<<INNER_END
238')
239Line 2: T_ENCAPSED_AND_WHITESPACE ('
240')
241Line 3: T_END_HEREDOC ('   INNER_END')
242
243Test case 13
244
245Line 1: T_OPEN_TAG ('<?php ')
246Line 1: T_START_HEREDOC ('<<<'INNER_END'
247')
248Line 2: T_ENCAPSED_AND_WHITESPACE ('ab
249')
250Line 3: T_END_HEREDOC ('INNER_END')
251
252Test case 14
253
254Line 1: T_OPEN_TAG ('<?php ')
255Line 1: T_START_HEREDOC ('<<<'INNER_END'
256')
257Line 2: T_ENCAPSED_AND_WHITESPACE ('  ab
258')
259Line 3: T_END_HEREDOC ('  INNER_END')
260
261Test case 15
262
263Line 1: T_OPEN_TAG ('<?php ')
264Line 1: T_START_HEREDOC ('<<<'INNER_END'
265')
266Line 2: T_ENCAPSED_AND_WHITESPACE ('abc
267')
268Line 3: T_END_HEREDOC ('   INNER_END')
269
270Test case 16
271
272Line 1: T_OPEN_TAG ('<?php ')
273Line 1: T_START_HEREDOC ('<<<'INNER_END'
274')
275Line 2: T_ENCAPSED_AND_WHITESPACE ('
276')
277Line 3: T_END_HEREDOC ('   INNER_END')
278
279Test case 17
280
281Line 1: T_OPEN_TAG ('<?php ')
282Line 1: T_START_HEREDOC ('<<<INNER_END
283')
284Line 2: T_ENCAPSED_AND_WHITESPACE ('ab
285ab
286	')
287
288Test case 18
289
290Line 1: T_OPEN_TAG ('<?php ')
291Line 1: T_START_HEREDOC ('<<<'INNER_END'
292')
293Line 2: T_ENCAPSED_AND_WHITESPACE ('ab
294ab
295	')
296
297With TOKEN_PARSE:
298
299Test case 1
300
301Line 1: T_OPEN_TAG ('<?php ')
302Line 1: T_START_HEREDOC ('<<<INNER_END
303')
304Line 2: T_END_HEREDOC ('INNER_END')
305
306Test case 2
307
308Line 1: T_OPEN_TAG ('<?php ')
309Line 1: T_START_HEREDOC ('<<<INNER_END
310')
311Line 2: T_END_HEREDOC ('  INNER_END')
312
313Test case 3
314
315Line 1: T_OPEN_TAG ('<?php ')
316Line 1: T_START_HEREDOC ('<<<'INNER_END'
317')
318Line 2: T_END_HEREDOC ('INNER_END')
319
320Test case 4
321
322Line 1: T_OPEN_TAG ('<?php ')
323Line 1: T_START_HEREDOC ('<<<'INNER_END'
324')
325Line 2: T_END_HEREDOC ('  INNER_END')
326
327Test case 5
328
329Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" on line 2
330
331Test case 6
332
333Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" on line 2
334
335Test case 7
336
337Line 1: T_OPEN_TAG ('<?php ')
338Line 1: T_START_HEREDOC ('<<<INNER_END
339')
340Line 2: T_ENCAPSED_AND_WHITESPACE ('a
341')
342Line 3: T_END_HEREDOC ('INNER_END')
343
344Test case 8
345
346Parse error: Invalid indentation - tabs and spaces cannot be mixed on line 3
347
348Test case 9
349
350Line 1: T_OPEN_TAG ('<?php ')
351Line 1: T_START_HEREDOC ('<<<INNER_END
352')
353Line 2: T_ENCAPSED_AND_WHITESPACE ('ab
354')
355Line 3: T_END_HEREDOC ('INNER_END')
356
357Test case 10
358
359Line 1: T_OPEN_TAG ('<?php ')
360Line 1: T_START_HEREDOC ('<<<INNER_END
361')
362Line 2: T_ENCAPSED_AND_WHITESPACE ('  ab
363')
364Line 3: T_END_HEREDOC ('  INNER_END')
365
366Test case 11
367
368Parse error: Invalid body indentation level (expecting an indentation level of at least 3) on line 2
369
370Test case 12
371
372Line 1: T_OPEN_TAG ('<?php ')
373Line 1: T_START_HEREDOC ('<<<INNER_END
374')
375Line 2: T_ENCAPSED_AND_WHITESPACE ('
376')
377Line 3: T_END_HEREDOC ('   INNER_END')
378
379Test case 13
380
381Line 1: T_OPEN_TAG ('<?php ')
382Line 1: T_START_HEREDOC ('<<<'INNER_END'
383')
384Line 2: T_ENCAPSED_AND_WHITESPACE ('ab
385')
386Line 3: T_END_HEREDOC ('INNER_END')
387
388Test case 14
389
390Line 1: T_OPEN_TAG ('<?php ')
391Line 1: T_START_HEREDOC ('<<<'INNER_END'
392')
393Line 2: T_ENCAPSED_AND_WHITESPACE ('  ab
394')
395Line 3: T_END_HEREDOC ('  INNER_END')
396
397Test case 15
398
399Parse error: Invalid body indentation level (expecting an indentation level of at least 3) on line 2
400
401Test case 16
402
403Line 1: T_OPEN_TAG ('<?php ')
404Line 1: T_START_HEREDOC ('<<<'INNER_END'
405')
406Line 2: T_ENCAPSED_AND_WHITESPACE ('
407')
408Line 3: T_END_HEREDOC ('   INNER_END')
409
410Test case 17
411
412Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" on line 4
413
414Test case 18
415
416Parse error: syntax error, unexpected end of file, expecting variable or heredoc end or "${" or "{$" on line 4
417