diff --git a/.travis.yml b/.travis.yml index 90889872..fb436132 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,8 +19,6 @@ matrix: - php: 7.2 env: STATIC_ANALYSIS=true fast_finish: true - allow_failures: - - env: VALIDATION=true cache: directories: diff --git a/src/Node/Statement/HaltCompilerStatement.php b/src/Node/Statement/HaltCompilerStatement.php new file mode 100644 index 00000000..009009fa --- /dev/null +++ b/src/Node/Statement/HaltCompilerStatement.php @@ -0,0 +1,36 @@ +parseUnsetStatement($parentNode); + + case TokenKind::HaltCompilerKeyword: + if ($parentNode instanceof SourceFileNode) { + return $this->parseHaltCompilerStatement($parentNode); + } + // __halt_compiler is a fatal compile error anywhere other than the top level. + // It won't be seen elsewhere in other programs - warn about the token being unexpected. + $this->advanceToken(); + return new SkippedToken($token); } $expressionStatement = new ExpressionStatement(); @@ -1141,6 +1151,9 @@ private function isStatementStart(Token $token) { // attributes case TokenKind::AttributeToken: + + // __halt_compiler + case TokenKind::HaltCompilerKeyword: return true; default: @@ -2844,6 +2857,18 @@ private function parseUnsetStatement($parentNode) { return $unsetStatement; } + private function parseHaltCompilerStatement($parentNode) { + $unsetStatement = new HaltCompilerStatement(); + $unsetStatement->parent = $parentNode; + + $unsetStatement->haltCompilerKeyword = $this->eat1(TokenKind::HaltCompilerKeyword); + $unsetStatement->openParen = $this->eat1(TokenKind::OpenParenToken); + $unsetStatement->closeParen = $this->eat1(TokenKind::CloseParenToken); + $unsetStatement->semicolon = $this->eatSemicolonOrAbortStatement(); + $unsetStatement->data = $this->eatOptional1(TokenKind::InlineHtml); + return $unsetStatement; + } + private function parseArrayCreationExpression($parentNode) { $arrayExpression = new ArrayCreationExpression(); $arrayExpression->parent = $parentNode; diff --git a/src/PhpTokenizer.php b/src/PhpTokenizer.php index be8cd711..08c57884 100644 --- a/src/PhpTokenizer.php +++ b/src/PhpTokenizer.php @@ -228,7 +228,6 @@ protected static function tokenGetAll(string $content, $parseContext): array T_DIR => TokenKind::Name, T_FILE => TokenKind::Name, T_FUNC_C => TokenKind::Name, - T_HALT_COMPILER => TokenKind::Name, T_METHOD_C => TokenKind::Name, T_NS_C => TokenKind::Name, T_TRAIT_C => TokenKind::Name, @@ -274,6 +273,7 @@ protected static function tokenGetAll(string $content, $parseContext): array T_FUNCTION => TokenKind::FunctionKeyword, T_GLOBAL => TokenKind::GlobalKeyword, T_GOTO => TokenKind::GotoKeyword, + T_HALT_COMPILER => TokenKind::HaltCompilerKeyword, T_IF => TokenKind::IfKeyword, T_IMPLEMENTS => TokenKind::ImplementsKeyword, T_INCLUDE => TokenKind::IncludeKeyword, diff --git a/src/TokenKind.php b/src/TokenKind.php index 49caca94..b4d59c2d 100644 --- a/src/TokenKind.php +++ b/src/TokenKind.php @@ -91,6 +91,7 @@ class TokenKind { const IterableKeyword = self::IterableReservedWord; const EnumKeyword = 171; const ReadonlyKeyword = 172; + const HaltCompilerKeyword = 173; const OpenBracketToken = 201; const CloseBracketToken = 202; diff --git a/tests/cases/parser/haltCompiler1.php b/tests/cases/parser/haltCompiler1.php new file mode 100644 index 00000000..fb034349 --- /dev/null +++ b/tests/cases/parser/haltCompiler1.php @@ -0,0 +1,2 @@ +