Skip to content

Commit 63bf6cc

Browse files
committed
Address other edge cases
1 parent 67623d2 commit 63bf6cc

7 files changed

+76
-71
lines changed

src/Parser.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2866,7 +2866,18 @@ private function parseHaltCompilerStatement($parentNode) {
28662866
$unsetStatement->closeParen = $this->eat1(TokenKind::CloseParenToken);
28672867
// There is an implicit ';' before the closing php tag.
28682868
$unsetStatement->semicolonOrCloseTag = $this->eat(TokenKind::SemicolonToken, TokenKind::ScriptSectionEndTag);
2869-
$unsetStatement->data = $this->eatOptional1(TokenKind::InlineHtml);
2869+
// token_get_all() will return up to 3 tokens after __halt_compiler regardless of whether they're the right ones.
2870+
// For invalid php snippets, combine the remaining tokens into InlineHtml
2871+
$remainingTokens = [];
2872+
while ($this->token->kind !== TokenKind::EndOfFileToken) {
2873+
$remainingTokens[] = $this->token;
2874+
$this->advanceToken();
2875+
}
2876+
if ($remainingTokens) {
2877+
$firstToken = $remainingTokens[0];
2878+
$lastToken = end($remainingTokens);
2879+
$unsetStatement->data = new Token(TokenKind::InlineHtml, $firstToken->fullStart, $firstToken->start, $lastToken->fullStart + $lastToken->length - $firstToken->fullStart);
2880+
}
28702881
return $unsetStatement;
28712882
}
28722883

src/Token.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ class Token implements \JsonSerializable {
1818
public $fullStart;
1919
/** @var int */
2020
public $start;
21-
/** @var int */
21+
/** @var int the length is equal to $this->getEndPosition() - $this->fullStart. */
2222
public $length;
2323

2424
/**

tests/cases/parser/haltCompiler4.php.diag

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,5 @@
1616
"message": "';' expected.",
1717
"start": 32,
1818
"length": 0
19-
},
20-
{
21-
"kind": 0,
22-
"message": "Unexpected '::'",
23-
"start": 32,
24-
"length": 2
25-
},
26-
{
27-
"kind": 0,
28-
"message": "')' expected.",
29-
"start": 38,
30-
"length": 0
31-
},
32-
{
33-
"kind": 0,
34-
"message": "';' expected.",
35-
"start": 38,
36-
"length": 0
37-
},
38-
{
39-
"kind": 0,
40-
"message": "Unexpected 'InlineHtml'",
41-
"start": 38,
42-
"length": 3
4319
}
4420
]

tests/cases/parser/haltCompiler4.php.tree

Lines changed: 3 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -32,53 +32,11 @@
3232
"kind": "SemicolonToken",
3333
"textLength": 0
3434
},
35-
"data": null
36-
}
37-
},
38-
{
39-
"error": "SkippedToken",
40-
"kind": "ColonColonToken",
41-
"textLength": 2
42-
},
43-
{
44-
"ExpressionStatement": {
45-
"expression": {
46-
"CallExpression": {
47-
"callableExpression": {
48-
"QualifiedName": {
49-
"globalSpecifier": null,
50-
"relativeSpecifier": null,
51-
"nameParts": [
52-
{
53-
"kind": "Name",
54-
"textLength": 3
55-
}
56-
]
57-
}
58-
},
59-
"openParen": {
60-
"kind": "OpenParenToken",
61-
"textLength": 1
62-
},
63-
"argumentExpressionList": null,
64-
"closeParen": {
65-
"error": "MissingToken",
66-
"kind": "CloseParenToken",
67-
"textLength": 0
68-
}
69-
}
70-
},
71-
"semicolon": {
72-
"error": "MissingToken",
73-
"kind": "SemicolonToken",
74-
"textLength": 0
35+
"data": {
36+
"kind": "InlineHtml",
37+
"textLength": 9
7538
}
7639
}
77-
},
78-
{
79-
"error": "SkippedToken",
80-
"kind": "InlineHtml",
81-
"textLength": 3
8240
}
8341
],
8442
"endOfFileToken": {

tests/cases/parser/haltCompiler7.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
// A MissingToken should be generated for the missing `;` or close php tag.
3+
// NOTE: token_get_all() will yield up to 3 tokens after T_HALT_COMPILER,
4+
// no matter what those tokens happen to be, so tolerant-php-parser combines unexpected tokens into T_INLINE_HTML
5+
// so that no subsequent statements get emitted.
6+
// (T_HALT_COMPILER is forbidden in other node types)
7+
__halt_compiler() + 1;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
{
3+
"kind": 0,
4+
"message": "';' expected.",
5+
"start": 390,
6+
"length": 0
7+
}
8+
]
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"SourceFileNode": {
3+
"statementList": [
4+
{
5+
"InlineHtml": {
6+
"scriptSectionEndTag": null,
7+
"text": null,
8+
"scriptSectionStartTag": {
9+
"kind": "ScriptSectionStartTag",
10+
"textLength": 6
11+
}
12+
}
13+
},
14+
{
15+
"HaltCompilerStatement": {
16+
"haltCompilerKeyword": {
17+
"kind": "HaltCompilerKeyword",
18+
"textLength": 15
19+
},
20+
"openParen": {
21+
"kind": "OpenParenToken",
22+
"textLength": 1
23+
},
24+
"closeParen": {
25+
"kind": "CloseParenToken",
26+
"textLength": 1
27+
},
28+
"semicolonOrCloseTag": {
29+
"error": "MissingToken",
30+
"kind": "SemicolonToken",
31+
"textLength": 0
32+
},
33+
"data": {
34+
"kind": "InlineHtml",
35+
"textLength": 4
36+
}
37+
}
38+
}
39+
],
40+
"endOfFileToken": {
41+
"kind": "EndOfFileToken",
42+
"textLength": 0
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)