Mercurial > hg > cmmr2012-drupal-site
comparison vendor/nikic/php-parser/UPGRADE-3.0.md @ 0:c75dbcec494b
Initial commit from drush-created site
author | Chris Cannam |
---|---|
date | Thu, 05 Jul 2018 14:24:15 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:c75dbcec494b |
---|---|
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 accommodate 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 overridden `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. Previously 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`. |