Skip to content

Commit 453e48f

Browse files
committed
Implemented separate parsing of useClauses and useGroupClauses
1 parent bc5ea05 commit 453e48f

39 files changed

+1851
-1377
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
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\DelimitedList;
8+
9+
use Microsoft\PhpParser\Node\DelimitedList;
10+
11+
class NamespaceUseClauseList extends DelimitedList {
12+
}

src/Node/NamespaceUseClause.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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;
8+
9+
use Microsoft\PhpParser\Node;
10+
use Microsoft\PhpParser\Node\DelimitedList;
11+
use Microsoft\PhpParser\Token;
12+
13+
class NamespaceUseClause extends Node {
14+
/** @var QualifiedName */
15+
public $namespaceName;
16+
/** @var NamespaceAliasingClause */
17+
public $namespaceAliasingClause;
18+
/** @var Token | null */
19+
public $openBrace;
20+
/** @var DelimitedList\NamespaceUseGroupClauseList | null */
21+
public $groupClauses;
22+
/** @var Token | null */
23+
public $closeBrace;
24+
}

src/Node/Statement/NamespaceUseDeclaration.php

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@
66

77
namespace Microsoft\PhpParser\Node\Statement;
88

9-
use Microsoft\PhpParser\Node\DelimitedList;
10-
use Microsoft\PhpParser\Node\NamespaceAliasingClause;
11-
use Microsoft\PhpParser\Node\QualifiedName;
9+
use Microsoft\PhpParser\Node\DelimitedList\NamespaceUseClauseList;
1210
use Microsoft\PhpParser\Node\StatementNode;
1311
use Microsoft\PhpParser\Token;
1412

@@ -17,16 +15,8 @@ class NamespaceUseDeclaration extends StatementNode {
1715
public $useKeyword;
1816
/** @var Token */
1917
public $functionOrConst;
20-
/** @var QualifiedName */
21-
public $namespaceName;
22-
/** @var NamespaceAliasingClause */
23-
public $namespaceAliasingClause;
24-
/** @var Token | null */
25-
public $openBrace;
26-
/** @var DelimitedList\NamespaceUseGroupClauseList | null */
27-
public $groupClauses;
28-
/** @var Token | null */
29-
public $closeBrace;
18+
/** @var NamespaceUseClauseList */
19+
public $useClauses;
3020
/** @var Token */
3121
public $semicolon;
3222
}

src/Parser.php

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@
6666
use Microsoft\PhpParser\Node\ReservedWord;
6767
use Microsoft\PhpParser\Node\StringLiteral;
6868
use Microsoft\PhpParser\Node\MethodDeclaration;
69-
use Microsoft\PhpParser\Node;
7069
use Microsoft\PhpParser\Node\Parameter;
7170
use Microsoft\PhpParser\Node\QualifiedName;
7271
use Microsoft\PhpParser\Node\RelativeSpecifier;
@@ -103,6 +102,7 @@
103102
use Microsoft\PhpParser\Node\TraitSelectOrAliasClause;
104103
use Microsoft\PhpParser\Node\TraitUseClause;
105104
use Microsoft\PhpParser\Node\UseVariableName;
105+
use Microsoft\PhpParser\Node\NamespaceUseClause;
106106

107107
class Parser {
108108
private $lexer;
@@ -2556,28 +2556,41 @@ private function parseNamespaceDefinition($parentNode) {
25562556
private function parseNamespaceUseDeclaration($parentNode) {
25572557
$namespaceUseDeclaration = new NamespaceUseDeclaration();
25582558
$namespaceUseDeclaration->parent = $parentNode;
2559-
25602559
$namespaceUseDeclaration->useKeyword = $this->eat(TokenKind::UseKeyword);
25612560
$namespaceUseDeclaration->functionOrConst = $this->eatOptional(TokenKind::FunctionKeyword, TokenKind::ConstKeyword);
2562-
if($this->lookahead(TokenKind::CommaToken)) {
2563-
$namespaceUseDeclaration->groupClauses = $this->parseNamespaceUseGroupClauses($namespaceUseDeclaration);
2564-
}
2565-
else {
2566-
$namespaceUseDeclaration->namespaceName = $this->parseQualifiedName($namespaceUseDeclaration);
2567-
if ($this->checkToken(TokenKind::AsKeyword)) {
2568-
$namespaceUseDeclaration->namespaceAliasingClause = $this->parseNamespaceAliasingClause($namespaceUseDeclaration);
2569-
} elseif ($this->checkToken(TokenKind::OpenBraceToken)) {
2570-
$namespaceUseDeclaration->openBrace = $this->eat(TokenKind::OpenBraceToken);
2571-
$namespaceUseDeclaration->groupClauses = $this->parseNamespaceUseGroupClauses($namespaceUseDeclaration);
2572-
$namespaceUseDeclaration->closeBrace = $this->eat(TokenKind::CloseBraceToken);
2573-
}
2574-
}
2561+
$namespaceUseDeclaration->useClauses = $this->parseNamespaceUseClauseList($namespaceUseDeclaration);
25752562
$namespaceUseDeclaration->semicolon = $this->eatSemicolonOrAbortStatement();
25762563
return $namespaceUseDeclaration;
25772564
}
25782565

2579-
private function parseNamespaceUseGroupClauses(NamespaceUseDeclaration $namespaceUseDeclaration) {
2580-
$groupClauses = $this->parseDelimitedList(
2566+
private function parseNamespaceUseClauseList($parentNode) {
2567+
return $this->parseDelimitedList(
2568+
DelimitedList\NamespaceUseClauseList::class,
2569+
TokenKind::CommaToken,
2570+
function ($token) {
2571+
return $this->isQualifiedNameStart($token) || $token->kind === TokenKind::FunctionKeyword || $token->kind === TokenKind::ConstKeyword;
2572+
},
2573+
function ($parentNode) {
2574+
$namespaceUseClause = new NamespaceUseClause();
2575+
$namespaceUseClause->parent = $parentNode;
2576+
$namespaceUseClause->namespaceName = $this->parseQualifiedName($namespaceUseClause);
2577+
if ($this->checkToken(TokenKind::AsKeyword)) {
2578+
$namespaceUseClause->namespaceAliasingClause = $this->parseNamespaceAliasingClause($namespaceUseClause);
2579+
}
2580+
if ($this->checkToken(TokenKind::OpenBraceToken)) {
2581+
$namespaceUseClause->openBrace = $this->eat(TokenKind::OpenBraceToken);
2582+
$namespaceUseClause->groupClauses = $this->parseNamespaceUseGroupClauseList($namespaceUseClause);
2583+
$namespaceUseClause->closeBrace = $this->eat(TokenKind::CloseBraceToken);
2584+
}
2585+
2586+
return $namespaceUseClause;
2587+
},
2588+
$parentNode
2589+
);
2590+
}
2591+
2592+
private function parseNamespaceUseGroupClauseList($parentNode) {
2593+
return $this->parseDelimitedList(
25812594
DelimitedList\NamespaceUseGroupClauseList::class,
25822595
TokenKind::CommaToken,
25832596
function ($token) {
@@ -2595,9 +2608,8 @@ function ($parentNode) {
25952608

25962609
return $namespaceUseGroupClause;
25972610
},
2598-
$namespaceUseDeclaration
2611+
$parentNode
25992612
);
2600-
return $groupClauses;
26012613
}
26022614

26032615
private function parseNamespaceAliasingClause($parentNode) {

tests/cases/parser/namespaceUseDeclaration1.php.tree

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,44 @@
2121
"kind": "FunctionKeyword",
2222
"textLength": 8
2323
},
24-
"namespaceName": {
25-
"QualifiedName": {
26-
"globalSpecifier": null,
27-
"relativeSpecifier": null,
28-
"nameParts": {
29-
"QualifiedNameParts": {
30-
"children": [
31-
{
32-
"kind": "Name",
33-
"textLength": 1
24+
"useClauses": {
25+
"NamespaceUseClauseList": {
26+
"children": [
27+
{
28+
"NamespaceUseClause": {
29+
"namespaceName": {
30+
"QualifiedName": {
31+
"globalSpecifier": null,
32+
"relativeSpecifier": null,
33+
"nameParts": {
34+
"QualifiedNameParts": {
35+
"children": [
36+
{
37+
"kind": "Name",
38+
"textLength": 1
39+
},
40+
{
41+
"kind": "BackslashToken",
42+
"textLength": 1
43+
},
44+
{
45+
"kind": "Name",
46+
"textLength": 1
47+
}
48+
]
49+
}
50+
}
51+
}
3452
},
35-
{
36-
"kind": "BackslashToken",
37-
"textLength": 1
38-
},
39-
{
40-
"kind": "Name",
41-
"textLength": 1
42-
}
43-
]
53+
"namespaceAliasingClause": null,
54+
"openBrace": null,
55+
"groupClauses": null,
56+
"closeBrace": null
57+
}
4458
}
45-
}
59+
]
4660
}
4761
},
48-
"namespaceAliasingClause": null,
49-
"openBrace": null,
50-
"groupClauses": null,
51-
"closeBrace": null,
5262
"semicolon": {
5363
"kind": "SemicolonToken",
5464
"textLength": 1

tests/cases/parser/namespaceUseDeclaration10.php.tree

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,37 @@
1818
"textLength": 3
1919
},
2020
"functionOrConst": null,
21-
"namespaceName": null,
22-
"namespaceAliasingClause": {
23-
"NamespaceAliasingClause": {
24-
"asKeyword": {
25-
"kind": "AsKeyword",
26-
"textLength": 2
27-
},
28-
"name": {
29-
"kind": "Name",
30-
"textLength": 1
21+
"useClauses": null,
22+
"semicolon": {
23+
"error": "MissingToken",
24+
"kind": "SemicolonToken",
25+
"textLength": 0
26+
}
27+
}
28+
},
29+
{
30+
"error": "SkippedToken",
31+
"kind": "AsKeyword",
32+
"textLength": 2
33+
},
34+
{
35+
"ExpressionStatement": {
36+
"expression": {
37+
"QualifiedName": {
38+
"globalSpecifier": null,
39+
"relativeSpecifier": null,
40+
"nameParts": {
41+
"QualifiedNameParts": {
42+
"children": [
43+
{
44+
"kind": "Name",
45+
"textLength": 1
46+
}
47+
]
48+
}
3149
}
3250
}
3351
},
34-
"openBrace": null,
35-
"groupClauses": null,
36-
"closeBrace": null,
3752
"semicolon": {
3853
"kind": "SemicolonToken",
3954
"textLength": 1

0 commit comments

Comments
 (0)