Security update to Drupal 8.4.6
[yaffs-website] / vendor / nikic / php-parser / UPGRADE-3.0.md
1 Upgrading from PHP-Parser 2.x to 3.0
2 ====================================
3
4 The backwards-incompatible changes in this release may be summarized as follows:
5
6  * The specific details of the node representation have changed in some cases, primarily to
7    accomodate new PHP 7.1 features.
8  * There have been significant changes to the error recovery implementation. This may affect you,
9    if you used the error recovery mode or have a custom lexer implementation.
10  * A number of deprecated methods were removed.
11
12 ### PHP version requirements
13
14 PHP-Parser now requires PHP 5.5 or newer to run. It is however still possible to *parse* PHP 5.2,
15 5.3 and 5.4 source code, while running on a newer version.
16
17 ### Changes to the node structure
18
19 The following changes are likely to require code changes if the respective nodes are used:
20
21  * The `List` subnode `vars` has been renamed to `items` and now contains `ArrayItem`s instead of
22    plain variables.
23  * The `Catch` subnode `type` has been renamed to `types` and is now an array of `Name`s.
24  * The `TryCatch` subnode `finallyStmts` has been replaced with a `finally` subnode that holds an
25    explicit `Finally` node.
26  * The `type` subnode on `Class`, `ClassMethod` and `Property` has been renamed to `flags`. The
27    `type` subnode has retained for backwards compatibility and is populated to the same value as
28    `flags`. However, writes to `type` will not update `flags` and use of `type` is discouraged.
29
30 The following changes are unlikely to require code changes:
31
32  * The `ClassConst` constructor changed to accept an additional `flags` subnode.
33  * The `Trait` constructor now has the same form as the `Class` and `Interface` constructors: It
34    takes an array of subnodes. Unlike classes/interfaces, traits can only have a `stmts` subnode.
35  * The `Array` subnode `items` may now contain `null` elements (due to destructuring).
36  * `void` and `iterable` types are now stored as strings if the PHP 7 parser is used. Previously
37    these would have been represented as `Name` instances.
38
39 ### Changes to error recovery mode
40
41 Previously, error recovery mode was enabled by setting the `throwOnError` option to `false` when
42 creating the parser, while collected errors were retrieved using the `getErrors()` method:
43
44 ```php
45 $lexer = ...;
46 $parser = (new ParserFactory)->create(ParserFactor::ONLY_PHP7, $lexer, [
47     'throwOnError' => true,
48 ]);
49
50 $stmts = $parser->parse($code);
51 $errors = $parser->getErrors();
52 if ($errors) {
53     handleErrors($errors);
54 }
55 processAst($stmts);
56 ```
57
58 Both the `throwOnError` option and the `getErrors()` method have been removed in PHP-Parser 3.0.
59 Instead an instance of `ErrorHandler\Collecting` should be passed to the `parse()` method:
60
61 ```php
62 $lexer = ...;
63 $parser = (new ParserFactory)->create(ParserFactor::ONLY_PHP7, $lexer);
64
65 $errorHandler = new ErrorHandler\Collecting;
66 $stmts = $parser->parse($code, $errorHandler);
67 if ($errorHandler->hasErrors()) {
68     handleErrors($errorHandler->getErrors());
69 }
70 processAst($stmts);
71 ```
72
73 #### Multiple parser fallback in error recovery mode
74
75 As a result of this change, if a `Multiple` parser is used (e.g. through the `ParserFactory` using
76 `PREFER_PHP7` or `PREFER_PHP5`), it will now return the result of the first *non-throwing* parse. As
77 parsing never throws in error recovery mode, the result from the first parser will always be
78 returned.
79
80 The PHP 7 parser is a superset of the PHP 5 parser, with the exceptions that `=& new` and
81 `global $$foo->bar` are not supported (other differences are in representation only). The PHP 7
82 parser will be able to recover from the error in both cases. For this reason, this change will
83 likely pass unnoticed if you do not specifically test for this syntax.
84
85 It is possible to restore the precise previous behavior with the following code:
86
87 ```php
88 $lexer = ...;
89 $parser7 = new Parser\Php7($lexer);
90 $parser5 = new Parser\Php5($lexer);
91
92 $errors7 = new ErrorHandler\Collecting();
93 $stmts7 = $parser7->parse($code, $errors7);
94 if ($errors7->hasErrors()) {
95     $errors5 = new ErrorHandler\Collecting();
96     $stmts5 = $parser5->parse($code, $errors5);
97     if (!$errors5->hasErrors()) {
98         // If PHP 7 parse has errors but PHP 5 parse has no errors, use PHP 5 result
99         return [$stmts5, $errors5];
100     }
101 }
102 // If PHP 7 succeeds or both fail use PHP 7 result
103 return [$stmts7, $errors7];
104 ```
105
106 #### Error handling in the lexer
107
108 In order to support recovery from lexer errors, the signature of the `startLexing()` method changed
109 to optionally accept an `ErrorHandler`:
110
111 ```php
112 // OLD
113 public function startLexing($code);
114 // NEW
115 public function startLexing($code, ErrorHandler $errorHandler = null);
116 ```
117
118 If you use a custom lexer with overriden `startLexing()` method, it needs to be changed to accept
119 the extra parameter. The value should be passed on to the parent method.
120
121 #### Error checks in node constructors
122
123 The constructors of certain nodes used to contain additional checks for semantic errors, such as
124 creating a try block without either catch or finally. These checks have been moved from the node
125 constructors into the parser. This allows recovery from such errors, as well as representing the
126 resulting (invalid) AST.
127
128 This means that certain error conditions are no longer checked for manually constructed nodes.
129
130 ### Removed methods, arguments, options
131
132 The following methods, arguments or options have been removed:
133
134  * `Comment::setLine()`, `Comment::setText()`: Create new `Comment` instances instead.
135  * `Name::set()`, `Name::setFirst()`, `Name::setLast()`, `Name::append()`, `Name::prepend()`:
136     Use `Name::concat()` in combination with `Name::slice()` instead.
137  * `Error::getRawLine()`, `Error::setRawLine()`. Use `Error::getStartLine()` and
138    `Error::setStartLine()` instead.
139  * `Parser::getErrors()`. Use `ErrorHandler\Collecting` instead.
140  * `$separator` argument of `Name::toString()`. Use `strtr()` instead, if you really need it.
141  * `$cloneNodes` argument of `NodeTraverser::__construct()`. Explicitly clone nodes in the visitor
142    instead.
143  * `throwOnError` parser option. Use `ErrorHandler\Collecting` instead.
144
145 ### Miscellaneous
146
147  * The `NameResolver` will now resolve unqualified function and constant names in the global
148    namespace into fully qualified names. For example `foo()` in the global namespace resolves to
149    `\foo()`. For names where no static resolution is possible, a `namespacedName` attribute is
150    added now, containing the namespaced variant of the name.
151  * All methods on `PrettyPrinter\Standard` are now protected. Previoulsy most of them were public.
152    The pretty printer should only be invoked using the `prettyPrint()`, `prettyPrintFile()` and
153    `prettyPrintExpr()` methods.
154  * The node dumper now prints numeric values that act as enums/flags in a string representation.
155    If node dumper results are used in tests, updates may be needed to account for this.
156  * The constants on `NameTraverserInterface` have been moved into the `NameTraverser` class.
157  * The emulative lexer now directly postprocesses tokens, instead of using `~__EMU__~` sequences.
158    This changes the protected API of the emulative lexer.
159  * The `Name::slice()` method now returns `null` for empty slices, previously `new Name([])` was
160    used. `Name::concat()` now also supports concatenation with `null`.