Skip to content

Commit f63081a

Browse files
committed
Partial documentation update
1 parent 44c6a97 commit f63081a

File tree

4 files changed

+65
-47
lines changed

4 files changed

+65
-47
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ PHP Parser
33

44
[![Coverage Status](https://coveralls.io/repos/github/nikic/PHP-Parser/badge.svg?branch=master)](https://coveralls.io/github/nikic/PHP-Parser?branch=master)
55

6-
This is a PHP 5.2 to PHP 8.1 parser written in PHP. Its purpose is to simplify static code analysis and
6+
This is a PHP parser written in PHP. Its purpose is to simplify static code analysis and
77
manipulation.
88

99
[Documentation for version 5.x][doc_master] (in development; for running on PHP >= 7.1; for parsing PHP 7.0 to PHP 8.2, with limited support for parsing PHP 5.x).
1010

11-
[**Documentation for version 4.x**][doc_4_x] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.1).
11+
[**Documentation for version 4.x**][doc_4_x] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.2).
1212

1313
[Documentation for version 3.x][doc_3_x] (unsupported; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2).
1414

@@ -17,12 +17,12 @@ Features
1717

1818
The main features provided by this library are:
1919

20-
* Parsing PHP 5, PHP 7, and PHP 8 code into an abstract syntax tree (AST).
20+
* Parsing PHP 7, and PHP 8 code into an abstract syntax tree (AST).
2121
* Invalid code can be parsed into a partial AST.
2222
* The AST contains accurate location information.
2323
* Dumping the AST in human-readable form.
2424
* Converting an AST back to PHP code.
25-
* Experimental: Formatting can be preserved for partially changed ASTs.
25+
* Formatting can be preserved for partially changed ASTs.
2626
* Infrastructure to traverse and modify ASTs.
2727
* Resolution of namespaced names.
2828
* Evaluation of constant expressions.
@@ -53,7 +53,7 @@ function test($foo)
5353
}
5454
CODE;
5555

56-
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
56+
$parser = (new ParserFactory())->createForNewestSupportedVersion();
5757
try {
5858
$ast = $parser->parse($code);
5959
} catch (Error $error) {

doc/0_Introduction.markdown

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Introduction
22
============
33

4-
This project is a PHP 5.2 to PHP 8.0 parser **written in PHP itself**.
4+
This project is a PHP parser **written in PHP itself**.
55

66
What is this for?
77
-----------------
@@ -26,16 +26,29 @@ programmatic PHP code analysis are incidentally PHP developers, not C developers
2626
What can it parse?
2727
------------------
2828

29-
The parser supports parsing PHP 5.2-8.0, with the following exceptions:
29+
The parser supports parsing PHP 7 and PHP 8 code, with the following exceptions:
3030

3131
* Namespaced names containing whitespace (e.g. `Foo \ Bar` instead of `Foo\Bar`) are not supported.
3232
These are illegal in PHP 8, but are legal in earlier versions. However, PHP-Parser does not
3333
support them for any version.
3434

35+
PHP-Parser 4.x had full support for parsing PHP 5. PHP-Parser 5.x has only limited support, with the
36+
following caveats:
37+
38+
* Some variable expressions like `$$foo[0]` are valid in both PHP 5 and PHP 7, but have different
39+
interpretation. In such cases, the PHP 7 AST will always be constructed (using `($$foo)[0]`
40+
rather than `${$foo[0]}`).
41+
* Declarations of the form `global $$var[0]` are not supported in PHP 7 and will cause a parse
42+
error. In error recovery mode, it is possible to continue parsing after such declarations.
43+
3544
As the parser is based on the tokens returned by `token_get_all` (which is only able to lex the PHP
3645
version it runs on), additionally a wrapper for emulating tokens from newer versions is provided.
37-
This allows to parse PHP 7.4 source code running on PHP 7.0, for example. This emulation is somewhat
38-
hacky and not perfect, but it should work well on any sane code.
46+
This allows to parse PHP 8.0 source code running on PHP 7.1, for example. This emulation is not
47+
perfect, but works well in practice.
48+
49+
Finally, it should be noted that the parser aims to accept all valid code, not reject all invalid
50+
code. It will generally accept code that is only valid in newer versions (even when targeting an
51+
older one), and accept code that is syntactically correct, but would result in a compiler error.
3952

4053
What output does it produce?
4154
----------------------------
@@ -63,7 +76,7 @@ This matches the structure of the code: An echo statement, which takes two strin
6376
with the values `Hi` and `World`.
6477

6578
You can also see that the AST does not contain any whitespace information (but most comments are saved).
66-
So using it for formatting analysis is not possible.
79+
However, it does retain accurate position information, which can be used to inspect precise formatting.
6780

6881
What else can it do?
6982
--------------------
@@ -74,7 +87,7 @@ Apart from the parser itself this package also bundles support for some other, r
7487
that "pretty printing" does not imply that the output is especially pretty. It's just how it's
7588
called ;)
7689
* Support for serializing and unserializing the node tree to JSON
77-
* Support for dumping the node tree in a human readable form (see the section above for an
90+
* Support for dumping the node tree in a human-readable form (see the section above for an
7891
example of how the output looks like)
7992
* Infrastructure for traversing and changing the AST (node traverser and node visitors)
8093
* A node visitor for resolving namespaced names

doc/2_Usage_of_basic_components.markdown

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ To bootstrap the library, include the autoloader generated by composer:
1212
require 'path/to/vendor/autoload.php';
1313
```
1414

15-
Additionally you may want to set the `xdebug.max_nesting_level` ini option to a higher value:
15+
Additionally, you may want to set the `xdebug.max_nesting_level` ini option to a higher value:
1616

1717
```php
1818
ini_set('xdebug.max_nesting_level', 3000);
@@ -29,25 +29,29 @@ In order to parse code, you first have to create a parser instance:
2929

3030
```php
3131
use PhpParser\ParserFactory;
32-
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
33-
```
32+
use PhpParser\PhpVersion;
33+
34+
// Parser for the version you are running on.
35+
$parser = (new ParserFactory())->createForHostVersion();
3436

35-
The factory accepts a kind argument, that determines how different PHP versions are treated:
37+
// Parser for the newest PHP version supported by the PHP-Parser library.
38+
$parser = (new ParserFactory())->createForNewestSupportedVersion();
3639

37-
Kind | Behavior
38-
-----|---------
39-
`ParserFactory::PREFER_PHP7` | Try to parse code as PHP 7. If this fails, try to parse it as PHP 5.
40-
`ParserFactory::PREFER_PHP5` | Try to parse code as PHP 5. If this fails, try to parse it as PHP 7.
41-
`ParserFactory::ONLY_PHP7` | Parse code as PHP 7.
42-
`ParserFactory::ONLY_PHP5` | Parse code as PHP 5.
40+
// Parser for a specific PHP version.
41+
$parser = (new ParserFactory())->createForVersion(PhpVersion::fromString('8.1'));
42+
```
4343

44-
Unless you have a strong reason to use something else, `PREFER_PHP7` is a reasonable default.
44+
Which version you should target depends on your use case. In many cases you will want to use the
45+
host version, as people typically analyze code for the version they are running on. However, when
46+
analyzing arbitrary code you are usually best off using the newest supported version, which tends
47+
to accept the widest range of code (unless there are breaking changes in PHP).
4548

46-
The `create()` method optionally accepts a `Lexer` instance as the second argument. Some use cases
47-
that require customized lexers are discussed in the [lexer documentation](component/Lexer.markdown).
49+
The `createXYZ()` methods optionally accept an array of lexer options. Some use cases that require
50+
customized lexer options are discussed in the [lexer documentation](component/Lexer.markdown).
4851

49-
Subsequently you can pass PHP code (including the opening `<?php` tag) to the `parse` method in order to
50-
create a syntax tree. If a syntax error is encountered, an `PhpParser\Error` exception will be thrown:
52+
Subsequently, you can pass PHP code (including the opening `<?php` tag) to the `parse()` method in
53+
order to create a syntax tree. If a syntax error is encountered, an `PhpParser\Error` exception will
54+
be thrown by default:
5155

5256
```php
5357
<?php
@@ -62,7 +66,7 @@ function printLine($msg) {
6266
printLine('Hello World!!!');
6367
CODE;
6468

65-
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
69+
$parser = (new ParserFactory())->createForHostVersion();
6670

6771
try {
6872
$stmts = $parser->parse($code);
@@ -77,7 +81,7 @@ A parser instance can be reused to parse multiple files.
7781
Node dumping
7882
------------
7983

80-
To dump the abstract syntax tree in human readable form, a `NodeDumper` can be used:
84+
To dump the abstract syntax tree in human-readable form, a `NodeDumper` can be used:
8185

8286
```php
8387
<?php
@@ -171,7 +175,7 @@ with them easier they are grouped into three categories:
171175

172176
* `PhpParser\Node\Stmt`s are statement nodes, i.e. language constructs that do not return
173177
a value and can not occur in an expression. For example a class definition is a statement.
174-
It doesn't return a value and you can't write something like `func(class A {});`.
178+
It doesn't return a value, and you can't write something like `func(class A {});`.
175179
* `PhpParser\Node\Expr`s are expression nodes, i.e. language constructs that return a value
176180
and thus can occur in other expressions. Examples of expressions are `$var`
177181
(`PhpParser\Node\Expr\Variable`) and `func()` (`PhpParser\Node\Expr\FuncCall`).
@@ -201,15 +205,14 @@ can then be retrieved using `hasAttribute()`, `getAttribute()` and `getAttribute
201205
By default the lexer adds the `startLine`, `endLine` and `comments` attributes. `comments` is an array
202206
of `PhpParser\Comment[\Doc]` instances.
203207

204-
The start line can also be accessed using `getLine()`/`setLine()` (instead of `getAttribute('startLine')`).
208+
The start line can also be accessed using `getStartLine()` (instead of `getAttribute('startLine')`).
205209
The last doc comment from the `comments` attribute can be obtained using `getDocComment()`.
206210

207211
Pretty printer
208212
--------------
209213

210-
The pretty printer component compiles the AST back to PHP code. As the parser does not retain formatting
211-
information the formatting is done using a specified scheme. Currently there is only one scheme available,
212-
namely `PhpParser\PrettyPrinter\Standard`.
214+
The pretty printer component compiles the AST back to PHP code according to a specified scheme.
215+
Currently, there is only one scheme available, namely `PhpParser\PrettyPrinter\Standard`.
213216

214217
```php
215218
use PhpParser\Error;
@@ -218,8 +221,8 @@ use PhpParser\PrettyPrinter;
218221

219222
$code = "<?php echo 'Hi ', hi\\getTarget();";
220223

221-
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
222-
$prettyPrinter = new PrettyPrinter\Standard;
224+
$parser = (new ParserFactory())->createForHostVersion();
225+
$prettyPrinter = new PrettyPrinter\Standard();
223226

224227
try {
225228
// parse
@@ -254,10 +257,13 @@ single expression using `prettyPrintExpr()`.
254257
The `prettyPrintFile()` method can be used to print an entire file. This will include the opening `<?php` tag
255258
and handle inline HTML as the first/last statement more gracefully.
256259

260+
There is also a pretty-printing mode which retains formatting for parts of the AST that have not
261+
been changed, which requires additional setup.
262+
257263
> Read more: [Pretty printing documentation](component/Pretty_printing.markdown)
258264
259-
Node traversation
260-
-----------------
265+
Node traversal
266+
--------------
261267

262268
The above pretty printing example used the fact that the source code was known and thus it was easy to
263269
write code that accesses a certain part of a node tree and changes it. Normally this is not the case.
@@ -272,7 +278,7 @@ use PhpParser\NodeTraverser;
272278
use PhpParser\ParserFactory;
273279
use PhpParser\PrettyPrinter;
274280

275-
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
281+
$parser = (new ParserFactory())->createForHostVersion();
276282
$traverser = new NodeTraverser;
277283
$prettyPrinter = new PrettyPrinter\Standard;
278284

@@ -303,8 +309,7 @@ The corresponding node visitor might look like this:
303309
use PhpParser\Node;
304310
use PhpParser\NodeVisitorAbstract;
305311

306-
class MyNodeVisitor extends NodeVisitorAbstract
307-
{
312+
class MyNodeVisitor extends NodeVisitorAbstract {
308313
public function leaveNode(Node $node) {
309314
if ($node instanceof Node\Scalar\String_) {
310315
$node->value = 'foo';
@@ -326,7 +331,7 @@ public function afterTraverse(array $nodes);
326331
```
327332

328333
The `beforeTraverse()` method is called once before the traversal begins and is passed the nodes the
329-
traverser was called with. This method can be used for resetting values before traversation or
334+
traverser was called with. This method can be used for resetting values before traversal or
330335
preparing the tree for traversal.
331336

332337
The `afterTraverse()` method is similar to the `beforeTraverse()` method, with the only difference that
@@ -342,8 +347,8 @@ The `enterNode()` method can additionally return the value `NodeTraverser::DONT_
342347
which instructs the traverser to skip all children of the current node. To furthermore prevent subsequent
343348
visitors from visiting the current node, `NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN` can be used instead.
344349

345-
The `leaveNode()` method can additionally return the value `NodeTraverser::REMOVE_NODE`, in which
346-
case the current node will be removed from the parent array. Furthermore it is possible to return
350+
Both methods can additionally return the value `NodeTraverser::REMOVE_NODE`, in which
351+
case the current node will be removed from the parent array. Furthermore, it is possible to return
347352
an array of nodes, which will be merged into the parent array at the offset of the current node.
348353
I.e. if in `array(A, B, C)` the node `B` should be replaced with `array(X, Y, Z)` the result will
349354
be `array(A, X, Y, Z, C)`.
@@ -372,8 +377,9 @@ unqualified function and constant names. These are resolved at runtime and thus
372377
know which function they are referring to. In most cases this is a non-issue as the global functions
373378
are meant.
374379

375-
Also the `NameResolver` adds a `namespacedName` subnode to class, function and constant declarations
376-
that contains the namespaced name instead of only the shortname that is available via `name`.
380+
Additionally, the `NameResolver` adds a `namespacedName` subnode to class, function and constant
381+
declarations that contains the namespaced name instead of only the shortname that is available via
382+
`name`.
377383

378384
> Read more: [Name resolution documentation](component/Name_resolution.markdown)
379385
@@ -396,7 +402,7 @@ use PhpParser\NodeVisitor\NameResolver;
396402
$inDir = '/some/path';
397403
$outDir = '/some/other/path';
398404

399-
$parser = (new ParserFactory)->create(ParserFactory::PREFER_PHP7);
405+
$parser = (new ParserFactory())->createForNewestSupportedVersion();
400406
$traverser = new NodeTraverser;
401407
$prettyPrinter = new PrettyPrinter\Standard;
402408

lib/PhpParser/Lexer.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ class Lexer {
1515
protected $pos;
1616
protected $prevCloseTagHasNewline;
1717

18-
protected $tokenMap;
1918
protected $dropTokens;
2019

2120
private $attributeStartLineUsed;

0 commit comments

Comments
 (0)