mirror of
https://github.com/nikic/PHP-Parser.git
synced 2025-07-20 05:41:35 +02:00
Compare commits
32 Commits
v5.0.0alph
...
v5.0.0alph
Author | SHA1 | Date | |
---|---|---|---|
|
571ca90b7e | ||
|
16c766eae1 | ||
|
53f6717329 | ||
|
5b65f9fc92 | ||
|
69993a181a | ||
|
23647573e8 | ||
|
df3a7057ab | ||
|
d43edfbb31 | ||
|
ad8daa12b2 | ||
|
5883189d61 | ||
|
afe1628a72 | ||
|
289756d056 | ||
|
8490c0e82d | ||
|
8bc698248d | ||
|
fb2c3ac97c | ||
|
c23976a299 | ||
|
a9dad5c54e | ||
|
74caed6446 | ||
|
a5d4c1005c | ||
|
93731c5cfa | ||
|
0a8a333a4a | ||
|
91da19147b | ||
|
5c267f55c9 | ||
|
9a5d5c112c | ||
|
779b6950c3 | ||
|
b68fb76f14 | ||
|
36a6dcd04e | ||
|
bb4263ea1a | ||
|
4ce0de2d12 | ||
|
a3bc900a41 | ||
|
7785d2b887 | ||
|
aa721520f9 |
34
CHANGELOG.md
34
CHANGELOG.md
@@ -1,3 +1,37 @@
|
||||
Version 5.0.0-alpha3 (2023-06-24)
|
||||
---------------------------------
|
||||
|
||||
See UPGRADE-5.0 for detailed migration instructions.
|
||||
|
||||
### Added
|
||||
|
||||
* [PHP 8.3] Added support for typed constants.
|
||||
* [PHP 8.3] Added support for readonly anonymous classes.
|
||||
* Added support for `NodeVisitor::REPLACE_WITH_NULL`.
|
||||
* Added support for CRLF newlines in the pretty printer, using the new `newline` option.
|
||||
|
||||
### Changed
|
||||
|
||||
* Use PHP 7.1 as the default target version for the pretty printer.
|
||||
* Print `else if { }` instead of `else { if { } }`.
|
||||
* The `leaveNode()` method on visitors is now invoked in reverse order of `enterNode()`.
|
||||
* Moved `NodeTraverser::REMOVE_NODE` etc. to `NodeVisitor::REMOVE_NODE`. The old constants are still
|
||||
available for compatibility.
|
||||
* The `Name` subnode `parts` has been replaced by `name`, which stores the name as a string rather
|
||||
than an array of parts separated by namespace separators. The `getParts()` method returns the old
|
||||
representation.
|
||||
* No longer accept strings for types in Node constructors. Instead, either an `Identifier`, `Name`
|
||||
or `ComplexType` must be passed.
|
||||
* `Comment::getReformattedText()` now normalizes CRLF newlines to LF newlines.
|
||||
|
||||
### Fixed
|
||||
|
||||
* Don't trim leading whitespace in formatting preserving printer.
|
||||
* Treat DEL as a label character in the formatting preserving printer depending on the targeted
|
||||
PHP version.
|
||||
* Fix error reporting in emulative lexer without explicitly specified error handler.
|
||||
* Gracefully handle non-contiguous array indices in the `Differ`.
|
||||
|
||||
Version 5.0.0-alpha2 (2023-03-05)
|
||||
---------------------------------
|
||||
|
||||
|
14
README.md
14
README.md
@@ -70,12 +70,17 @@ This dumps an AST looking something like this:
|
||||
```
|
||||
array(
|
||||
0: Stmt_Function(
|
||||
attrGroups: array(
|
||||
)
|
||||
byRef: false
|
||||
name: Identifier(
|
||||
name: test
|
||||
)
|
||||
params: array(
|
||||
0: Param(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
byRef: false
|
||||
variadic: false
|
||||
@@ -90,12 +95,11 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: var_dump
|
||||
)
|
||||
name: var_dump
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
name: null
|
||||
value: Expr_Variable(
|
||||
name: foo
|
||||
)
|
||||
@@ -137,12 +141,16 @@ This gives us an AST where the `Function_::$stmts` are empty:
|
||||
```
|
||||
array(
|
||||
0: Stmt_Function(
|
||||
attrGroups: array(
|
||||
)
|
||||
byRef: false
|
||||
name: Identifier(
|
||||
name: test
|
||||
)
|
||||
params: array(
|
||||
0: Param(
|
||||
attrGroups: array(
|
||||
)
|
||||
type: null
|
||||
byRef: false
|
||||
variadic: false
|
||||
|
@@ -71,6 +71,17 @@ Now, destructuring is always represented using `Node\Expr\List_`. The `kind` att
|
||||
`Node\Expr\List_::KIND_LIST` or `Node\Expr\List_::KIND_ARRAY` specifies which syntax was actually
|
||||
used.
|
||||
|
||||
### Changes to the name representation
|
||||
|
||||
Previously, `Name` nodes had a `parts` subnode, which stores an array of name parts, split by
|
||||
namespace separators. Now, `Name` nodes instead have a `name` subnode, which stores a plain string.
|
||||
|
||||
For example, the name `Foo\Bar` was previously represented by `Name(parts: ['Foo', 'Bar'])` and is
|
||||
now represented by `Name(name: 'Foo\Bar')` instead.
|
||||
|
||||
It is possible to convert the name to the previous representation using `$name->getParts()`. The
|
||||
`Name` constructor continues to accept both the string and the array representation.
|
||||
|
||||
### Renamed nodes
|
||||
|
||||
A number of AST nodes have been renamed or moved in the AST hierarchy:
|
||||
@@ -104,6 +115,21 @@ PhpParser\Node\Stmt\Class_::MODIFIER_READONLY -> PhpParser\Modifiers::READONLY
|
||||
PhpParser\Node\Stmt\Class_::VISIBILITY_MODIFIER_MASK -> PhpParser\Modifiers::VISIBILITY_MASK
|
||||
```
|
||||
|
||||
### Changes to node constructors
|
||||
|
||||
Node constructor arguments accepting types now longer accept plain strings. Either an `Identifier` or `Name` (or `ComplexType`) should be passed instead. This affects the following constructor arguments:
|
||||
|
||||
* The `'returnType'` key of `$subNodes` argument of `Node\Expr\ArrowFunction`.
|
||||
* The `'returnType'` key of `$subNodes` argument of `Node\Expr\Closure`.
|
||||
* The `'returnType'` key of `$subNodes` argument of `Node\Stmt\ClassMethod`.
|
||||
* The `'returnType'` key of `$subNodes` argument of `Node\Stmt\Function_`.
|
||||
* The `$type` argument of `Node\NullableType`.
|
||||
* The `$type` argument of `Node\Param`.
|
||||
* The `$type` argument of `Node\Stmt\Property`.
|
||||
* The `$type` argument of `Node\ClassConst` (new in PHP-Parser 5.0, listed for completeness only).
|
||||
|
||||
To follow the previous behavior, an `Identifier` should be passed, which indicates a built-in type.
|
||||
|
||||
### Changes to the pretty printer
|
||||
|
||||
A number of changes to the standard pretty printer have been made, to make it match contemporary coding style conventions (and in particular PSR-12). Options to restore the previous behavior are not provided, but it is possible to override the formatting methods (such as `pStmt_ClassMethod`) with your preferred formatting.
|
||||
@@ -156,12 +182,27 @@ Backslashes in single-quoted strings are now only printed if they are necessary:
|
||||
'\\\\';
|
||||
```
|
||||
|
||||
The pretty printer now accepts a `phpVersion` option, which accepts a `PhpVersion` object and defaults to PHP 7.0. The pretty printer will make formatting choices to make the code valid for that version. It currently controls the following behavior:
|
||||
`else if` structures will now omit redundant parentheses:
|
||||
|
||||
```php
|
||||
# Before
|
||||
else {
|
||||
if ($x) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
# After
|
||||
else if ($x) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The pretty printer now accepts a `phpVersion` option, which accepts a `PhpVersion` object and defaults to PHP 7.1. The pretty printer will make formatting choices to make the code valid for that version. It currently controls the following behavior:
|
||||
|
||||
* For PHP >= 7.0 (default), short array syntax `[]` will be used by default. This does not affect nodes that specify an explicit array syntax using the `kind` attribute.
|
||||
* For PHP >= 7.0 (default), parentheses around `yield` expressions will only be printed when necessary. Previously, parentheses were always printed, even if `yield` was used as a statement.
|
||||
* For PHP >= 7.1, the short array syntax `[]` will be used for destructuring by default (instead of
|
||||
`list()`). This does not affect nodes that specify and explicit syntax using the `kind` attribute.
|
||||
* For PHP >= 7.1 (default), the short array syntax `[]` will be used for destructuring by default (instead of `list()`). This does not affect nodes that specify and explicit syntax using the `kind` attribute.
|
||||
* For PHP >= 7.3, a newline is no longer forced after heredoc/nowdoc strings, as the requirement for this has been removed with the introduction of flexible heredoc/nowdoc strings.
|
||||
|
||||
### Changes to precedence handling in the pretty printer
|
||||
@@ -197,6 +238,33 @@ protected function pExpr_UnaryPlus(
|
||||
|
||||
The new `$precedence` and `$lhsPrecedence` arguments need to be passed down to the `pInfixOp()`, `pPrefixOp()` and `pPostfixOp()` methods.
|
||||
|
||||
### Changes to the node traverser
|
||||
|
||||
If there are multiple visitors, the node traverser will now call `leaveNode()` and `afterTraverse()` methods in the reverse order of the corresponding `enterNode()` and `beforeTraverse()` calls:
|
||||
|
||||
```php
|
||||
# Before
|
||||
$visitor1->enterNode($node);
|
||||
$visitor2->enterNode($node);
|
||||
$visitor1->leaveNode($node);
|
||||
$visitor2->leaveNode($node);
|
||||
|
||||
# After
|
||||
$visitor1->enterNode($node);
|
||||
$visitor2->enterNode($node);
|
||||
$visitor2->leaveNode($node);
|
||||
$visitor1->leaveNode($node);
|
||||
```
|
||||
|
||||
Additionally, the special `NodeVisitor` return values have been moved from `NodeTraverser` to `NodeVisitor`. The old names are deprecated, but still available.
|
||||
|
||||
```php
|
||||
PhpParser\NodeTraverser::REMOVE_NODE -> PhpParser\NodeVisitor::REMOVE_NODE
|
||||
PhpParser\NodeTraverser::DONT_TRAVERSE_CHILDREN -> PhpParser\NodeVisitor::DONT_TRAVERSE_CHILDREN
|
||||
PhpParser\NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN -> PhpParser\NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN
|
||||
PhpParser\NodeTraverser::STOP_TRAVERSAL -> PhpParser\NodeVisitor::STOP_TRAVERSAL
|
||||
```
|
||||
|
||||
### Changes to token representation
|
||||
|
||||
Tokens are now internally represented using the `PhpParser\Token` class, which exposes the same base interface as
|
||||
@@ -217,7 +285,8 @@ class Token {
|
||||
The `Lexer::getTokens()` method will now return an array of `Token`s, rather than an array of arrays and strings.
|
||||
Additionally, the token array is now terminated by a sentinel token with ID 0.
|
||||
|
||||
### Other removed functionality
|
||||
### Miscellaneous changes
|
||||
|
||||
* The deprecated `Builder\Param::setTypeHint()` method has been removed in favor of `Builder\Param::setType()`.
|
||||
* The deprecated `Error` constructor taking a start line has been removed. Pass `['startLine' => $startLine]` attributes instead.
|
||||
* `Comment::getReformattedText()` now normalizes CRLF newlines to LF newlines.
|
||||
|
@@ -96,12 +96,17 @@ For the sample code from the previous section, this will produce the following o
|
||||
```
|
||||
array(
|
||||
0: Stmt_Function(
|
||||
attrGroups: array(
|
||||
)
|
||||
byRef: false
|
||||
name: Identifier(
|
||||
name: printLine
|
||||
)
|
||||
params: array(
|
||||
0: Param(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
byRef: false
|
||||
variadic: false
|
||||
@@ -129,12 +134,11 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: printLine
|
||||
)
|
||||
name: printLine
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
name: null
|
||||
value: Scalar_String(
|
||||
value: Hello World!!!
|
||||
)
|
||||
@@ -343,15 +347,18 @@ i.e. before its subnodes are traversed, the latter when it is left.
|
||||
All four methods can either return the changed node or not return at all (i.e. `null`) in which
|
||||
case the current node is not changed.
|
||||
|
||||
The `enterNode()` method can additionally return the value `NodeTraverser::DONT_TRAVERSE_CHILDREN`,
|
||||
The `enterNode()` method can additionally return the value `NodeVisitor::DONT_TRAVERSE_CHILDREN`,
|
||||
which instructs the traverser to skip all children of the current node. To furthermore prevent subsequent
|
||||
visitors from visiting the current node, `NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN` can be used instead.
|
||||
visitors from visiting the current node, `NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN` can be used instead.
|
||||
|
||||
Both methods can additionally return the value `NodeTraverser::REMOVE_NODE`, in which
|
||||
case the current node will be removed from the parent array. Furthermore, it is possible to return
|
||||
an array of nodes, which will be merged into the parent array at the offset of the current node.
|
||||
I.e. if in `array(A, B, C)` the node `B` should be replaced with `array(X, Y, Z)` the result will
|
||||
be `array(A, X, Y, Z, C)`.
|
||||
Both methods can additionally return the following values:
|
||||
|
||||
* `NodeVisitor::STOP_TRAVERSAL`, in which case no further nodes will be visited.
|
||||
* `NodeVisitor::REMOVE_NODE`, in which case the current node will be removed from the parent array.
|
||||
* `NodeVisitor::REPLACE_WITH_NULL`, in which case the current node will be replaced with `null`.
|
||||
* An array of nodes, which will be merged into the parent array at the offset of the current node.
|
||||
I.e. if in `array(A, B, C)` the node `B` should be replaced with `array(X, Y, Z)` the result will
|
||||
be `array(A, X, Y, Z, C)`.
|
||||
|
||||
Instead of manually implementing the `NodeVisitor` interface you can also extend the `NodeVisitorAbstract`
|
||||
class, which will define empty default implementations for all the above methods.
|
||||
@@ -493,7 +500,7 @@ The last thing we need to do is remove the `namespace` and `use` statements:
|
||||
```php
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\NodeTraverser;
|
||||
use PhpParser\NodeVisitor;
|
||||
|
||||
class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract
|
||||
{
|
||||
@@ -513,7 +520,7 @@ class NodeVisitor_NamespaceConverter extends \PhpParser\NodeVisitorAbstract
|
||||
return $node->stmts;
|
||||
} elseif ($node instanceof Stmt\Use_) {
|
||||
// remove use nodes altogether
|
||||
return NodeTraverser::REMOVE_NODE;
|
||||
return NodeVisitor::REMOVE_NODE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -42,24 +42,3 @@ When possible, objects should be reused rather than being newly instantiated for
|
||||
objects have expensive initialization procedures, which will be unnecessarily repeated if the object
|
||||
is not reused. (Currently two objects with particularly expensive setup are lexers and pretty
|
||||
printers, though the details might change between versions of this library.)
|
||||
|
||||
Garbage collection
|
||||
------------------
|
||||
|
||||
A limitation in PHP's cyclic garbage collector may lead to major performance degradation when the
|
||||
active working set exceeds 10000 objects (or arrays). Especially when parsing very large files this
|
||||
limit is significantly exceeded and PHP will spend the majority of time performing unnecessary
|
||||
garbage collection attempts.
|
||||
|
||||
Without GC, parsing time is roughly linear in the input size. With GC, this degenerates to quadratic
|
||||
runtime for large files. While the specifics may differ, as a rough guideline you may expect a 2.5x
|
||||
GC overhead for 500KB files and a 5x overhead for 1MB files.
|
||||
|
||||
Because this a limitation in PHP's implementation, there is no easy way to work around this. If
|
||||
possible, you should avoid parsing very large files, as they will impact overall execution time
|
||||
disproportionally (and are usually generated anyway).
|
||||
|
||||
Of course, you can also try to (temporarily) disable GC. By design the AST generated by PHP-Parser
|
||||
is cycle-free, so the AST itself will never cause leaks with GC disabled. However, other code
|
||||
(including for example the parser object itself) may hold cycles, so disabling of GC should be
|
||||
approached with care.
|
||||
|
@@ -32,10 +32,11 @@ Customizing the formatting
|
||||
--------------------------
|
||||
|
||||
The pretty printer respects a number of `kind` attributes used by some notes (e.g., whether an
|
||||
integer should be printed as decimal, hexadecimal, etc). Additionally, it supports two options:
|
||||
integer should be printed as decimal, hexadecimal, etc). Additionally, it supports three options:
|
||||
|
||||
* `phpVersion` (defaults to 7.0) allows opting into formatting that is not supported by older PHP
|
||||
* `phpVersion` (defaults to 7.1) allows opting into formatting that is not supported by older PHP
|
||||
versions.
|
||||
* `newline` (defaults to `"\n"`) can be set to `"\r\n"` in order to produce Windows newlines.
|
||||
* `shortArraySyntax` determines the used array syntax if the `kind` attribute is not set. This is
|
||||
a legacy option, and `phpVersion` should be used to control this behavior instead.
|
||||
|
||||
|
@@ -129,13 +129,13 @@ Now `$a && $b` will be replaced by `!($a && $b)`. Then the traverser will go int
|
||||
only) child of `!($a && $b)`, which is `$a && $b`. The transformation applies again and we end up
|
||||
with `!!($a && $b)`. This will continue until PHP hits the memory limit.
|
||||
|
||||
Finally, there are two special replacement types. The first is removal of a node:
|
||||
Finally, there are three special replacement types. The first is removal of a node:
|
||||
|
||||
```php
|
||||
public function leaveNode(Node $node) {
|
||||
if ($node instanceof Node\Stmt\Return_) {
|
||||
// Remove all return statements
|
||||
return NodeTraverser::REMOVE_NODE;
|
||||
return NodeVisitor::REMOVE_NODE;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -155,7 +155,7 @@ public function leaveNode(Node $node) {
|
||||
&& $node->expr->name instanceof Node\Name
|
||||
&& $node->expr->name->toString() === 'var_dump'
|
||||
) {
|
||||
return NodeTraverser::REMOVE_NODE;
|
||||
return NodeVisitor::REMOVE_NODE;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -164,6 +164,20 @@ This example will remove all calls to `var_dump()` which occur as expression sta
|
||||
that `var_dump($a);` will be removed, but `if (var_dump($a))` will not be removed (and there is no
|
||||
obvious way in which it can be removed).
|
||||
|
||||
Another way to remove nodes is to replace them with `null`. For example, all `else` statements could
|
||||
be removed as follows:
|
||||
|
||||
```php
|
||||
public function leaveNode(Node $node) {
|
||||
if ($node instanceof Node\Stmt\Else_) {
|
||||
return NodeVisitor::REPLACE_WITH_NULL;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is only safe to do if the subnode the node is stored in is nullable. `Node\Stmt\Else_` only
|
||||
occurs inside `Node\Stmt\If_::$else`, which is nullable, so this particular replacement is safe.
|
||||
|
||||
Next to removing nodes, it is also possible to replace one node with multiple nodes. This
|
||||
only works if the parent structure is an array.
|
||||
|
||||
@@ -197,7 +211,7 @@ private $classes = [];
|
||||
public function enterNode(Node $node) {
|
||||
if ($node instanceof Node\Stmt\Class_) {
|
||||
$this->classes[] = $node;
|
||||
return NodeTraverser::DONT_TRAVERSE_CHILDREN;
|
||||
return NodeVisitor::DONT_TRAVERSE_CHILDREN;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -217,7 +231,7 @@ public function enterNode(Node $node) {
|
||||
$node->namespacedName->toString() === 'Foo\Bar\Baz'
|
||||
) {
|
||||
$this->class = $node;
|
||||
return NodeTraverser::STOP_TRAVERSAL;
|
||||
return NodeVisitor::STOP_TRAVERSAL;
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -255,13 +269,14 @@ $visitorA->enterNode(Stmt_Return)
|
||||
$visitorB->enterNode(Stmt_Return)
|
||||
$visitorA->enterNode(Expr_Variable)
|
||||
$visitorB->enterNode(Expr_Variable)
|
||||
$visitorA->leaveNode(Expr_Variable)
|
||||
$visitorB->leaveNode(Expr_Variable)
|
||||
$visitorA->leaveNode(Stmt_Return)
|
||||
$visitorA->leaveNode(Expr_Variable)
|
||||
$visitorB->leaveNode(Stmt_Return)
|
||||
$visitorA->leaveNode(Stmt_Return)
|
||||
```
|
||||
|
||||
That is, when visiting a node, enterNode and leaveNode will always be called for all visitors.
|
||||
That is, when visiting a node, `enterNode()` and `leaveNode()` will always be called for all
|
||||
visitors, with the `leaveNode()` calls happening in the reverse order of the `enterNode()` calls.
|
||||
Running multiple visitors in parallel improves performance, as the AST only has to be traversed
|
||||
once. However, it is not always possible to write visitors in a way that allows interleaved
|
||||
execution. In this case, you can always fall back to performing multiple traversals:
|
||||
@@ -286,6 +301,7 @@ special enterNode/leaveNode return values:
|
||||
* If a visitor returns a replacement node, subsequent visitors will be passed the replacement node,
|
||||
not the original one.
|
||||
* If a visitor returns `REMOVE_NODE`, subsequent visitors will not see this node.
|
||||
* If a visitor returns `REPLACE_WITH_NULL`, subsequent visitors will not see this node.
|
||||
* If a visitor returns an array of replacement nodes, subsequent visitors will see neither the node
|
||||
that was replaced, nor the replacement nodes.
|
||||
|
||||
|
@@ -340,7 +340,10 @@ non_empty_class_const_list:
|
||||
;
|
||||
|
||||
class_const:
|
||||
identifier_maybe_reserved '=' expr { $$ = Node\Const_[$1, $3]; }
|
||||
T_STRING '=' expr
|
||||
{ $$ = Node\Const_[new Node\Identifier($1, stackAttributes(#1)), $3]; }
|
||||
| semi_reserved '=' expr
|
||||
{ $$ = Node\Const_[new Node\Identifier($1, stackAttributes(#1)), $3]; }
|
||||
;
|
||||
|
||||
inner_statement_list_ex:
|
||||
@@ -842,6 +845,9 @@ class_statement:
|
||||
| optional_attributes method_modifiers T_CONST class_const_list semi
|
||||
{ $$ = new Stmt\ClassConst($4, $2, attributes(), $1);
|
||||
$this->checkClassConst($$, #2); }
|
||||
| optional_attributes method_modifiers T_CONST type_expr class_const_list semi
|
||||
{ $$ = new Stmt\ClassConst($5, $2, attributes(), $1, $4);
|
||||
$this->checkClassConst($$, #2); }
|
||||
| optional_attributes method_modifiers T_FUNCTION optional_ref identifier_maybe_reserved '(' parameter_list ')'
|
||||
optional_return_type method_body
|
||||
{ $$ = Stmt\ClassMethod[$5, ['type' => $2, 'byRef' => $4, 'params' => $7, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]];
|
||||
@@ -1070,8 +1076,8 @@ expr:
|
||||
;
|
||||
|
||||
anonymous_class:
|
||||
optional_attributes T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
|
||||
{ $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]], $3);
|
||||
optional_attributes class_entry_type ctor_arguments extends_from implements_list '{' class_statement_list '}'
|
||||
{ $$ = array(Stmt\Class_[null, ['type' => $2, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]], $3);
|
||||
$this->checkClass($$[0], -1); }
|
||||
;
|
||||
|
||||
|
@@ -22,6 +22,8 @@ class ClassConst implements PhpParser\Builder {
|
||||
|
||||
/** @var list<Node\AttributeGroup> */
|
||||
protected $attributeGroups = [];
|
||||
/** @var Identifier|Node\Name|Node\ComplexType */
|
||||
protected $type;
|
||||
|
||||
/**
|
||||
* Creates a class constant builder
|
||||
@@ -119,6 +121,19 @@ class ClassConst implements PhpParser\Builder {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the constant type.
|
||||
*
|
||||
* @param string|Node\Name|Identifier|Node\ComplexType $type
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setType($type) {
|
||||
$this->type = BuilderHelpers::normalizeType($type);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the built class node.
|
||||
*
|
||||
@@ -129,7 +144,8 @@ class ClassConst implements PhpParser\Builder {
|
||||
$this->constants,
|
||||
$this->flags,
|
||||
$this->attributes,
|
||||
$this->attributeGroups
|
||||
$this->attributeGroups,
|
||||
$this->type
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,7 @@ namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser;
|
||||
use PhpParser\BuilderHelpers;
|
||||
use PhpParser\Modifiers;
|
||||
use PhpParser\Node;
|
||||
|
||||
class Param implements PhpParser\Builder {
|
||||
@@ -15,6 +16,8 @@ class Param implements PhpParser\Builder {
|
||||
protected $type = null;
|
||||
/** @var bool */
|
||||
protected $byRef = false;
|
||||
/** @var int */
|
||||
protected $flags = 0;
|
||||
/** @var bool */
|
||||
protected $variadic = false;
|
||||
/** @var list<Node\AttributeGroup> */
|
||||
@@ -80,6 +83,50 @@ class Param implements PhpParser\Builder {
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the (promoted) parameter public.
|
||||
*
|
||||
* @return $this The builder instance (for fluid interface)
|
||||
*/
|
||||
public function makePublic() {
|
||||
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PUBLIC);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the (promoted) parameter protected.
|
||||
*
|
||||
* @return $this The builder instance (for fluid interface)
|
||||
*/
|
||||
public function makeProtected() {
|
||||
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the (promoted) parameter private.
|
||||
*
|
||||
* @return $this The builder instance (for fluid interface)
|
||||
*/
|
||||
public function makePrivate() {
|
||||
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes the (promoted) parameter readonly.
|
||||
*
|
||||
* @return $this The builder instance (for fluid interface)
|
||||
*/
|
||||
public function makeReadonly() {
|
||||
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::READONLY);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an attribute group.
|
||||
*
|
||||
@@ -101,7 +148,7 @@ class Param implements PhpParser\Builder {
|
||||
public function getNode(): Node {
|
||||
return new Node\Param(
|
||||
new Node\Expr\Variable($this->name),
|
||||
$this->default, $this->type, $this->byRef, $this->variadic, [], 0, $this->attributeGroups
|
||||
$this->default, $this->type, $this->byRef, $this->variadic, [], $this->flags, $this->attributeGroups
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -150,19 +150,21 @@ class Comment implements \JsonSerializable {
|
||||
*
|
||||
* "Reformatted" here means that we try to clean up the whitespace at the
|
||||
* starts of the lines. This is necessary because we receive the comments
|
||||
* without trailing whitespace on the first line, but with trailing whitespace
|
||||
* without leading whitespace on the first line, but with leading whitespace
|
||||
* on all subsequent lines.
|
||||
*
|
||||
* @return mixed|string
|
||||
* Additionally, this normalizes CRLF newlines to LF newlines.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getReformattedText() {
|
||||
$text = $this->text;
|
||||
public function getReformattedText(): string {
|
||||
$text = str_replace("\r\n", "\n", $this->text);
|
||||
$newlinePos = strpos($text, "\n");
|
||||
if (false === $newlinePos) {
|
||||
// Single line comments don't need further processing
|
||||
return $text;
|
||||
}
|
||||
if (preg_match('((*BSR_ANYCRLF)(*ANYCRLF)^.*(?:\R\s+\*.*)+$)', $text)) {
|
||||
if (preg_match('(^.*(?:\n\s+\*.*)+$)', $text)) {
|
||||
// Multi line comment of the type
|
||||
//
|
||||
// /*
|
||||
@@ -171,9 +173,9 @@ class Comment implements \JsonSerializable {
|
||||
// */
|
||||
//
|
||||
// is handled by replacing the whitespace sequences before the * by a single space
|
||||
return preg_replace('(^\s+\*)m', ' *', $this->text);
|
||||
return preg_replace('(^\s+\*)m', ' *', $text);
|
||||
}
|
||||
if (preg_match('(^/\*\*?\s*[\r\n])', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) {
|
||||
if (preg_match('(^/\*\*?\s*\n)', $text) && preg_match('(\n(\s*)\*/$)', $text, $matches)) {
|
||||
// Multi line comment of the type
|
||||
//
|
||||
// /*
|
||||
|
@@ -33,6 +33,8 @@ class Differ {
|
||||
* @return DiffElem[] Diff (edit script)
|
||||
*/
|
||||
public function diff(array $old, array $new): array {
|
||||
$old = \array_values($old);
|
||||
$new = \array_values($new);
|
||||
list($trace, $x, $y) = $this->calculateTrace($old, $new);
|
||||
return $this->extractDiff($trace, $x, $y, $old, $new);
|
||||
}
|
||||
|
@@ -18,6 +18,8 @@ use PhpParser\Node\Expr;
|
||||
class PrintableNewAnonClassNode extends Expr {
|
||||
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||
public $attrGroups;
|
||||
/** @var int Modifiers */
|
||||
public $flags;
|
||||
/** @var (Node\Arg|Node\VariadicPlaceholder)[] Arguments */
|
||||
public $args;
|
||||
/** @var null|Node\Name Name of extended class */
|
||||
@@ -36,11 +38,12 @@ class PrintableNewAnonClassNode extends Expr {
|
||||
* @param array<string, mixed> $attributes Attributes
|
||||
*/
|
||||
public function __construct(
|
||||
array $attrGroups, array $args, ?Node\Name $extends, array $implements,
|
||||
array $attrGroups, int $flags, array $args, ?Node\Name $extends, array $implements,
|
||||
array $stmts, array $attributes
|
||||
) {
|
||||
parent::__construct($attributes);
|
||||
$this->attrGroups = $attrGroups;
|
||||
$this->flags = $flags;
|
||||
$this->args = $args;
|
||||
$this->extends = $extends;
|
||||
$this->implements = $implements;
|
||||
@@ -53,7 +56,7 @@ class PrintableNewAnonClassNode extends Expr {
|
||||
// We don't assert that $class->name is null here, to allow consumers to assign unique names
|
||||
// to anonymous classes for their own purposes. We simplify ignore the name here.
|
||||
return new self(
|
||||
$class->attrGroups, $newNode->args, $class->extends, $class->implements,
|
||||
$class->attrGroups, $class->flags, $newNode->args, $class->extends, $class->implements,
|
||||
$class->stmts, $newNode->getAttributes()
|
||||
);
|
||||
}
|
||||
@@ -63,6 +66,6 @@ class PrintableNewAnonClassNode extends Expr {
|
||||
}
|
||||
|
||||
public function getSubNodeNames(): array {
|
||||
return ['attrGroups', 'args', 'extends', 'implements', 'stmts'];
|
||||
return ['attrGroups', 'flags', 'args', 'extends', 'implements', 'stmts'];
|
||||
}
|
||||
}
|
||||
|
@@ -85,6 +85,10 @@ class Emulative extends Lexer {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($errorHandler === null) {
|
||||
$errorHandler = new ErrorHandler\Throwing();
|
||||
}
|
||||
|
||||
$this->patches = [];
|
||||
foreach ($emulators as $emulator) {
|
||||
$code = $emulator->preprocessCode($code, $this->patches);
|
||||
|
@@ -45,7 +45,7 @@ abstract class KeywordEmulator extends TokenEmulator {
|
||||
|
||||
public function reverseEmulate(string $code, array $tokens): array {
|
||||
$keywordToken = $this->getKeywordToken();
|
||||
foreach ($tokens as $i => $token) {
|
||||
foreach ($tokens as $token) {
|
||||
if ($token->id === $keywordToken) {
|
||||
$token->id = \T_STRING;
|
||||
}
|
||||
|
@@ -30,7 +30,7 @@ class ArrowFunction extends Expr implements FunctionLike {
|
||||
* static?: bool,
|
||||
* byRef?: bool,
|
||||
* params?: Node\Param[],
|
||||
* returnType?: null|string|Node\Identifier|Node\Name|Node\ComplexType,
|
||||
* returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
|
||||
* attrGroups?: Node\AttributeGroup[]
|
||||
* } $subNodes Array of the following subnodes:
|
||||
* 'expr' : Expression body
|
||||
@@ -46,8 +46,7 @@ class ArrowFunction extends Expr implements FunctionLike {
|
||||
$this->static = $subNodes['static'] ?? false;
|
||||
$this->byRef = $subNodes['byRef'] ?? false;
|
||||
$this->params = $subNodes['params'] ?? [];
|
||||
$returnType = $subNodes['returnType'] ?? null;
|
||||
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
||||
$this->returnType = $subNodes['returnType'] ?? null;
|
||||
$this->expr = $subNodes['expr'];
|
||||
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ class Closure extends Expr implements FunctionLike {
|
||||
* byRef?: bool,
|
||||
* params?: Node\Param[],
|
||||
* uses?: ClosureUse[],
|
||||
* returnType?: null|string|Node\Identifier|Node\Name|Node\ComplexType,
|
||||
* returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
|
||||
* stmts?: Node\Stmt[],
|
||||
* attrGroups?: Node\AttributeGroup[],
|
||||
* } $subNodes Array of the following optional subnodes:
|
||||
@@ -50,8 +50,7 @@ class Closure extends Expr implements FunctionLike {
|
||||
$this->byRef = $subNodes['byRef'] ?? false;
|
||||
$this->params = $subNodes['params'] ?? [];
|
||||
$this->uses = $subNodes['uses'] ?? [];
|
||||
$returnType = $subNodes['returnType'] ?? null;
|
||||
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
||||
$this->returnType = $subNodes['returnType'] ?? null;
|
||||
$this->stmts = $subNodes['stmts'] ?? [];
|
||||
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||
}
|
||||
|
@@ -5,8 +5,8 @@ namespace PhpParser\Node;
|
||||
use PhpParser\NodeAbstract;
|
||||
|
||||
class Name extends NodeAbstract {
|
||||
/** @var string[] Parts of the name */
|
||||
public $parts;
|
||||
/** @var string Name as string */
|
||||
public $name;
|
||||
|
||||
/** @var array<string, bool> */
|
||||
private static $specialClassNames = [
|
||||
@@ -23,11 +23,20 @@ class Name extends NodeAbstract {
|
||||
*/
|
||||
final public function __construct($name, array $attributes = []) {
|
||||
$this->attributes = $attributes;
|
||||
$this->parts = self::prepareName($name);
|
||||
$this->name = self::prepareName($name);
|
||||
}
|
||||
|
||||
public function getSubNodeNames(): array {
|
||||
return ['parts'];
|
||||
return ['name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get parts of name (split by the namespace separator).
|
||||
*
|
||||
* @return string[] Parts of name
|
||||
*/
|
||||
public function getParts(): array {
|
||||
return \explode('\\', $this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -36,7 +45,10 @@ class Name extends NodeAbstract {
|
||||
* @return string First part of the name
|
||||
*/
|
||||
public function getFirst(): string {
|
||||
return $this->parts[0];
|
||||
if (false !== $pos = \strpos($this->name, '\\')) {
|
||||
return \substr($this->name, 0, $pos);
|
||||
}
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,7 +57,10 @@ class Name extends NodeAbstract {
|
||||
* @return string Last part of the name
|
||||
*/
|
||||
public function getLast(): string {
|
||||
return $this->parts[count($this->parts) - 1];
|
||||
if (false !== $pos = \strrpos($this->name, '\\')) {
|
||||
return \substr($this->name, $pos + 1);
|
||||
}
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +69,7 @@ class Name extends NodeAbstract {
|
||||
* @return bool Whether the name is unqualified
|
||||
*/
|
||||
public function isUnqualified(): bool {
|
||||
return 1 === count($this->parts);
|
||||
return false === \strpos($this->name, '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,7 +78,7 @@ class Name extends NodeAbstract {
|
||||
* @return bool Whether the name is qualified
|
||||
*/
|
||||
public function isQualified(): bool {
|
||||
return 1 < count($this->parts);
|
||||
return false !== \strpos($this->name, '\\');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -91,7 +106,7 @@ class Name extends NodeAbstract {
|
||||
* @return string String representation
|
||||
*/
|
||||
public function toString(): string {
|
||||
return implode('\\', $this->parts);
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +126,7 @@ class Name extends NodeAbstract {
|
||||
* @return string Lowercased string representation
|
||||
*/
|
||||
public function toLowerString(): string {
|
||||
return strtolower(implode('\\', $this->parts));
|
||||
return strtolower($this->name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,8 +135,7 @@ class Name extends NodeAbstract {
|
||||
* @return bool Whether identifier is a special class name
|
||||
*/
|
||||
public function isSpecialClassName(): bool {
|
||||
return count($this->parts) === 1
|
||||
&& isset(self::$specialClassNames[strtolower($this->parts[0])]);
|
||||
return isset(self::$specialClassNames[strtolower($this->name)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,7 +145,7 @@ class Name extends NodeAbstract {
|
||||
* @return string String representation
|
||||
*/
|
||||
public function __toString(): string {
|
||||
return implode('\\', $this->parts);
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +165,16 @@ class Name extends NodeAbstract {
|
||||
* @return static|null Sliced name
|
||||
*/
|
||||
public function slice(int $offset, ?int $length = null) {
|
||||
$numParts = count($this->parts);
|
||||
if ($offset === 1 && $length === null) {
|
||||
// Short-circuit the common case.
|
||||
if (false !== $pos = \strpos($this->name, '\\')) {
|
||||
return new static(\substr($this->name, $pos + 1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
$parts = \explode('\\', $this->name);
|
||||
$numParts = \count($parts);
|
||||
|
||||
$realOffset = $offset < 0 ? $offset + $numParts : $offset;
|
||||
if ($realOffset < 0 || $realOffset > $numParts) {
|
||||
@@ -172,7 +195,7 @@ class Name extends NodeAbstract {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new static(array_slice($this->parts, $realOffset, $realLength), $this->attributes);
|
||||
return new static(array_slice($parts, $realOffset, $realLength), $this->attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -197,42 +220,42 @@ class Name extends NodeAbstract {
|
||||
return null;
|
||||
}
|
||||
if (null === $name1) {
|
||||
return new static(self::prepareName($name2), $attributes);
|
||||
return new static($name2, $attributes);
|
||||
}
|
||||
if (null === $name2) {
|
||||
return new static(self::prepareName($name1), $attributes);
|
||||
return new static($name1, $attributes);
|
||||
} else {
|
||||
return new static(
|
||||
array_merge(self::prepareName($name1), self::prepareName($name2)), $attributes
|
||||
self::prepareName($name1) . '\\' . self::prepareName($name2), $attributes
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares a (string, array or Name node) name for use in name changing methods by converting
|
||||
* it to an array.
|
||||
* it to a string.
|
||||
*
|
||||
* @param string|string[]|self $name Name to prepare
|
||||
*
|
||||
* @return string[] Prepared name
|
||||
* @return string Prepared name
|
||||
*/
|
||||
private static function prepareName($name): array {
|
||||
private static function prepareName($name): string {
|
||||
if (\is_string($name)) {
|
||||
if ('' === $name) {
|
||||
throw new \InvalidArgumentException('Name cannot be empty');
|
||||
}
|
||||
|
||||
return explode('\\', $name);
|
||||
return $name;
|
||||
}
|
||||
if (\is_array($name)) {
|
||||
if (empty($name)) {
|
||||
throw new \InvalidArgumentException('Name cannot be empty');
|
||||
}
|
||||
|
||||
return $name;
|
||||
return implode('\\', $name);
|
||||
}
|
||||
if ($name instanceof self) {
|
||||
return $name->parts;
|
||||
return $name->name;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException(
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace PhpParser\Node;
|
||||
|
||||
use PhpParser\Node;
|
||||
|
||||
class NullableType extends ComplexType {
|
||||
/** @var Identifier|Name Type */
|
||||
public $type;
|
||||
@@ -9,12 +11,12 @@ class NullableType extends ComplexType {
|
||||
/**
|
||||
* Constructs a nullable type (wrapping another type).
|
||||
*
|
||||
* @param string|Identifier|Name $type Type
|
||||
* @param Identifier|Name $type Type
|
||||
* @param array<string, mixed> $attributes Additional attributes
|
||||
*/
|
||||
public function __construct($type, array $attributes = []) {
|
||||
public function __construct(Node $type, array $attributes = []) {
|
||||
$this->attributes = $attributes;
|
||||
$this->type = \is_string($type) ? new Identifier($type) : $type;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function getSubNodeNames(): array {
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace PhpParser\Node;
|
||||
|
||||
use PhpParser\Modifiers;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeAbstract;
|
||||
|
||||
class Param extends NodeAbstract {
|
||||
@@ -26,7 +27,7 @@ class Param extends NodeAbstract {
|
||||
*
|
||||
* @param Expr\Variable|Expr\Error $var Parameter variable
|
||||
* @param null|Expr $default Default value
|
||||
* @param null|string|Identifier|Name|ComplexType $type Type declaration
|
||||
* @param null|Identifier|Name|ComplexType $type Type declaration
|
||||
* @param bool $byRef Whether is passed by reference
|
||||
* @param bool $variadic Whether this is a variadic argument
|
||||
* @param array<string, mixed> $attributes Additional attributes
|
||||
@@ -34,14 +35,14 @@ class Param extends NodeAbstract {
|
||||
* @param list<AttributeGroup> $attrGroups PHP attribute groups
|
||||
*/
|
||||
public function __construct(
|
||||
$var, ?Expr $default = null, $type = null,
|
||||
$var, ?Expr $default = null, ?Node $type = null,
|
||||
bool $byRef = false, bool $variadic = false,
|
||||
array $attributes = [],
|
||||
int $flags = 0,
|
||||
array $attrGroups = []
|
||||
) {
|
||||
$this->attributes = $attributes;
|
||||
$this->type = \is_string($type) ? new Identifier($type) : $type;
|
||||
$this->type = $type;
|
||||
$this->byRef = $byRef;
|
||||
$this->variadic = $variadic;
|
||||
$this->var = $var;
|
||||
|
@@ -10,31 +10,36 @@ class ClassConst extends Node\Stmt {
|
||||
public $flags;
|
||||
/** @var Node\Const_[] Constant declarations */
|
||||
public $consts;
|
||||
/** @var Node\AttributeGroup[] */
|
||||
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||
public $attrGroups;
|
||||
/** @var Node\Identifier|Node\Name|Node\ComplexType|null Type declaration */
|
||||
public $type;
|
||||
|
||||
/**
|
||||
* Constructs a class const list node.
|
||||
*
|
||||
* @param Node\Const_[] $consts Constant declarations
|
||||
* @param int $flags Modifiers
|
||||
* @param Node\Const_[] $consts Constant declarations
|
||||
* @param int $flags Modifiers
|
||||
* @param array<string, mixed> $attributes Additional attributes
|
||||
* @param list<Node\AttributeGroup> $attrGroups PHP attribute groups
|
||||
* @param null|Node\Identifier|Node\Name|Node\ComplexType $type Type declaration
|
||||
*/
|
||||
public function __construct(
|
||||
array $consts,
|
||||
int $flags = 0,
|
||||
array $attributes = [],
|
||||
array $attrGroups = []
|
||||
array $attrGroups = [],
|
||||
?Node $type = null
|
||||
) {
|
||||
$this->attributes = $attributes;
|
||||
$this->flags = $flags;
|
||||
$this->consts = $consts;
|
||||
$this->attrGroups = $attrGroups;
|
||||
$this->type = $type;
|
||||
}
|
||||
|
||||
public function getSubNodeNames(): array {
|
||||
return ['attrGroups', 'flags', 'consts'];
|
||||
return ['attrGroups', 'flags', 'type', 'consts'];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -51,7 +51,7 @@ class ClassMethod extends Node\Stmt implements FunctionLike {
|
||||
* flags?: int,
|
||||
* byRef?: bool,
|
||||
* params?: Node\Param[],
|
||||
* returnType?: null|string|Node\Identifier|Node\Name|Node\ComplexType,
|
||||
* returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
|
||||
* stmts?: Node\Stmt[]|null,
|
||||
* attrGroups?: Node\AttributeGroup[],
|
||||
* } $subNodes Array of the following optional subnodes:
|
||||
@@ -69,8 +69,7 @@ class ClassMethod extends Node\Stmt implements FunctionLike {
|
||||
$this->byRef = $subNodes['byRef'] ?? false;
|
||||
$this->name = \is_string($name) ? new Node\Identifier($name) : $name;
|
||||
$this->params = $subNodes['params'] ?? [];
|
||||
$returnType = $subNodes['returnType'] ?? null;
|
||||
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
||||
$this->returnType = $subNodes['returnType'] ?? null;
|
||||
$this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : [];
|
||||
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||
}
|
||||
|
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace PhpParser\Node\Stmt;
|
||||
|
||||
use PhpParser\Error;
|
||||
use PhpParser\Modifiers;
|
||||
use PhpParser\Node;
|
||||
|
||||
|
@@ -29,7 +29,7 @@ class Function_ extends Node\Stmt implements FunctionLike {
|
||||
* @param array{
|
||||
* byRef?: bool,
|
||||
* params?: Node\Param[],
|
||||
* returnType?: null|string|Node\Identifier|Node\Name|Node\ComplexType,
|
||||
* returnType?: null|Node\Identifier|Node\Name|Node\ComplexType,
|
||||
* stmts?: Node\Stmt[],
|
||||
* attrGroups?: Node\AttributeGroup[],
|
||||
* } $subNodes Array of the following optional subnodes:
|
||||
@@ -45,8 +45,7 @@ class Function_ extends Node\Stmt implements FunctionLike {
|
||||
$this->byRef = $subNodes['byRef'] ?? false;
|
||||
$this->name = \is_string($name) ? new Node\Identifier($name) : $name;
|
||||
$this->params = $subNodes['params'] ?? [];
|
||||
$returnType = $subNodes['returnType'] ?? null;
|
||||
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
||||
$this->returnType = $subNodes['returnType'] ?? null;
|
||||
$this->stmts = $subNodes['stmts'] ?? [];
|
||||
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||
}
|
||||
|
@@ -25,14 +25,14 @@ class Property extends Node\Stmt {
|
||||
* @param int $flags Modifiers
|
||||
* @param PropertyItem[] $props Properties
|
||||
* @param array<string, mixed> $attributes Additional attributes
|
||||
* @param null|string|Identifier|Name|ComplexType $type Type declaration
|
||||
* @param null|Identifier|Name|ComplexType $type Type declaration
|
||||
* @param Node\AttributeGroup[] $attrGroups PHP attribute groups
|
||||
*/
|
||||
public function __construct(int $flags, array $props, array $attributes = [], $type = null, array $attrGroups = []) {
|
||||
public function __construct(int $flags, array $props, array $attributes = [], ?Node $type = null, array $attrGroups = []) {
|
||||
$this->attributes = $attributes;
|
||||
$this->flags = $flags;
|
||||
$this->props = $props;
|
||||
$this->type = \is_string($type) ? new Identifier($type) : $type;
|
||||
$this->type = $type;
|
||||
$this->attrGroups = $attrGroups;
|
||||
}
|
||||
|
||||
|
@@ -3,7 +3,6 @@
|
||||
namespace PhpParser\Node;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
|
||||
class UseItem extends Node\Stmt {
|
||||
|
@@ -3,7 +3,6 @@
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr\Include_;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\GroupUse;
|
||||
use PhpParser\Node\Stmt\Use_;
|
||||
use PhpParser\Node\UseItem;
|
||||
|
@@ -4,39 +4,24 @@ namespace PhpParser;
|
||||
|
||||
class NodeTraverser implements NodeTraverserInterface {
|
||||
/**
|
||||
* If NodeVisitor::enterNode() returns DONT_TRAVERSE_CHILDREN, child nodes
|
||||
* of the current node will not be traversed for any visitors.
|
||||
*
|
||||
* For subsequent visitors enterNode() will still be called on the current
|
||||
* node and leaveNode() will also be invoked for the current node.
|
||||
* @deprecated Use NodeVisitor::DONT_TRAVERSE_CHILDREN instead.
|
||||
*/
|
||||
public const DONT_TRAVERSE_CHILDREN = 1;
|
||||
public const DONT_TRAVERSE_CHILDREN = NodeVisitor::DONT_TRAVERSE_CHILDREN;
|
||||
|
||||
/**
|
||||
* If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns
|
||||
* STOP_TRAVERSAL, traversal is aborted.
|
||||
*
|
||||
* The afterTraverse() method will still be invoked.
|
||||
* @deprecated Use NodeVisitor::STOP_TRAVERSAL instead.
|
||||
*/
|
||||
public const STOP_TRAVERSAL = 2;
|
||||
public const STOP_TRAVERSAL = NodeVisitor::STOP_TRAVERSAL;
|
||||
|
||||
/**
|
||||
* If NodeVisitor::leaveNode() returns REMOVE_NODE for a node that occurs
|
||||
* in an array, it will be removed from the array.
|
||||
*
|
||||
* For subsequent visitors leaveNode() will still be invoked for the
|
||||
* removed node.
|
||||
* @deprecated Use NodeVisitor::REMOVE_NODE instead.
|
||||
*/
|
||||
public const REMOVE_NODE = 3;
|
||||
public const REMOVE_NODE = NodeVisitor::REMOVE_NODE;
|
||||
|
||||
/**
|
||||
* If NodeVisitor::enterNode() returns DONT_TRAVERSE_CURRENT_AND_CHILDREN, child nodes
|
||||
* of the current node will not be traversed for any visitors.
|
||||
*
|
||||
* For subsequent visitors enterNode() will not be called as well.
|
||||
* leaveNode() will be invoked for visitors that has enterNode() method invoked.
|
||||
* @deprecated Use NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN instead.
|
||||
*/
|
||||
public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = 4;
|
||||
public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
|
||||
|
||||
/** @var list<NodeVisitor> Visitors */
|
||||
protected $visitors = [];
|
||||
@@ -63,11 +48,9 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
* @param NodeVisitor $visitor
|
||||
*/
|
||||
public function removeVisitor(NodeVisitor $visitor): void {
|
||||
foreach ($this->visitors as $index => $storedVisitor) {
|
||||
if ($storedVisitor === $visitor) {
|
||||
unset($this->visitors[$index]);
|
||||
break;
|
||||
}
|
||||
$index = array_search($visitor, $this->visitors);
|
||||
if ($index !== false) {
|
||||
array_splice($this->visitors, $index, 1, []);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +72,8 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
|
||||
$nodes = $this->traverseArray($nodes);
|
||||
|
||||
foreach ($this->visitors as $visitor) {
|
||||
for ($i = \count($this->visitors) - 1; $i >= 0; --$i) {
|
||||
$visitor = $this->visitors[$i];
|
||||
if (null !== $return = $visitor->afterTraverse($nodes)) {
|
||||
$nodes = $return;
|
||||
}
|
||||
@@ -102,37 +86,37 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
* Recursively traverse a node.
|
||||
*
|
||||
* @param Node $node Node to traverse.
|
||||
*
|
||||
* @return Node Result of traversal (may be original node or new one)
|
||||
*/
|
||||
protected function traverseNode(Node $node): Node {
|
||||
protected function traverseNode(Node $node): void {
|
||||
foreach ($node->getSubNodeNames() as $name) {
|
||||
$subNode =& $node->$name;
|
||||
$subNode = $node->$name;
|
||||
|
||||
if (\is_array($subNode)) {
|
||||
$subNode = $this->traverseArray($subNode);
|
||||
$node->$name = $this->traverseArray($subNode);
|
||||
if ($this->stopTraversal) {
|
||||
break;
|
||||
}
|
||||
} elseif ($subNode instanceof Node) {
|
||||
$traverseChildren = true;
|
||||
$breakVisitorIndex = null;
|
||||
$visitorIndex = -1;
|
||||
|
||||
foreach ($this->visitors as $visitorIndex => $visitor) {
|
||||
$return = $visitor->enterNode($subNode);
|
||||
if (null !== $return) {
|
||||
if ($return instanceof Node) {
|
||||
$this->ensureReplacementReasonable($subNode, $return);
|
||||
$subNode = $return;
|
||||
} elseif (self::DONT_TRAVERSE_CHILDREN === $return) {
|
||||
$subNode = $node->$name = $return;
|
||||
} elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) {
|
||||
$traverseChildren = false;
|
||||
} elseif (self::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
|
||||
} elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
|
||||
$traverseChildren = false;
|
||||
$breakVisitorIndex = $visitorIndex;
|
||||
break;
|
||||
} elseif (self::STOP_TRAVERSAL === $return) {
|
||||
} elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
|
||||
$this->stopTraversal = true;
|
||||
break 2;
|
||||
} elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
|
||||
$node->$name = null;
|
||||
continue 2;
|
||||
} else {
|
||||
throw new \LogicException(
|
||||
'enterNode() returned invalid value of type ' . gettype($return)
|
||||
@@ -142,22 +126,26 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
}
|
||||
|
||||
if ($traverseChildren) {
|
||||
$subNode = $this->traverseNode($subNode);
|
||||
$this->traverseNode($subNode);
|
||||
if ($this->stopTraversal) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->visitors as $visitorIndex => $visitor) {
|
||||
for (; $visitorIndex >= 0; --$visitorIndex) {
|
||||
$visitor = $this->visitors[$visitorIndex];
|
||||
$return = $visitor->leaveNode($subNode);
|
||||
|
||||
if (null !== $return) {
|
||||
if ($return instanceof Node) {
|
||||
$this->ensureReplacementReasonable($subNode, $return);
|
||||
$subNode = $return;
|
||||
} elseif (self::STOP_TRAVERSAL === $return) {
|
||||
$subNode = $node->$name = $return;
|
||||
} elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
|
||||
$this->stopTraversal = true;
|
||||
break 2;
|
||||
} elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
|
||||
$node->$name = null;
|
||||
break;
|
||||
} elseif (\is_array($return)) {
|
||||
throw new \LogicException(
|
||||
'leaveNode() may only return an array ' .
|
||||
@@ -169,15 +157,9 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($breakVisitorIndex === $visitorIndex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +175,7 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
foreach ($nodes as $i => &$node) {
|
||||
if ($node instanceof Node) {
|
||||
$traverseChildren = true;
|
||||
$breakVisitorIndex = null;
|
||||
$visitorIndex = -1;
|
||||
|
||||
foreach ($this->visitors as $visitorIndex => $visitor) {
|
||||
$return = $visitor->enterNode($node);
|
||||
@@ -204,18 +186,20 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
} elseif (\is_array($return)) {
|
||||
$doNodes[] = [$i, $return];
|
||||
continue 2;
|
||||
} elseif (self::REMOVE_NODE === $return) {
|
||||
} elseif (NodeVisitor::REMOVE_NODE === $return) {
|
||||
$doNodes[] = [$i, []];
|
||||
continue 2;
|
||||
} elseif (self::DONT_TRAVERSE_CHILDREN === $return) {
|
||||
} elseif (NodeVisitor::DONT_TRAVERSE_CHILDREN === $return) {
|
||||
$traverseChildren = false;
|
||||
} elseif (self::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
|
||||
} elseif (NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN === $return) {
|
||||
$traverseChildren = false;
|
||||
$breakVisitorIndex = $visitorIndex;
|
||||
break;
|
||||
} elseif (self::STOP_TRAVERSAL === $return) {
|
||||
} elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
|
||||
$this->stopTraversal = true;
|
||||
break 2;
|
||||
} elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
|
||||
throw new \LogicException(
|
||||
'REPLACE_WITH_NULL can not be used if the parent structure is an array');
|
||||
} else {
|
||||
throw new \LogicException(
|
||||
'enterNode() returned invalid value of type ' . gettype($return)
|
||||
@@ -225,13 +209,14 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
}
|
||||
|
||||
if ($traverseChildren) {
|
||||
$node = $this->traverseNode($node);
|
||||
$this->traverseNode($node);
|
||||
if ($this->stopTraversal) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->visitors as $visitorIndex => $visitor) {
|
||||
for (; $visitorIndex >= 0; --$visitorIndex) {
|
||||
$visitor = $this->visitors[$visitorIndex];
|
||||
$return = $visitor->leaveNode($node);
|
||||
|
||||
if (null !== $return) {
|
||||
@@ -241,22 +226,21 @@ class NodeTraverser implements NodeTraverserInterface {
|
||||
} elseif (\is_array($return)) {
|
||||
$doNodes[] = [$i, $return];
|
||||
break;
|
||||
} elseif (self::REMOVE_NODE === $return) {
|
||||
} elseif (NodeVisitor::REMOVE_NODE === $return) {
|
||||
$doNodes[] = [$i, []];
|
||||
break;
|
||||
} elseif (self::STOP_TRAVERSAL === $return) {
|
||||
} elseif (NodeVisitor::STOP_TRAVERSAL === $return) {
|
||||
$this->stopTraversal = true;
|
||||
break 2;
|
||||
} elseif (NodeVisitor::REPLACE_WITH_NULL === $return) {
|
||||
throw new \LogicException(
|
||||
'REPLACE_WITH_NULL can not be used if the parent structure is an array');
|
||||
} else {
|
||||
throw new \LogicException(
|
||||
'leaveNode() returned invalid value of type ' . gettype($return)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ($breakVisitorIndex === $visitorIndex) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} elseif (\is_array($node)) {
|
||||
throw new \LogicException('Invalid node structure: Contains nested arrays');
|
||||
|
@@ -3,6 +3,48 @@
|
||||
namespace PhpParser;
|
||||
|
||||
interface NodeVisitor {
|
||||
/**
|
||||
* If NodeVisitor::enterNode() returns DONT_TRAVERSE_CHILDREN, child nodes
|
||||
* of the current node will not be traversed for any visitors.
|
||||
*
|
||||
* For subsequent visitors enterNode() will still be called on the current
|
||||
* node and leaveNode() will also be invoked for the current node.
|
||||
*/
|
||||
public const DONT_TRAVERSE_CHILDREN = 1;
|
||||
|
||||
/**
|
||||
* If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns
|
||||
* STOP_TRAVERSAL, traversal is aborted.
|
||||
*
|
||||
* The afterTraverse() method will still be invoked.
|
||||
*/
|
||||
public const STOP_TRAVERSAL = 2;
|
||||
|
||||
/**
|
||||
* If NodeVisitor::leaveNode() returns REMOVE_NODE for a node that occurs
|
||||
* in an array, it will be removed from the array.
|
||||
*
|
||||
* For subsequent visitors leaveNode() will still be invoked for the
|
||||
* removed node.
|
||||
*/
|
||||
public const REMOVE_NODE = 3;
|
||||
|
||||
/**
|
||||
* If NodeVisitor::enterNode() returns DONT_TRAVERSE_CURRENT_AND_CHILDREN, child nodes
|
||||
* of the current node will not be traversed for any visitors.
|
||||
*
|
||||
* For subsequent visitors enterNode() will not be called as well.
|
||||
* leaveNode() will be invoked for visitors that has enterNode() method invoked.
|
||||
*/
|
||||
public const DONT_TRAVERSE_CURRENT_AND_CHILDREN = 4;
|
||||
|
||||
/**
|
||||
* If NodeVisitor::enterNode() or NodeVisitor::leaveNode() returns REPLACE_WITH_NULL,
|
||||
* the node will be replaced with null. This is not a legal return value if the node is part
|
||||
* of an array, rather than another node.
|
||||
*/
|
||||
public const REPLACE_WITH_NULL = 5;
|
||||
|
||||
/**
|
||||
* Called once before traversal.
|
||||
*
|
||||
@@ -24,14 +66,16 @@ interface NodeVisitor {
|
||||
* => $node stays as-is
|
||||
* * array (of Nodes)
|
||||
* => The return value is merged into the parent array (at the position of the $node)
|
||||
* * NodeTraverser::REMOVE_NODE
|
||||
* * NodeVisitor::REMOVE_NODE
|
||||
* => $node is removed from the parent array
|
||||
* * NodeTraverser::DONT_TRAVERSE_CHILDREN
|
||||
* * NodeVisitor::REPLACE_WITH_NULL
|
||||
* => $node is replaced with null
|
||||
* * NodeVisitor::DONT_TRAVERSE_CHILDREN
|
||||
* => Children of $node are not traversed. $node stays as-is
|
||||
* * NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN
|
||||
* * NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN
|
||||
* => Further visitors for the current node are skipped, and its children are not
|
||||
* traversed. $node stays as-is.
|
||||
* * NodeTraverser::STOP_TRAVERSAL
|
||||
* * NodeVisitor::STOP_TRAVERSAL
|
||||
* => Traversal is aborted. $node stays as-is
|
||||
* * otherwise
|
||||
* => $node is set to the return value
|
||||
@@ -48,9 +92,11 @@ interface NodeVisitor {
|
||||
* Return value semantics:
|
||||
* * null
|
||||
* => $node stays as-is
|
||||
* * NodeTraverser::REMOVE_NODE
|
||||
* * NodeVisitor::REMOVE_NODE
|
||||
* => $node is removed from the parent array
|
||||
* * NodeTraverser::STOP_TRAVERSAL
|
||||
* * NodeVisitor::REPLACE_WITH_NULL
|
||||
* => $node is replaced with null
|
||||
* * NodeVisitor::STOP_TRAVERSAL
|
||||
* => Traversal is aborted. $node stays as-is
|
||||
* * array (of Nodes)
|
||||
* => The return value is merged into the parent array (at the position of the $node)
|
||||
|
@@ -3,7 +3,7 @@
|
||||
namespace PhpParser\NodeVisitor;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeTraverser;
|
||||
use PhpParser\NodeVisitor;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
|
||||
/**
|
||||
@@ -41,7 +41,7 @@ class FirstFindingVisitor extends NodeVisitorAbstract {
|
||||
$filterCallback = $this->filterCallback;
|
||||
if ($filterCallback($node)) {
|
||||
$this->foundNode = $node;
|
||||
return NodeTraverser::STOP_TRAVERSAL;
|
||||
return NodeVisitor::STOP_TRAVERSAL;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -141,6 +141,13 @@ class PhpVersion {
|
||||
return $this->id < 70000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this version allows DEL (\x7f) to occur in identifiers.
|
||||
*/
|
||||
public function allowsDelInIdentifiers(): bool {
|
||||
return $this->id < 70100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this version support yield in expression context without parentheses.
|
||||
*/
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser;
|
||||
|
||||
|
@@ -80,15 +80,15 @@ class Standard extends PrettyPrinterAbstract {
|
||||
// Names
|
||||
|
||||
protected function pName(Name $node): string {
|
||||
return implode('\\', $node->parts);
|
||||
return $node->name;
|
||||
}
|
||||
|
||||
protected function pName_FullyQualified(Name\FullyQualified $node): string {
|
||||
return '\\' . implode('\\', $node->parts);
|
||||
return '\\' . $node->name;
|
||||
}
|
||||
|
||||
protected function pName_Relative(Name\Relative $node): string {
|
||||
return 'namespace\\' . implode('\\', $node->parts);
|
||||
return 'namespace\\' . $node->name;
|
||||
}
|
||||
|
||||
// Magic Constants
|
||||
@@ -134,12 +134,12 @@ class Standard extends PrettyPrinterAbstract {
|
||||
$label = $node->getAttribute('docLabel');
|
||||
if ($label && !$this->containsEndLabel($node->value, $label)) {
|
||||
if ($node->value === '') {
|
||||
return "<<<'$label'\n$label" . $this->docStringEndToken;
|
||||
return "<<<'$label'{$this->newline}$label{$this->docStringEndToken}";
|
||||
}
|
||||
|
||||
// Make sure trailing \r is not combined with following \n into CRLF.
|
||||
if ($node->value[strlen($node->value) - 1] !== "\r") {
|
||||
return "<<<'$label'\n$node->value\n$label"
|
||||
return "<<<'$label'{$this->newline}{$node->value}{$this->newline}$label"
|
||||
. $this->docStringEndToken;
|
||||
}
|
||||
}
|
||||
@@ -152,10 +152,10 @@ class Standard extends PrettyPrinterAbstract {
|
||||
$escaped = $this->escapeString($node->value, null);
|
||||
if ($label && !$this->containsEndLabel($escaped, $label)) {
|
||||
if ($escaped === '') {
|
||||
return "<<<$label\n$label" . $this->docStringEndToken;
|
||||
return "<<<$label{$this->newline}$label{$this->docStringEndToken}";
|
||||
}
|
||||
|
||||
return "<<<$label\n" . $escaped . "\n$label"
|
||||
return "<<<$label{$this->newline}$escaped{$this->newline}$label"
|
||||
. $this->docStringEndToken;
|
||||
}
|
||||
/* break missing intentionally */
|
||||
@@ -174,11 +174,11 @@ class Standard extends PrettyPrinterAbstract {
|
||||
&& $node->parts[0] instanceof Node\InterpolatedStringPart
|
||||
&& $node->parts[0]->value === ''
|
||||
) {
|
||||
return "<<<$label\n$label" . $this->docStringEndToken;
|
||||
return "<<<$label{$this->newline}$label{$this->docStringEndToken}";
|
||||
}
|
||||
|
||||
return "<<<$label\n" . $this->pEncapsList($node->parts, null) . "\n$label"
|
||||
. $this->docStringEndToken;
|
||||
return "<<<$label{$this->newline}" . $this->pEncapsList($node->parts, null)
|
||||
. "{$this->newline}$label{$this->docStringEndToken}";
|
||||
}
|
||||
}
|
||||
return '"' . $this->pEncapsList($node->parts, '"') . '"';
|
||||
@@ -728,7 +728,7 @@ class Standard extends PrettyPrinterAbstract {
|
||||
}
|
||||
return $this->pPrefixOp(
|
||||
Expr\Yield_::class, 'yield ' . $this->pKey($node->key),
|
||||
$node->value, $precedence, $lhsPrecedence);
|
||||
$node->value, $precedence, $lhsPrecedence);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -842,7 +842,9 @@ class Standard extends PrettyPrinterAbstract {
|
||||
protected function pStmt_ClassConst(Stmt\ClassConst $node): string {
|
||||
return $this->pAttrGroups($node->attrGroups)
|
||||
. $this->pModifiers($node->flags)
|
||||
. 'const ' . $this->pCommaSeparated($node->consts) . ';';
|
||||
. 'const '
|
||||
. (null !== $node->type ? $this->p($node->type) . ' ' : '')
|
||||
. $this->pCommaSeparated($node->consts) . ';';
|
||||
}
|
||||
|
||||
protected function pStmt_Function(Stmt\Function_ $node): string {
|
||||
@@ -881,6 +883,10 @@ class Standard extends PrettyPrinterAbstract {
|
||||
}
|
||||
|
||||
protected function pStmt_Else(Stmt\Else_ $node): string {
|
||||
if (\count($node->stmts) === 1 && $node->stmts[0] instanceof Stmt\If_) {
|
||||
// Print as "else if" rather than "else { if }"
|
||||
return 'else ' . $this->p($node->stmts[0]);
|
||||
}
|
||||
return 'else {' . $this->pStmts($node->stmts) . $this->nl . '}';
|
||||
}
|
||||
|
||||
@@ -987,7 +993,7 @@ class Standard extends PrettyPrinterAbstract {
|
||||
}
|
||||
|
||||
protected function pStmt_InlineHTML(Stmt\InlineHTML $node): string {
|
||||
$newline = $node->getAttribute('hasLeadingNewline', true) ? "\n" : '';
|
||||
$newline = $node->getAttribute('hasLeadingNewline', true) ? $this->newline : '';
|
||||
return '?>' . $newline . $node->value . '<?php ';
|
||||
}
|
||||
|
||||
|
@@ -104,6 +104,8 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
|
||||
/** @var int Current indentation level. */
|
||||
protected $indentLevel;
|
||||
/** @var string Newline style. Does not include current indentation. */
|
||||
protected $newline;
|
||||
/** @var string Newline including current indentation. */
|
||||
protected $nl;
|
||||
/** @var string|null Token placed at end of doc string to ensure it is followed by a newline.
|
||||
@@ -159,20 +161,29 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
* Creates a pretty printer instance using the given options.
|
||||
*
|
||||
* Supported options:
|
||||
* * PhpVersion $phpVersion: The PHP version to target (default to PHP 7.0). This option
|
||||
* * PhpVersion $phpVersion: The PHP version to target (default to PHP 7.1). This option
|
||||
* controls compatibility of the generated code with older PHP
|
||||
* versions in cases where a simple stylistic choice exists (e.g.
|
||||
* array() vs []). It is safe to pretty-print an AST for a newer
|
||||
* PHP version while specifying an older target (but the result will
|
||||
* of course not be compatible with the older version in that case).
|
||||
* * string $newline: The newline style to use. Should be "\n" (default) or "\r\n".
|
||||
* * bool $shortArraySyntax: Whether to use [] instead of array() as the default array
|
||||
* syntax, if the node does not specify a format. Defaults to whether
|
||||
* the phpVersion support short array syntax.
|
||||
*
|
||||
* @param array{phpVersion?: PhpVersion, shortArraySyntax?: bool} $options Dictionary of formatting options
|
||||
* @param array{
|
||||
* phpVersion?: PhpVersion, newline?: string, shortArraySyntax?: bool
|
||||
* } $options Dictionary of formatting options
|
||||
*/
|
||||
public function __construct(array $options = []) {
|
||||
$this->phpVersion = $options['phpVersion'] ?? PhpVersion::fromComponents(7, 0);
|
||||
$this->phpVersion = $options['phpVersion'] ?? PhpVersion::fromComponents(7, 1);
|
||||
|
||||
$this->newline = $options['newline'] ?? "\n";
|
||||
if ($this->newline !== "\n" && $this->newline != "\r\n") {
|
||||
throw new \LogicException('Option "newline" must be one of "\n" or "\r\n"');
|
||||
}
|
||||
|
||||
$this->shortArraySyntax =
|
||||
$options['shortArraySyntax'] ?? $this->phpVersion->supportsShortArraySyntax();
|
||||
$this->docStringEndToken =
|
||||
@@ -184,7 +195,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
*/
|
||||
protected function resetState(): void {
|
||||
$this->indentLevel = 0;
|
||||
$this->nl = "\n";
|
||||
$this->nl = $this->newline;
|
||||
$this->origTokens = null;
|
||||
}
|
||||
|
||||
@@ -195,7 +206,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
*/
|
||||
protected function setIndentLevel(int $level): void {
|
||||
$this->indentLevel = $level;
|
||||
$this->nl = "\n" . \str_repeat(' ', $level);
|
||||
$this->nl = $this->newline . \str_repeat(' ', $level);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,7 +223,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
protected function outdent(): void {
|
||||
assert($this->indentLevel >= 4);
|
||||
$this->indentLevel -= 4;
|
||||
$this->nl = "\n" . str_repeat(' ', $this->indentLevel);
|
||||
$this->nl = $this->newline . str_repeat(' ', $this->indentLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -250,13 +261,13 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
*/
|
||||
public function prettyPrintFile(array $stmts): string {
|
||||
if (!$stmts) {
|
||||
return "<?php\n\n";
|
||||
return "<?php" . $this->newline . $this->newline;
|
||||
}
|
||||
|
||||
$p = "<?php\n\n" . $this->prettyPrint($stmts);
|
||||
$p = "<?php" . $this->newline . $this->newline . $this->prettyPrint($stmts);
|
||||
|
||||
if ($stmts[0] instanceof Stmt\InlineHTML) {
|
||||
$p = preg_replace('/^<\?php\s+\?>\n?/', '', $p);
|
||||
$p = preg_replace('/^<\?php\s+\?>\r?\n?/', '', $p);
|
||||
}
|
||||
if ($stmts[count($stmts) - 1] instanceof Stmt\InlineHTML) {
|
||||
$p = preg_replace('/<\?php$/', '', rtrim($p));
|
||||
@@ -290,8 +301,11 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
protected function handleMagicTokens(string $str): string {
|
||||
if ($this->docStringEndToken !== null) {
|
||||
// Replace doc-string-end tokens with nothing or a newline
|
||||
$str = str_replace($this->docStringEndToken . ";\n", ";\n", $str);
|
||||
$str = str_replace($this->docStringEndToken, "\n", $str);
|
||||
$str = str_replace(
|
||||
$this->docStringEndToken . ';' . $this->newline,
|
||||
';' . $this->newline,
|
||||
$str);
|
||||
$str = str_replace($this->docStringEndToken, $this->newline, $str);
|
||||
}
|
||||
|
||||
return $str;
|
||||
@@ -537,10 +551,10 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
} else {
|
||||
// Fallback
|
||||
// TODO Add <?php properly
|
||||
$result = "<?php\n" . $this->pStmts($stmts, false);
|
||||
$result = "<?php" . $this->newline . $this->pStmts($stmts, false);
|
||||
}
|
||||
|
||||
return ltrim($this->handleMagicTokens($result));
|
||||
return $this->handleMagicTokens($result);
|
||||
}
|
||||
|
||||
protected function pFallback(Node $node, int $precedence, int $lhsPrecedence): string {
|
||||
@@ -1244,10 +1258,12 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
|
||||
$this->labelCharMap = [];
|
||||
for ($i = 0; $i < 256; $i++) {
|
||||
// Since PHP 7.1 The lower range is 0x80. However, we also want to support code for
|
||||
// older versions.
|
||||
$chr = chr($i);
|
||||
$this->labelCharMap[$chr] = $i >= 0x7f || ctype_alnum($chr);
|
||||
$this->labelCharMap[$chr] = $i >= 0x80 || ctype_alnum($chr);
|
||||
}
|
||||
|
||||
if ($this->phpVersion->allowsDelInIdentifiers()) {
|
||||
$this->labelCharMap["\x7f"] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1389,6 +1405,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
'Param->default' => $stripEquals,
|
||||
'Stmt_Break->num' => $stripBoth,
|
||||
'Stmt_Catch->var' => $stripLeft,
|
||||
'Stmt_ClassConst->type' => $stripRight,
|
||||
'Stmt_ClassMethod->returnType' => $stripColon,
|
||||
'Stmt_Class->extends' => ['left' => \T_EXTENDS],
|
||||
'Stmt_Enum->scalarType' => $stripColon,
|
||||
@@ -1432,6 +1449,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
'Stmt_Break->num' => [\T_BREAK, false, ' ', null],
|
||||
'Stmt_Catch->var' => [null, false, ' ', null],
|
||||
'Stmt_ClassMethod->returnType' => [')', false, ': ', null],
|
||||
'Stmt_ClassConst->type' => [\T_CONST, false, ' ', null],
|
||||
'Stmt_Class->extends' => [null, false, ' extends ', null],
|
||||
'Stmt_Enum->scalarType' => [null, false, ' : ', null],
|
||||
'Stmt_EnumCase->expr' => [null, false, ' = ', null],
|
||||
@@ -1629,6 +1647,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
|
||||
Stmt\ClassMethod::class . '->flags' => ['pModifiers', \T_FUNCTION],
|
||||
Stmt\Class_::class . '->flags' => ['pModifiers', \T_CLASS],
|
||||
Stmt\Property::class . '->flags' => ['pModifiers', \T_VARIABLE],
|
||||
PrintableNewAnonClassNode::class . '->flags' => ['pModifiers', \T_CLASS],
|
||||
Param::class . '->flags' => ['pModifiers', \T_VARIABLE],
|
||||
Expr\Closure::class . '->static' => ['pStatic', \T_FUNCTION],
|
||||
Expr\ArrowFunction::class . '->static' => ['pStatic', \T_FN],
|
||||
|
@@ -142,6 +142,18 @@ class ClassConstTest extends \PHPUnit\Framework\TestCase {
|
||||
);
|
||||
}
|
||||
|
||||
public function testType() {
|
||||
$node = $this->createClassConstBuilder('TYPE', 1)
|
||||
->setType('int')
|
||||
->getNode();
|
||||
$this->assertEquals(
|
||||
new Stmt\ClassConst(
|
||||
[new Const_('TYPE', new Int_(1))],
|
||||
0, [], [], new Identifier('int')),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestDefaultValues
|
||||
*/
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace PhpParser\Builder;
|
||||
|
||||
use PhpParser\Modifiers;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Attribute;
|
||||
@@ -204,6 +205,54 @@ class ParamTest extends \PHPUnit\Framework\TestCase {
|
||||
);
|
||||
}
|
||||
|
||||
public function testMakePublic() {
|
||||
$node = $this->createParamBuilder('test')
|
||||
->makePublic()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Node\Param(new Expr\Variable('test'), null, null, false, false, [], Modifiers::PUBLIC),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testMakeProtected() {
|
||||
$node = $this->createParamBuilder('test')
|
||||
->makeProtected()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Node\Param(new Expr\Variable('test'), null, null, false, false, [], Modifiers::PROTECTED),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testMakePrivate() {
|
||||
$node = $this->createParamBuilder('test')
|
||||
->makePrivate()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Node\Param(new Expr\Variable('test'), null, null, false, false, [], Modifiers::PRIVATE),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testMakeReadonly() {
|
||||
$node = $this->createParamBuilder('test')
|
||||
->makeReadonly()
|
||||
->getNode()
|
||||
;
|
||||
|
||||
$this->assertEquals(
|
||||
new Node\Param(new Expr\Variable('test'), null, null, false, false, [], Modifiers::READONLY),
|
||||
$node
|
||||
);
|
||||
}
|
||||
|
||||
public function testAddAttribute() {
|
||||
$attribute = new Attribute(
|
||||
new Name('Attr'),
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Builder\Class_;
|
||||
use PhpParser\Node\Identifier;
|
||||
use PhpParser\Node\Scalar;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Expr;
|
||||
@@ -136,7 +137,7 @@ class BuilderHelpersTest extends \PHPUnit\Framework\TestCase {
|
||||
$intName = new Node\Name('int');
|
||||
$this->assertSame($intName, BuilderHelpers::normalizeType($intName));
|
||||
|
||||
$intNullable = new Node\NullableType('int');
|
||||
$intNullable = new Node\NullableType(new Identifier('int'));
|
||||
$this->assertSame($intNullable, BuilderHelpers::normalizeType($intNullable));
|
||||
|
||||
$unionType = new Node\UnionType([new Node\Identifier('int'), new Node\Identifier('string')]);
|
||||
|
@@ -47,7 +47,7 @@ class CodeTestParser {
|
||||
}
|
||||
$result .= $lastPart;
|
||||
}
|
||||
return $result;
|
||||
return $result . "\n";
|
||||
}
|
||||
|
||||
private function extractMode(string $expected): array {
|
||||
|
@@ -33,47 +33,37 @@ class CommentTest extends \PHPUnit\Framework\TestCase {
|
||||
['// Some text', '// Some text'],
|
||||
['/* Some text */', '/* Some text */'],
|
||||
[
|
||||
'/**
|
||||
* Some text.
|
||||
* Some more text.
|
||||
*/',
|
||||
'/**
|
||||
* Some text.
|
||||
* Some more text.
|
||||
*/'
|
||||
"/**\n * Some text.\n * Some more text.\n */",
|
||||
"/**\n * Some text.\n * Some more text.\n */"
|
||||
],
|
||||
[
|
||||
'/*
|
||||
Some text.
|
||||
Some more text.
|
||||
*/',
|
||||
'/*
|
||||
Some text.
|
||||
Some more text.
|
||||
*/'
|
||||
"/**\r\n * Some text.\r\n * Some more text.\r\n */",
|
||||
"/**\n * Some text.\n * Some more text.\n */"
|
||||
],
|
||||
[
|
||||
'/* Some text.
|
||||
More text.
|
||||
Even more text. */',
|
||||
'/* Some text.
|
||||
More text.
|
||||
Even more text. */'
|
||||
"/*\n Some text.\n Some more text.\n */",
|
||||
"/*\n Some text.\n Some more text.\n*/"
|
||||
],
|
||||
[
|
||||
'/* Some text.
|
||||
More text.
|
||||
Indented text. */',
|
||||
'/* Some text.
|
||||
More text.
|
||||
Indented text. */',
|
||||
"/*\r\n Some text.\r\n Some more text.\r\n */",
|
||||
"/*\n Some text.\n Some more text.\n*/"
|
||||
],
|
||||
[
|
||||
"/* Some text.\n More text.\n Even more text. */",
|
||||
"/* Some text.\n More text.\n Even more text. */"
|
||||
],
|
||||
[
|
||||
"/* Some text.\r\n More text.\r\n Even more text. */",
|
||||
"/* Some text.\n More text.\n Even more text. */"
|
||||
],
|
||||
[
|
||||
"/* Some text.\n More text.\n Indented text. */",
|
||||
"/* Some text.\n More text.\n Indented text. */",
|
||||
],
|
||||
// invalid comment -> no reformatting
|
||||
[
|
||||
'hallo
|
||||
world',
|
||||
'hallo
|
||||
world',
|
||||
"hello\n world",
|
||||
"hello\n world",
|
||||
],
|
||||
];
|
||||
}
|
||||
|
@@ -65,4 +65,15 @@ class DifferTest extends \PHPUnit\Framework\TestCase {
|
||||
['abcde', 'axyzue', 'a-b-c-d+x+y+z+ue'],
|
||||
];
|
||||
}
|
||||
|
||||
public function testNonContiguousIndices() {
|
||||
$differ = new Differ(function ($a, $b) {
|
||||
return $a === $b;
|
||||
});
|
||||
$diff = $differ->diff([0 => 'a', 2 => 'b'], [0 => 'a', 3 => 'b']);
|
||||
$this->assertEquals([
|
||||
new DiffElem(DiffElem::TYPE_KEEP, 'a', 'a'),
|
||||
new DiffElem(DiffElem::TYPE_KEEP, 'b', 'b'),
|
||||
], $diff);
|
||||
}
|
||||
}
|
||||
|
@@ -47,6 +47,14 @@ class LexerTest extends \PHPUnit\Framework\TestCase {
|
||||
];
|
||||
}
|
||||
|
||||
public function testDefaultErrorHandler() {
|
||||
$this->expectException(Error::class);
|
||||
$this->expectExceptionMessage('Unterminated comment on line 1');
|
||||
$lexer = $this->getLexer();
|
||||
$lexer->startLexing("<?php readonly /*");
|
||||
$lexer->getNextToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideTestLex
|
||||
*/
|
||||
|
@@ -5,23 +5,25 @@ namespace PhpParser\Node;
|
||||
class NameTest extends \PHPUnit\Framework\TestCase {
|
||||
public function testConstruct() {
|
||||
$name = new Name(['foo', 'bar']);
|
||||
$this->assertSame(['foo', 'bar'], $name->parts);
|
||||
$this->assertSame('foo\bar', $name->name);
|
||||
|
||||
$name = new Name('foo\bar');
|
||||
$this->assertSame(['foo', 'bar'], $name->parts);
|
||||
$this->assertSame('foo\bar', $name->name);
|
||||
|
||||
$name = new Name($name);
|
||||
$this->assertSame(['foo', 'bar'], $name->parts);
|
||||
$this->assertSame('foo\bar', $name->name);
|
||||
}
|
||||
|
||||
public function testGet() {
|
||||
$name = new Name('foo');
|
||||
$this->assertSame('foo', $name->getFirst());
|
||||
$this->assertSame('foo', $name->getLast());
|
||||
$this->assertSame(['foo'], $name->getParts());
|
||||
|
||||
$name = new Name('foo\bar');
|
||||
$this->assertSame('foo', $name->getFirst());
|
||||
$this->assertSame('bar', $name->getLast());
|
||||
$this->assertSame(['foo', 'bar'], $name->getParts());
|
||||
}
|
||||
|
||||
public function testToString() {
|
||||
|
@@ -34,10 +34,7 @@ class NodeDumperTest extends \PHPUnit\Framework\TestCase {
|
||||
[
|
||||
new Node\Name(['Hallo', 'World']),
|
||||
'Name(
|
||||
parts: array(
|
||||
0: Hallo
|
||||
1: World
|
||||
)
|
||||
name: Hallo\World
|
||||
)'
|
||||
],
|
||||
[
|
||||
|
@@ -3,7 +3,10 @@
|
||||
namespace PhpParser;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Scalar\Int_;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use PhpParser\Node\Stmt\Else_;
|
||||
use PhpParser\Node\Stmt\If_;
|
||||
|
||||
class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
public function testNonModifying() {
|
||||
@@ -34,8 +37,9 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
$str2Node = new String_('Bar');
|
||||
$printNode = new Expr\Print_($str1Node);
|
||||
|
||||
// first visitor changes the node, second verifies the change
|
||||
$visitor1 = new NodeVisitorForTesting([
|
||||
// Visitor 2 performs changes, visitors 1 and 3 observe the changes.
|
||||
$visitor1 = new NodeVisitorForTesting();
|
||||
$visitor2 = new NodeVisitorForTesting([
|
||||
['beforeTraverse', [], [$str1Node]],
|
||||
['enterNode', $str1Node, $printNode],
|
||||
['enterNode', $str1Node, $str2Node],
|
||||
@@ -43,22 +47,35 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
['leaveNode', $printNode, $str1Node],
|
||||
['afterTraverse', [$str1Node], []],
|
||||
]);
|
||||
$visitor2 = new NodeVisitorForTesting();
|
||||
$visitor3 = new NodeVisitorForTesting();
|
||||
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor1);
|
||||
$traverser->addVisitor($visitor2);
|
||||
$traverser->addVisitor($visitor3);
|
||||
|
||||
// as all operations are reversed we end where we start
|
||||
$this->assertEquals([], $traverser->traverse([]));
|
||||
$this->assertEquals([
|
||||
['beforeTraverse', [$str1Node]],
|
||||
['enterNode', $printNode],
|
||||
['enterNode', $str2Node],
|
||||
// Sees nodes before changes on entry.
|
||||
['beforeTraverse', []],
|
||||
['enterNode', $str1Node],
|
||||
['enterNode', $str1Node],
|
||||
// Sees nodes after changes on leave.
|
||||
['leaveNode', $str1Node],
|
||||
['leaveNode', $str1Node],
|
||||
['afterTraverse', []],
|
||||
], $visitor2->trace);
|
||||
], $visitor1->trace);
|
||||
$this->assertEquals([
|
||||
// Sees nodes after changes on entry.
|
||||
['beforeTraverse', [$str1Node]],
|
||||
['enterNode', $printNode],
|
||||
['enterNode', $str2Node],
|
||||
// Sees nodes before changes on leave.
|
||||
['leaveNode', $str2Node],
|
||||
['leaveNode', $printNode],
|
||||
['afterTraverse', [$str1Node]],
|
||||
], $visitor3->trace);
|
||||
}
|
||||
|
||||
public function testRemoveFromLeave() {
|
||||
@@ -66,13 +83,13 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
$str2Node = new String_('Bar');
|
||||
|
||||
$visitor = new NodeVisitorForTesting([
|
||||
['leaveNode', $str1Node, NodeTraverser::REMOVE_NODE],
|
||||
['leaveNode', $str1Node, NodeVisitor::REMOVE_NODE],
|
||||
]);
|
||||
$visitor2 = new NodeVisitorForTesting();
|
||||
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor);
|
||||
$traverser->addVisitor($visitor2);
|
||||
$traverser->addVisitor($visitor);
|
||||
|
||||
$stmts = [$str1Node, $str2Node];
|
||||
$this->assertEquals([$str2Node], $traverser->traverse($stmts));
|
||||
@@ -90,7 +107,7 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
$str2Node = new String_('Bar');
|
||||
|
||||
$visitor = new NodeVisitorForTesting([
|
||||
['enterNode', $str1Node, NodeTraverser::REMOVE_NODE],
|
||||
['enterNode', $str1Node, NodeVisitor::REMOVE_NODE],
|
||||
]);
|
||||
$visitor2 = new NodeVisitorForTesting();
|
||||
|
||||
@@ -172,10 +189,10 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
$stmts = [$printNode, $negNode];
|
||||
|
||||
$visitor1 = new NodeVisitorForTesting([
|
||||
['enterNode', $printNode, NodeTraverser::DONT_TRAVERSE_CHILDREN],
|
||||
['enterNode', $printNode, NodeVisitor::DONT_TRAVERSE_CHILDREN],
|
||||
]);
|
||||
$visitor2 = new NodeVisitorForTesting([
|
||||
['enterNode', $mulNode, NodeTraverser::DONT_TRAVERSE_CHILDREN],
|
||||
['enterNode', $mulNode, NodeVisitor::DONT_TRAVERSE_CHILDREN],
|
||||
]);
|
||||
|
||||
$expectedTrace = [
|
||||
@@ -209,8 +226,8 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
$stmts = [$printNode, $negNode];
|
||||
|
||||
$visitor1 = new NodeVisitorForTesting([
|
||||
['enterNode', $printNode, NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN],
|
||||
['enterNode', $mulNode, NodeTraverser::DONT_TRAVERSE_CURRENT_AND_CHILDREN],
|
||||
['enterNode', $printNode, NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN],
|
||||
['enterNode', $mulNode, NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN],
|
||||
['leaveNode', $mulNode, $divNode],
|
||||
]);
|
||||
$visitor2 = new NodeVisitorForTesting();
|
||||
@@ -250,7 +267,7 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
// From enterNode() with array parent
|
||||
$visitor = new NodeVisitorForTesting([
|
||||
['enterNode', $mulNode, NodeTraverser::STOP_TRAVERSAL],
|
||||
['enterNode', $mulNode, NodeVisitor::STOP_TRAVERSAL],
|
||||
]);
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor);
|
||||
@@ -263,7 +280,7 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
// From enterNode with Node parent
|
||||
$visitor = new NodeVisitorForTesting([
|
||||
['enterNode', $varNode1, NodeTraverser::STOP_TRAVERSAL],
|
||||
['enterNode', $varNode1, NodeVisitor::STOP_TRAVERSAL],
|
||||
]);
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor);
|
||||
@@ -277,7 +294,7 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
// From leaveNode with Node parent
|
||||
$visitor = new NodeVisitorForTesting([
|
||||
['leaveNode', $varNode1, NodeTraverser::STOP_TRAVERSAL],
|
||||
['leaveNode', $varNode1, NodeVisitor::STOP_TRAVERSAL],
|
||||
]);
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor);
|
||||
@@ -292,7 +309,7 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
// From leaveNode with array parent
|
||||
$visitor = new NodeVisitorForTesting([
|
||||
['leaveNode', $mulNode, NodeTraverser::STOP_TRAVERSAL],
|
||||
['leaveNode', $mulNode, NodeVisitor::STOP_TRAVERSAL],
|
||||
]);
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor);
|
||||
@@ -310,8 +327,8 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
// Check that pending array modifications are still carried out
|
||||
$visitor = new NodeVisitorForTesting([
|
||||
['leaveNode', $mulNode, NodeTraverser::REMOVE_NODE],
|
||||
['enterNode', $printNode, NodeTraverser::STOP_TRAVERSAL],
|
||||
['leaveNode', $mulNode, NodeVisitor::REMOVE_NODE],
|
||||
['enterNode', $printNode, NodeVisitor::STOP_TRAVERSAL],
|
||||
]);
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor);
|
||||
@@ -329,6 +346,44 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
], $visitor->trace);
|
||||
}
|
||||
|
||||
public function testReplaceWithNull() {
|
||||
$one = new Int_(1);
|
||||
$else1 = new Else_();
|
||||
$else2 = new Else_();
|
||||
$if1 = new If_($one, ['else' => $else1]);
|
||||
$if2 = new If_($one, ['else' => $else2]);
|
||||
$stmts = [$if1, $if2];
|
||||
$visitor1 = new NodeVisitorForTesting([
|
||||
['enterNode', $else1, NodeVisitor::REPLACE_WITH_NULL],
|
||||
['leaveNode', $else2, NodeVisitor::REPLACE_WITH_NULL],
|
||||
]);
|
||||
$visitor2 = new NodeVisitorForTesting();
|
||||
$traverser = new NodeTraverser();
|
||||
$traverser->addVisitor($visitor1);
|
||||
$traverser->addVisitor($visitor2);
|
||||
$newStmts = $traverser->traverse($stmts);
|
||||
$this->assertEquals([
|
||||
new If_($one),
|
||||
new If_($one),
|
||||
], $newStmts);
|
||||
$this->assertEquals([
|
||||
['beforeTraverse', $stmts],
|
||||
['enterNode', $if1],
|
||||
['enterNode', $one],
|
||||
// We never see the if1 Else node.
|
||||
['leaveNode', $one],
|
||||
['leaveNode', $if1],
|
||||
['enterNode', $if2],
|
||||
['enterNode', $one],
|
||||
['leaveNode', $one],
|
||||
// We do see the if2 Else node, as it will only be replaced afterwards.
|
||||
['enterNode', $else2],
|
||||
['leaveNode', $else2],
|
||||
['leaveNode', $if2],
|
||||
['afterTraverse', $stmts],
|
||||
], $visitor2->trace);
|
||||
}
|
||||
|
||||
public function testRemovingVisitor() {
|
||||
$visitor1 = new class () extends NodeVisitorAbstract {};
|
||||
$visitor2 = new class () extends NodeVisitorAbstract {};
|
||||
@@ -348,7 +403,7 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
|
||||
$traverser->removeVisitor($visitor2);
|
||||
|
||||
$postExpected = [0 => $visitor1, 2 => $visitor3];
|
||||
$postExpected = [$visitor1, $visitor3];
|
||||
$this->assertSame($postExpected, $getVisitors());
|
||||
}
|
||||
|
||||
@@ -401,6 +456,12 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
$visitor8 = new NodeVisitorForTesting([
|
||||
['enterNode', $num, new Node\Stmt\Return_()],
|
||||
]);
|
||||
$visitor9 = new NodeVisitorForTesting([
|
||||
['enterNode', $expr, NodeVisitor::REPLACE_WITH_NULL],
|
||||
]);
|
||||
$visitor10 = new NodeVisitorForTesting([
|
||||
['leaveNode', $expr, NodeVisitor::REPLACE_WITH_NULL],
|
||||
]);
|
||||
|
||||
return [
|
||||
[$stmts, $visitor1, 'enterNode() returned invalid value of type string'],
|
||||
@@ -411,6 +472,8 @@ class NodeTraverserTest extends \PHPUnit\Framework\TestCase {
|
||||
[$stmts, $visitor6, 'leaveNode() returned invalid value of type bool'],
|
||||
[$stmts, $visitor7, 'Trying to replace statement (Stmt_Expression) with expression (Scalar_Int). Are you missing a Stmt_Expression wrapper?'],
|
||||
[$stmts, $visitor8, 'Trying to replace expression (Scalar_Int) with statement (Stmt_Return)'],
|
||||
[$stmts, $visitor9, 'REPLACE_WITH_NULL can not be used if the parent structure is an array'],
|
||||
[$stmts, $visitor10, 'REPLACE_WITH_NULL can not be used if the parent structure is an array'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -460,7 +460,7 @@ EOC;
|
||||
$stmt = $stmts[0];
|
||||
|
||||
$assign = $stmt->stmts[1]->expr;
|
||||
$this->assertSame(['Bar', 'Baz'], $assign->expr->class->parts);
|
||||
$this->assertSame('Bar\\Baz', $assign->expr->class->name);
|
||||
}
|
||||
|
||||
public function testSpecialClassNamesAreCaseInsensitive() {
|
||||
|
@@ -210,6 +210,7 @@ use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Scalar;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Modifiers;
|
||||
\$fn = function(&\$stmts) { $modification };
|
||||
CODE
|
||||
);
|
||||
@@ -269,4 +270,49 @@ CODE
|
||||
$this->getTests(__DIR__ . '/../code/parser', 'test')
|
||||
);
|
||||
}
|
||||
|
||||
public function testWindowsNewline() {
|
||||
$prettyPrinter = new Standard(['newline' => "\r\n"]);
|
||||
$stmts = [
|
||||
new Stmt\If_(new Int_(1), [
|
||||
'stmts' => [
|
||||
new Stmt\Echo_([new String_('Hello')]),
|
||||
new Stmt\Echo_([new String_('World')]),
|
||||
],
|
||||
]),
|
||||
];
|
||||
$code = $prettyPrinter->prettyPrint($stmts);
|
||||
$this->assertSame("if (1) {\r\n echo 'Hello';\r\n echo 'World';\r\n}", $code);
|
||||
$code = $prettyPrinter->prettyPrintFile($stmts);
|
||||
$this->assertSame("<?php\r\n\r\nif (1) {\r\n echo 'Hello';\r\n echo 'World';\r\n}", $code);
|
||||
|
||||
$stmts = [new Stmt\InlineHTML('Hello world')];
|
||||
$code = $prettyPrinter->prettyPrintFile($stmts);
|
||||
$this->assertSame("Hello world", $code);
|
||||
|
||||
$stmts = [
|
||||
new Stmt\Expression(new String_('Test', [
|
||||
'kind' => String_::KIND_NOWDOC,
|
||||
'docLabel' => 'STR'
|
||||
])),
|
||||
new Stmt\Expression(new String_('Test 2', [
|
||||
'kind' => String_::KIND_HEREDOC,
|
||||
'docLabel' => 'STR'
|
||||
])),
|
||||
new Stmt\Expression(new InterpolatedString([new InterpolatedStringPart('Test 3')], [
|
||||
'kind' => String_::KIND_HEREDOC,
|
||||
'docLabel' => 'STR'
|
||||
])),
|
||||
];
|
||||
$code = $prettyPrinter->prettyPrint($stmts);
|
||||
$this->assertSame(
|
||||
"<<<'STR'\r\nTest\r\nSTR;\r\n<<<STR\r\nTest 2\r\nSTR;\r\n<<<STR\r\nTest 3\r\nSTR\r\n;",
|
||||
$code);
|
||||
}
|
||||
|
||||
public function testInvalidNewline() {
|
||||
$this->expectException(\LogicException::class);
|
||||
$this->expectExceptionMessage('Option "newline" must be one of "\n" or "\r\n"');
|
||||
new PrettyPrinter\Standard(['newline' => 'foo']);
|
||||
}
|
||||
}
|
||||
|
9
test/code/formatPreservation/delAfterIdentifier.test
Normal file
9
test/code/formatPreservation/delAfterIdentifier.test
Normal file
@@ -0,0 +1,9 @@
|
||||
DEL after identifier
|
||||
-----
|
||||
<?php
|
||||
"$a@@{ "\x7f" }@@";
|
||||
-----
|
||||
/* do nothing */
|
||||
-----
|
||||
<?php
|
||||
"$a@@{ "\x7f" }@@";
|
@@ -110,3 +110,13 @@ function test()
|
||||
foo();
|
||||
baz();
|
||||
}
|
||||
-----
|
||||
|
||||
|
||||
<?php $x;
|
||||
-----
|
||||
/* Do nothing, but make sure leading newlines are preserved. */
|
||||
-----
|
||||
|
||||
|
||||
<?php $x;
|
||||
|
@@ -49,6 +49,10 @@ X
|
||||
private
|
||||
$x
|
||||
;
|
||||
|
||||
const
|
||||
X
|
||||
= 1;
|
||||
}
|
||||
|
||||
foreach (
|
||||
@@ -86,6 +90,7 @@ $stmts[9]->expr = new Expr\Variable('x');
|
||||
$stmts[10]->extends = new Node\Name\FullyQualified('Bar');
|
||||
$stmts[10]->stmts[0]->returnType = new Node\Name('Y');
|
||||
$stmts[10]->stmts[1]->props[0]->default = new Scalar\DNumber(42.0);
|
||||
$stmts[10]->stmts[2]->type = new Node\Identifier('int');
|
||||
$stmts[11]->keyVar = new Expr\Variable('z');
|
||||
$stmts[12]->vars[0]->default = new Scalar\String_('abc');
|
||||
$stmts[13]->finally = new Stmt\Finally_([]);
|
||||
@@ -140,6 +145,10 @@ X extends \Bar
|
||||
private
|
||||
$x = 42.0
|
||||
;
|
||||
|
||||
const int
|
||||
X
|
||||
= 1;
|
||||
}
|
||||
|
||||
foreach (
|
||||
|
@@ -141,7 +141,7 @@ function test() {
|
||||
namespace
|
||||
Foo;
|
||||
-----
|
||||
$stmts[0]->name->parts[0] = 'Xyz';
|
||||
$stmts[0]->name->name = 'Xyz';
|
||||
-----
|
||||
<?php
|
||||
namespace
|
||||
|
@@ -208,3 +208,15 @@ class Foo
|
||||
{
|
||||
}
|
||||
}
|
||||
-----
|
||||
<?php
|
||||
class Test {
|
||||
use A, B;
|
||||
}
|
||||
-----
|
||||
unset($stmts[0]->stmts[0]->traits[0]);
|
||||
-----
|
||||
<?php
|
||||
class Test {
|
||||
use B;
|
||||
}
|
||||
|
@@ -55,3 +55,14 @@ function test(
|
||||
public T3 $z
|
||||
= 'x',
|
||||
) {}
|
||||
-----
|
||||
<?php
|
||||
new class {};
|
||||
new readonly class {};
|
||||
-----
|
||||
$stmts[0]->expr->class->flags = Modifiers::READONLY;
|
||||
$stmts[1]->expr->class->flags = 0;
|
||||
-----
|
||||
<?php
|
||||
readonly class {};
|
||||
class {};
|
||||
|
@@ -35,6 +35,11 @@ Bar
|
||||
y
|
||||
;
|
||||
}
|
||||
|
||||
const
|
||||
int
|
||||
X
|
||||
= 1;
|
||||
}
|
||||
|
||||
$foo [ $bar ];
|
||||
@@ -97,6 +102,7 @@ $stmts[2]->extends = null;
|
||||
$stmts[2]->stmts[0]->returnType = null;
|
||||
$stmts[2]->stmts[1]->props[0]->default = null;
|
||||
$stmts[2]->stmts[2]->adaptations[0]->newName = null;
|
||||
$stmts[2]->stmts[3]->type = null;
|
||||
$stmts[3]->expr->dim = null;
|
||||
$stmts[4]->expr->expr = null;
|
||||
$stmts[5]->expr->if = null;
|
||||
@@ -141,6 +147,10 @@ Foo
|
||||
public
|
||||
;
|
||||
}
|
||||
|
||||
const
|
||||
X
|
||||
= 1;
|
||||
}
|
||||
|
||||
$foo [];
|
||||
|
@@ -7,9 +7,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -22,9 +20,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@@ -13,9 +13,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -24,9 +22,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: bar
|
||||
)
|
||||
name: bar
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -35,9 +31,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: baz
|
||||
)
|
||||
name: baz
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -56,9 +50,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -67,9 +59,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: bar
|
||||
)
|
||||
name: bar
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -78,9 +68,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: baz
|
||||
)
|
||||
name: baz
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -99,9 +87,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -110,9 +96,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: bar
|
||||
)
|
||||
name: bar
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -121,9 +105,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: baz
|
||||
)
|
||||
name: baz
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -140,9 +122,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: abc
|
||||
)
|
||||
name: abc
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -339,9 +319,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: T
|
||||
)
|
||||
name: T
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -402,9 +380,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
name: Expr_Error(
|
||||
)
|
||||
@@ -420,9 +396,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
name: Expr_Error(
|
||||
)
|
||||
@@ -455,9 +429,7 @@ Syntax error, unexpected T_THROW, expecting ';' from 15:1 to 15:5
|
||||
array(
|
||||
0: Stmt_Namespace(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
stmts: array(
|
||||
0: Stmt_Use(
|
||||
@@ -466,9 +438,7 @@ array(
|
||||
0: UseItem(
|
||||
type: TYPE_UNKNOWN (0)
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
alias: null
|
||||
)
|
||||
@@ -480,9 +450,7 @@ array(
|
||||
0: UseItem(
|
||||
type: TYPE_UNKNOWN (0)
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: a
|
||||
)
|
||||
name: a
|
||||
)
|
||||
alias: null
|
||||
)
|
||||
@@ -491,17 +459,13 @@ array(
|
||||
2: Stmt_GroupUse(
|
||||
type: TYPE_UNKNOWN (0)
|
||||
prefix: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
uses: array(
|
||||
0: UseItem(
|
||||
type: TYPE_NORMAL (1)
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
name: B
|
||||
)
|
||||
alias: null
|
||||
)
|
||||
@@ -619,17 +583,13 @@ array(
|
||||
0: Stmt_GroupUse(
|
||||
type: TYPE_UNKNOWN (0)
|
||||
prefix: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
uses: array(
|
||||
0: UseItem(
|
||||
type: TYPE_NORMAL (1)
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
name: B
|
||||
)
|
||||
alias: null
|
||||
)
|
||||
@@ -638,17 +598,13 @@ array(
|
||||
1: Stmt_GroupUse(
|
||||
type: TYPE_FUNCTION (2)
|
||||
prefix: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
uses: array(
|
||||
0: UseItem(
|
||||
type: TYPE_UNKNOWN (0)
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: b
|
||||
)
|
||||
name: b
|
||||
)
|
||||
alias: null
|
||||
)
|
||||
@@ -660,9 +616,7 @@ array(
|
||||
0: UseItem(
|
||||
type: TYPE_UNKNOWN (0)
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
alias: null
|
||||
)
|
||||
@@ -690,18 +644,14 @@ array(
|
||||
extends: null
|
||||
implements: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: Y
|
||||
)
|
||||
name: Y
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
0: Stmt_TraitUse(
|
||||
traits: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
)
|
||||
adaptations: array(
|
||||
@@ -710,26 +660,20 @@ array(
|
||||
1: Stmt_TraitUse(
|
||||
traits: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
)
|
||||
adaptations: array(
|
||||
0: Stmt_TraitUseAdaptation_Precedence(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
method: Identifier(
|
||||
name: b
|
||||
)
|
||||
insteadof: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: C
|
||||
)
|
||||
name: C
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -739,6 +683,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -774,9 +719,7 @@ array(
|
||||
)
|
||||
extends: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: J
|
||||
)
|
||||
name: J
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -866,18 +809,14 @@ array(
|
||||
0: Stmt_Expression[3:1 - 3:11](
|
||||
expr: Expr_FuncCall[3:1 - 3:10](
|
||||
name: Name[3:1 - 3:3](
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
0: Arg[3:5 - 3:9](
|
||||
name: null
|
||||
value: Expr_ClassConstFetch[3:5 - 3:9](
|
||||
class: Name[3:5 - 3:7](
|
||||
parts: array(
|
||||
0: Bar
|
||||
)
|
||||
name: Bar
|
||||
)
|
||||
name: Expr_Error[3:10 - 3:9](
|
||||
)
|
||||
@@ -1017,9 +956,7 @@ array(
|
||||
)
|
||||
flags: 0
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: Type
|
||||
)
|
||||
name: Type
|
||||
)
|
||||
byRef: false
|
||||
variadic: false
|
||||
@@ -1050,9 +987,7 @@ array(
|
||||
)
|
||||
flags: 0
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: Type1
|
||||
)
|
||||
name: Type1
|
||||
)
|
||||
byRef: false
|
||||
variadic: false
|
||||
@@ -1066,9 +1001,7 @@ array(
|
||||
)
|
||||
flags: 0
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: Type2
|
||||
)
|
||||
name: Type2
|
||||
)
|
||||
byRef: false
|
||||
variadic: false
|
||||
@@ -1157,9 +1090,7 @@ array(
|
||||
)
|
||||
flags: 0
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: Bar
|
||||
)
|
||||
name: Bar
|
||||
)
|
||||
byRef: false
|
||||
variadic: false
|
||||
@@ -1197,9 +1128,7 @@ array(
|
||||
)
|
||||
flags: 0
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: Baz
|
||||
)
|
||||
name: Baz
|
||||
)
|
||||
byRef: false
|
||||
variadic: false
|
||||
@@ -1226,9 +1155,7 @@ array(
|
||||
)
|
||||
flags: 0
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
byRef: false
|
||||
variadic: false
|
||||
@@ -1495,6 +1422,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
|
@@ -220,9 +220,7 @@ array(
|
||||
key: null
|
||||
value: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: getArr
|
||||
)
|
||||
name: getArr
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -240,9 +238,7 @@ array(
|
||||
key: null
|
||||
value: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: arrGen
|
||||
)
|
||||
name: arrGen
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -260,9 +256,7 @@ array(
|
||||
key: null
|
||||
value: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: ArrayIterator
|
||||
)
|
||||
name: ArrayIterator
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -329,9 +323,7 @@ array(
|
||||
key: null
|
||||
value: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: getArr
|
||||
)
|
||||
name: getArr
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -383,9 +375,7 @@ array(
|
||||
key: null
|
||||
value: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: arrGen
|
||||
)
|
||||
name: arrGen
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -12,9 +12,7 @@ array(
|
||||
)
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
name: B
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -36,9 +34,7 @@ array(
|
||||
)
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
name: B
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -190,10 +190,7 @@ array(
|
||||
)
|
||||
)
|
||||
returnType: Name_FullyQualified(
|
||||
parts: array(
|
||||
0: Foo
|
||||
1: Bar
|
||||
)
|
||||
name: Foo\Bar
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
|
@@ -110,9 +110,7 @@ array(
|
||||
name: a
|
||||
)
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
name: B
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@@ -682,9 +682,7 @@ array(
|
||||
value: Expr_BooleanNot(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: false
|
||||
)
|
||||
name: false
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@@ -8,15 +8,11 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
name: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: bar
|
||||
)
|
||||
name: bar
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -30,9 +26,7 @@ array(
|
||||
)
|
||||
name: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: bar
|
||||
)
|
||||
name: bar
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -12,9 +12,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: f
|
||||
)
|
||||
name: f
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -23,9 +21,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: f
|
||||
)
|
||||
name: f
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -42,9 +38,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: f
|
||||
)
|
||||
name: f
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -69,9 +63,7 @@ array(
|
||||
3: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: f
|
||||
)
|
||||
name: f
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -88,9 +80,7 @@ array(
|
||||
4: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: f
|
||||
)
|
||||
name: f
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
|
@@ -12,18 +12,14 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -33,9 +29,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: class
|
||||
|
@@ -210,9 +210,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: FOO
|
||||
)
|
||||
name: FOO
|
||||
)
|
||||
)
|
||||
dim: Scalar_Int(
|
||||
@@ -224,9 +222,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
name: Identifier(
|
||||
name: BAR
|
||||
|
@@ -19,9 +19,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: a
|
||||
)
|
||||
name: a
|
||||
comments: array(
|
||||
0: // function name variations
|
||||
)
|
||||
@@ -131,9 +129,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: a
|
||||
)
|
||||
name: a
|
||||
comments: array(
|
||||
0: // array dereferencing
|
||||
)
|
||||
|
@@ -8,9 +8,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -39,9 +37,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: bar
|
||||
)
|
||||
name: bar
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
|
@@ -12,9 +12,7 @@ array(
|
||||
expr: Expr_PropertyFetch(
|
||||
var: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -28,9 +26,7 @@ array(
|
||||
expr: Expr_MethodCall(
|
||||
var: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -46,9 +42,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -63,9 +57,7 @@ array(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -22,9 +22,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
comments: array(
|
||||
0: // method name variations
|
||||
)
|
||||
@@ -45,9 +43,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Scalar_String(
|
||||
value: b
|
||||
@@ -59,9 +55,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Expr_Variable(
|
||||
name: b
|
||||
@@ -75,9 +69,7 @@ array(
|
||||
name: Expr_ArrayDimFetch(
|
||||
var: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: VarLikeIdentifier(
|
||||
name: b
|
||||
@@ -97,9 +89,7 @@ array(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: VarLikeIdentifier(
|
||||
name: b
|
||||
@@ -121,9 +111,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
comments: array(
|
||||
0: // array dereferencing
|
||||
)
|
||||
@@ -151,9 +139,7 @@ array(
|
||||
6: Stmt_Expression(
|
||||
expr: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: static
|
||||
)
|
||||
name: static
|
||||
comments: array(
|
||||
0: // class name variations
|
||||
)
|
||||
|
@@ -17,9 +17,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
comments: array(
|
||||
0: // property name variations
|
||||
)
|
||||
@@ -38,9 +36,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Expr_Variable(
|
||||
name: b
|
||||
@@ -50,9 +46,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Scalar_String(
|
||||
value: b
|
||||
@@ -63,9 +57,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
comments: array(
|
||||
0: // array access
|
||||
)
|
||||
@@ -92,9 +84,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: VarLikeIdentifier(
|
||||
name: b
|
||||
|
@@ -16,9 +16,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
0: VariadicPlaceholder(
|
||||
@@ -43,9 +41,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: foo
|
||||
@@ -59,9 +55,7 @@ array(
|
||||
3: Stmt_Expression(
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
args: array(
|
||||
0: VariadicPlaceholder(
|
||||
@@ -95,9 +89,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
args: array(
|
||||
0: VariadicPlaceholder(
|
||||
|
@@ -44,9 +44,7 @@ array(
|
||||
expr: Expr_Empty(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -14,55 +14,41 @@ private\protected\public\static\abstract\final();
|
||||
array(
|
||||
0: Stmt_Namespace(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: fn
|
||||
)
|
||||
name: fn
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
1: Stmt_Namespace(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: fn
|
||||
1: use
|
||||
)
|
||||
name: fn\use
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
2: Stmt_Namespace(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: self
|
||||
)
|
||||
name: self
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
3: Stmt_Namespace(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: parent
|
||||
)
|
||||
name: parent
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
4: Stmt_Namespace(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: static
|
||||
)
|
||||
name: static
|
||||
)
|
||||
stmts: array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: fn
|
||||
1: use
|
||||
)
|
||||
name: fn\use
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -71,10 +57,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name_FullyQualified(
|
||||
parts: array(
|
||||
0: fn
|
||||
1: use
|
||||
)
|
||||
name: fn\use
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -83,10 +66,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name_Relative(
|
||||
parts: array(
|
||||
0: fn
|
||||
1: use
|
||||
)
|
||||
name: fn\use
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -95,14 +75,7 @@ array(
|
||||
3: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: private
|
||||
1: protected
|
||||
2: public
|
||||
3: static
|
||||
4: abstract
|
||||
5: final
|
||||
)
|
||||
name: private\protected\public\static\abstract\final
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -105,9 +105,7 @@ array(
|
||||
conds: array(
|
||||
0: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: BinaryOperator
|
||||
)
|
||||
name: BinaryOperator
|
||||
)
|
||||
name: Identifier(
|
||||
name: ADD
|
||||
|
@@ -22,9 +22,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -33,9 +31,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -82,9 +78,7 @@ array(
|
||||
expr: Expr_New(
|
||||
class: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: VarLikeIdentifier(
|
||||
name: b
|
||||
@@ -174,9 +168,7 @@ array(
|
||||
9: Stmt_Expression(
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -8,9 +8,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: test
|
||||
)
|
||||
name: test
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -34,9 +32,7 @@ array(
|
||||
right: Expr_Throw(
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Exception
|
||||
)
|
||||
name: Exception
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -13,9 +13,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -68,9 +66,7 @@ array(
|
||||
2: Stmt_Expression(
|
||||
expr: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
name: Identifier(
|
||||
name: bar
|
||||
@@ -98,9 +94,7 @@ array(
|
||||
3: Stmt_Expression(
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Foo
|
||||
)
|
||||
name: Foo
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
|
@@ -26,9 +26,7 @@ array(
|
||||
expr: Expr_PropertyFetch(
|
||||
var: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
)
|
||||
name: Identifier(
|
||||
@@ -40,9 +38,7 @@ array(
|
||||
expr: Expr_MethodCall(
|
||||
var: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
)
|
||||
name: Identifier(
|
||||
@@ -56,9 +52,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
)
|
||||
dim: Scalar_Int(
|
||||
@@ -72,9 +66,7 @@ array(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
)
|
||||
dim: Scalar_Int(
|
||||
@@ -94,9 +86,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
)
|
||||
dim: Scalar_Int(
|
||||
@@ -108,9 +98,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -127,9 +115,7 @@ array(
|
||||
var: Expr_ArrayDimFetch(
|
||||
var: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -152,9 +138,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -169,9 +153,7 @@ array(
|
||||
expr: Expr_PropertyFetch(
|
||||
var: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -186,9 +168,7 @@ array(
|
||||
expr: Expr_MethodCall(
|
||||
var: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -205,9 +185,7 @@ array(
|
||||
expr: Expr_ClassConstFetch(
|
||||
class: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -222,9 +200,7 @@ array(
|
||||
expr: Expr_StaticPropertyFetch(
|
||||
class: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -239,9 +215,7 @@ array(
|
||||
expr: Expr_StaticCall(
|
||||
class: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Identifier(
|
||||
name: B
|
||||
@@ -276,9 +250,7 @@ array(
|
||||
expr: Expr_MethodCall(
|
||||
var: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: __FUNCIONT__
|
||||
)
|
||||
name: __FUNCIONT__
|
||||
)
|
||||
)
|
||||
name: Identifier(
|
||||
|
@@ -17,9 +17,7 @@ array(
|
||||
1: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: bar
|
||||
)
|
||||
name: bar
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@@ -20,9 +20,7 @@ array(
|
||||
expr: Expr_FuncCall(
|
||||
name: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: id
|
||||
)
|
||||
name: id
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -52,9 +50,7 @@ array(
|
||||
name: Expr_FuncCall(
|
||||
name: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: id
|
||||
)
|
||||
name: id
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -96,9 +92,7 @@ array(
|
||||
name: Expr_FuncCall(
|
||||
name: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: id
|
||||
)
|
||||
name: id
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -136,9 +130,7 @@ array(
|
||||
name: Expr_ArrayDimFetch(
|
||||
var: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: id
|
||||
)
|
||||
name: id
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -294,9 +286,7 @@ array(
|
||||
)
|
||||
default: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: null
|
||||
)
|
||||
name: null
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@@ -65,9 +65,7 @@ array(
|
||||
expr: Expr_New(
|
||||
class: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Test
|
||||
)
|
||||
name: Test
|
||||
)
|
||||
name: VarLikeIdentifier(
|
||||
name: className
|
||||
|
@@ -14,9 +14,7 @@ array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: VarLikeIdentifier(
|
||||
name: b
|
||||
@@ -76,9 +74,7 @@ array(
|
||||
5: Stmt_Expression(
|
||||
expr: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Expr_Variable(
|
||||
name: b
|
||||
@@ -89,9 +85,7 @@ array(
|
||||
expr: Expr_ArrayDimFetch(
|
||||
var: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: Expr_Variable(
|
||||
name: c
|
||||
@@ -106,9 +100,7 @@ array(
|
||||
expr: Expr_StaticPropertyFetch(
|
||||
class: Expr_StaticPropertyFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
name: VarLikeIdentifier(
|
||||
name: A
|
||||
|
@@ -26,9 +26,7 @@ array(
|
||||
expr: Expr_Variable(
|
||||
name: Expr_FuncCall(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: foo
|
||||
)
|
||||
name: foo
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -58,9 +58,7 @@ array(
|
||||
5: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: _100
|
||||
)
|
||||
name: _100
|
||||
comments: array(
|
||||
0: // already a valid constant name
|
||||
)
|
||||
@@ -87,9 +85,7 @@ array(
|
||||
7: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: _
|
||||
)
|
||||
name: _
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -101,9 +97,7 @@ array(
|
||||
9: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: __1
|
||||
)
|
||||
name: __1
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -115,9 +109,7 @@ array(
|
||||
11: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: _
|
||||
)
|
||||
name: _
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -134,9 +126,7 @@ array(
|
||||
14: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: _0
|
||||
)
|
||||
name: _0
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -148,9 +138,7 @@ array(
|
||||
16: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: x_123
|
||||
)
|
||||
name: x_123
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -162,9 +150,7 @@ array(
|
||||
18: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: b_101
|
||||
)
|
||||
name: b_101
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -176,9 +162,7 @@ array(
|
||||
20: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: _e2
|
||||
)
|
||||
name: _e2
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -190,9 +174,7 @@ array(
|
||||
22: Stmt_Expression(
|
||||
expr: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: e_2
|
||||
)
|
||||
name: e_2
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@@ -152,6 +152,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -175,6 +176,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -256,9 +258,7 @@ array(
|
||||
)
|
||||
expr: Expr_New(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Test
|
||||
)
|
||||
name: Test
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -292,9 +292,7 @@ array(
|
||||
4: Stmt_Expression(
|
||||
expr: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Test
|
||||
)
|
||||
name: Test
|
||||
)
|
||||
name: Identifier(
|
||||
name: list
|
||||
@@ -306,9 +304,7 @@ array(
|
||||
5: Stmt_Expression(
|
||||
expr: Expr_StaticCall(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Test
|
||||
)
|
||||
name: Test
|
||||
)
|
||||
name: Identifier(
|
||||
name: protected
|
||||
@@ -340,9 +336,7 @@ array(
|
||||
8: Stmt_Expression(
|
||||
expr: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Test
|
||||
)
|
||||
name: Test
|
||||
)
|
||||
name: Identifier(
|
||||
name: TRAIT
|
||||
@@ -352,9 +346,7 @@ array(
|
||||
9: Stmt_Expression(
|
||||
expr: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: Test
|
||||
)
|
||||
name: Test
|
||||
)
|
||||
name: Identifier(
|
||||
name: FINAL
|
||||
@@ -375,39 +367,29 @@ array(
|
||||
0: Stmt_TraitUse(
|
||||
traits: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: TraitA
|
||||
)
|
||||
name: TraitA
|
||||
)
|
||||
1: Name(
|
||||
parts: array(
|
||||
0: TraitB
|
||||
)
|
||||
name: TraitB
|
||||
)
|
||||
)
|
||||
adaptations: array(
|
||||
0: Stmt_TraitUseAdaptation_Precedence(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: TraitA
|
||||
)
|
||||
name: TraitA
|
||||
)
|
||||
method: Identifier(
|
||||
name: catch
|
||||
)
|
||||
insteadof: array(
|
||||
0: Name_Relative(
|
||||
parts: array(
|
||||
0: TraitB
|
||||
)
|
||||
name: TraitB
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Stmt_TraitUseAdaptation_Alias(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: TraitA
|
||||
)
|
||||
name: TraitA
|
||||
)
|
||||
method: Identifier(
|
||||
name: list
|
||||
@@ -419,9 +401,7 @@ array(
|
||||
)
|
||||
2: Stmt_TraitUseAdaptation_Alias(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: TraitB
|
||||
)
|
||||
name: TraitB
|
||||
)
|
||||
method: Identifier(
|
||||
name: throw
|
||||
@@ -433,9 +413,7 @@ array(
|
||||
)
|
||||
3: Stmt_TraitUseAdaptation_Alias(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: TraitB
|
||||
)
|
||||
name: TraitB
|
||||
)
|
||||
method: Identifier(
|
||||
name: self
|
||||
@@ -455,9 +433,7 @@ array(
|
||||
)
|
||||
5: Stmt_TraitUseAdaptation_Alias(
|
||||
trait: Name_FullyQualified(
|
||||
parts: array(
|
||||
0: TraitC
|
||||
)
|
||||
name: TraitC
|
||||
)
|
||||
method: Identifier(
|
||||
name: exit
|
||||
@@ -469,9 +445,7 @@ array(
|
||||
)
|
||||
6: Stmt_TraitUseAdaptation_Alias(
|
||||
trait: Name_Relative(
|
||||
parts: array(
|
||||
0: TraitC
|
||||
)
|
||||
name: TraitC
|
||||
)
|
||||
method: Identifier(
|
||||
name: exit
|
||||
@@ -483,9 +457,7 @@ array(
|
||||
)
|
||||
7: Stmt_TraitUseAdaptation_Precedence(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: TraitA
|
||||
)
|
||||
name: TraitA
|
||||
)
|
||||
method: Identifier(
|
||||
name: catch
|
||||
@@ -497,9 +469,7 @@ array(
|
||||
)
|
||||
insteadof: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: TraitB
|
||||
)
|
||||
name: TraitB
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@@ -38,27 +38,21 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A1
|
||||
)
|
||||
name: A1
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
1: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A2
|
||||
)
|
||||
name: A2
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
2: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A3
|
||||
)
|
||||
name: A3
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -73,9 +67,7 @@ array(
|
||||
)
|
||||
3: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A4
|
||||
)
|
||||
name: A4
|
||||
)
|
||||
args: array(
|
||||
0: Arg(
|
||||
@@ -109,9 +101,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A5
|
||||
)
|
||||
name: A5
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -133,9 +123,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A6
|
||||
)
|
||||
name: A6
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -155,9 +143,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A7
|
||||
)
|
||||
name: A7
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -185,9 +171,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A14
|
||||
)
|
||||
name: A14
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -214,9 +198,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A8
|
||||
)
|
||||
name: A8
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -238,9 +220,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A9
|
||||
)
|
||||
name: A9
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -265,9 +245,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A10
|
||||
)
|
||||
name: A10
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -298,9 +276,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A11
|
||||
)
|
||||
name: A11
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -330,9 +306,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A12
|
||||
)
|
||||
name: A12
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
@@ -363,9 +337,7 @@ array(
|
||||
attrs: array(
|
||||
0: Attribute(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: A13
|
||||
)
|
||||
name: A13
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
|
@@ -61,20 +61,14 @@ array(
|
||||
flags: 0
|
||||
name: null
|
||||
extends: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
implements: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
name: B
|
||||
)
|
||||
1: Name(
|
||||
parts: array(
|
||||
0: C
|
||||
)
|
||||
name: C
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -123,9 +117,7 @@ array(
|
||||
flags: 0
|
||||
name: null
|
||||
extends: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
implements: array(
|
||||
)
|
||||
@@ -133,9 +125,7 @@ array(
|
||||
0: Stmt_TraitUse(
|
||||
traits: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: T
|
||||
)
|
||||
name: T
|
||||
)
|
||||
)
|
||||
adaptations: array(
|
||||
@@ -194,9 +184,7 @@ array(
|
||||
flags: 0
|
||||
name: null
|
||||
extends: Name(
|
||||
parts: array(
|
||||
0: A
|
||||
)
|
||||
name: A
|
||||
)
|
||||
implements: array(
|
||||
)
|
||||
@@ -205,6 +193,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
|
@@ -10,9 +10,7 @@ array(
|
||||
0: Stmt_If(
|
||||
cond: Expr_ConstFetch(
|
||||
name: Name(
|
||||
parts: array(
|
||||
0: true
|
||||
)
|
||||
name: true
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
|
@@ -22,6 +22,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: STATIC (8)
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -59,6 +60,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: ABSTRACT (16)
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -96,6 +98,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: READONLY (64)
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -133,6 +136,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: PUBLIC (1)
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
|
@@ -26,6 +26,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -41,6 +42,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: PUBLIC (1)
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -56,6 +58,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: PROTECTED (2)
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -71,6 +74,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: PRIVATE (4)
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -86,6 +90,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: FINAL (32)
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
|
@@ -41,14 +41,10 @@ array(
|
||||
scalarType: null
|
||||
implements: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: Bar
|
||||
)
|
||||
name: Bar
|
||||
)
|
||||
1: Name(
|
||||
parts: array(
|
||||
0: Baz
|
||||
)
|
||||
name: Baz
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -65,9 +61,7 @@ array(
|
||||
)
|
||||
implements: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: Bar
|
||||
)
|
||||
name: Bar
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
|
@@ -15,14 +15,10 @@ array(
|
||||
)
|
||||
extends: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: C
|
||||
)
|
||||
name: C
|
||||
)
|
||||
1: Name(
|
||||
parts: array(
|
||||
0: D
|
||||
)
|
||||
name: D
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
|
@@ -56,9 +56,7 @@ array(
|
||||
name: A
|
||||
)
|
||||
extends: Name(
|
||||
parts: array(
|
||||
0: self
|
||||
)
|
||||
name: self
|
||||
)
|
||||
implements: array(
|
||||
)
|
||||
@@ -79,9 +77,7 @@ array(
|
||||
name: A
|
||||
)
|
||||
extends: Name(
|
||||
parts: array(
|
||||
0: PARENT
|
||||
)
|
||||
name: PARENT
|
||||
)
|
||||
implements: array(
|
||||
)
|
||||
@@ -102,9 +98,7 @@ array(
|
||||
name: A
|
||||
)
|
||||
extends: Name(
|
||||
parts: array(
|
||||
0: static
|
||||
)
|
||||
name: static
|
||||
)
|
||||
implements: array(
|
||||
)
|
||||
@@ -127,9 +121,7 @@ array(
|
||||
extends: null
|
||||
implements: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: self
|
||||
)
|
||||
name: self
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -151,9 +143,7 @@ array(
|
||||
extends: null
|
||||
implements: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: PARENT
|
||||
)
|
||||
name: PARENT
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -175,9 +165,7 @@ array(
|
||||
extends: null
|
||||
implements: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: static
|
||||
)
|
||||
name: static
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -237,9 +225,7 @@ array(
|
||||
)
|
||||
extends: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: self
|
||||
)
|
||||
name: self
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -259,9 +245,7 @@ array(
|
||||
)
|
||||
extends: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: PARENT
|
||||
)
|
||||
name: PARENT
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -281,9 +265,7 @@ array(
|
||||
)
|
||||
extends: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: static
|
||||
)
|
||||
name: static
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
|
@@ -42,9 +42,7 @@ array(
|
||||
)
|
||||
flags: PROTECTED | STATIC (10)
|
||||
type: Name(
|
||||
parts: array(
|
||||
0: D
|
||||
)
|
||||
name: D
|
||||
)
|
||||
props: array(
|
||||
0: PropertyItem(
|
||||
|
25
test/code/parser/stmt/class/readonlyAnonyous.test
Normal file
25
test/code/parser/stmt/class/readonlyAnonyous.test
Normal file
@@ -0,0 +1,25 @@
|
||||
Readonly anonymous class
|
||||
-----
|
||||
<?php
|
||||
|
||||
new readonly class {};
|
||||
-----
|
||||
array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_New(
|
||||
class: Stmt_Class(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: READONLY (64)
|
||||
name: null
|
||||
extends: null
|
||||
implements: array(
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
)
|
||||
args: array(
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
@@ -23,9 +23,7 @@ array(
|
||||
0: Stmt_TraitUse(
|
||||
traits: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: T
|
||||
)
|
||||
name: T
|
||||
)
|
||||
)
|
||||
adaptations: array(
|
||||
|
@@ -25,20 +25,14 @@ array(
|
||||
name: A
|
||||
)
|
||||
extends: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
name: B
|
||||
)
|
||||
implements: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: C
|
||||
)
|
||||
name: C
|
||||
)
|
||||
1: Name(
|
||||
parts: array(
|
||||
0: D
|
||||
)
|
||||
name: D
|
||||
)
|
||||
)
|
||||
stmts: array(
|
||||
@@ -46,6 +40,7 @@ array(
|
||||
attrGroups: array(
|
||||
)
|
||||
flags: 0
|
||||
type: null
|
||||
consts: array(
|
||||
0: Const(
|
||||
name: Identifier(
|
||||
@@ -168,9 +163,7 @@ array(
|
||||
params: array(
|
||||
)
|
||||
returnType: Name(
|
||||
parts: array(
|
||||
0: B
|
||||
)
|
||||
name: B
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
|
@@ -28,9 +28,7 @@ array(
|
||||
params: array(
|
||||
)
|
||||
returnType: Name(
|
||||
parts: array(
|
||||
0: static
|
||||
)
|
||||
name: static
|
||||
)
|
||||
stmts: array(
|
||||
)
|
||||
|
@@ -59,9 +59,7 @@ array(
|
||||
0: Stmt_TraitUse(
|
||||
traits: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: C
|
||||
)
|
||||
name: C
|
||||
)
|
||||
)
|
||||
adaptations: array(
|
||||
@@ -70,9 +68,7 @@ array(
|
||||
1: Stmt_TraitUse(
|
||||
traits: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: D
|
||||
)
|
||||
name: D
|
||||
)
|
||||
)
|
||||
adaptations: array(
|
||||
@@ -109,49 +105,35 @@ array(
|
||||
2: Stmt_TraitUse(
|
||||
traits: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: E
|
||||
)
|
||||
name: E
|
||||
)
|
||||
1: Name(
|
||||
parts: array(
|
||||
0: F
|
||||
)
|
||||
name: F
|
||||
)
|
||||
2: Name(
|
||||
parts: array(
|
||||
0: G
|
||||
)
|
||||
name: G
|
||||
)
|
||||
)
|
||||
adaptations: array(
|
||||
0: Stmt_TraitUseAdaptation_Precedence(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: E
|
||||
)
|
||||
name: E
|
||||
)
|
||||
method: Identifier(
|
||||
name: a
|
||||
)
|
||||
insteadof: array(
|
||||
0: Name(
|
||||
parts: array(
|
||||
0: F
|
||||
)
|
||||
name: F
|
||||
)
|
||||
1: Name(
|
||||
parts: array(
|
||||
0: G
|
||||
)
|
||||
name: G
|
||||
)
|
||||
)
|
||||
)
|
||||
1: Stmt_TraitUseAdaptation_Alias(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: E
|
||||
)
|
||||
name: E
|
||||
)
|
||||
method: Identifier(
|
||||
name: b
|
||||
@@ -163,9 +145,7 @@ array(
|
||||
)
|
||||
2: Stmt_TraitUseAdaptation_Alias(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: E
|
||||
)
|
||||
name: E
|
||||
)
|
||||
method: Identifier(
|
||||
name: d
|
||||
@@ -177,9 +157,7 @@ array(
|
||||
)
|
||||
3: Stmt_TraitUseAdaptation_Alias(
|
||||
trait: Name(
|
||||
parts: array(
|
||||
0: E
|
||||
)
|
||||
name: E
|
||||
)
|
||||
method: Identifier(
|
||||
name: f
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user