Skip to content

Commit 6f49c64

Browse files
authored
Merge pull request microsoft#379 from TysonAndre/fix-base-clause
Add MissingToken for missing QualifiedName
2 parents 9d9b602 + 7e6cb20 commit 6f49c64

10 files changed

+166
-16
lines changed

src/Parser.php

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3307,7 +3307,7 @@ private function parseClassBaseClause($parentNode) {
33073307
if ($classBaseClause->extendsKeyword === null) {
33083308
return null;
33093309
}
3310-
$classBaseClause->baseClass = $this->parseQualifiedName($classBaseClause);
3310+
$classBaseClause->baseClass = $this->parseQualifiedName($classBaseClause) ?? new MissingToken(TokenKind::QualifiedName, $this->token->fullStart);
33113311

33123312
return $classBaseClause;
33133313
}
@@ -3500,12 +3500,18 @@ private function parseNamespaceDefinition($parentNode) {
35003500
$namespaceDefinition->namespaceKeyword = $this->eat1(TokenKind::NamespaceKeyword);
35013501

35023502
if (!$this->checkToken(TokenKind::NamespaceKeyword)) {
3503-
$namespaceDefinition->name = $this->parseQualifiedName($namespaceDefinition); // TODO only optional with compound statement block
3503+
$namespaceDefinition->name = $this->parseQualifiedName($namespaceDefinition);
35043504
}
35053505

3506-
$namespaceDefinition->compoundStatementOrSemicolon =
3507-
$this->checkToken(TokenKind::OpenBraceToken) ?
3508-
$this->parseCompoundStatement($namespaceDefinition) : $this->eatSemicolonOrAbortStatement();
3506+
if ($this->checkToken(TokenKind::OpenBraceToken)) {
3507+
$namespaceDefinition->compoundStatementOrSemicolon = $this->parseCompoundStatement($namespaceDefinition);
3508+
} else {
3509+
if (!$namespaceDefinition->name) {
3510+
// only optional with compound statement block
3511+
$namespaceDefinition->name = new MissingToken(TokenKind::QualifiedName, $this->token->fullStart);
3512+
}
3513+
$namespaceDefinition->compoundStatementOrSemicolon = $this->eatSemicolonOrAbortStatement();
3514+
}
35093515

35103516
return $namespaceDefinition;
35113517
}
@@ -3531,13 +3537,17 @@ function ($parentNode) {
35313537
$namespaceUseClause = new NamespaceUseClause();
35323538
$namespaceUseClause->parent = $parentNode;
35333539
$namespaceUseClause->namespaceName = $this->parseQualifiedName($namespaceUseClause);
3534-
if ($this->checkToken(TokenKind::AsKeyword)) {
3535-
$namespaceUseClause->namespaceAliasingClause = $this->parseNamespaceAliasingClause($namespaceUseClause);
3536-
}
3537-
elseif ($this->checkToken(TokenKind::OpenBraceToken)) {
3540+
if ($this->checkToken(TokenKind::OpenBraceToken)) {
35383541
$namespaceUseClause->openBrace = $this->eat1(TokenKind::OpenBraceToken);
35393542
$namespaceUseClause->groupClauses = $this->parseNamespaceUseGroupClauseList($namespaceUseClause);
35403543
$namespaceUseClause->closeBrace = $this->eat1(TokenKind::CloseBraceToken);
3544+
} else {
3545+
if (!$namespaceUseClause->namespaceName) {
3546+
$namespaceUseClause->namespaceName = new MissingToken(TokenKind::QualifiedName, $this->token->fullStart);
3547+
}
3548+
if ($this->checkToken(TokenKind::AsKeyword)) {
3549+
$namespaceUseClause->namespaceAliasingClause = $this->parseNamespaceAliasingClause($namespaceUseClause);
3550+
}
35413551
}
35423552

35433553
return $namespaceUseClause;
@@ -3558,7 +3568,7 @@ function ($parentNode) {
35583568
$namespaceUseGroupClause->parent = $parentNode;
35593569

35603570
$namespaceUseGroupClause->functionOrConst = $this->eatOptional(TokenKind::FunctionKeyword, TokenKind::ConstKeyword);
3561-
$namespaceUseGroupClause->namespaceName = $this->parseQualifiedName($namespaceUseGroupClause);
3571+
$namespaceUseGroupClause->namespaceName = $this->parseQualifiedName($namespaceUseGroupClause) ?? new MissingToken(TokenKind::QualifiedName, $this->token->fullStart);
35623572
if ($this->checkToken(TokenKind::AsKeyword)) {
35633573
$namespaceUseGroupClause->namespaceAliasingClause = $this->parseNamespaceAliasingClause($namespaceUseGroupClause);
35643574
}
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
[]
1+
[
2+
{
3+
"kind": 0,
4+
"message": "'QualifiedName' expected.",
5+
"start": 48,
6+
"length": 0
7+
}
8+
]

tests/cases/parser/classBaseClause2.php.tree

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@
3030
"kind": "ExtendsKeyword",
3131
"textLength": 7
3232
},
33-
"baseClass": null
33+
"baseClass": {
34+
"error": "MissingToken",
35+
"kind": "QualifiedName",
36+
"textLength": 0
37+
}
3438
}
3539
},
3640
"classInterfaceClause": null,
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,8 @@
1-
[]
1+
[
2+
{
3+
"kind": 0,
4+
"message": "'QualifiedName' expected.",
5+
"start": 64,
6+
"length": 0
7+
}
8+
]

tests/cases/parser/namespaceDefinition2.php.tree

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
"kind": "NamespaceKeyword",
1818
"textLength": 9
1919
},
20-
"name": null,
20+
"name": {
21+
"error": "MissingToken",
22+
"kind": "QualifiedName",
23+
"textLength": 0
24+
},
2125
"compoundStatementOrSemicolon": {
2226
"kind": "SemicolonToken",
2327
"textLength": 1

tests/cases/parser/namespaceDefinition4.php.diag

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
11
[
2+
{
3+
"kind": 0,
4+
"message": "'QualifiedName' expected.",
5+
"start": 16,
6+
"length": 0
7+
},
28
{
39
"kind": 0,
410
"message": "';' expected.",
511
"start": 16,
612
"length": 0
713
},
14+
{
15+
"kind": 0,
16+
"message": "'QualifiedName' expected.",
17+
"start": 26,
18+
"length": 0
19+
},
820
{
921
"kind": 0,
1022
"message": "';' expected.",

tests/cases/parser/namespaceDefinition4.php.tree

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
"kind": "NamespaceKeyword",
1818
"textLength": 9
1919
},
20-
"name": null,
20+
"name": {
21+
"error": "MissingToken",
22+
"kind": "QualifiedName",
23+
"textLength": 0
24+
},
2125
"compoundStatementOrSemicolon": {
2226
"error": "MissingToken",
2327
"kind": "SemicolonToken",
@@ -31,7 +35,11 @@
3135
"kind": "NamespaceKeyword",
3236
"textLength": 9
3337
},
34-
"name": null,
38+
"name": {
39+
"error": "MissingToken",
40+
"kind": "QualifiedName",
41+
"textLength": 0
42+
},
3543
"compoundStatementOrSemicolon": {
3644
"error": "MissingToken",
3745
"kind": "SemicolonToken",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<?php
2+
use A\{ function };
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[
2+
{
3+
"kind": 0,
4+
"message": "'QualifiedName' expected.",
5+
"start": 22,
6+
"length": 0
7+
}
8+
]
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
"NamespaceUseDeclaration": {
16+
"useKeyword": {
17+
"kind": "UseKeyword",
18+
"textLength": 3
19+
},
20+
"functionOrConst": null,
21+
"useClauses": {
22+
"NamespaceUseClauseList": {
23+
"children": [
24+
{
25+
"NamespaceUseClause": {
26+
"namespaceName": {
27+
"QualifiedName": {
28+
"globalSpecifier": null,
29+
"relativeSpecifier": null,
30+
"nameParts": [
31+
{
32+
"kind": "Name",
33+
"textLength": 1
34+
},
35+
{
36+
"kind": "BackslashToken",
37+
"textLength": 1
38+
}
39+
]
40+
}
41+
},
42+
"namespaceAliasingClause": null,
43+
"openBrace": {
44+
"kind": "OpenBraceToken",
45+
"textLength": 1
46+
},
47+
"groupClauses": {
48+
"NamespaceUseGroupClauseList": {
49+
"children": [
50+
{
51+
"NamespaceUseGroupClause": {
52+
"functionOrConst": {
53+
"kind": "FunctionKeyword",
54+
"textLength": 8
55+
},
56+
"namespaceName": {
57+
"error": "MissingToken",
58+
"kind": "QualifiedName",
59+
"textLength": 0
60+
},
61+
"namespaceAliasingClause": null
62+
}
63+
}
64+
]
65+
}
66+
},
67+
"closeBrace": {
68+
"kind": "CloseBraceToken",
69+
"textLength": 1
70+
}
71+
}
72+
}
73+
]
74+
}
75+
},
76+
"semicolon": {
77+
"kind": "SemicolonToken",
78+
"textLength": 1
79+
}
80+
}
81+
}
82+
],
83+
"endOfFileToken": {
84+
"kind": "EndOfFileToken",
85+
"textLength": 0
86+
}
87+
}
88+
}

0 commit comments

Comments
 (0)