Skip to content

Commit 2a48939

Browse files
committed
[WIP] v1.0.0 proposal
Drop support for byRefToken in ArgumentExpression - it's a syntax error in php 7.0+ and is prohibited in php 5.4+. Convert the foo and otherFooList to fooList for union types in catch name lists, parameters, properties, and return union types. Remove ThrowStatement in favor of ThrowExpression for php 8.0. Remove EchoExpression in favor of EchoStatement - echo cannot be used as an expression. Remove statement from NamedLabelStatement - it's always null since a named label is a single statement by itself. TODO: Consistently support MissingToken in a single-element list in cases where a non-empty list is required, such as after `?` in types (php 8.0 union types forbid combining `?` with multiple types) TODO: Check for any regressions in diagnostics TODO: Validate that this can be used with real projects
1 parent 35646d5 commit 2a48939

File tree

250 files changed

+2913
-2954
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

250 files changed

+2913
-2954
lines changed

README.md

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@
22
[![Build Status](https://travis-ci.org/Microsoft/tolerant-php-parser.svg?branch=master)](https://travis-ci.org/Microsoft/tolerant-php-parser)
33

44
This is an early-stage PHP parser designed, from the beginning, for IDE usage scenarios (see [Design Goals](#design-goals) for more details). There is
5-
still a ton of work to be done, so at this point, this repo mostly serves as
5+
still a ton of work to be done, so at this point, this repo mostly serves as
66
an experiment and the start of a conversation.
77

88
![image](https://cloud.githubusercontent.com/assets/762848/19023070/4ab01c92-889a-11e6-9bb5-ec1a6816aba2.png)
99

10+
This is the v1 branch, which changes data structures to support syntax added after the initial release for php 7.0.
11+
1012
## Get Started
11-
After you've [configured your machine](docs/GettingStarted.md), you can use the parser to generate and work
13+
After you've [configured your machine](docs/GettingStarted.md), you can use the parser to generate and work
1214
with the Abstract Syntax Tree (AST) via a friendly API.
1315
```php
1416
<?php
@@ -38,17 +40,17 @@ foreach ($astNode->getDescendantNodes() as $descendant) {
3840
// All Nodes link back to their parents, so it's easy to navigate the tree.
3941
$grandParent = $descendant->getParent()->getParent();
4042
var_dump($grandParent->getNodeKindName());
41-
43+
4244
// The AST is fully-representative, and round-trippable to the original source.
4345
// This enables consumers to build reliable formatting and refactoring tools.
4446
var_dump($grandParent->getLeadingCommentAndWhitespaceText());
4547
}
46-
48+
4749
// In addition to retrieving all children or descendants of a Node,
4850
// Nodes expose properties specific to the Node type.
4951
if ($descendant instanceof Node\Expression\EchoExpression) {
5052
$echoKeywordStartPosition = $descendant->echoKeyword->getStartPosition();
51-
// To cut down on memory consumption, positions are represented as a single integer
53+
// To cut down on memory consumption, positions are represented as a single integer
5254
// index into the document, but their line and character positions are easily retrieved.
5355
$lineCharacterPosition = PositionUtilities::getLineCharacterPositionFromPosition(
5456
$echoKeywordStartPosition,
@@ -59,15 +61,15 @@ foreach ($astNode->getDescendantNodes() as $descendant) {
5961
}
6062
```
6163

62-
> Note: [the API](docs/ApiDocumentation.md) is not yet finalized, so please file issues let us know what functionality you want exposed,
64+
> Note: [the API](docs/ApiDocumentation.md) is not yet finalized, so please file issues let us know what functionality you want exposed,
6365
and we'll see what we can do! Also please file any bugs with unexpected behavior in the parse tree. We're still
6466
in our early stages, and any feedback you have is much appreciated :smiley:.
6567

6668
## Design Goals
6769
* Error tolerant design - in IDE scenarios, code is, by definition, incomplete. In the case that invalid code is entered, the
68-
parser should still be able to recover and produce a valid + complete tree, as well as relevant diagnostics.
70+
parser should still be able to recover and produce a valid + complete tree, as well as relevant diagnostics.
6971
* Fast and lightweight (should be able to parse several MB of source code per second,
70-
to leave room for other features).
72+
to leave room for other features).
7173
* Memory-efficient data structures
7274
* Allow for incremental parsing in the future
7375
* Adheres to [PHP language spec](https://github.com/php/php-langspec),
@@ -83,34 +85,34 @@ so each language server operation should be < 50 ms to leave room for all the
8385
confusing, really fast, so readability and debug-ability is high priority.
8486
* Testable - the parser should produce provably valid parse trees. We achieve this by defining and continuously testing
8587
a set of invariants about the tree.
86-
* Friendly and descriptive API to make it easy for others to build on.
88+
* Friendly and descriptive API to make it easy for others to build on.
8789
* Written in PHP - make it as easy as possible for the PHP community to consume and contribute.
8890

8991
## Current Status and Approach
9092
To ensure a sufficient level of correctness at every step of the way, the
9193
parser is being developed using the following incremental approach:
9294

93-
* [x] **Phase 1:** Write lexer that does not support PHP grammar, but supports EOF
95+
* [x] **Phase 1:** Write lexer that does not support PHP grammar, but supports EOF
9496
and Unknown tokens. Write tests for all invariants.
9597
* [x] **Phase 2:** Support PHP lexical grammar, lots of tests
96-
* [x] **Phase 3:** Write a parser that does not support PHP grammar, but produces tree of
98+
* [x] **Phase 3:** Write a parser that does not support PHP grammar, but produces tree of
9799
Error Nodes. Write tests for all invariants.
98100
* [x] **Phase 4:** Support PHP syntactic grammar, lots of tests
99101
* [ ] **Phase 5 (in progress :running:):** Real-world validation and optimization
100102
* [ ] _**Correctness:**_ validate that there are no errors produced on sample codebases, benchmark against other parsers (investigate any instance of disagreement), fuzz-testing
101103
* [ ] _**Performance:**_ profile, benchmark against large PHP applications
102-
* [ ] **Phase 6:** Finalize API to make it as easy as possible for people to consume.
104+
* [ ] **Phase 6:** Finalize API to make it as easy as possible for people to consume.
103105

104106
### Additional notes
105107
A few of the PHP grammatical constructs (namely yield-expression, and template strings)
106108
are not yet supported and there are also other miscellaneous bugs. However, because the parser is error-tolerant,
107109
these errors are handled gracefully, and the resulting tree is otherwise complete. To get a more holistic sense for
108-
where we are, you can run the "validation" test suite (see [Contributing Guidelines](Contributing.md) for more info
110+
where we are, you can run the "validation" test suite (see [Contributing Guidelines](Contributing.md) for more info
109111
on running tests). Or simply, take a look at the current [validation test results](https://travis-ci.org/Microsoft/tolerant-php-parser).
110112

111-
Even though we haven't yet begun the performance optimization stage, we have seen promising results so far,
112-
and have plenty more room for improvement. See [How It Works](docs/HowItWorks.md) for details on our current
113-
approach, and run the [Performance Tests](Contributing.md#running-performance-tests) on your
113+
Even though we haven't yet begun the performance optimization stage, we have seen promising results so far,
114+
and have plenty more room for improvement. See [How It Works](docs/HowItWorks.md) for details on our current
115+
approach, and run the [Performance Tests](Contributing.md#running-performance-tests) on your
114116
own machine to see for yourself.
115117

116118
## Learn more
@@ -119,7 +121,7 @@ own machine to see for yourself.
119121
**:book: [Documentation](docs/GettingStarted.md#getting-started)** - learn how to reference the parser from your project, and how to perform
120122
operations on the AST to answer questions about your code.
121123

122-
**:eyes: [Syntax Visualizer Tool](syntax-visualizer/client#php-parser-syntax-visualizer-tool)** - get a more tangible feel for the AST. Get creative - see if you can break it!
124+
**:eyes: [Syntax Visualizer Tool](syntax-visualizer/client#php-parser-syntax-visualizer-tool)** - get a more tangible feel for the AST. Get creative - see if you can break it!
123125

124126
**:chart_with_upwards_trend: [Current Status and Approach](#current-status-and-approach)** - how much of the grammar is supported? Performance? Memory? API stability?
125127

@@ -131,10 +133,10 @@ operations on the AST to answer questions about your code.
131133
* [Validation Strategy](docs/HowItWorks.md#validation-strategy)
132134

133135
**:sparkling_heart: [Contribute!](Contributing.md)** - learn how to get involved, check out some pointers to educational commits that'll
134-
help you ramp up on the codebase (even if you've never worked on a parser before),
136+
help you ramp up on the codebase (even if you've never worked on a parser before),
135137
and recommended workflows that make it easier to iterate.
136138

137139
---
138-
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
139-
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
140+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
141+
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact
140142
[[email protected]](mailto:[email protected]) with any additional questions or comments.

composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
"description": "Tolerant PHP-to-AST parser designed for IDE usage scenarios",
44
"type": "library",
55
"require": {
6-
"php": ">=7.0"
6+
"php": ">=7.2"
77
},
88
"require-dev": {
9-
"phpunit/phpunit": "^6.4|^7.5.20"
9+
"phpunit/phpunit": "^7.5.20"
1010
},
1111
"license": "MIT",
1212
"authors": [

src/Node/CatchClause.php

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,17 @@
77
namespace Microsoft\PhpParser\Node;
88

99
use Microsoft\PhpParser\Node;
10+
use Microsoft\PhpParser\Node\DelimitedList\QualifiedNameList;
11+
use Microsoft\PhpParser\MissingToken;
1012
use Microsoft\PhpParser\Token;
1113

1214
class CatchClause extends Node {
1315
/** @var Token */
1416
public $catch;
1517
/** @var Token */
1618
public $openParen;
17-
/** @var QualifiedName */
18-
public $qualifiedName;
19-
/**
20-
* @var QualifiedName[]|Token[] Remaining tokens and qualified names in the catch clause
21-
* (e.g. `catch (FirstException|SecondException $x)` would contain
22-
* the representation of `|SecondException`)
23-
*
24-
* TODO: In the next backwards incompatible release, replace qualifiedName with qualifiedNameList?
25-
*/
26-
public $otherQualifiedNameList;
19+
/** @var QualifiedNameList[]|MissingToken */
20+
public $qualifiedNameList;
2721
/** @var Token|null */
2822
public $variableName;
2923
/** @var Token */
@@ -34,8 +28,7 @@ class CatchClause extends Node {
3428
const CHILD_NAMES = [
3529
'catch',
3630
'openParen',
37-
'qualifiedName',
38-
'otherQualifiedNameList',
31+
'qualifiedNameList',
3932
'variableName',
4033
'closeParen',
4134
'compoundStatement'

src/Node/Expression/AnonymousFunctionCreationExpression.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ class AnonymousFunctionCreationExpression extends Expression implements Function
3838
// FunctionReturnType
3939
'colonToken',
4040
'questionToken',
41-
'returnType',
42-
'otherReturnTypes',
41+
'returnTypeList',
4342

4443
// FunctionBody
4544
'compoundStatementOrSemicolon'

src/Node/Expression/ArgumentExpression.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@
1010
use Microsoft\PhpParser\Token;
1111

1212
class ArgumentExpression extends Expression {
13-
/** @var Token|null for php named arguments. If this is set, byRefToken and dotDotDotToken will not be set. */
13+
/** @var Token|null for php named arguments. If this is set, dotDotDotToken will not be set. */
1414
public $name;
1515

1616
/** @var Token|null */
1717
public $colonToken;
1818

19-
/** @var Token|null */
20-
public $byRefToken; // TODO removed in newer versions of PHP. Also only accept variable, not expression if byRef
21-
2219
/** @var Token|null */
2320
public $dotDotDotToken;
2421

@@ -28,7 +25,6 @@ class ArgumentExpression extends Expression {
2825
const CHILD_NAMES = [
2926
'name',
3027
'colonToken',
31-
'byRefToken',
3228
'dotDotDotToken',
3329
'expression'
3430
];

src/Node/Expression/ArrowFunctionCreationExpression.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ class ArrowFunctionCreationExpression extends Expression implements FunctionLike
4040
// FunctionReturnType
4141
'colonToken',
4242
'questionToken',
43-
'returnType',
44-
'otherReturnTypes',
43+
'returnTypeList',
4544

4645
// body
4746
'arrowToken',

src/Node/FunctionReturnType.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111
trait FunctionReturnType {
1212
/** @var Token */
1313
public $colonToken;
14+
// TODO: This may be the wrong choice if ?type can ever be mixed with other types in union types
1415
/** @var Token|null */
1516
public $questionToken;
16-
/** @var Token|QualifiedName */
17-
public $returnType;
18-
/** @var DelimitedList\QualifiedNameList|null TODO: Merge with returnType in a future backwards incompatible release */
19-
public $otherReturnTypes;
17+
/** @var DelimitedList\QualifiedNameList|null */
18+
public $returnTypeList;
2019
}

src/Node/MethodDeclaration.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ class MethodDeclaration extends Node implements FunctionLike, ModifiedTypeInterf
3434
// FunctionReturnType
3535
'colonToken',
3636
'questionToken',
37-
'returnType',
38-
'otherReturnTypes',
37+
'returnTypeList',
3938

4039
// FunctionBody
4140
'compoundStatementOrSemicolon'

src/Node/Parameter.php

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

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\MissingToken;
910
use Microsoft\PhpParser\Node;
1011
use Microsoft\PhpParser\Token;
1112

@@ -16,13 +17,8 @@ class Parameter extends Node {
1617
public $visibilityToken;
1718
/** @var Token|null */
1819
public $questionToken;
19-
/** @var QualifiedName|Token|null */
20-
public $typeDeclaration;
21-
/**
22-
* @var DelimitedList\QualifiedNameList a list of other types, to support php 8 union types while remaining backwards compatible.
23-
* TODO: Merge with typeDeclaration in a future backwards incompatible release.
24-
*/
25-
public $otherTypeDeclarations;
20+
/** @var DelimitedList\QualifiedNameList|MissingToken|null */
21+
public $typeDeclarationList;
2622
/** @var Token|null */
2723
public $byRefToken;
2824
/** @var Token|null */
@@ -38,8 +34,7 @@ class Parameter extends Node {
3834
'attributes',
3935
'visibilityToken',
4036
'questionToken',
41-
'typeDeclaration',
42-
'otherTypeDeclarations',
37+
'typeDeclarationList',
4338
'byRefToken',
4439
'dotDotDotToken',
4540
'variableName',

src/Node/PropertyDeclaration.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66

77
namespace Microsoft\PhpParser\Node;
88

9+
use Microsoft\PhpParser\MissingToken;
910
use Microsoft\PhpParser\ModifiedTypeInterface;
1011
use Microsoft\PhpParser\ModifiedTypeTrait;
1112
use Microsoft\PhpParser\Node;
13+
use Microsoft\PhpParser\Node\DelimitedList\QualifiedNameList;
1214
use Microsoft\PhpParser\Token;
1315

1416
class PropertyDeclaration extends Node implements ModifiedTypeInterface {
@@ -20,14 +22,8 @@ class PropertyDeclaration extends Node implements ModifiedTypeInterface {
2022
/** @var Token|null question token for PHP 7.4 type declaration */
2123
public $questionToken;
2224

23-
/** @var QualifiedName|Token|null */
24-
public $typeDeclaration;
25-
26-
/**
27-
* @var DelimitedList\QualifiedNameList|null
28-
* TODO: Unify with typeDeclaration in a future backwards incompatible release
29-
*/
30-
public $otherTypeDeclarations;
25+
/** @var QualifiedNameList|MissingToken|null */
26+
public $typeDeclarationList;
3127

3228
/** @var DelimitedList\ExpressionList */
3329
public $propertyElements;
@@ -39,8 +35,7 @@ class PropertyDeclaration extends Node implements ModifiedTypeInterface {
3935
'attributes',
4036
'modifiers',
4137
'questionToken',
42-
'typeDeclaration',
43-
'otherTypeDeclarations',
38+
'typeDeclarationList',
4439
'propertyElements',
4540
'semicolon'
4641
];

0 commit comments

Comments
 (0)