Skip to content

Commit ba1f1e8

Browse files
authored
Merge pull request microsoft#382 from TysonAndre/halt-compiler-support
Support `__halt_compiler` statement
2 parents 6f49c64 + 8e63602 commit ba1f1e8

17 files changed

+471
-3
lines changed

.travis.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ matrix:
1919
- php: 7.2
2020
env: STATIC_ANALYSIS=true
2121
fast_finish: true
22-
allow_failures:
23-
- env: VALIDATION=true
2422

2523
cache:
2624
directories:
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
/*---------------------------------------------------------------------------------------------
3+
* Copyright (c) Microsoft Corporation. All rights reserved.
4+
* Licensed under the MIT License. See License.txt in the project root for license information.
5+
*--------------------------------------------------------------------------------------------*/
6+
7+
namespace Microsoft\PhpParser\Node\Statement;
8+
9+
use Microsoft\PhpParser\Node\Expression;
10+
use Microsoft\PhpParser\Token;
11+
12+
class HaltCompilerStatement extends Expression {
13+
14+
/** @var Token */
15+
public $haltCompilerKeyword;
16+
17+
/** @var Token */
18+
public $openParen;
19+
20+
/** @var Token */
21+
public $closeParen;
22+
23+
/** @var Token */
24+
public $semicolon;
25+
26+
/** @var Token */
27+
public $data;
28+
29+
const CHILD_NAMES = [
30+
'haltCompilerKeyword',
31+
'openParen',
32+
'closeParen',
33+
'semicolon',
34+
'data',
35+
];
36+
}

src/Parser.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
ForStatement,
9898
FunctionDeclaration,
9999
GotoStatement,
100+
HaltCompilerStatement,
100101
IfStatementNode,
101102
InlineHtml,
102103
InterfaceDeclaration,
@@ -615,6 +616,15 @@ private function parseStatementFn() {
615616

616617
case TokenKind::UnsetKeyword:
617618
return $this->parseUnsetStatement($parentNode);
619+
620+
case TokenKind::HaltCompilerKeyword:
621+
if ($parentNode instanceof SourceFileNode) {
622+
return $this->parseHaltCompilerStatement($parentNode);
623+
}
624+
// __halt_compiler is a fatal compile error anywhere other than the top level.
625+
// It won't be seen elsewhere in other programs - warn about the token being unexpected.
626+
$this->advanceToken();
627+
return new SkippedToken($token);
618628
}
619629

620630
$expressionStatement = new ExpressionStatement();
@@ -1141,6 +1151,9 @@ private function isStatementStart(Token $token) {
11411151

11421152
// attributes
11431153
case TokenKind::AttributeToken:
1154+
1155+
// __halt_compiler
1156+
case TokenKind::HaltCompilerKeyword:
11441157
return true;
11451158

11461159
default:
@@ -2844,6 +2857,18 @@ private function parseUnsetStatement($parentNode) {
28442857
return $unsetStatement;
28452858
}
28462859

2860+
private function parseHaltCompilerStatement($parentNode) {
2861+
$unsetStatement = new HaltCompilerStatement();
2862+
$unsetStatement->parent = $parentNode;
2863+
2864+
$unsetStatement->haltCompilerKeyword = $this->eat1(TokenKind::HaltCompilerKeyword);
2865+
$unsetStatement->openParen = $this->eat1(TokenKind::OpenParenToken);
2866+
$unsetStatement->closeParen = $this->eat1(TokenKind::CloseParenToken);
2867+
$unsetStatement->semicolon = $this->eatSemicolonOrAbortStatement();
2868+
$unsetStatement->data = $this->eatOptional1(TokenKind::InlineHtml);
2869+
return $unsetStatement;
2870+
}
2871+
28472872
private function parseArrayCreationExpression($parentNode) {
28482873
$arrayExpression = new ArrayCreationExpression();
28492874
$arrayExpression->parent = $parentNode;

src/PhpTokenizer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ protected static function tokenGetAll(string $content, $parseContext): array
228228
T_DIR => TokenKind::Name,
229229
T_FILE => TokenKind::Name,
230230
T_FUNC_C => TokenKind::Name,
231-
T_HALT_COMPILER => TokenKind::Name,
232231
T_METHOD_C => TokenKind::Name,
233232
T_NS_C => TokenKind::Name,
234233
T_TRAIT_C => TokenKind::Name,
@@ -274,6 +273,7 @@ protected static function tokenGetAll(string $content, $parseContext): array
274273
T_FUNCTION => TokenKind::FunctionKeyword,
275274
T_GLOBAL => TokenKind::GlobalKeyword,
276275
T_GOTO => TokenKind::GotoKeyword,
276+
T_HALT_COMPILER => TokenKind::HaltCompilerKeyword,
277277
T_IF => TokenKind::IfKeyword,
278278
T_IMPLEMENTS => TokenKind::ImplementsKeyword,
279279
T_INCLUDE => TokenKind::IncludeKeyword,

src/TokenKind.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class TokenKind {
9191
const IterableKeyword = self::IterableReservedWord;
9292
const EnumKeyword = 171;
9393
const ReadonlyKeyword = 172;
94+
const HaltCompilerKeyword = 173;
9495

9596
const OpenBracketToken = 201;
9697
const CloseBracketToken = 202;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
__halt_compiler();
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[]
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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+
"semicolon": {
29+
"kind": "SemicolonToken",
30+
"textLength": 1
31+
},
32+
"data": {
33+
"kind": "InlineHtml",
34+
"textLength": 1
35+
}
36+
}
37+
}
38+
],
39+
"endOfFileToken": {
40+
"kind": "EndOfFileToken",
41+
"textLength": 0
42+
}
43+
}
44+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?php
2+
if (true) {
3+
__halt_compiler();
4+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[
2+
{
3+
"kind": 0,
4+
"message": "Unexpected 'HaltCompilerKeyword'",
5+
"start": 22,
6+
"length": 15
7+
},
8+
{
9+
"kind": 0,
10+
"message": "'Expression' expected.",
11+
"start": 38,
12+
"length": 0
13+
},
14+
{
15+
"kind": 0,
16+
"message": "Unexpected 'InlineHtml'",
17+
"start": 40,
18+
"length": 3
19+
},
20+
{
21+
"kind": 0,
22+
"message": "'}' expected.",
23+
"start": 43,
24+
"length": 0
25+
}
26+
]

0 commit comments

Comments
 (0)