This commit is contained in:
Sara Itani 2016-11-05 16:06:10 -07:00
Родитель cc242b252f
Коммит 61b430da80
31 изменённых файлов: 1332 добавлений и 21 удалений

16
Node/ForeachKey.php Normal file
Просмотреть файл

@ -0,0 +1,16 @@
<?php
namespace PhpParser\Node;
use PhpParser\NodeKind;
use PhpParser\Token;
class ForeachKey extends Node {
/** @var Expression */
public $expression;
/** @var Token */
public $arrow;
public function __construct() {
parent::__construct(NodeKind::ForeachKeyNode);
}
}

34
Node/ForeachStatement.php Normal file
Просмотреть файл

@ -0,0 +1,34 @@
<?php
namespace PhpParser\Node;
use PhpParser\NodeKind;
use PhpParser\Token;
class ForeachStatement extends StatementNode {
/** @var Token */
public $foreach;
/** @var Token */
public $openParen;
/** @var Expression */
public $forEachCollectionName;
/** @var Token */
public $asKeyword;
/** @var ForeachKey | null */
public $foreachKey;
/** @var ForeachValue */
public $foreachValue;
/**@var Token */
public $closeParen;
/** @var Token | null */
public $colon;
/**@var StatementNode | StatementNode[] */
public $statements;
/**@var Token | null */
public $endForeach;
/**@var Token | null */
public $endForeachSemicolon;
public function __construct() {
parent::__construct(NodeKind::ForeachStatementNode);
}
}

16
Node/ForeachValue.php Normal file
Просмотреть файл

@ -0,0 +1,16 @@
<?php
namespace PhpParser\Node;
use PhpParser\NodeKind;
use PhpParser\Token;
class ForeachValue extends Node {
/** @var Token | null */
public $ampersand;
/** @var Expression */
public $expression;
public function __construct() {
parent::__construct(NodeKind::ForeachValueNode);
}
}

Просмотреть файл

@ -31,4 +31,7 @@ class NodeKind {
const WhileStatementNode = 25;
const DoWhileStatementNode = 26;
const ForStatementNode = 27;
const ForeachStatementNode = 28;
const ForeachKeyNode = 29;
const ForeachValueNode = 30;
}

Просмотреть файл

@ -186,6 +186,7 @@ class TokenKind {
const DotDotDotToken = 254;
const BackslashToken = 255;
const ColonColonToken = 256;
const DoubleArrowToken = 257; // TODO missing from spec
const DecimalLiteralToken = 301;
const OctalLiteralToken = 302;

Просмотреть файл

@ -819,6 +819,7 @@ const OPERATORS_AND_PUNCTUATORS = array(
"}" => TokenKind::CloseBraceToken,
"." => TokenKind::DotToken,
"->" => TokenKind::ArrowToken,
"=>" => TokenKind::DoubleArrowToken,
"++" => TokenKind::PlusPlusToken,
"--" => TokenKind::MinusMinusToken,
"**" => TokenKind::AsteriskAsteriskToken,

Просмотреть файл

@ -22,6 +22,9 @@ use PhpParser\Node\ElseClauseNode;
use PhpParser\Node\ElseIfClauseNode;
use PhpParser\Node\EmptyStatementNode;
use PhpParser\Node\Expression;
use PhpParser\Node\ForeachKey;
use PhpParser\Node\ForeachStatement;
use PhpParser\Node\ForeachValue;
use PhpParser\Node\ForStatement;
use PhpParser\Node\Function_;
use PhpParser\Node\FunctionDefinition;
@ -208,9 +211,13 @@ class Parser {
return
$tokenKind === TokenKind::CaseKeyword ||
$tokenKind === TokenKind::DefaultKeyword;
case ParseContext::ForStatementElements:
return
$tokenKind === TokenKind::EndForKeyword;
case ParseContext::ForeachStatementElements:
return $tokenKind === TokenKind::EndForEachKeyword;
}
// TODO warn about unhandled parse context
return false;
@ -226,6 +233,7 @@ class Parser {
case ParseContext::CaseStatementElements:
case ParseContext::WhileStatementElements:
case ParseContext::ForStatementElements:
case ParseContext::ForeachStatementElements:
return $this->isStatementStart($token);
case ParseContext::ClassMembers:
@ -247,6 +255,7 @@ class Parser {
case ParseContext::CaseStatementElements:
case ParseContext::WhileStatementElements:
case ParseContext::ForStatementElements:
case ParseContext::ForeachStatementElements:
return $this->parseStatementFn();
case ParseContext::ClassMembers:
return $this->parseClassElement();
@ -351,7 +360,8 @@ class Parser {
return $this->parseDoStatement($parentNode);
case TokenKind::ForKeyword: // for-statement
return $this->parseForStatement($parentNode);
// case TokenKind::ForeachKeyword: // foreach-statement
case TokenKind::ForeachKeyword: // foreach-statement
return $this->parseForeachStatement($parentNode);
// function-declaration
case TokenKind::FunctionKeyword:
@ -1035,7 +1045,7 @@ class Parser {
array_push($expression->children, $token);
} else {
array_push($expression->children, new Token(TokenKind::MissingToken, $token->fullStart, $token->fullStart, 0));
array_push($expression->children, new Token(TokenKind::SkippedToken, $token->fullStart, $token->start, $token->length));
return $expression;
}
$this->advanceToken();
return $expression;
@ -1076,6 +1086,56 @@ class Parser {
}
return $forStatement;
}
private function parseForeachStatement($parentNode) {
$foreachStatement = new ForeachStatement();
$foreachStatement->parent = $parentNode;
$foreachStatement->foreach = $this->eat(TokenKind::ForeachKeyword);
$foreachStatement->openParen = $this->eat(TokenKind::OpenParenToken);
$foreachStatement->forEachCollectionName = $this->parseExpression($foreachStatement);
$foreachStatement->asKeyword = $this->eat(TokenKind::AsKeyword);
$foreachStatement->foreachKey = $this->tryParseForeachKey($foreachStatement);
$foreachStatement->foreachValue = $this->parseForeachValue($foreachStatement);
$foreachStatement->closeParen = $this->eat(TokenKind::CloseParenToken);
$foreachStatement->colon = $this->eatOptional(TokenKind::ColonToken);
if ($foreachStatement->colon !== null) {
$foreachStatement->statements = $this->parseList($foreachStatement, ParseContext::ForeachStatementElements);
$foreachStatement->endForeach = $this->eat(TokenKind::EndForEachKeyword);
$foreachStatement->endForeachSemicolon = $this->eat(TokenKind::SemicolonToken);
} else {
$foreachStatement->statements = $this->parseStatement($foreachStatement);
}
return $foreachStatement;
}
private function tryParseForeachKey($parentNode) {
if (!$this->isExpressionStart($this->getCurrentToken())) {
return null;
}
$startPos = $this->lexer->pos;
$startToken = $this->getCurrentToken();
$foreachKey = new ForeachKey();
$foreachKey->parent = $parentNode;
$foreachKey->expression = $this->parseExpression($foreachKey);
if (!$this->lookahead(TokenKind::DoubleArrowToken)) {
$this->lexer->pos = $startPos;
$this->token = $startToken;
return null;
}
$foreachKey->arrow = $this->eat(TokenKind::DoubleArrowToken);
return $foreachKey;
}
private function parseForeachValue($parentNode) {
$foreachValue = new ForeachValue();
$foreachValue->parent = $parentNode;
$foreachValue->ampersand = $this->eatOptional(TokenKind::AmpersandToken);
$foreachValue->expression = $this->parseExpression($foreachValue);
return $foreachValue;
}
}
class ParseContext {
@ -1087,5 +1147,6 @@ class ParseContext {
const CaseStatementElements = 5;
const WhileStatementElements = 6;
const ForStatementElements = 7;
const Count = 8;
const ForeachStatementElements = 8;
const Count = 9;
}

Просмотреть файл

@ -105,10 +105,6 @@
{
"kind": "MissingToken",
"textLength": 0
},
{
"kind": "SkippedToken",
"textLength": 0
}
]
}

Просмотреть файл

@ -66,10 +66,6 @@
{
"kind": "MissingToken",
"textLength": 0
},
{
"kind": "SkippedToken",
"textLength": 0
}
]
}

Просмотреть файл

@ -0,0 +1,6 @@
<?php
foreach ($a as $a) {
;
;
}

Просмотреть файл

@ -0,0 +1,108 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": null,
"foreachValue": {
"ForeachValueNode": {
"ampersand": null,
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"colon": null,
"statements": {
"CompoundStatementNode": {
"children": [
{
"kind": "OpenBraceToken",
"textLength": 1
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"kind": "CloseBraceToken",
"textLength": 1
}
]
}
},
"endForeach": null,
"endForeachSemicolon": null
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<?php
foreach ($a as $b = > $c) {
;
}

Просмотреть файл

@ -0,0 +1,114 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": null,
"foreachValue": {
"ForeachValueNode": {
"ampersand": null,
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
}
}
},
"closeParen": {
"kind": "MissingToken",
"textLength": 0
},
"colon": null,
"statements": {
"kind": "EqualsToken",
"textLength": 1
},
"endForeach": null,
"endForeachSemicolon": null
}
},
{
"kind": "SkippedToken",
"textLength": 1
},
{
"kind": "VariableName",
"textLength": 2
},
{
"kind": "SkippedToken",
"textLength": 1
},
{
"CompoundStatementNode": {
"children": [
{
"kind": "OpenBraceToken",
"textLength": 1
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"kind": "CloseBraceToken",
"textLength": 1
}
]
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<?php
foreach ($a as $a)
;
;

Просмотреть файл

@ -0,0 +1,94 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": null,
"foreachValue": {
"ForeachValueNode": {
"ampersand": null,
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"colon": null,
"statements": {
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
"endForeach": null,
"endForeachSemicolon": null
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<?php
foreach ($a as $a=>$a)
;
;

Просмотреть файл

@ -0,0 +1,111 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": {
"ForeachKeyNode": {
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"arrow": {
"kind": "DoubleArrowToken",
"textLength": 2
}
}
},
"foreachValue": {
"ForeachValueNode": {
"ampersand": null,
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"colon": null,
"statements": {
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
"endForeach": null,
"endForeachSemicolon": null
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<?php
foreach ($a as $a=> & $a)
;
;

Просмотреть файл

@ -0,0 +1,114 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": {
"ForeachKeyNode": {
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"arrow": {
"kind": "DoubleArrowToken",
"textLength": 2
}
}
},
"foreachValue": {
"ForeachValueNode": {
"ampersand": {
"kind": "AmpersandToken",
"textLength": 1
},
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"colon": null,
"statements": {
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
"endForeach": null,
"endForeachSemicolon": null
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,6 @@
<?php
foreach ($a as $a=> & $a) :
;
;
endforeach;

Просмотреть файл

@ -0,0 +1,125 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": {
"ForeachKeyNode": {
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"arrow": {
"kind": "DoubleArrowToken",
"textLength": 2
}
}
},
"foreachValue": {
"ForeachValueNode": {
"ampersand": {
"kind": "AmpersandToken",
"textLength": 1
},
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"colon": {
"kind": "ColonToken",
"textLength": 1
},
"statements": [
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
}
],
"endForeach": {
"kind": "EndForEachKeyword",
"textLength": 10
},
"endForeachSemicolon": {
"kind": "SemicolonToken",
"textLength": 1
}
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,6 @@
<?php
foreach ($a as $a=>) :
;
;
endforeach;

Просмотреть файл

@ -0,0 +1,122 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": {
"ForeachKeyNode": {
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"arrow": {
"kind": "DoubleArrowToken",
"textLength": 2
}
}
},
"foreachValue": {
"ForeachValueNode": {
"ampersand": null,
"expression": {
"Expression": {
"children": [
{
"kind": "MissingToken",
"textLength": 0
}
]
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"colon": {
"kind": "ColonToken",
"textLength": 1
},
"statements": [
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
}
],
"endForeach": {
"kind": "EndForEachKeyword",
"textLength": 10
},
"endForeachSemicolon": {
"kind": "SemicolonToken",
"textLength": 1
}
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,6 @@
<?php
foreach ($a as ) :
;
;
endforeach;

Просмотреть файл

@ -0,0 +1,105 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": null,
"foreachValue": {
"ForeachValueNode": {
"ampersand": null,
"expression": {
"Expression": {
"children": [
{
"kind": "MissingToken",
"textLength": 0
}
]
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"colon": {
"kind": "ColonToken",
"textLength": 1
},
"statements": [
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
}
],
"endForeach": {
"kind": "EndForEachKeyword",
"textLength": 10
},
"endForeachSemicolon": {
"kind": "SemicolonToken",
"textLength": 1
}
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,6 @@
<?php
foreach $a as $a=>$b {
;
;
}

Просмотреть файл

@ -0,0 +1,125 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "MissingToken",
"textLength": 0
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": {
"ForeachKeyNode": {
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"arrow": {
"kind": "DoubleArrowToken",
"textLength": 2
}
}
},
"foreachValue": {
"ForeachValueNode": {
"ampersand": null,
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
}
}
},
"closeParen": {
"kind": "MissingToken",
"textLength": 0
},
"colon": null,
"statements": {
"CompoundStatementNode": {
"children": [
{
"kind": "OpenBraceToken",
"textLength": 1
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"kind": "CloseBraceToken",
"textLength": 1
}
]
}
},
"endForeach": null,
"endForeachSemicolon": null
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -0,0 +1,5 @@
<?php
foreach $a as $a=>$b :
;
;

Просмотреть файл

@ -0,0 +1,122 @@
{
"SourceFileNode": {
"scriptSectionList": [
{
"ScriptSection": {
"text": {
"kind": "ScriptSectionPrependedText",
"textLength": 0
},
"startTag": {
"kind": "ScriptSectionStartTag",
"textLength": 6
},
"statementList": [
{
"ForeachStatementNode": {
"foreach": {
"kind": "ForeachKeyword",
"textLength": 7
},
"openParen": {
"kind": "MissingToken",
"textLength": 0
},
"forEachCollectionName": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"asKeyword": {
"kind": "AsKeyword",
"textLength": 2
},
"foreachKey": {
"ForeachKeyNode": {
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
},
"arrow": {
"kind": "DoubleArrowToken",
"textLength": 2
}
}
},
"foreachValue": {
"ForeachValueNode": {
"ampersand": null,
"expression": {
"Expression": {
"children": [
{
"kind": "VariableName",
"textLength": 2
}
]
}
}
}
},
"closeParen": {
"kind": "MissingToken",
"textLength": 0
},
"colon": {
"kind": "ColonToken",
"textLength": 1
},
"statements": [
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
},
{
"EmptyStatement": {
"children": [
{
"kind": "SemicolonToken",
"textLength": 1
}
]
}
}
],
"endForeach": {
"kind": "MissingToken",
"textLength": 0
},
"endForeachSemicolon": {
"kind": "MissingToken",
"textLength": 0
}
}
}
],
"endTag": null
}
}
],
"endOfFileToken": {
"kind": "EndOfFileToken",
"textLength": 0
}
}
}

Просмотреть файл

@ -54,17 +54,13 @@
{
"kind": "MissingToken",
"textLength": 0
},
{
"kind": "SkippedToken",
"textLength": 1
}
]
}
},
"defaultLabelTerminator": {
"kind": "MissingToken",
"textLength": 0
"kind": "ColonToken",
"textLength": 1
},
"statementList": []
}

Просмотреть файл

@ -28,10 +28,6 @@
{
"kind": "MissingToken",
"textLength": 0
},
{
"kind": "SkippedToken",
"textLength": 0
}
]
}