v0.1.0: Raise minimum php version, change some AST representations

Raise the minimum php version from 7.0 to 7.2.
Depend on phpunit 8 for local development

Unify method names for Node and Token to getFullStartPosition and getStartPosition
(Consistently end public API methods with Position).
Avoid the need for callers to check if an object is a Node/Token before
calling a method.

Convert UnsetIntrinsicExpression to UnsetStatement - it can only be used
as a statement.

Unify previously split up lists into a single list in some AST node
properties (initially done that way for backward compatibility)

Clean up unnecessary special case for throw
- This continues to be parsed as an ExpressionStatement with the same
  precedence

Rename throwStatement to throwExpression in test file names.
This commit is contained in:
Tyson Andre 2020-12-14 22:07:17 -05:00
Родитель 2a48939763
Коммит 465d02f146
70 изменённых файлов: 542 добавлений и 666 удалений

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

@ -1,13 +1,10 @@
language: php
php:
- 7.0
- 7.1
- 7.2
- 7.3
- 7.4
# Should be changed to 8.0 once travis officially provides that label.
- nightly
- '7.2'
- '7.3'
- '7.4'
- '8.0'
env:
- VALIDATION=false
@ -30,12 +27,7 @@ cache:
before_script:
- if [[ $STATIC_ANALYSIS = true ]]; then composer require phpstan/phpstan --no-update; fi
- |
if php -r 'exit(PHP_MAJOR_VERSION < 8 ? 0 : 1);';
then composer install
else
composer install --ignore-platform-reqs
fi
- composer install
- set -e # Stop on first error.
- phpenv config-rm xdebug.ini || true
- if find . -name "*.php" -path "./src/*" -path "./experiments/*" -path "./tools/*" -path "./syntax-visualizer/server/src/*" -exec php -l {} 2>&1 \; | grep "syntax error, unexpected"; then exit 1; fi

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

@ -6,7 +6,7 @@
"php": ">=7.2"
},
"require-dev": {
"phpunit/phpunit": "^7.5.20"
"phpunit/phpunit": "^8.5.15"
},
"license": "MIT",
"authors": [

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

@ -10,15 +10,15 @@
```php
public function getNodeKindName ( ) : string
```
### Node::getStart
### Node::getStartPosition
Gets start position of Node, not including leading comments and whitespace.
```php
public function getStart ( ) : int
public function getStartPosition ( ) : int
```
### Node::getFullStart
### Node::getFullStartPosition
Gets start position of Node, including leading comments and whitespace
```php
public function getFullStart ( ) : int
public function getFullStartPosition ( ) : int
```
### Node::getParent
Gets parent of current node (returns null if has no parent)
@ -198,11 +198,11 @@ public function getFullText ( string & $document ) : string
```php
public function getStartPosition ( )
```
### Token::getFullStart
### Token::getFullStartPosition
> TODO: add doc comment
```php
public function getFullStart ( )
public function getFullStartPosition ( )
```
### Token::getWidth
> TODO: add doc comment

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

@ -34,33 +34,11 @@ class FilePositionMap {
$this->lineForCurrentOffset = 1;
}
/**
* @param Node $node the node to get the start line for.
* TODO deprecate and merge this and getTokenStartLine into getStartLine
* if https://github.com/Microsoft/tolerant-php-parser/issues/166 is fixed,
* (i.e. if there is a consistent way to get the start offset)
*/
public function getNodeStartLine(Node $node) : int {
return $this->getLineNumberForOffset($node->getStart());
}
/**
* @param Token $token the token to get the start line for.
*/
public function getTokenStartLine(Token $token) : int {
return $this->getLineNumberForOffset($token->start);
}
/**
* @param Node|Token $node
*/
public function getStartLine($node) : int {
if ($node instanceof Token) {
$offset = $node->start;
} else {
$offset = $node->getStart();
}
return $this->getLineNumberForOffset($offset);
return $this->getLineNumberForOffset($node->getStartPosition());
}
/**
@ -68,12 +46,7 @@ class FilePositionMap {
* Similar to getStartLine but includes the column
*/
public function getStartLineCharacterPositionForOffset($node) : LineCharacterPosition {
if ($node instanceof Token) {
$offset = $node->start;
} else {
$offset = $node->getStart();
}
return $this->getLineCharacterPositionForOffset($offset);
return $this->getLineCharacterPositionForOffset($node->getStartPosition());
}
/** @param Node|Token $node */

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

@ -31,10 +31,10 @@ abstract class Node implements \JsonSerializable {
* @return int
* @throws \Exception
*/
public function getStart() : int {
public function getStartPosition() : int {
$child = $this->getChildNodesAndTokens()->current();
if ($child instanceof Node) {
return $child->getStart();
return $child->getStartPosition();
} elseif ($child instanceof Token) {
return $child->start;
}
@ -46,7 +46,7 @@ abstract class Node implements \JsonSerializable {
* @return int
* @throws \Exception
*/
public function getFullStart() : int {
public function getFullStartPosition() : int {
foreach($this::CHILD_NAMES as $name) {
if (($child = $this->$name) !== null) {
@ -59,7 +59,7 @@ abstract class Node implements \JsonSerializable {
}
if ($child instanceof Node) {
return $child->getFullStart();
return $child->getFullStartPosition();
}
if ($child instanceof Token) {
@ -330,7 +330,7 @@ abstract class Node implements \JsonSerializable {
* @return int
*/
public function getWidth() : int {
$first = $this->getStart();
$first = $this->getStartPosition();
$last = $this->getEndPosition();
return $last - $first;
@ -342,7 +342,7 @@ abstract class Node implements \JsonSerializable {
* @return int
*/
public function getFullWidth() : int {
$first = $this->getFullStart();
$first = $this->getFullStartPosition();
$last = $this->getEndPosition();
return $last - $first;
@ -353,7 +353,7 @@ abstract class Node implements \JsonSerializable {
* @return string
*/
public function getText() : string {
$start = $this->getStart();
$start = $this->getStartPosition();
$end = $this->getEndPosition();
$fileContents = $this->getFileContents();
@ -365,7 +365,7 @@ abstract class Node implements \JsonSerializable {
* @return string
*/
public function getFullText() : string {
$start = $this->getFullStart();
$start = $this->getFullStartPosition();
$end = $this->getEndPosition();
$fileContents = $this->getFileContents();
@ -463,7 +463,7 @@ abstract class Node implements \JsonSerializable {
* @return bool
*/
private function containsPosition(int $pos): bool {
return $this->getStart() <= $pos && $pos <= $this->getEndPosition();
return $this->getStartPosition() <= $pos && $pos <= $this->getEndPosition();
}
/**
@ -476,7 +476,7 @@ abstract class Node implements \JsonSerializable {
public function getDocCommentText() {
$leadingTriviaText = $this->getLeadingCommentAndWhitespaceText();
$leadingTriviaTokens = PhpTokenizer::getTokensArrayFromContent(
$leadingTriviaText, ParseContext::SourceElements, $this->getFullStart(), false
$leadingTriviaText, ParseContext::SourceElements, $this->getFullStartPosition(), false
);
for ($i = \count($leadingTriviaTokens) - 1; $i >= 0; $i--) {
$token = $leadingTriviaTokens[$i];
@ -509,13 +509,13 @@ abstract class Node implements \JsonSerializable {
$topLevelNamespaceStatements = $namespaceDefinition->compoundStatementOrSemicolon instanceof Token
? $namespaceDefinition->parent->statementList // we need to start from the namespace definition.
: $namespaceDefinition->compoundStatementOrSemicolon->statements;
$namespaceFullStart = $namespaceDefinition->getFullStart();
$namespaceFullStart = $namespaceDefinition->getFullStartPosition();
} else {
$topLevelNamespaceStatements = $this->getRoot()->statementList;
$namespaceFullStart = 0;
}
$nodeFullStart = $this->getFullStart();
$nodeFullStart = $this->getFullStartPosition();
// TODO optimize performance
// Currently we rebuild the import tables on every call (and therefore every name resolution operation)
@ -535,10 +535,10 @@ abstract class Node implements \JsonSerializable {
$contents = $this->getFileContents();
foreach ($topLevelNamespaceStatements as $useDeclaration) {
if ($useDeclaration->getFullStart() <= $namespaceFullStart) {
if ($useDeclaration->getFullStartPosition() <= $namespaceFullStart) {
continue;
}
if ($useDeclaration->getFullStart() > $nodeFullStart) {
if ($useDeclaration->getFullStartPosition() > $nodeFullStart) {
break;
} elseif (!($useDeclaration instanceof NamespaceUseDeclaration)) {
continue;
@ -609,11 +609,11 @@ abstract class Node implements \JsonSerializable {
throw new \Exception("Invalid tree - SourceFileNode must always exist at root of tree.");
}
$fullStart = $this->getFullStart();
$fullStart = $this->getFullStartPosition();
$lastNamespaceDefinition = null;
if ($namespaceDefinition instanceof SourceFileNode) {
foreach ($namespaceDefinition->getChildNodes() as $childNode) {
if ($childNode instanceof NamespaceDefinition && $childNode->getFullStart() < $fullStart) {
if ($childNode instanceof NamespaceDefinition && $childNode->getFullStartPosition() < $fullStart) {
$lastNamespaceDefinition = $childNode;
}
}
@ -662,7 +662,7 @@ abstract class Node implements \JsonSerializable {
* Add the alias and resolved name to the corresponding namespace, function, or const import table.
* If the alias already exists, it will get replaced by the most recent using.
*
* TODO - worth throwing an error here in stead?
* TODO - worth throwing an error here instead?
*/
private function addToImportTable($alias, $functionOrConst, $namespaceNameParts, $contents, & $namespaceImportTable, & $functionImportTable, & $constImportTable):array
{

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

@ -20,17 +20,13 @@ class MissingMemberDeclaration extends Node implements ModifiedTypeInterface {
/** @var Token|null needed along with typeDeclaration for what looked like typed property declarations but was missing VariableName */
public $questionToken;
/** @var QualifiedName|Token|null */
public $typeDeclaration;
/** @var DelimitedList\QualifiedNameList|null */
public $otherTypeDeclarations;
public $typeDeclarationList;
const CHILD_NAMES = [
'attributes',
'modifiers',
'questionToken',
'typeDeclaration',
'otherTypeDeclarations',
'typeDeclarationList',
];
}

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

@ -81,7 +81,7 @@ class QualifiedName extends Node implements NamespacedNameInterface {
*/
public function getResolvedName($namespaceDefinition = null) {
// Name resolution not applicable to constructs that define symbol names or aliases.
if (($this->parent instanceof Node\Statement\NamespaceDefinition && $this->parent->name->getStart() === $this->getStart()) ||
if (($this->parent instanceof Node\Statement\NamespaceDefinition && $this->parent->name->getStartPosition() === $this->getStartPosition()) ||
$this->parent instanceof Node\Statement\NamespaceUseDeclaration ||
$this->parent instanceof Node\NamespaceUseClause ||
$this->parent instanceof Node\NamespaceUseGroupClause ||

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

@ -60,12 +60,7 @@ class BreakOrContinueStatement extends StatementNode {
}
}
if ($breakoutLevel instanceof Token) {
$start = $breakoutLevel->getStartPosition();
}
else {
$start = $breakoutLevel->getStart();
}
$start = $breakoutLevel->getStartPosition();
$end = $breakoutLevel->getEndPosition();
return new Diagnostic(

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

@ -4,13 +4,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
namespace Microsoft\PhpParser\Node\Expression;
namespace Microsoft\PhpParser\Node\Statement;
use Microsoft\PhpParser\Node\DelimitedList;
use Microsoft\PhpParser\Node\Expression;
use Microsoft\PhpParser\Token;
class UnsetIntrinsicExpression extends Expression {
class UnsetStatement extends Expression {
/** @var Token */
public $unsetKeyword;
@ -24,10 +24,14 @@ class UnsetIntrinsicExpression extends Expression {
/** @var Token */
public $closeParen;
/** @var Token */
public $semicolon;
const CHILD_NAMES = [
'unsetKeyword',
'openParen',
'expressions',
'closeParen'
'closeParen',
'semicolon',
];
}

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

@ -50,7 +50,6 @@ use Microsoft\PhpParser\Node\Expression\{
ThrowExpression,
UnaryExpression,
UnaryOpExpression,
UnsetIntrinsicExpression,
Variable,
YieldExpression
};
@ -106,6 +105,7 @@ use Microsoft\PhpParser\Node\Statement\{
SwitchStatementNode,
TraitDeclaration,
TryStatement,
UnsetStatement,
WhileStatement
};
use Microsoft\PhpParser\Node\TraitMembers;
@ -533,8 +533,6 @@ class Parser {
return $this->parseBreakOrContinueStatement($parentNode);
case TokenKind::ReturnKeyword: // return-statement
return $this->parseReturnStatement($parentNode);
case TokenKind::ThrowKeyword: // throw-statement
return $this->parseThrowStatement($parentNode);
// try-statement
case TokenKind::TryKeyword:
@ -2401,16 +2399,6 @@ class Parser {
return $returnStatement;
}
/** @return ExpressionStatement */
private function parseThrowStatement($parentNode) {
$throwStatement = new ExpressionStatement();
$throwStatement->expression = $this->parseThrowExpression($throwStatement);
$throwStatement->parent = $parentNode;
$throwStatement->semicolon = $this->eatSemicolonOrAbortStatement();
return $throwStatement;
}
/** @return ThrowExpression */
private function parseThrowExpression($parentNode) {
$throwExpression = new ThrowExpression();
@ -2625,20 +2613,6 @@ class Parser {
return $echoStatement;
}
/** @return ExpressionStatement */
private function parseUnsetStatement($parentNode) {
$expressionStatement = new ExpressionStatement();
// FIXME: flatten into UnsetStatement instead?
$unsetExpression = $this->parseUnsetIntrinsicExpression($expressionStatement);
$expressionStatement->parent = $parentNode;
$expressionStatement->expression = $unsetExpression;
$expressionStatement->semicolon = $this->eatSemicolonOrAbortStatement();
return $expressionStatement;
}
private function parseListIntrinsicExpression($parentNode) {
$listExpression = new ListIntrinsicExpression();
$listExpression->parent = $parentNode;
@ -2703,16 +2677,16 @@ class Parser {
);
}
private function parseUnsetIntrinsicExpression($parentNode) {
$unsetExpression = new UnsetIntrinsicExpression();
$unsetExpression->parent = $parentNode;
private function parseUnsetStatement($parentNode) {
$unsetStatement = new UnsetStatement();
$unsetStatement->parent = $parentNode;
$unsetExpression->unsetKeyword = $this->eat1(TokenKind::UnsetKeyword);
$unsetExpression->openParen = $this->eat1(TokenKind::OpenParenToken);
$unsetExpression->expressions = $this->parseExpressionList($unsetExpression);
$unsetExpression->closeParen = $this->eat1(TokenKind::CloseParenToken);
return $unsetExpression;
$unsetStatement->unsetKeyword = $this->eat1(TokenKind::UnsetKeyword);
$unsetStatement->openParen = $this->eat1(TokenKind::OpenParenToken);
$unsetStatement->expressions = $this->parseExpressionList($unsetStatement);
$unsetStatement->closeParen = $this->eat1(TokenKind::CloseParenToken);
$unsetStatement->semicolon = $this->eatSemicolonOrAbortStatement();
return $unsetStatement;
}
private function parseArrayCreationExpression($parentNode) {
@ -3225,6 +3199,7 @@ class Parser {
$propertyDeclaration->questionToken = $questionToken;
if ($typeDeclarationList) {
$propertyDeclaration->typeDeclarationList = $typeDeclarationList;
$typeDeclarationList->parent = $propertyDeclaration;
} elseif ($questionToken) {
$propertyDeclaration->typeDeclarationList = new MissingToken(TokenKind::PropertyType, $this->token->fullStart);
}
@ -3618,14 +3593,10 @@ class Parser {
$missingTraitMemberDeclaration->modifiers = $modifiers;
$missingTraitMemberDeclaration->questionToken = $questionToken;
if ($typeDeclarationList) {
$missingTraitMemberDeclaration->typeDeclaration = \array_shift($typeDeclarationList->children);
$missingTraitMemberDeclaration->typeDeclaration->parent = $missingTraitMemberDeclaration;
if ($typeDeclarationList->children) {
$missingTraitMemberDeclaration->otherTypeDeclarations = $typeDeclarationList;
$typeDeclarationList->parent = $missingTraitMemberDeclaration;
}
$missingTraitMemberDeclaration->typeDeclarationList = $typeDeclarationList;
$missingTraitMemberDeclaration->typeDeclarationList->parent = $missingTraitMemberDeclaration;
} elseif ($questionToken) {
$missingTraitMemberDeclaration->typeDeclaration = new MissingToken(TokenKind::PropertyType, $this->token->fullStart);
$missingTraitMemberDeclaration->typeDeclarationList = new MissingToken(TokenKind::PropertyType, $this->token->fullStart);
}
return $missingTraitMemberDeclaration;
}

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

@ -61,7 +61,7 @@ class Token implements \JsonSerializable {
/**
* @return int
*/
public function getFullStart() {
public function getFullStartPosition() {
return $this->fullStart;
}

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

@ -18,7 +18,7 @@ class LexicalGrammarTest extends TestCase {
public function run(TestResult $result = null) : TestResult {
if (!isset($GLOBALS["GIT_CHECKOUT_LEXER"])) {
$GLOBALS["GIT_CHECKOUT_LEXER"] = true;
// exec("git -C " . dirname(self::FILE_PATTERN) . " checkout *.php.tokens");
exec("git -C " . dirname(self::FILE_PATTERN) . " checkout *.php.tokens");
}
$result->addListener(new CallbackTestListener(function (Test $test) {
@ -39,7 +39,7 @@ class LexicalGrammarTest extends TestCase {
$fileContents = file_get_contents($testCaseFile);
if (!file_exists($expectedTokensFile)) {
file_put_contents($expectedTokensFile, $fileContents);
// exec("git add " . $expectedTokensFile);
exec("git add " . $expectedTokensFile);
}
$expectedTokens = str_replace("\r\n", "\n", file_get_contents($expectedTokensFile));

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

@ -18,7 +18,7 @@ class ParserGrammarTest extends TestCase {
public function run(TestResult $result = null) : TestResult {
if (!isset($GLOBALS["GIT_CHECKOUT_PARSER"])) {
$GLOBALS["GIT_CHECKOUT_PARSER"] = true;
// exec("git -C " . dirname(self::FILE_PATTERN) . " checkout *.php.tree *.php.diag");
exec("git -C " . dirname(self::FILE_PATTERN) . " checkout *.php.tree *.php.diag");
}
$result->addListener(new CallbackTestListener(function (Test $test) {
@ -44,12 +44,12 @@ class ParserGrammarTest extends TestCase {
$fileContents = file_get_contents($testCaseFile);
if (!file_exists($expectedTokensFile)) {
file_put_contents($expectedTokensFile, $fileContents);
// exec("git add " . $expectedTokensFile);
exec("git add " . $expectedTokensFile);
}
if (!file_exists($expectedDiagnosticsFile)) {
file_put_contents($expectedDiagnosticsFile, $fileContents);
// exec("git add " . $expectedDiagnosticsFile);
exec("git add " . $expectedDiagnosticsFile);
}
$parser = new \Microsoft\PhpParser\Parser();

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

@ -25,7 +25,7 @@ PHP;
public static $sourceFileNode;
public static function setUpBeforeClass() {
public static function setUpBeforeClass(): void {
$parser = new Parser();
self::$sourceFileNode = $parser->parseSourceFile(self::FILE_CONTENTS);
parent::setUpBeforeClass();

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

@ -12,17 +12,21 @@
}
},
{
"ThrowStatement": {
"throwKeyword": {
"kind": "ThrowKeyword",
"textLength": 5
},
"ExpressionStatement": {
"expression": {
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
"ThrowExpression": {
"throwKeyword": {
"kind": "ThrowKeyword",
"textLength": 5
},
"expression": {
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
}
}
},

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

@ -42,11 +42,16 @@
}
],
"questionToken": null,
"typeDeclaration": {
"kind": "IntReservedWord",
"textLength": 3
},
"otherTypeDeclarations": null
"typeDeclarationList": {
"QualifiedNameList": {
"children": [
{
"kind": "IntReservedWord",
"textLength": 3
}
]
}
}
}
},
{

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

@ -49,12 +49,11 @@
"kind": "QuestionToken",
"textLength": 1
},
"typeDeclaration": {
"typeDeclarationList": {
"error": "MissingToken",
"kind": "PropertyType",
"textLength": 0
},
"otherTypeDeclarations": null
}
}
},
{

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

@ -42,13 +42,13 @@
}
],
"questionToken": null,
"typeDeclaration": {
"kind": "IntReservedWord",
"textLength": 3
},
"otherTypeDeclarations": {
"typeDeclarationList": {
"QualifiedNameList": {
"children": [
{
"kind": "IntReservedWord",
"textLength": 3
},
{
"kind": "BarToken",
"textLength": 1

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

@ -12,51 +12,47 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
]
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
}
]
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"semicolon": {
"kind": "SemicolonToken",
"textLength": 1

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

@ -12,24 +12,20 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": null,
"closeParen": {
"error": "MissingToken",
"kind": "CloseParenToken",
"textLength": 0
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": null,
"closeParen": {
"error": "MissingToken",
"kind": "CloseParenToken",
"textLength": 0
},
"semicolon": {
"error": "MissingToken",

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

@ -12,51 +12,47 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
]
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
}
]
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"semicolon": {
"error": "MissingToken",
"kind": "SemicolonToken",

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

@ -42,38 +42,34 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
]
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
}
]
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"semicolon": {
"kind": "SemicolonToken",
"textLength": 1

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

@ -12,38 +12,34 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
]
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
}
]
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"semicolon": {
"kind": "SemicolonToken",
"textLength": 1

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

@ -12,25 +12,21 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"error": "MissingToken",
"kind": "OpenParenToken",
"textLength": 0
},
"expressions": null,
"closeParen": {
"error": "MissingToken",
"kind": "CloseParenToken",
"textLength": 0
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"error": "MissingToken",
"kind": "OpenParenToken",
"textLength": 0
},
"expressions": null,
"closeParen": {
"error": "MissingToken",
"kind": "CloseParenToken",
"textLength": 0
},
"semicolon": {
"kind": "SemicolonToken",

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

@ -12,51 +12,47 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 3
}
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 6
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 3
}
]
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 6
}
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
}
]
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"semicolon": {
"kind": "SemicolonToken",
"textLength": 1

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

@ -12,65 +12,61 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 3
}
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 6
}
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"StringLiteral": {
"startQuote": null,
"children": {
"kind": "StringLiteralToken",
"textLength": 2
},
"endQuote": null
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 3
}
]
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 6
}
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"StringLiteral": {
"startQuote": null,
"children": {
"kind": "StringLiteralToken",
"textLength": 2
},
"endQuote": null
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
}
]
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"semicolon": {
"kind": "SemicolonToken",
"textLength": 1

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

@ -12,56 +12,52 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 3
}
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 6
}
}
},
{
"kind": "CommaToken",
"textLength": 1
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 3
}
]
}
},
{
"kind": "CommaToken",
"textLength": 1
},
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 6
}
}
},
{
"kind": "CommaToken",
"textLength": 1
}
},
"closeParen": {
"error": "MissingToken",
"kind": "CloseParenToken",
"textLength": 0
}
]
}
},
"closeParen": {
"error": "MissingToken",
"kind": "CloseParenToken",
"textLength": 0
},
"semicolon": {
"error": "MissingToken",
"kind": "SemicolonToken",

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

@ -12,38 +12,34 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 3
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 3
}
]
}
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
}
]
}
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"semicolon": {
"kind": "SemicolonToken",
"textLength": 1

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

@ -12,40 +12,36 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"error": "MissingToken",
"kind": "OpenParenToken",
"textLength": 0
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"error": "MissingToken",
"kind": "OpenParenToken",
"textLength": 0
},
"expressions": {
"ExpressionList": {
"children": [
{
"Variable": {
"dollar": null,
"name": {
"kind": "VariableName",
"textLength": 2
}
]
}
}
},
"closeParen": {
"error": "MissingToken",
"kind": "CloseParenToken",
"textLength": 0
}
]
}
},
"closeParen": {
"error": "MissingToken",
"kind": "CloseParenToken",
"textLength": 0
},
"semicolon": {
"kind": "SemicolonToken",
"textLength": 1

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

@ -12,23 +12,19 @@
}
},
{
"ExpressionStatement": {
"expression": {
"UnsetIntrinsicExpression": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": null,
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
}
}
"UnsetStatement": {
"unsetKeyword": {
"kind": "UnsetKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expressions": null,
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"semicolon": {
"kind": "SemicolonToken",

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

@ -249,7 +249,7 @@
"QualifiedNameList": {
"children": [
{
"kind": "IterableKeyword",
"kind": "IterableReservedWord",
"textLength": 8
},
{
@ -406,7 +406,7 @@
"QualifiedNameList": {
"children": [
{
"kind": "IterableKeyword",
"kind": "IterableReservedWord",
"textLength": 8
},
{
@ -611,4 +611,4 @@
"textLength": 0
}
}
}
}

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

@ -72,8 +72,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {

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

@ -116,8 +116,7 @@
"anonymousFunctionUseClause": null,
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {

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

@ -34,8 +34,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {

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

@ -85,7 +85,6 @@
"ArgumentExpression": {
"name": null,
"colonToken": null,
"byRefToken": null,
"dotDotDotToken": null,
"expression": {
"NumericLiteral": {

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

@ -55,8 +55,7 @@
],
"modifiers": [],
"questionToken": null,
"typeDeclaration": null,
"otherTypeDeclarations": null
"typeDeclarationList": null
}
}
],

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

@ -56,8 +56,7 @@
],
"modifiers": [],
"questionToken": null,
"typeDeclaration": null,
"otherTypeDeclarations": null
"typeDeclarationList": null
}
}
],

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

@ -55,8 +55,7 @@
],
"visibilityToken": null,
"questionToken": null,
"typeDeclaration": null,
"otherTypeDeclarations": null,
"typeDeclarationList": null,
"byRefToken": null,
"dotDotDotToken": null,
"variableName": {
@ -78,8 +77,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"arrowToken": {
"error": "MissingToken",
"kind": "DoubleArrowToken",

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

@ -48,7 +48,6 @@
"ArgumentExpression": {
"name": null,
"colonToken": null,
"byRefToken": null,
"dotDotDotToken": null,
"expression": {
"StringLiteral": {

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

@ -120,8 +120,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {

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

@ -91,8 +91,7 @@
}
],
"questionToken": null,
"typeDeclaration": null,
"otherTypeDeclarations": null,
"typeDeclarationList": null,
"propertyElements": {
"ExpressionList": {
"children": [
@ -188,7 +187,6 @@
"ArgumentExpression": {
"name": null,
"colonToken": null,
"byRefToken": null,
"dotDotDotToken": null,
"expression": {
"BinaryExpression": {

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

@ -73,8 +73,7 @@
],
"visibilityToken": null,
"questionToken": null,
"typeDeclaration": null,
"otherTypeDeclarations": null,
"typeDeclarationList": null,
"byRefToken": null,
"dotDotDotToken": null,
"variableName": {
@ -98,8 +97,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {

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

@ -73,8 +73,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {

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

@ -78,8 +78,7 @@
],
"modifiers": [],
"questionToken": null,
"typeDeclaration": null,
"otherTypeDeclarations": null
"typeDeclarationList": null
}
}
],

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

@ -98,8 +98,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"arrowToken": {
"kind": "DoubleArrowToken",
"textLength": 2

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

@ -12,83 +12,79 @@
}
},
{
"ExpressionStatement": {
"expression": {
"EchoExpression": {
"echoKeyword": {
"kind": "EchoKeyword",
"textLength": 4
},
"expressions": {
"ExpressionList": {
"children": [
{
"MatchExpression": {
"matchToken": {
"kind": "MatchKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expression": {
"error": "MissingToken",
"kind": "Expression",
"textLength": 0
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"openBrace": {
"kind": "OpenBraceToken",
"textLength": 1
},
"arms": {
"MatchExpressionArmList": {
"children": [
{
"MatchArm": {
"conditionList": {
"MatchArmConditionList": {
"children": [
{
"StringLiteral": {
"startQuote": null,
"children": {
"kind": "StringLiteralToken",
"textLength": 7
},
"endQuote": null
}
}
]
"EchoStatement": {
"echoKeyword": {
"kind": "EchoKeyword",
"textLength": 4
},
"expressions": {
"ExpressionList": {
"children": [
{
"MatchExpression": {
"matchToken": {
"kind": "MatchKeyword",
"textLength": 5
},
"openParen": {
"kind": "OpenParenToken",
"textLength": 1
},
"expression": {
"error": "MissingToken",
"kind": "Expression",
"textLength": 0
},
"closeParen": {
"kind": "CloseParenToken",
"textLength": 1
},
"openBrace": {
"kind": "OpenBraceToken",
"textLength": 1
},
"arms": {
"MatchExpressionArmList": {
"children": [
{
"MatchArm": {
"conditionList": {
"MatchArmConditionList": {
"children": [
{
"StringLiteral": {
"startQuote": null,
"children": {
"kind": "StringLiteralToken",
"textLength": 7
},
"endQuote": null
}
}
},
"arrowToken": {
"kind": "DoubleArrowToken",
"textLength": 2
},
"body": {
"error": "MissingToken",
"kind": "Expression",
"textLength": 0
}
]
}
},
"arrowToken": {
"kind": "DoubleArrowToken",
"textLength": 2
},
"body": {
"error": "MissingToken",
"kind": "Expression",
"textLength": 0
}
]
}
}
},
"closeBrace": {
"kind": "CloseBraceToken",
"textLength": 1
}
]
}
},
"closeBrace": {
"kind": "CloseBraceToken",
"textLength": 1
}
]
}
}
}
]
}
},
"semicolon": {

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

@ -35,11 +35,16 @@
"attributes": null,
"visibilityToken": null,
"questionToken": null,
"typeDeclaration": {
"kind": "MixedReservedWord",
"textLength": 5
"typeDeclarationList": {
"QualifiedNameList": {
"children": [
{
"kind": "MixedReservedWord",
"textLength": 5
}
]
}
},
"otherTypeDeclarations": null,
"byRefToken": null,
"dotDotDotToken": null,
"variableName": {
@ -62,11 +67,16 @@
"textLength": 1
},
"questionToken": null,
"returnType": {
"kind": "MixedReservedWord",
"textLength": 5
"returnTypeList": {
"QualifiedNameList": {
"children": [
{
"kind": "MixedReservedWord",
"textLength": 5
}
]
}
},
"otherReturnTypes": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {

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

@ -47,7 +47,6 @@
"ArgumentExpression": {
"name": null,
"colonToken": null,
"byRefToken": null,
"dotDotDotToken": null,
"expression": {
"NumericLiteral": {

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

@ -106,8 +106,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {
@ -164,8 +163,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {

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

@ -97,8 +97,7 @@
},
"colonToken": null,
"questionToken": null,
"returnType": null,
"otherReturnTypes": null,
"returnTypeList": null,
"compoundStatementOrSemicolon": {
"CompoundStatementNode": {
"openBrace": {