mirror of
https://github.com/nikic/PHP-Parser.git
synced 2025-07-17 04:11:31 +02:00
Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1c13d05035 | ||
|
c7dc3ce552 | ||
|
9f6ad686a7 | ||
|
1899471f80 | ||
|
8505acd151 | ||
|
c3e20d9970 | ||
|
4c22c62783 | ||
|
f66a32e2df | ||
|
75abbbd2d4 | ||
|
39b046007d | ||
|
e3872b8906 | ||
|
4a40a84cf6 |
@@ -35,7 +35,7 @@ matrix:
|
|||||||
- name: PHP 8.0 Code on PHP 7.0 Integration Tests
|
- name: PHP 8.0 Code on PHP 7.0 Integration Tests
|
||||||
php: 7.0
|
php: 7.0
|
||||||
script:
|
script:
|
||||||
- test_old/run-php-src.sh 8.0.0beta1
|
- test_old/run-php-src.sh 8.0.0beta4
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- name: PHP 8.0 Code on PHP 7.0 Integration Tests
|
- name: PHP 8.0 Code on PHP 7.0 Integration Tests
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
21
CHANGELOG.md
21
CHANGELOG.md
@@ -1,8 +1,25 @@
|
|||||||
Version 4.9.2-dev
|
Version 4.10.1-dev
|
||||||
-----------------
|
------------------
|
||||||
|
|
||||||
Nothing yet.
|
Nothing yet.
|
||||||
|
|
||||||
|
Version 4.10.0 (2020-09-19)
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
* [PHP 8.0] Added support for attributes. These are represented using a new `AttributeGroup` node
|
||||||
|
containing `Attribute` nodes. A new `attrGroups` subnode is available on all node types that
|
||||||
|
support attributes, i.e. `Stmt\Class_`, `Stmt\Trait_`, `Stmt\Interface_`, `Stmt\Function_`,
|
||||||
|
`Stmt\ClassMethod`, `Stmt\ClassConst`, `Stmt\Property`, `Expr\Closure`, `Expr\ArrowFunction` and
|
||||||
|
`Param`.
|
||||||
|
* [PHP 8.0] Added support for nullsafe properties inside interpolated strings, in line with an
|
||||||
|
upstream change.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
* Improved compatibility with other libraries that use forward compatibility defines for PHP tokens.
|
||||||
|
|
||||||
Version 4.9.1 (2020-08-30)
|
Version 4.9.1 (2020-08-30)
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|
||||||
|
101
grammar/php7.y
101
grammar/php7.y
@@ -82,6 +82,31 @@ no_comma:
|
|||||||
optional_comma:
|
optional_comma:
|
||||||
/* empty */
|
/* empty */
|
||||||
| ','
|
| ','
|
||||||
|
;
|
||||||
|
|
||||||
|
attribute_decl:
|
||||||
|
class_name { $$ = Node\Attribute[$1, []]; }
|
||||||
|
| class_name argument_list { $$ = Node\Attribute[$1, $2]; }
|
||||||
|
;
|
||||||
|
|
||||||
|
attribute_group:
|
||||||
|
attribute_decl { init($1); }
|
||||||
|
| attribute_group ',' attribute_decl { push($1, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
attribute:
|
||||||
|
T_ATTRIBUTE attribute_group optional_comma ']' { $$ = Node\AttributeGroup[$2]; }
|
||||||
|
;
|
||||||
|
|
||||||
|
attributes:
|
||||||
|
attribute { init($1); }
|
||||||
|
| attributes attribute { push($1, $2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
optional_attributes:
|
||||||
|
/* empty */ { $$ = []; }
|
||||||
|
| attributes { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
top_statement:
|
top_statement:
|
||||||
statement { $$ = $1; }
|
statement { $$ = $1; }
|
||||||
@@ -316,19 +341,24 @@ block_or_error:
|
|||||||
;
|
;
|
||||||
|
|
||||||
function_declaration_statement:
|
function_declaration_statement:
|
||||||
T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type block_or_error
|
T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type block_or_error
|
||||||
{ $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $8]]; }
|
{ $$ = Stmt\Function_[$3, ['byRef' => $2, 'params' => $5, 'returnType' => $7, 'stmts' => $8, 'attrGroups' => []]]; }
|
||||||
|
| attributes T_FUNCTION optional_ref identifier '(' parameter_list ')' optional_return_type block_or_error
|
||||||
|
{ $$ = Stmt\Function_[$4, ['byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => $1]]; }
|
||||||
;
|
;
|
||||||
|
|
||||||
class_declaration_statement:
|
class_declaration_statement:
|
||||||
class_entry_type identifier extends_from implements_list '{' class_statement_list '}'
|
class_entry_type identifier extends_from implements_list '{' class_statement_list '}'
|
||||||
{ $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6]];
|
{ $$ = Stmt\Class_[$2, ['type' => $1, 'extends' => $3, 'implements' => $4, 'stmts' => $6, 'attrGroups' => []]];
|
||||||
$this->checkClass($$, #2); }
|
$this->checkClass($$, #2); }
|
||||||
| T_INTERFACE identifier interface_extends_list '{' class_statement_list '}'
|
| attributes class_entry_type identifier extends_from implements_list '{' class_statement_list '}'
|
||||||
{ $$ = Stmt\Interface_[$2, ['extends' => $3, 'stmts' => $5]];
|
{ $$ = Stmt\Class_[$3, ['type' => $2, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]];
|
||||||
$this->checkInterface($$, #2); }
|
$this->checkClass($$, #3); }
|
||||||
| T_TRAIT identifier '{' class_statement_list '}'
|
| optional_attributes T_INTERFACE identifier interface_extends_list '{' class_statement_list '}'
|
||||||
{ $$ = Stmt\Trait_[$2, ['stmts' => $4]]; }
|
{ $$ = Stmt\Interface_[$3, ['extends' => $4, 'stmts' => $6, 'attrGroups' => $1]];
|
||||||
|
$this->checkInterface($$, #3); }
|
||||||
|
| optional_attributes T_TRAIT identifier '{' class_statement_list '}'
|
||||||
|
{ $$ = Stmt\Trait_[$3, ['stmts' => $5, 'attrGroups' => $1]]; }
|
||||||
;
|
;
|
||||||
|
|
||||||
class_entry_type:
|
class_entry_type:
|
||||||
@@ -489,14 +519,14 @@ optional_visibility_modifier:
|
|||||||
;
|
;
|
||||||
|
|
||||||
parameter:
|
parameter:
|
||||||
optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable
|
optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable
|
||||||
{ $$ = new Node\Param($5, null, $2, $3, $4, attributes(), $1);
|
{ $$ = new Node\Param($6, null, $3, $4, $5, attributes(), $2, $1);
|
||||||
$this->checkParam($$); }
|
$this->checkParam($$); }
|
||||||
| optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable '=' expr
|
| optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis plain_variable '=' expr
|
||||||
{ $$ = new Node\Param($5, $7, $2, $3, $4, attributes(), $1);
|
{ $$ = new Node\Param($6, $8, $3, $4, $5, attributes(), $2, $1);
|
||||||
$this->checkParam($$); }
|
$this->checkParam($$); }
|
||||||
| optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis error
|
| optional_attributes optional_visibility_modifier optional_type_without_static optional_ref optional_ellipsis error
|
||||||
{ $$ = new Node\Param(Expr\Error[], null, $2, $3, $4, attributes(), $1); }
|
{ $$ = new Node\Param(Expr\Error[], null, $3, $4, $5, attributes(), $2, $1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
type_expr:
|
type_expr:
|
||||||
@@ -600,14 +630,15 @@ class_statement_list:
|
|||||||
;
|
;
|
||||||
|
|
||||||
class_statement:
|
class_statement:
|
||||||
variable_modifiers optional_type_without_static property_declaration_list ';'
|
optional_attributes variable_modifiers optional_type_without_static property_declaration_list ';'
|
||||||
{ $attrs = attributes();
|
{ $$ = new Stmt\Property($2, $4, attributes(), $3, $1);
|
||||||
$$ = new Stmt\Property($1, $3, $attrs, $2); $this->checkProperty($$, #1); }
|
$this->checkProperty($$, #2); }
|
||||||
| method_modifiers T_CONST class_const_list ';'
|
| optional_attributes method_modifiers T_CONST class_const_list ';'
|
||||||
{ $$ = Stmt\ClassConst[$3, $1]; $this->checkClassConst($$, #1); }
|
{ $$ = new Stmt\ClassConst($4, $2, attributes(), $1);
|
||||||
| method_modifiers T_FUNCTION optional_ref identifier_ex '(' parameter_list ')' optional_return_type method_body
|
$this->checkClassConst($$, #2); }
|
||||||
{ $$ = Stmt\ClassMethod[$4, ['type' => $1, 'byRef' => $3, 'params' => $6, 'returnType' => $8, 'stmts' => $9]];
|
| optional_attributes method_modifiers T_FUNCTION optional_ref identifier_ex '(' parameter_list ')' optional_return_type method_body
|
||||||
$this->checkClassMethod($$, #1); }
|
{ $$ = Stmt\ClassMethod[$5, ['type' => $2, 'byRef' => $4, 'params' => $7, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]];
|
||||||
|
$this->checkClassMethod($$, #2); }
|
||||||
| T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; }
|
| T_USE class_name_list trait_adaptations { $$ = Stmt\TraitUse[$2, $3]; }
|
||||||
| error { $$ = null; /* will be skipped */ }
|
| error { $$ = null; /* will be skipped */ }
|
||||||
;
|
;
|
||||||
@@ -802,21 +833,27 @@ expr:
|
|||||||
| T_THROW expr { $$ = Expr\Throw_[$2]; }
|
| T_THROW expr { $$ = Expr\Throw_[$2]; }
|
||||||
|
|
||||||
| T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
|
| T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
|
||||||
{ $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $2, 'params' => $4, 'returnType' => $6, 'expr' => $8]]; }
|
{ $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $2, 'params' => $4, 'returnType' => $6, 'expr' => $8, 'attrGroups' => []]]; }
|
||||||
| T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
|
| T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
|
||||||
{ $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9]]; }
|
{ $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9, 'attrGroups' => []]]; }
|
||||||
|
| T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
|
||||||
|
{ $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $8, 'attrGroups' => []]]; }
|
||||||
|
| T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
|
||||||
|
{ $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => []]]; }
|
||||||
|
|
||||||
| T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
|
| attributes T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
|
||||||
block_or_error
|
{ $$ = Expr\ArrowFunction[['static' => false, 'byRef' => $3, 'params' => $5, 'returnType' => $7, 'expr' => $9, 'attrGroups' => $1]]; }
|
||||||
{ $$ = Expr\Closure[['static' => false, 'byRef' => $2, 'params' => $4, 'uses' => $6, 'returnType' => $7, 'stmts' => $8]]; }
|
| attributes T_STATIC T_FN optional_ref '(' parameter_list ')' optional_return_type T_DOUBLE_ARROW expr
|
||||||
| T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type
|
{ $$ = Expr\ArrowFunction[['static' => true, 'byRef' => $4, 'params' => $6, 'returnType' => $8, 'expr' => $10, 'attrGroups' => $1]]; }
|
||||||
block_or_error
|
| attributes T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
|
||||||
{ $$ = Expr\Closure[['static' => true, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9]]; }
|
{ $$ = Expr\Closure[['static' => false, 'byRef' => $3, 'params' => $5, 'uses' => $7, 'returnType' => $8, 'stmts' => $9, 'attrGroups' => $1]]; }
|
||||||
|
| attributes T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars optional_return_type block_or_error
|
||||||
|
{ $$ = Expr\Closure[['static' => true, 'byRef' => $4, 'params' => $6, 'uses' => $8, 'returnType' => $9, 'stmts' => $10, 'attrGroups' => $1]]; }
|
||||||
;
|
;
|
||||||
|
|
||||||
anonymous_class:
|
anonymous_class:
|
||||||
T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
|
optional_attributes T_CLASS ctor_arguments extends_from implements_list '{' class_statement_list '}'
|
||||||
{ $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $3, 'implements' => $4, 'stmts' => $6]], $2);
|
{ $$ = array(Stmt\Class_[null, ['type' => 0, 'extends' => $4, 'implements' => $5, 'stmts' => $7, 'attrGroups' => $1]], $3);
|
||||||
$this->checkClass($$[0], -1); }
|
$this->checkClass($$[0], -1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@@ -117,28 +117,28 @@ function resolveMacros($code) {
|
|||||||
$matches['args']
|
$matches['args']
|
||||||
);
|
);
|
||||||
|
|
||||||
if ('attributes' == $name) {
|
if ('attributes' === $name) {
|
||||||
assertArgs(0, $args, $name);
|
assertArgs(0, $args, $name);
|
||||||
return '$this->startAttributeStack[#1] + $this->endAttributes';
|
return '$this->startAttributeStack[#1] + $this->endAttributes';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('stackAttributes' == $name) {
|
if ('stackAttributes' === $name) {
|
||||||
assertArgs(1, $args, $name);
|
assertArgs(1, $args, $name);
|
||||||
return '$this->startAttributeStack[' . $args[0] . ']'
|
return '$this->startAttributeStack[' . $args[0] . ']'
|
||||||
. ' + $this->endAttributeStack[' . $args[0] . ']';
|
. ' + $this->endAttributeStack[' . $args[0] . ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('init' == $name) {
|
if ('init' === $name) {
|
||||||
return '$$ = array(' . implode(', ', $args) . ')';
|
return '$$ = array(' . implode(', ', $args) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('push' == $name) {
|
if ('push' === $name) {
|
||||||
assertArgs(2, $args, $name);
|
assertArgs(2, $args, $name);
|
||||||
|
|
||||||
return $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0];
|
return $args[0] . '[] = ' . $args[1] . '; $$ = ' . $args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('pushNormalizing' == $name) {
|
if ('pushNormalizing' === $name) {
|
||||||
assertArgs(2, $args, $name);
|
assertArgs(2, $args, $name);
|
||||||
|
|
||||||
return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); }'
|
return 'if (is_array(' . $args[1] . ')) { $$ = array_merge(' . $args[0] . ', ' . $args[1] . '); }'
|
||||||
@@ -151,20 +151,20 @@ function resolveMacros($code) {
|
|||||||
return 'is_array(' . $args[0] . ') ? ' . $args[0] . ' : array(' . $args[0] . ')';
|
return 'is_array(' . $args[0] . ') ? ' . $args[0] . ' : array(' . $args[0] . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('parseVar' == $name) {
|
if ('parseVar' === $name) {
|
||||||
assertArgs(1, $args, $name);
|
assertArgs(1, $args, $name);
|
||||||
|
|
||||||
return 'substr(' . $args[0] . ', 1)';
|
return 'substr(' . $args[0] . ', 1)';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('parseEncapsed' == $name) {
|
if ('parseEncapsed' === $name) {
|
||||||
assertArgs(3, $args, $name);
|
assertArgs(3, $args, $name);
|
||||||
|
|
||||||
return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {'
|
return 'foreach (' . $args[0] . ' as $s) { if ($s instanceof Node\Scalar\EncapsedStringPart) {'
|
||||||
. ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, ' . $args[1] . ', ' . $args[2] . '); } }';
|
. ' $s->value = Node\Scalar\String_::parseEscapeSequences($s->value, ' . $args[1] . ', ' . $args[2] . '); } }';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('makeNop' == $name) {
|
if ('makeNop' === $name) {
|
||||||
assertArgs(3, $args, $name);
|
assertArgs(3, $args, $name);
|
||||||
|
|
||||||
return '$startAttributes = ' . $args[1] . ';'
|
return '$startAttributes = ' . $args[1] . ';'
|
||||||
@@ -182,7 +182,7 @@ function resolveMacros($code) {
|
|||||||
. ' else { ' . $args[0] . ' = null; }';
|
. ' else { ' . $args[0] . ' = null; }';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('strKind' == $name) {
|
if ('strKind' === $name) {
|
||||||
assertArgs(1, $args, $name);
|
assertArgs(1, $args, $name);
|
||||||
|
|
||||||
return '(' . $args[0] . '[0] === "\'" || (' . $args[0] . '[1] === "\'" && '
|
return '(' . $args[0] . '[0] === "\'" || (' . $args[0] . '[1] === "\'" && '
|
||||||
@@ -190,7 +190,7 @@ function resolveMacros($code) {
|
|||||||
. '? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED)';
|
. '? Scalar\String_::KIND_SINGLE_QUOTED : Scalar\String_::KIND_DOUBLE_QUOTED)';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('prependLeadingComments' == $name) {
|
if ('prependLeadingComments' === $name) {
|
||||||
assertArgs(1, $args, $name);
|
assertArgs(1, $args, $name);
|
||||||
|
|
||||||
return '$attrs = $this->startAttributeStack[#1]; $stmts = ' . $args[0] . '; '
|
return '$attrs = $this->startAttributeStack[#1]; $stmts = ' . $args[0] . '; '
|
||||||
|
@@ -110,3 +110,4 @@
|
|||||||
%token T_NAME_FULLY_QUALIFIED
|
%token T_NAME_FULLY_QUALIFIED
|
||||||
%token T_NAME_QUALIFIED
|
%token T_NAME_QUALIFIED
|
||||||
%token T_NAME_RELATIVE
|
%token T_NAME_RELATIVE
|
||||||
|
%token T_ATTRIBUTE
|
@@ -17,6 +17,8 @@ use PhpParser\Node\Expr;
|
|||||||
*/
|
*/
|
||||||
class PrintableNewAnonClassNode extends Expr
|
class PrintableNewAnonClassNode extends Expr
|
||||||
{
|
{
|
||||||
|
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||||
|
public $attrGroups;
|
||||||
/** @var Node\Arg[] Arguments */
|
/** @var Node\Arg[] Arguments */
|
||||||
public $args;
|
public $args;
|
||||||
/** @var null|Node\Name Name of extended class */
|
/** @var null|Node\Name Name of extended class */
|
||||||
@@ -27,9 +29,11 @@ class PrintableNewAnonClassNode extends Expr
|
|||||||
public $stmts;
|
public $stmts;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
array $args, Node\Name $extends = null, array $implements, array $stmts, array $attributes
|
array $attrGroups, array $args, Node\Name $extends = null, array $implements,
|
||||||
|
array $stmts, array $attributes
|
||||||
) {
|
) {
|
||||||
parent::__construct($attributes);
|
parent::__construct($attributes);
|
||||||
|
$this->attrGroups = $attrGroups;
|
||||||
$this->args = $args;
|
$this->args = $args;
|
||||||
$this->extends = $extends;
|
$this->extends = $extends;
|
||||||
$this->implements = $implements;
|
$this->implements = $implements;
|
||||||
@@ -42,7 +46,7 @@ class PrintableNewAnonClassNode extends Expr
|
|||||||
// We don't assert that $class->name is null here, to allow consumers to assign unique names
|
// 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.
|
// to anonymous classes for their own purposes. We simplify ignore the name here.
|
||||||
return new self(
|
return new self(
|
||||||
$newNode->args, $class->extends, $class->implements,
|
$class->attrGroups, $newNode->args, $class->extends, $class->implements,
|
||||||
$class->stmts, $newNode->getAttributes()
|
$class->stmts, $newNode->getAttributes()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -52,6 +56,6 @@ class PrintableNewAnonClassNode extends Expr
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['args', 'extends', 'implements', 'stmts'];
|
return ['attrGroups', 'args', 'extends', 'implements', 'stmts'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -405,33 +405,58 @@ class Lexer
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function defineCompatibilityTokens() {
|
private function defineCompatibilityTokens() {
|
||||||
// PHP 7.4
|
static $compatTokensDefined = false;
|
||||||
if (!defined('T_BAD_CHARACTER')) {
|
if ($compatTokensDefined) {
|
||||||
\define('T_BAD_CHARACTER', -1);
|
return;
|
||||||
}
|
|
||||||
if (!defined('T_FN')) {
|
|
||||||
\define('T_FN', -2);
|
|
||||||
}
|
|
||||||
if (!defined('T_COALESCE_EQUAL')) {
|
|
||||||
\define('T_COALESCE_EQUAL', -3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PHP 8.0
|
$compatTokens = [
|
||||||
if (!defined('T_NAME_QUALIFIED')) {
|
// PHP 7.4
|
||||||
\define('T_NAME_QUALIFIED', -4);
|
'T_BAD_CHARACTER',
|
||||||
|
'T_FN',
|
||||||
|
'T_COALESCE_EQUAL',
|
||||||
|
// PHP 8.0
|
||||||
|
'T_NAME_QUALIFIED',
|
||||||
|
'T_NAME_FULLY_QUALIFIED',
|
||||||
|
'T_NAME_RELATIVE',
|
||||||
|
'T_MATCH',
|
||||||
|
'T_NULLSAFE_OBJECT_OPERATOR',
|
||||||
|
'T_ATTRIBUTE',
|
||||||
|
];
|
||||||
|
|
||||||
|
// PHP-Parser might be used together with another library that also emulates some or all
|
||||||
|
// of these tokens. Perform a sanity-check that all already defined tokens have been
|
||||||
|
// assigned a unique ID.
|
||||||
|
$usedTokenIds = [];
|
||||||
|
foreach ($compatTokens as $token) {
|
||||||
|
if (\defined($token)) {
|
||||||
|
$tokenId = \constant($token);
|
||||||
|
$clashingToken = $usedTokenIds[$tokenId] ?? null;
|
||||||
|
if ($clashingToken !== null) {
|
||||||
|
throw new \Error(sprintf(
|
||||||
|
'Token %s has same ID as token %s, ' .
|
||||||
|
'you may be using a library with broken token emulation',
|
||||||
|
$token, $clashingToken
|
||||||
|
));
|
||||||
|
}
|
||||||
|
$usedTokenIds[$token] = $tokenId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!defined('T_NAME_FULLY_QUALIFIED')) {
|
|
||||||
\define('T_NAME_FULLY_QUALIFIED', -5);
|
// Now define any tokens that have not yet been emulated. Try to assign IDs from -1
|
||||||
}
|
// downwards, but skip any IDs that may already be in use.
|
||||||
if (!defined('T_NAME_RELATIVE')) {
|
$newTokenId = -1;
|
||||||
\define('T_NAME_RELATIVE', -6);
|
foreach ($compatTokens as $token) {
|
||||||
}
|
if (!\defined($token)) {
|
||||||
if (!defined('T_MATCH')) {
|
while (isset($usedTokenIds[$newTokenId])) {
|
||||||
\define('T_MATCH', -7);
|
$newTokenId--;
|
||||||
}
|
}
|
||||||
if (!defined('T_NULLSAFE_OBJECT_OPERATOR')) {
|
\define($token, $newTokenId);
|
||||||
\define('T_NULLSAFE_OBJECT_OPERATOR', -8);
|
$newTokenId--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$compatTokensDefined = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -486,6 +511,7 @@ class Lexer
|
|||||||
$tokenMap[\T_NAME_RELATIVE] = Tokens::T_NAME_RELATIVE;
|
$tokenMap[\T_NAME_RELATIVE] = Tokens::T_NAME_RELATIVE;
|
||||||
$tokenMap[\T_MATCH] = Tokens::T_MATCH;
|
$tokenMap[\T_MATCH] = Tokens::T_MATCH;
|
||||||
$tokenMap[\T_NULLSAFE_OBJECT_OPERATOR] = Tokens::T_NULLSAFE_OBJECT_OPERATOR;
|
$tokenMap[\T_NULLSAFE_OBJECT_OPERATOR] = Tokens::T_NULLSAFE_OBJECT_OPERATOR;
|
||||||
|
$tokenMap[\T_ATTRIBUTE] = Tokens::T_ATTRIBUTE;
|
||||||
|
|
||||||
return $tokenMap;
|
return $tokenMap;
|
||||||
}
|
}
|
||||||
|
@@ -5,12 +5,15 @@ namespace PhpParser\Lexer;
|
|||||||
use PhpParser\Error;
|
use PhpParser\Error;
|
||||||
use PhpParser\ErrorHandler;
|
use PhpParser\ErrorHandler;
|
||||||
use PhpParser\Lexer;
|
use PhpParser\Lexer;
|
||||||
|
use PhpParser\Lexer\TokenEmulator\AttributeEmulator;
|
||||||
use PhpParser\Lexer\TokenEmulator\CoaleseEqualTokenEmulator;
|
use PhpParser\Lexer\TokenEmulator\CoaleseEqualTokenEmulator;
|
||||||
|
use PhpParser\Lexer\TokenEmulator\FlexibleDocStringEmulator;
|
||||||
use PhpParser\Lexer\TokenEmulator\FnTokenEmulator;
|
use PhpParser\Lexer\TokenEmulator\FnTokenEmulator;
|
||||||
use PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
|
use PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
|
||||||
use PhpParser\Lexer\TokenEmulator\NullsafeTokenEmulator;
|
use PhpParser\Lexer\TokenEmulator\NullsafeTokenEmulator;
|
||||||
use PhpParser\Lexer\TokenEmulator\NumericLiteralSeparatorEmulator;
|
use PhpParser\Lexer\TokenEmulator\NumericLiteralSeparatorEmulator;
|
||||||
use PhpParser\Lexer\TokenEmulator\TokenEmulatorInterface;
|
use PhpParser\Lexer\TokenEmulator\ReverseEmulator;
|
||||||
|
use PhpParser\Lexer\TokenEmulator\TokenEmulator;
|
||||||
use PhpParser\Parser\Tokens;
|
use PhpParser\Parser\Tokens;
|
||||||
|
|
||||||
class Emulative extends Lexer
|
class Emulative extends Lexer
|
||||||
@@ -19,17 +22,11 @@ class Emulative extends Lexer
|
|||||||
const PHP_7_4 = '7.4dev';
|
const PHP_7_4 = '7.4dev';
|
||||||
const PHP_8_0 = '8.0dev';
|
const PHP_8_0 = '8.0dev';
|
||||||
|
|
||||||
const FLEXIBLE_DOC_STRING_REGEX = <<<'REGEX'
|
|
||||||
/<<<[ \t]*(['"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\1\r?\n
|
|
||||||
(?:.*\r?\n)*?
|
|
||||||
(?<indentation>\h*)\2(?![a-zA-Z0-9_\x80-\xff])(?<separator>(?:;?[\r\n])?)/x
|
|
||||||
REGEX;
|
|
||||||
|
|
||||||
/** @var mixed[] Patches used to reverse changes introduced in the code */
|
/** @var mixed[] Patches used to reverse changes introduced in the code */
|
||||||
private $patches = [];
|
private $patches = [];
|
||||||
|
|
||||||
/** @var TokenEmulatorInterface[] */
|
/** @var TokenEmulator[] */
|
||||||
private $tokenEmulators = [];
|
private $emulators = [];
|
||||||
|
|
||||||
/** @var string */
|
/** @var string */
|
||||||
private $targetPhpVersion;
|
private $targetPhpVersion;
|
||||||
@@ -46,27 +43,47 @@ REGEX;
|
|||||||
|
|
||||||
parent::__construct($options);
|
parent::__construct($options);
|
||||||
|
|
||||||
$this->tokenEmulators[] = new FnTokenEmulator();
|
$emulators = [
|
||||||
$this->tokenEmulators[] = new MatchTokenEmulator();
|
new FlexibleDocStringEmulator(),
|
||||||
$this->tokenEmulators[] = new CoaleseEqualTokenEmulator();
|
new FnTokenEmulator(),
|
||||||
$this->tokenEmulators[] = new NumericLiteralSeparatorEmulator();
|
new MatchTokenEmulator(),
|
||||||
$this->tokenEmulators[] = new NullsafeTokenEmulator();
|
new CoaleseEqualTokenEmulator(),
|
||||||
|
new NumericLiteralSeparatorEmulator(),
|
||||||
|
new NullsafeTokenEmulator(),
|
||||||
|
new AttributeEmulator(),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Collect emulators that are relevant for the PHP version we're running
|
||||||
|
// and the PHP version we're targeting for emulation.
|
||||||
|
foreach ($emulators as $emulator) {
|
||||||
|
$emulatorPhpVersion = $emulator->getPhpVersion();
|
||||||
|
if ($this->isForwardEmulationNeeded($emulatorPhpVersion)) {
|
||||||
|
$this->emulators[] = $emulator;
|
||||||
|
} else if ($this->isReverseEmulationNeeded($emulatorPhpVersion)) {
|
||||||
|
$this->emulators[] = new ReverseEmulator($emulator);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function startLexing(string $code, ErrorHandler $errorHandler = null) {
|
public function startLexing(string $code, ErrorHandler $errorHandler = null) {
|
||||||
$this->patches = [];
|
$emulators = array_filter($this->emulators, function($emulator) use($code) {
|
||||||
|
return $emulator->isEmulationNeeded($code);
|
||||||
|
});
|
||||||
|
|
||||||
if ($this->isEmulationNeeded($code) === false) {
|
if (empty($emulators)) {
|
||||||
// Nothing to emulate, yay
|
// Nothing to emulate, yay
|
||||||
parent::startLexing($code, $errorHandler);
|
parent::startLexing($code, $errorHandler);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$collector = new ErrorHandler\Collecting();
|
$this->patches = [];
|
||||||
|
foreach ($emulators as $emulator) {
|
||||||
|
$code = $emulator->preprocessCode($code, $this->patches);
|
||||||
|
}
|
||||||
|
|
||||||
// 1. emulation of heredoc and nowdoc new syntax
|
$collector = new ErrorHandler\Collecting();
|
||||||
$preparedCode = $this->processHeredocNowdoc($code);
|
parent::startLexing($code, $collector);
|
||||||
parent::startLexing($preparedCode, $collector);
|
$this->sortPatches();
|
||||||
$this->fixupTokens();
|
$this->fixupTokens();
|
||||||
|
|
||||||
$errors = $collector->getErrors();
|
$errors = $collector->getErrors();
|
||||||
@@ -77,84 +94,28 @@ REGEX;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->tokenEmulators as $tokenEmulator) {
|
foreach ($emulators as $emulator) {
|
||||||
$emulatorPhpVersion = $tokenEmulator->getPhpVersion();
|
$this->tokens = $emulator->emulate($code, $this->tokens);
|
||||||
if (version_compare(\PHP_VERSION, $emulatorPhpVersion, '<')
|
|
||||||
&& version_compare($this->targetPhpVersion, $emulatorPhpVersion, '>=')
|
|
||||||
&& $tokenEmulator->isEmulationNeeded($code)) {
|
|
||||||
$this->tokens = $tokenEmulator->emulate($code, $this->tokens);
|
|
||||||
} else if (version_compare(\PHP_VERSION, $emulatorPhpVersion, '>=')
|
|
||||||
&& version_compare($this->targetPhpVersion, $emulatorPhpVersion, '<')
|
|
||||||
&& $tokenEmulator->isEmulationNeeded($code)) {
|
|
||||||
$this->tokens = $tokenEmulator->reverseEmulate($code, $this->tokens);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isHeredocNowdocEmulationNeeded(string $code): bool
|
private function isForwardEmulationNeeded(string $emulatorPhpVersion): bool {
|
||||||
{
|
return version_compare(\PHP_VERSION, $emulatorPhpVersion, '<')
|
||||||
// skip version where this works without emulation
|
&& version_compare($this->targetPhpVersion, $emulatorPhpVersion, '>=');
|
||||||
if (version_compare(\PHP_VERSION, self::PHP_7_3, '>=')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return strpos($code, '<<<') !== false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function processHeredocNowdoc(string $code): string
|
private function isReverseEmulationNeeded(string $emulatorPhpVersion): bool {
|
||||||
{
|
return version_compare(\PHP_VERSION, $emulatorPhpVersion, '>=')
|
||||||
if ($this->isHeredocNowdocEmulationNeeded($code) === false) {
|
&& version_compare($this->targetPhpVersion, $emulatorPhpVersion, '<');
|
||||||
return $code;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!preg_match_all(self::FLEXIBLE_DOC_STRING_REGEX, $code, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE)) {
|
|
||||||
// No heredoc/nowdoc found
|
|
||||||
return $code;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keep track of how much we need to adjust string offsets due to the modifications we
|
|
||||||
// already made
|
|
||||||
$posDelta = 0;
|
|
||||||
foreach ($matches as $match) {
|
|
||||||
$indentation = $match['indentation'][0];
|
|
||||||
$indentationStart = $match['indentation'][1];
|
|
||||||
|
|
||||||
$separator = $match['separator'][0];
|
|
||||||
$separatorStart = $match['separator'][1];
|
|
||||||
|
|
||||||
if ($indentation === '' && $separator !== '') {
|
|
||||||
// Ordinary heredoc/nowdoc
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($indentation !== '') {
|
|
||||||
// Remove indentation
|
|
||||||
$indentationLen = strlen($indentation);
|
|
||||||
$code = substr_replace($code, '', $indentationStart + $posDelta, $indentationLen);
|
|
||||||
$this->patches[] = [$indentationStart + $posDelta, 'add', $indentation];
|
|
||||||
$posDelta -= $indentationLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($separator === '') {
|
|
||||||
// Insert newline as separator
|
|
||||||
$code = substr_replace($code, "\n", $separatorStart + $posDelta, 0);
|
|
||||||
$this->patches[] = [$separatorStart + $posDelta, 'remove', "\n"];
|
|
||||||
$posDelta += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function isEmulationNeeded(string $code): bool
|
private function sortPatches()
|
||||||
{
|
{
|
||||||
foreach ($this->tokenEmulators as $emulativeToken) {
|
// Patches may be contributed by different emulators.
|
||||||
if ($emulativeToken->isEmulationNeeded($code)) {
|
// Make sure they are sorted by increasing patch position.
|
||||||
return true;
|
usort($this->patches, function($p1, $p2) {
|
||||||
}
|
return $p1[0] <=> $p2[0];
|
||||||
}
|
});
|
||||||
|
|
||||||
return $this->isHeredocNowdocEmulationNeeded($code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function fixupTokens()
|
private function fixupTokens()
|
||||||
@@ -173,7 +134,20 @@ REGEX;
|
|||||||
for ($i = 0, $c = \count($this->tokens); $i < $c; $i++) {
|
for ($i = 0, $c = \count($this->tokens); $i < $c; $i++) {
|
||||||
$token = $this->tokens[$i];
|
$token = $this->tokens[$i];
|
||||||
if (\is_string($token)) {
|
if (\is_string($token)) {
|
||||||
// We assume that patches don't apply to string tokens
|
if ($patchPos === $pos) {
|
||||||
|
// Only support replacement for string tokens.
|
||||||
|
assert($patchType === 'replace');
|
||||||
|
$this->tokens[$i] = $patchText;
|
||||||
|
|
||||||
|
// Fetch the next patch
|
||||||
|
$patchIdx++;
|
||||||
|
if ($patchIdx >= \count($this->patches)) {
|
||||||
|
// No more patches, we're done
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
list($patchPos, $patchType, $patchText) = $this->patches[$patchIdx];
|
||||||
|
}
|
||||||
|
|
||||||
$pos += \strlen($token);
|
$pos += \strlen($token);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -201,6 +175,11 @@ REGEX;
|
|||||||
$token[1], $patchText, $patchPos - $pos + $posDelta, 0
|
$token[1], $patchText, $patchPos - $pos + $posDelta, 0
|
||||||
);
|
);
|
||||||
$posDelta += $patchTextLen;
|
$posDelta += $patchTextLen;
|
||||||
|
} else if ($patchType === 'replace') {
|
||||||
|
// Replace inside the token string
|
||||||
|
$this->tokens[$i][1] = substr_replace(
|
||||||
|
$token[1], $patchText, $patchPos - $pos + $posDelta, $patchTextLen
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
@@ -247,7 +226,7 @@ REGEX;
|
|||||||
if ($patchType === 'add') {
|
if ($patchType === 'add') {
|
||||||
$posDelta += strlen($patchText);
|
$posDelta += strlen($patchText);
|
||||||
$lineDelta += substr_count($patchText, "\n");
|
$lineDelta += substr_count($patchText, "\n");
|
||||||
} else {
|
} else if ($patchType === 'remove') {
|
||||||
$posDelta -= strlen($patchText);
|
$posDelta -= strlen($patchText);
|
||||||
$lineDelta -= substr_count($patchText, "\n");
|
$lineDelta -= substr_count($patchText, "\n");
|
||||||
}
|
}
|
||||||
|
56
lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php
Normal file
56
lib/PhpParser/Lexer/TokenEmulator/AttributeEmulator.php
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpParser\Lexer\TokenEmulator;
|
||||||
|
|
||||||
|
use PhpParser\Lexer\Emulative;
|
||||||
|
|
||||||
|
final class AttributeEmulator extends TokenEmulator
|
||||||
|
{
|
||||||
|
public function getPhpVersion(): string
|
||||||
|
{
|
||||||
|
return Emulative::PHP_8_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEmulationNeeded(string $code) : bool
|
||||||
|
{
|
||||||
|
return strpos($code, '#[') !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function emulate(string $code, array $tokens): array
|
||||||
|
{
|
||||||
|
// We need to manually iterate and manage a count because we'll change
|
||||||
|
// the tokens array on the way.
|
||||||
|
$line = 1;
|
||||||
|
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
|
||||||
|
if ($tokens[$i] === '#' && isset($tokens[$i + 1]) && $tokens[$i + 1] === '[') {
|
||||||
|
array_splice($tokens, $i, 2, [
|
||||||
|
[\T_ATTRIBUTE, '#[', $line]
|
||||||
|
]);
|
||||||
|
$c--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (\is_array($tokens[$i])) {
|
||||||
|
$line += substr_count($tokens[$i][1], "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reverseEmulate(string $code, array $tokens): array
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return $tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function preprocessCode(string $code, array &$patches): string {
|
||||||
|
$pos = 0;
|
||||||
|
while (false !== $pos = strpos($code, '#[', $pos)) {
|
||||||
|
// Replace #[ with %[
|
||||||
|
$code[$pos] = '%';
|
||||||
|
$patches[] = [$pos, 'replace', '#'];
|
||||||
|
$pos += 2;
|
||||||
|
}
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
}
|
@@ -4,7 +4,7 @@ namespace PhpParser\Lexer\TokenEmulator;
|
|||||||
|
|
||||||
use PhpParser\Lexer\Emulative;
|
use PhpParser\Lexer\Emulative;
|
||||||
|
|
||||||
final class CoaleseEqualTokenEmulator implements TokenEmulatorInterface
|
final class CoaleseEqualTokenEmulator extends TokenEmulator
|
||||||
{
|
{
|
||||||
public function getPhpVersion(): string
|
public function getPhpVersion(): string
|
||||||
{
|
{
|
||||||
|
@@ -0,0 +1,76 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpParser\Lexer\TokenEmulator;
|
||||||
|
|
||||||
|
use PhpParser\Lexer\Emulative;
|
||||||
|
|
||||||
|
final class FlexibleDocStringEmulator extends TokenEmulator
|
||||||
|
{
|
||||||
|
const FLEXIBLE_DOC_STRING_REGEX = <<<'REGEX'
|
||||||
|
/<<<[ \t]*(['"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\1\r?\n
|
||||||
|
(?:.*\r?\n)*?
|
||||||
|
(?<indentation>\h*)\2(?![a-zA-Z0-9_\x80-\xff])(?<separator>(?:;?[\r\n])?)/x
|
||||||
|
REGEX;
|
||||||
|
|
||||||
|
public function getPhpVersion(): string
|
||||||
|
{
|
||||||
|
return Emulative::PHP_7_3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEmulationNeeded(string $code) : bool
|
||||||
|
{
|
||||||
|
return strpos($code, '<<<') !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function emulate(string $code, array $tokens): array
|
||||||
|
{
|
||||||
|
// Handled by preprocessing + fixup.
|
||||||
|
return $tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reverseEmulate(string $code, array $tokens): array
|
||||||
|
{
|
||||||
|
// Not supported.
|
||||||
|
return $tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function preprocessCode(string $code, array &$patches): string {
|
||||||
|
if (!preg_match_all(self::FLEXIBLE_DOC_STRING_REGEX, $code, $matches, PREG_SET_ORDER|PREG_OFFSET_CAPTURE)) {
|
||||||
|
// No heredoc/nowdoc found
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep track of how much we need to adjust string offsets due to the modifications we
|
||||||
|
// already made
|
||||||
|
$posDelta = 0;
|
||||||
|
foreach ($matches as $match) {
|
||||||
|
$indentation = $match['indentation'][0];
|
||||||
|
$indentationStart = $match['indentation'][1];
|
||||||
|
|
||||||
|
$separator = $match['separator'][0];
|
||||||
|
$separatorStart = $match['separator'][1];
|
||||||
|
|
||||||
|
if ($indentation === '' && $separator !== '') {
|
||||||
|
// Ordinary heredoc/nowdoc
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($indentation !== '') {
|
||||||
|
// Remove indentation
|
||||||
|
$indentationLen = strlen($indentation);
|
||||||
|
$code = substr_replace($code, '', $indentationStart + $posDelta, $indentationLen);
|
||||||
|
$patches[] = [$indentationStart + $posDelta, 'add', $indentation];
|
||||||
|
$posDelta -= $indentationLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($separator === '') {
|
||||||
|
// Insert newline as separator
|
||||||
|
$code = substr_replace($code, "\n", $separatorStart + $posDelta, 0);
|
||||||
|
$patches[] = [$separatorStart + $posDelta, 'remove', "\n"];
|
||||||
|
$posDelta += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
}
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace PhpParser\Lexer\TokenEmulator;
|
namespace PhpParser\Lexer\TokenEmulator;
|
||||||
|
|
||||||
abstract class KeywordEmulator implements TokenEmulatorInterface
|
abstract class KeywordEmulator extends TokenEmulator
|
||||||
{
|
{
|
||||||
abstract function getKeywordString(): string;
|
abstract function getKeywordString(): string;
|
||||||
abstract function getKeywordToken(): int;
|
abstract function getKeywordToken(): int;
|
||||||
|
@@ -4,7 +4,7 @@ namespace PhpParser\Lexer\TokenEmulator;
|
|||||||
|
|
||||||
use PhpParser\Lexer\Emulative;
|
use PhpParser\Lexer\Emulative;
|
||||||
|
|
||||||
final class NullsafeTokenEmulator implements TokenEmulatorInterface
|
final class NullsafeTokenEmulator extends TokenEmulator
|
||||||
{
|
{
|
||||||
public function getPhpVersion(): string
|
public function getPhpVersion(): string
|
||||||
{
|
{
|
||||||
@@ -22,15 +22,35 @@ final class NullsafeTokenEmulator implements TokenEmulatorInterface
|
|||||||
// the tokens array on the way
|
// the tokens array on the way
|
||||||
$line = 1;
|
$line = 1;
|
||||||
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
|
for ($i = 0, $c = count($tokens); $i < $c; ++$i) {
|
||||||
if (isset($tokens[$i + 1])) {
|
if ($tokens[$i] === '?' && isset($tokens[$i + 1]) && $tokens[$i + 1][0] === \T_OBJECT_OPERATOR) {
|
||||||
if ($tokens[$i] === '?' && $tokens[$i + 1][0] === \T_OBJECT_OPERATOR) {
|
array_splice($tokens, $i, 2, [
|
||||||
array_splice($tokens, $i, 2, [
|
[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line]
|
||||||
[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line]
|
]);
|
||||||
]);
|
$c--;
|
||||||
$c--;
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle ?-> inside encapsed string.
|
||||||
|
if ($tokens[$i][0] === \T_ENCAPSED_AND_WHITESPACE && isset($tokens[$i - 1])
|
||||||
|
&& $tokens[$i - 1][0] === \T_VARIABLE
|
||||||
|
&& preg_match('/^\?->([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)/', $tokens[$i][1], $matches)
|
||||||
|
) {
|
||||||
|
$replacement = [
|
||||||
|
[\T_NULLSAFE_OBJECT_OPERATOR, '?->', $line],
|
||||||
|
[\T_STRING, $matches[1], $line],
|
||||||
|
];
|
||||||
|
if (\strlen($matches[0]) !== \strlen($tokens[$i][1])) {
|
||||||
|
$replacement[] = [
|
||||||
|
\T_ENCAPSED_AND_WHITESPACE,
|
||||||
|
\substr($tokens[$i][1], \strlen($matches[0])),
|
||||||
|
$line
|
||||||
|
];
|
||||||
|
}
|
||||||
|
array_splice($tokens, $i, 1, $replacement);
|
||||||
|
$c += \count($replacement) - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (\is_array($tokens[$i])) {
|
if (\is_array($tokens[$i])) {
|
||||||
$line += substr_count($tokens[$i][1], "\n");
|
$line += substr_count($tokens[$i][1], "\n");
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,7 @@ namespace PhpParser\Lexer\TokenEmulator;
|
|||||||
|
|
||||||
use PhpParser\Lexer\Emulative;
|
use PhpParser\Lexer\Emulative;
|
||||||
|
|
||||||
final class NumericLiteralSeparatorEmulator implements TokenEmulatorInterface
|
final class NumericLiteralSeparatorEmulator extends TokenEmulator
|
||||||
{
|
{
|
||||||
const BIN = '(?:0b[01]+(?:_[01]+)*)';
|
const BIN = '(?:0b[01]+(?:_[01]+)*)';
|
||||||
const HEX = '(?:0x[0-9a-f]+(?:_[0-9a-f]+)*)';
|
const HEX = '(?:0x[0-9a-f]+(?:_[0-9a-f]+)*)';
|
||||||
|
36
lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php
Normal file
36
lib/PhpParser/Lexer/TokenEmulator/ReverseEmulator.php
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpParser\Lexer\TokenEmulator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverses emulation direction of the inner emulator.
|
||||||
|
*/
|
||||||
|
final class ReverseEmulator extends TokenEmulator
|
||||||
|
{
|
||||||
|
/** @var TokenEmulator Inner emulator */
|
||||||
|
private $emulator;
|
||||||
|
|
||||||
|
public function __construct(TokenEmulator $emulator) {
|
||||||
|
$this->emulator = $emulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPhpVersion(): string {
|
||||||
|
return $this->emulator->getPhpVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isEmulationNeeded(string $code): bool {
|
||||||
|
return $this->emulator->isEmulationNeeded($code);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function emulate(string $code, array $tokens): array {
|
||||||
|
return $this->emulator->reverseEmulate($code, $tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function reverseEmulate(string $code, array $tokens): array {
|
||||||
|
return $this->emulator->emulate($code, $tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function preprocessCode(string $code, array &$patches): string {
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
}
|
25
lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php
Normal file
25
lib/PhpParser/Lexer/TokenEmulator/TokenEmulator.php
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpParser\Lexer\TokenEmulator;
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
abstract class TokenEmulator
|
||||||
|
{
|
||||||
|
abstract public function getPhpVersion(): string;
|
||||||
|
|
||||||
|
abstract public function isEmulationNeeded(string $code): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array Modified Tokens
|
||||||
|
*/
|
||||||
|
abstract public function emulate(string $code, array $tokens): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array Modified Tokens
|
||||||
|
*/
|
||||||
|
abstract public function reverseEmulate(string $code, array $tokens): array;
|
||||||
|
|
||||||
|
public function preprocessCode(string $code, array &$patches): string {
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
}
|
@@ -1,21 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace PhpParser\Lexer\TokenEmulator;
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
interface TokenEmulatorInterface
|
|
||||||
{
|
|
||||||
public function getPhpVersion(): string;
|
|
||||||
|
|
||||||
public function isEmulationNeeded(string $code): bool;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array Modified Tokens
|
|
||||||
*/
|
|
||||||
public function emulate(string $code, array $tokens): array;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array Modified Tokens
|
|
||||||
*/
|
|
||||||
public function reverseEmulate(string $code, array $tokens): array;
|
|
||||||
}
|
|
34
lib/PhpParser/Node/Attribute.php
Normal file
34
lib/PhpParser/Node/Attribute.php
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpParser\Node;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\NodeAbstract;
|
||||||
|
|
||||||
|
class Attribute extends NodeAbstract
|
||||||
|
{
|
||||||
|
/** @var Name Attribute name */
|
||||||
|
public $name;
|
||||||
|
|
||||||
|
/** @var Arg[] Attribute arguments */
|
||||||
|
public $args;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Node\Name $name Attribute name
|
||||||
|
* @param Arg[] $args Attribute arguments
|
||||||
|
* @param array $attributes Additional node attributes
|
||||||
|
*/
|
||||||
|
public function __construct(Name $name, array $args = [], array $attributes = []) {
|
||||||
|
$this->attributes = $attributes;
|
||||||
|
$this->name = $name;
|
||||||
|
$this->args = $args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubNodeNames() : array {
|
||||||
|
return ['name', 'args'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getType() : string {
|
||||||
|
return 'Attribute';
|
||||||
|
}
|
||||||
|
}
|
29
lib/PhpParser/Node/AttributeGroup.php
Normal file
29
lib/PhpParser/Node/AttributeGroup.php
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace PhpParser\Node;
|
||||||
|
|
||||||
|
use PhpParser\Node;
|
||||||
|
use PhpParser\NodeAbstract;
|
||||||
|
|
||||||
|
class AttributeGroup extends NodeAbstract
|
||||||
|
{
|
||||||
|
/** @var Attribute[] Attributes */
|
||||||
|
public $attrs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Attribute[] $attrs PHP attributes
|
||||||
|
* @param array $attributes Additional node attributes
|
||||||
|
*/
|
||||||
|
public function __construct(array $attrs, array $attributes = []) {
|
||||||
|
$this->attributes = $attributes;
|
||||||
|
$this->attrs = $attrs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubNodeNames() : array {
|
||||||
|
return ['attrs'];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getType() : string {
|
||||||
|
return 'AttributeGroup';
|
||||||
|
}
|
||||||
|
}
|
@@ -5,7 +5,7 @@ namespace PhpParser\Node;
|
|||||||
use PhpParser\NodeAbstract;
|
use PhpParser\NodeAbstract;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @property Name $namespacedName Namespaced name (for class constants, if using NameResolver)
|
* @property Name $namespacedName Namespaced name (for global constants, if using NameResolver)
|
||||||
*/
|
*/
|
||||||
class Const_ extends NodeAbstract
|
class Const_ extends NodeAbstract
|
||||||
{
|
{
|
||||||
|
@@ -22,6 +22,8 @@ class ArrowFunction extends Expr implements FunctionLike
|
|||||||
|
|
||||||
/** @var Expr */
|
/** @var Expr */
|
||||||
public $expr;
|
public $expr;
|
||||||
|
/** @var Node\AttributeGroup[] */
|
||||||
|
public $attrGroups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $subNodes Array of the following optional subnodes:
|
* @param array $subNodes Array of the following optional subnodes:
|
||||||
@@ -30,6 +32,7 @@ class ArrowFunction extends Expr implements FunctionLike
|
|||||||
* 'params' => array() : Parameters
|
* 'params' => array() : Parameters
|
||||||
* 'returnType' => null : Return type
|
* 'returnType' => null : Return type
|
||||||
* 'expr' => Expr : Expression body
|
* 'expr' => Expr : Expression body
|
||||||
|
* 'attrGroups' => array() : PHP attribute groups
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $subNodes = [], array $attributes = []) {
|
public function __construct(array $subNodes = [], array $attributes = []) {
|
||||||
@@ -40,10 +43,11 @@ class ArrowFunction extends Expr implements FunctionLike
|
|||||||
$returnType = $subNodes['returnType'] ?? null;
|
$returnType = $subNodes['returnType'] ?? null;
|
||||||
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
||||||
$this->expr = $subNodes['expr'] ?? null;
|
$this->expr = $subNodes['expr'] ?? null;
|
||||||
|
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['static', 'byRef', 'params', 'returnType', 'expr'];
|
return ['attrGroups', 'static', 'byRef', 'params', 'returnType', 'expr'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function returnsByRef() : bool {
|
public function returnsByRef() : bool {
|
||||||
@@ -58,6 +62,10 @@ class ArrowFunction extends Expr implements FunctionLike
|
|||||||
return $this->returnType;
|
return $this->returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAttrGroups() : array {
|
||||||
|
return $this->attrGroups;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Node\Stmt\Return_[]
|
* @return Node\Stmt\Return_[]
|
||||||
*/
|
*/
|
||||||
|
@@ -20,6 +20,8 @@ class Closure extends Expr implements FunctionLike
|
|||||||
public $returnType;
|
public $returnType;
|
||||||
/** @var Node\Stmt[] Statements */
|
/** @var Node\Stmt[] Statements */
|
||||||
public $stmts;
|
public $stmts;
|
||||||
|
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||||
|
public $attrGroups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a lambda function node.
|
* Constructs a lambda function node.
|
||||||
@@ -31,6 +33,7 @@ class Closure extends Expr implements FunctionLike
|
|||||||
* 'uses' => array(): use()s
|
* 'uses' => array(): use()s
|
||||||
* 'returnType' => null : Return type
|
* 'returnType' => null : Return type
|
||||||
* 'stmts' => array(): Statements
|
* 'stmts' => array(): Statements
|
||||||
|
* 'attrGroups' => array(): PHP attributes groups
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct(array $subNodes = [], array $attributes = []) {
|
public function __construct(array $subNodes = [], array $attributes = []) {
|
||||||
@@ -42,10 +45,11 @@ class Closure extends Expr implements FunctionLike
|
|||||||
$returnType = $subNodes['returnType'] ?? null;
|
$returnType = $subNodes['returnType'] ?? null;
|
||||||
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
||||||
$this->stmts = $subNodes['stmts'] ?? [];
|
$this->stmts = $subNodes['stmts'] ?? [];
|
||||||
|
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['static', 'byRef', 'params', 'uses', 'returnType', 'stmts'];
|
return ['attrGroups', 'static', 'byRef', 'params', 'uses', 'returnType', 'stmts'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function returnsByRef() : bool {
|
public function returnsByRef() : bool {
|
||||||
@@ -65,6 +69,10 @@ class Closure extends Expr implements FunctionLike
|
|||||||
return $this->stmts;
|
return $this->stmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAttrGroups() : array {
|
||||||
|
return $this->attrGroups;
|
||||||
|
}
|
||||||
|
|
||||||
public function getType() : string {
|
public function getType() : string {
|
||||||
return 'Expr_Closure';
|
return 'Expr_Closure';
|
||||||
}
|
}
|
||||||
|
@@ -16,21 +16,28 @@ interface FunctionLike extends Node
|
|||||||
/**
|
/**
|
||||||
* List of parameters
|
* List of parameters
|
||||||
*
|
*
|
||||||
* @return Node\Param[]
|
* @return Param[]
|
||||||
*/
|
*/
|
||||||
public function getParams() : array;
|
public function getParams() : array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the declared return type or null
|
* Get the declared return type or null
|
||||||
*
|
*
|
||||||
* @return null|Identifier|Node\Name|Node\NullableType|Node\UnionType
|
* @return null|Identifier|Name|NullableType|UnionType
|
||||||
*/
|
*/
|
||||||
public function getReturnType();
|
public function getReturnType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The function body
|
* The function body
|
||||||
*
|
*
|
||||||
* @return Node\Stmt[]|null
|
* @return Stmt[]|null
|
||||||
*/
|
*/
|
||||||
public function getStmts();
|
public function getStmts();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get PHP attribute groups.
|
||||||
|
*
|
||||||
|
* @return AttributeGroup[]
|
||||||
|
*/
|
||||||
|
public function getAttrGroups() : array;
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,8 @@ class Param extends NodeAbstract
|
|||||||
public $default;
|
public $default;
|
||||||
/** @var int */
|
/** @var int */
|
||||||
public $flags;
|
public $flags;
|
||||||
|
/** @var AttributeGroup[] PHP attribute groups */
|
||||||
|
public $attrGroups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a parameter node.
|
* Constructs a parameter node.
|
||||||
@@ -27,14 +29,16 @@ class Param extends NodeAbstract
|
|||||||
* @param null|string|Identifier|Name|NullableType|UnionType $type Type declaration
|
* @param null|string|Identifier|Name|NullableType|UnionType $type Type declaration
|
||||||
* @param bool $byRef Whether is passed by reference
|
* @param bool $byRef Whether is passed by reference
|
||||||
* @param bool $variadic Whether this is a variadic argument
|
* @param bool $variadic Whether this is a variadic argument
|
||||||
* @param array $flags Optional visibility flags
|
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
|
* @param int $flags Optional visibility flags
|
||||||
|
* @param AttributeGroup[] $attrGroups PHP attribute groups
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$var, Expr $default = null, $type = null,
|
$var, Expr $default = null, $type = null,
|
||||||
bool $byRef = false, bool $variadic = false,
|
bool $byRef = false, bool $variadic = false,
|
||||||
array $attributes = [],
|
array $attributes = [],
|
||||||
int $flags = 0
|
int $flags = 0,
|
||||||
|
array $attrGroups = []
|
||||||
) {
|
) {
|
||||||
$this->attributes = $attributes;
|
$this->attributes = $attributes;
|
||||||
$this->type = \is_string($type) ? new Identifier($type) : $type;
|
$this->type = \is_string($type) ? new Identifier($type) : $type;
|
||||||
@@ -43,10 +47,11 @@ class Param extends NodeAbstract
|
|||||||
$this->var = $var;
|
$this->var = $var;
|
||||||
$this->default = $default;
|
$this->default = $default;
|
||||||
$this->flags = $flags;
|
$this->flags = $flags;
|
||||||
|
$this->attrGroups = $attrGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['flags', 'type', 'byRef', 'variadic', 'var', 'default'];
|
return ['attrGroups', 'flags', 'type', 'byRef', 'variadic', 'var', 'default'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getType() : string {
|
public function getType() : string {
|
||||||
|
@@ -10,22 +10,31 @@ class ClassConst extends Node\Stmt
|
|||||||
public $flags;
|
public $flags;
|
||||||
/** @var Node\Const_[] Constant declarations */
|
/** @var Node\Const_[] Constant declarations */
|
||||||
public $consts;
|
public $consts;
|
||||||
|
/** @var Node\AttributeGroup[] */
|
||||||
|
public $attrGroups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a class const list node.
|
* Constructs a class const list node.
|
||||||
*
|
*
|
||||||
* @param Node\Const_[] $consts Constant declarations
|
* @param Node\Const_[] $consts Constant declarations
|
||||||
* @param int $flags Modifiers
|
* @param int $flags Modifiers
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
|
* @param Node\AttributeGroup[] $attrGroups PHP attribute groups
|
||||||
*/
|
*/
|
||||||
public function __construct(array $consts, int $flags = 0, array $attributes = []) {
|
public function __construct(
|
||||||
|
array $consts,
|
||||||
|
int $flags = 0,
|
||||||
|
array $attributes = [],
|
||||||
|
array $attrGroups = []
|
||||||
|
) {
|
||||||
$this->attributes = $attributes;
|
$this->attributes = $attributes;
|
||||||
$this->flags = $flags;
|
$this->flags = $flags;
|
||||||
$this->consts = $consts;
|
$this->consts = $consts;
|
||||||
|
$this->attrGroups = $attrGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['flags', 'consts'];
|
return ['attrGroups', 'flags', 'consts'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -13,6 +13,8 @@ abstract class ClassLike extends Node\Stmt
|
|||||||
public $name;
|
public $name;
|
||||||
/** @var Node\Stmt[] Statements */
|
/** @var Node\Stmt[] Statements */
|
||||||
public $stmts;
|
public $stmts;
|
||||||
|
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||||
|
public $attrGroups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return TraitUse[]
|
* @return TraitUse[]
|
||||||
|
@@ -19,6 +19,8 @@ class ClassMethod extends Node\Stmt implements FunctionLike
|
|||||||
public $returnType;
|
public $returnType;
|
||||||
/** @var Node\Stmt[]|null Statements */
|
/** @var Node\Stmt[]|null Statements */
|
||||||
public $stmts;
|
public $stmts;
|
||||||
|
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||||
|
public $attrGroups;
|
||||||
|
|
||||||
private static $magicNames = [
|
private static $magicNames = [
|
||||||
'__construct' => true,
|
'__construct' => true,
|
||||||
@@ -48,6 +50,7 @@ class ClassMethod extends Node\Stmt implements FunctionLike
|
|||||||
* 'params' => array() : Parameters
|
* 'params' => array() : Parameters
|
||||||
* 'returnType' => null : Return type
|
* 'returnType' => null : Return type
|
||||||
* 'stmts' => array() : Statements
|
* 'stmts' => array() : Statements
|
||||||
|
* 'attrGroups' => array() : PHP attribute groups
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
||||||
@@ -59,10 +62,11 @@ class ClassMethod extends Node\Stmt implements FunctionLike
|
|||||||
$returnType = $subNodes['returnType'] ?? null;
|
$returnType = $subNodes['returnType'] ?? null;
|
||||||
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
||||||
$this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : [];
|
$this->stmts = array_key_exists('stmts', $subNodes) ? $subNodes['stmts'] : [];
|
||||||
|
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['flags', 'byRef', 'name', 'params', 'returnType', 'stmts'];
|
return ['attrGroups', 'flags', 'byRef', 'name', 'params', 'returnType', 'stmts'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function returnsByRef() : bool {
|
public function returnsByRef() : bool {
|
||||||
@@ -81,6 +85,10 @@ class ClassMethod extends Node\Stmt implements FunctionLike
|
|||||||
return $this->stmts;
|
return $this->stmts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAttrGroups() : array {
|
||||||
|
return $this->attrGroups;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the method is explicitly or implicitly public.
|
* Whether the method is explicitly or implicitly public.
|
||||||
*
|
*
|
||||||
|
@@ -28,10 +28,11 @@ class Class_ extends ClassLike
|
|||||||
*
|
*
|
||||||
* @param string|Node\Identifier|null $name Name
|
* @param string|Node\Identifier|null $name Name
|
||||||
* @param array $subNodes Array of the following optional subnodes:
|
* @param array $subNodes Array of the following optional subnodes:
|
||||||
* 'flags' => 0 : Flags
|
* 'flags' => 0 : Flags
|
||||||
* 'extends' => null : Name of extended class
|
* 'extends' => null : Name of extended class
|
||||||
* 'implements' => array(): Names of implemented interfaces
|
* 'implements' => array(): Names of implemented interfaces
|
||||||
* 'stmts' => array(): Statements
|
* 'stmts' => array(): Statements
|
||||||
|
* '$attrGroups' => array(): PHP attribute groups
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
||||||
@@ -41,10 +42,11 @@ class Class_ extends ClassLike
|
|||||||
$this->extends = $subNodes['extends'] ?? null;
|
$this->extends = $subNodes['extends'] ?? null;
|
||||||
$this->implements = $subNodes['implements'] ?? [];
|
$this->implements = $subNodes['implements'] ?? [];
|
||||||
$this->stmts = $subNodes['stmts'] ?? [];
|
$this->stmts = $subNodes['stmts'] ?? [];
|
||||||
|
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['flags', 'name', 'extends', 'implements', 'stmts'];
|
return ['attrGroups', 'flags', 'name', 'extends', 'implements', 'stmts'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -20,6 +20,8 @@ class Function_ extends Node\Stmt implements FunctionLike
|
|||||||
public $returnType;
|
public $returnType;
|
||||||
/** @var Node\Stmt[] Statements */
|
/** @var Node\Stmt[] Statements */
|
||||||
public $stmts;
|
public $stmts;
|
||||||
|
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||||
|
public $attrGroups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a function node.
|
* Constructs a function node.
|
||||||
@@ -30,6 +32,7 @@ class Function_ extends Node\Stmt implements FunctionLike
|
|||||||
* 'params' => array(): Parameters
|
* 'params' => array(): Parameters
|
||||||
* 'returnType' => null : Return type
|
* 'returnType' => null : Return type
|
||||||
* 'stmts' => array(): Statements
|
* 'stmts' => array(): Statements
|
||||||
|
* 'attrGroups' => array(): PHP attribute groups
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
||||||
@@ -40,10 +43,11 @@ class Function_ extends Node\Stmt implements FunctionLike
|
|||||||
$returnType = $subNodes['returnType'] ?? null;
|
$returnType = $subNodes['returnType'] ?? null;
|
||||||
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
$this->returnType = \is_string($returnType) ? new Node\Identifier($returnType) : $returnType;
|
||||||
$this->stmts = $subNodes['stmts'] ?? [];
|
$this->stmts = $subNodes['stmts'] ?? [];
|
||||||
|
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['byRef', 'name', 'params', 'returnType', 'stmts'];
|
return ['attrGroups', 'byRef', 'name', 'params', 'returnType', 'stmts'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function returnsByRef() : bool {
|
public function returnsByRef() : bool {
|
||||||
@@ -58,6 +62,10 @@ class Function_ extends Node\Stmt implements FunctionLike
|
|||||||
return $this->returnType;
|
return $this->returnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAttrGroups() : array {
|
||||||
|
return $this->attrGroups;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return Node\Stmt[] */
|
/** @return Node\Stmt[] */
|
||||||
public function getStmts() : array {
|
public function getStmts() : array {
|
||||||
return $this->stmts;
|
return $this->stmts;
|
||||||
|
@@ -14,8 +14,9 @@ class Interface_ extends ClassLike
|
|||||||
*
|
*
|
||||||
* @param string|Node\Identifier $name Name
|
* @param string|Node\Identifier $name Name
|
||||||
* @param array $subNodes Array of the following optional subnodes:
|
* @param array $subNodes Array of the following optional subnodes:
|
||||||
* 'extends' => array(): Name of extended interfaces
|
* 'extends' => array(): Name of extended interfaces
|
||||||
* 'stmts' => array(): Statements
|
* 'stmts' => array(): Statements
|
||||||
|
* 'attrGroups' => array(): PHP attribute groups
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
||||||
@@ -23,10 +24,11 @@ class Interface_ extends ClassLike
|
|||||||
$this->name = \is_string($name) ? new Node\Identifier($name) : $name;
|
$this->name = \is_string($name) ? new Node\Identifier($name) : $name;
|
||||||
$this->extends = $subNodes['extends'] ?? [];
|
$this->extends = $subNodes['extends'] ?? [];
|
||||||
$this->stmts = $subNodes['stmts'] ?? [];
|
$this->stmts = $subNodes['stmts'] ?? [];
|
||||||
|
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['name', 'extends', 'stmts'];
|
return ['attrGroups', 'name', 'extends', 'stmts'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getType() : string {
|
public function getType() : string {
|
||||||
|
@@ -16,6 +16,8 @@ class Property extends Node\Stmt
|
|||||||
public $props;
|
public $props;
|
||||||
/** @var null|Identifier|Name|NullableType|UnionType Type declaration */
|
/** @var null|Identifier|Name|NullableType|UnionType Type declaration */
|
||||||
public $type;
|
public $type;
|
||||||
|
/** @var Node\AttributeGroup[] PHP attribute groups */
|
||||||
|
public $attrGroups;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a class property list node.
|
* Constructs a class property list node.
|
||||||
@@ -24,16 +26,18 @@ class Property extends Node\Stmt
|
|||||||
* @param PropertyProperty[] $props Properties
|
* @param PropertyProperty[] $props Properties
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
* @param null|string|Identifier|Name|NullableType|UnionType $type Type declaration
|
* @param null|string|Identifier|Name|NullableType|UnionType $type Type declaration
|
||||||
|
* @param Node\AttributeGroup[] $attrGroups PHP attribute groups
|
||||||
*/
|
*/
|
||||||
public function __construct(int $flags, array $props, array $attributes = [], $type = null) {
|
public function __construct(int $flags, array $props, array $attributes = [], $type = null, array $attrGroups = []) {
|
||||||
$this->attributes = $attributes;
|
$this->attributes = $attributes;
|
||||||
$this->flags = $flags;
|
$this->flags = $flags;
|
||||||
$this->props = $props;
|
$this->props = $props;
|
||||||
$this->type = \is_string($type) ? new Identifier($type) : $type;
|
$this->type = \is_string($type) ? new Identifier($type) : $type;
|
||||||
|
$this->attrGroups = $attrGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['flags', 'type', 'props'];
|
return ['attrGroups', 'flags', 'type', 'props'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -11,17 +11,19 @@ class Trait_ extends ClassLike
|
|||||||
*
|
*
|
||||||
* @param string|Node\Identifier $name Name
|
* @param string|Node\Identifier $name Name
|
||||||
* @param array $subNodes Array of the following optional subnodes:
|
* @param array $subNodes Array of the following optional subnodes:
|
||||||
* 'stmts' => array(): Statements
|
* 'stmts' => array(): Statements
|
||||||
|
* 'attrGroups' => array(): PHP attribute groups
|
||||||
* @param array $attributes Additional attributes
|
* @param array $attributes Additional attributes
|
||||||
*/
|
*/
|
||||||
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
public function __construct($name, array $subNodes = [], array $attributes = []) {
|
||||||
$this->attributes = $attributes;
|
$this->attributes = $attributes;
|
||||||
$this->name = \is_string($name) ? new Node\Identifier($name) : $name;
|
$this->name = \is_string($name) ? new Node\Identifier($name) : $name;
|
||||||
$this->stmts = $subNodes['stmts'] ?? [];
|
$this->stmts = $subNodes['stmts'] ?? [];
|
||||||
|
$this->attrGroups = $subNodes['attrGroups'] ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getSubNodeNames() : array {
|
public function getSubNodeNames() : array {
|
||||||
return ['name', 'stmts'];
|
return ['attrGroups', 'name', 'stmts'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getType() : string {
|
public function getType() : string {
|
||||||
|
@@ -75,6 +75,7 @@ class NameResolver extends NodeVisitorAbstract
|
|||||||
$interface = $this->resolveClassName($interface);
|
$interface = $this->resolveClassName($interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->resolveAttrGroups($node);
|
||||||
if (null !== $node->name) {
|
if (null !== $node->name) {
|
||||||
$this->addNamespacedName($node);
|
$this->addNamespacedName($node);
|
||||||
}
|
}
|
||||||
@@ -83,25 +84,32 @@ class NameResolver extends NodeVisitorAbstract
|
|||||||
$interface = $this->resolveClassName($interface);
|
$interface = $this->resolveClassName($interface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->resolveAttrGroups($node);
|
||||||
$this->addNamespacedName($node);
|
$this->addNamespacedName($node);
|
||||||
} elseif ($node instanceof Stmt\Trait_) {
|
} elseif ($node instanceof Stmt\Trait_) {
|
||||||
|
$this->resolveAttrGroups($node);
|
||||||
$this->addNamespacedName($node);
|
$this->addNamespacedName($node);
|
||||||
} elseif ($node instanceof Stmt\Function_) {
|
} elseif ($node instanceof Stmt\Function_) {
|
||||||
$this->addNamespacedName($node);
|
|
||||||
$this->resolveSignature($node);
|
$this->resolveSignature($node);
|
||||||
|
$this->resolveAttrGroups($node);
|
||||||
|
$this->addNamespacedName($node);
|
||||||
} elseif ($node instanceof Stmt\ClassMethod
|
} elseif ($node instanceof Stmt\ClassMethod
|
||||||
|| $node instanceof Expr\Closure
|
|| $node instanceof Expr\Closure
|
||||||
|| $node instanceof Expr\ArrowFunction
|
|| $node instanceof Expr\ArrowFunction
|
||||||
) {
|
) {
|
||||||
$this->resolveSignature($node);
|
$this->resolveSignature($node);
|
||||||
|
$this->resolveAttrGroups($node);
|
||||||
} elseif ($node instanceof Stmt\Property) {
|
} elseif ($node instanceof Stmt\Property) {
|
||||||
if (null !== $node->type) {
|
if (null !== $node->type) {
|
||||||
$node->type = $this->resolveType($node->type);
|
$node->type = $this->resolveType($node->type);
|
||||||
}
|
}
|
||||||
|
$this->resolveAttrGroups($node);
|
||||||
} elseif ($node instanceof Stmt\Const_) {
|
} elseif ($node instanceof Stmt\Const_) {
|
||||||
foreach ($node->consts as $const) {
|
foreach ($node->consts as $const) {
|
||||||
$this->addNamespacedName($const);
|
$this->addNamespacedName($const);
|
||||||
}
|
}
|
||||||
|
} else if ($node instanceof Stmt\ClassConst) {
|
||||||
|
$this->resolveAttrGroups($node);
|
||||||
} elseif ($node instanceof Expr\StaticCall
|
} elseif ($node instanceof Expr\StaticCall
|
||||||
|| $node instanceof Expr\StaticPropertyFetch
|
|| $node instanceof Expr\StaticPropertyFetch
|
||||||
|| $node instanceof Expr\ClassConstFetch
|
|| $node instanceof Expr\ClassConstFetch
|
||||||
@@ -157,6 +165,7 @@ class NameResolver extends NodeVisitorAbstract
|
|||||||
private function resolveSignature($node) {
|
private function resolveSignature($node) {
|
||||||
foreach ($node->params as $param) {
|
foreach ($node->params as $param) {
|
||||||
$param->type = $this->resolveType($param->type);
|
$param->type = $this->resolveType($param->type);
|
||||||
|
$this->resolveAttrGroups($param);
|
||||||
}
|
}
|
||||||
$node->returnType = $this->resolveType($node->returnType);
|
$node->returnType = $this->resolveType($node->returnType);
|
||||||
}
|
}
|
||||||
@@ -225,4 +234,13 @@ class NameResolver extends NodeVisitorAbstract
|
|||||||
$node->namespacedName = Name::concat(
|
$node->namespacedName = Name::concat(
|
||||||
$this->nameContext->getNamespace(), (string) $node->name);
|
$this->nameContext->getNamespace(), (string) $node->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function resolveAttrGroups(Node $node)
|
||||||
|
{
|
||||||
|
foreach ($node->attrGroups as $attrGroup) {
|
||||||
|
foreach ($attrGroup->attrs as $attr) {
|
||||||
|
$attr->name = $this->resolveClassName($attr->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -17,11 +17,11 @@ use PhpParser\Node\Stmt;
|
|||||||
*/
|
*/
|
||||||
class Php5 extends \PhpParser\ParserAbstract
|
class Php5 extends \PhpParser\ParserAbstract
|
||||||
{
|
{
|
||||||
protected $tokenToSymbolMapSize = 391;
|
protected $tokenToSymbolMapSize = 392;
|
||||||
protected $actionTableSize = 1069;
|
protected $actionTableSize = 1069;
|
||||||
protected $gotoTableSize = 580;
|
protected $gotoTableSize = 580;
|
||||||
|
|
||||||
protected $invalidSymbol = 164;
|
protected $invalidSymbol = 165;
|
||||||
protected $errorSymbol = 1;
|
protected $errorSymbol = 1;
|
||||||
protected $defaultAction = -32766;
|
protected $defaultAction = -32766;
|
||||||
protected $unexpectedTokenRule = 32767;
|
protected $unexpectedTokenRule = 32767;
|
||||||
@@ -193,36 +193,37 @@ class Php5 extends \PhpParser\ParserAbstract
|
|||||||
"'`'",
|
"'`'",
|
||||||
"']'",
|
"']'",
|
||||||
"'\"'",
|
"'\"'",
|
||||||
"T_NULLSAFE_OBJECT_OPERATOR"
|
"T_NULLSAFE_OBJECT_OPERATOR",
|
||||||
|
"T_ATTRIBUTE"
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $tokenToSymbol = array(
|
protected $tokenToSymbol = array(
|
||||||
0, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
0, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 55, 162, 164, 159, 54, 37, 164,
|
165, 165, 165, 55, 162, 165, 159, 54, 37, 165,
|
||||||
157, 158, 52, 49, 8, 50, 51, 53, 164, 164,
|
157, 158, 52, 49, 8, 50, 51, 53, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 31, 154,
|
165, 165, 165, 165, 165, 165, 165, 165, 31, 154,
|
||||||
43, 16, 45, 30, 67, 164, 164, 164, 164, 164,
|
43, 16, 45, 30, 67, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 69, 164, 161, 36, 164, 160, 164, 164, 164,
|
165, 69, 165, 161, 36, 165, 160, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 155, 35, 156, 57, 164, 164, 164,
|
165, 165, 165, 155, 35, 156, 57, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
|
165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
|
||||||
164, 164, 164, 164, 164, 164, 1, 2, 3, 4,
|
165, 165, 165, 165, 165, 165, 1, 2, 3, 4,
|
||||||
5, 6, 7, 9, 10, 11, 12, 13, 14, 15,
|
5, 6, 7, 9, 10, 11, 12, 13, 14, 15,
|
||||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
|
17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
|
||||||
27, 28, 29, 32, 33, 34, 38, 39, 40, 41,
|
27, 28, 29, 32, 33, 34, 38, 39, 40, 41,
|
||||||
@@ -236,7 +237,7 @@ class Php5 extends \PhpParser\ParserAbstract
|
|||||||
124, 125, 126, 127, 128, 129, 130, 131, 163, 132,
|
124, 125, 126, 127, 128, 129, 130, 131, 163, 132,
|
||||||
133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
|
133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
|
||||||
143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
|
143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
|
||||||
153
|
153, 164
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $action = array(
|
protected $action = array(
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -140,4 +140,5 @@ final class Tokens
|
|||||||
const T_NAME_FULLY_QUALIFIED = 388;
|
const T_NAME_FULLY_QUALIFIED = 388;
|
||||||
const T_NAME_QUALIFIED = 389;
|
const T_NAME_QUALIFIED = 389;
|
||||||
const T_NAME_RELATIVE = 390;
|
const T_NAME_RELATIVE = 390;
|
||||||
|
const T_ATTRIBUTE = 391;
|
||||||
}
|
}
|
||||||
|
@@ -18,7 +18,8 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
// Special nodes
|
// Special nodes
|
||||||
|
|
||||||
protected function pParam(Node\Param $node) {
|
protected function pParam(Node\Param $node) {
|
||||||
return ($this->pModifiers($node->flags))
|
return $this->pAttrGroups($node->attrGroups, true)
|
||||||
|
. $this->pModifiers($node->flags)
|
||||||
. ($node->type ? $this->p($node->type) . ' ' : '')
|
. ($node->type ? $this->p($node->type) . ' ' : '')
|
||||||
. ($node->byRef ? '&' : '')
|
. ($node->byRef ? '&' : '')
|
||||||
. ($node->variadic ? '...' : '')
|
. ($node->variadic ? '...' : '')
|
||||||
@@ -52,6 +53,15 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
return '$' . $node->name;
|
return '$' . $node->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function pAttribute(Node\Attribute $node) {
|
||||||
|
return $this->p($node->name)
|
||||||
|
. ($node->args ? '(' . $this->pCommaSeparated($node->args) . ')' : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function pAttributeGroup(Node\AttributeGroup $node) {
|
||||||
|
return '#[' . $this->pCommaSeparated($node->attrs) . ']';
|
||||||
|
}
|
||||||
|
|
||||||
// Names
|
// Names
|
||||||
|
|
||||||
protected function pName(Name $node) {
|
protected function pName(Name $node) {
|
||||||
@@ -600,7 +610,8 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function pExpr_Closure(Expr\Closure $node) {
|
protected function pExpr_Closure(Expr\Closure $node) {
|
||||||
return ($node->static ? 'static ' : '')
|
return $this->pAttrGroups($node->attrGroups, true)
|
||||||
|
. ($node->static ? 'static ' : '')
|
||||||
. 'function ' . ($node->byRef ? '&' : '')
|
. 'function ' . ($node->byRef ? '&' : '')
|
||||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||||
. (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')' : '')
|
. (!empty($node->uses) ? ' use(' . $this->pCommaSeparated($node->uses) . ')' : '')
|
||||||
@@ -621,7 +632,8 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function pExpr_ArrowFunction(Expr\ArrowFunction $node) {
|
protected function pExpr_ArrowFunction(Expr\ArrowFunction $node) {
|
||||||
return ($node->static ? 'static ' : '')
|
return $this->pAttrGroups($node->attrGroups, true)
|
||||||
|
. ($node->static ? 'static ' : '')
|
||||||
. 'fn' . ($node->byRef ? '&' : '')
|
. 'fn' . ($node->byRef ? '&' : '')
|
||||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||||
. (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '')
|
. (null !== $node->returnType ? ': ' . $this->p($node->returnType) : '')
|
||||||
@@ -709,7 +721,8 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function pStmt_Interface(Stmt\Interface_ $node) {
|
protected function pStmt_Interface(Stmt\Interface_ $node) {
|
||||||
return 'interface ' . $node->name
|
return $this->pAttrGroups($node->attrGroups)
|
||||||
|
. 'interface ' . $node->name
|
||||||
. (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '')
|
. (!empty($node->extends) ? ' extends ' . $this->pCommaSeparated($node->extends) : '')
|
||||||
. $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
|
. $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
|
||||||
}
|
}
|
||||||
@@ -719,7 +732,8 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function pStmt_Trait(Stmt\Trait_ $node) {
|
protected function pStmt_Trait(Stmt\Trait_ $node) {
|
||||||
return 'trait ' . $node->name
|
return $this->pAttrGroups($node->attrGroups)
|
||||||
|
. 'trait ' . $node->name
|
||||||
. $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
|
. $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -744,7 +758,8 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function pStmt_Property(Stmt\Property $node) {
|
protected function pStmt_Property(Stmt\Property $node) {
|
||||||
return (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags))
|
return $this->pAttrGroups($node->attrGroups)
|
||||||
|
. (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags))
|
||||||
. ($node->type ? $this->p($node->type) . ' ' : '')
|
. ($node->type ? $this->p($node->type) . ' ' : '')
|
||||||
. $this->pCommaSeparated($node->props) . ';';
|
. $this->pCommaSeparated($node->props) . ';';
|
||||||
}
|
}
|
||||||
@@ -755,7 +770,8 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function pStmt_ClassMethod(Stmt\ClassMethod $node) {
|
protected function pStmt_ClassMethod(Stmt\ClassMethod $node) {
|
||||||
return $this->pModifiers($node->flags)
|
return $this->pAttrGroups($node->attrGroups)
|
||||||
|
. $this->pModifiers($node->flags)
|
||||||
. 'function ' . ($node->byRef ? '&' : '') . $node->name
|
. 'function ' . ($node->byRef ? '&' : '') . $node->name
|
||||||
. '(' . $this->pMaybeMultiline($node->params) . ')'
|
. '(' . $this->pMaybeMultiline($node->params) . ')'
|
||||||
. (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '')
|
. (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '')
|
||||||
@@ -765,12 +781,14 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected function pStmt_ClassConst(Stmt\ClassConst $node) {
|
protected function pStmt_ClassConst(Stmt\ClassConst $node) {
|
||||||
return $this->pModifiers($node->flags)
|
return $this->pAttrGroups($node->attrGroups)
|
||||||
|
. $this->pModifiers($node->flags)
|
||||||
. 'const ' . $this->pCommaSeparated($node->consts) . ';';
|
. 'const ' . $this->pCommaSeparated($node->consts) . ';';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function pStmt_Function(Stmt\Function_ $node) {
|
protected function pStmt_Function(Stmt\Function_ $node) {
|
||||||
return 'function ' . ($node->byRef ? '&' : '') . $node->name
|
return $this->pAttrGroups($node->attrGroups)
|
||||||
|
. 'function ' . ($node->byRef ? '&' : '') . $node->name
|
||||||
. '(' . $this->pCommaSeparated($node->params) . ')'
|
. '(' . $this->pCommaSeparated($node->params) . ')'
|
||||||
. (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '')
|
. (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '')
|
||||||
. $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
|
. $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
|
||||||
@@ -925,11 +943,12 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) {
|
protected function pClassCommon(Stmt\Class_ $node, $afterClassToken) {
|
||||||
return $this->pModifiers($node->flags)
|
return $this->pAttrGroups($node->attrGroups, $node->name === null)
|
||||||
. 'class' . $afterClassToken
|
. $this->pModifiers($node->flags)
|
||||||
. (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '')
|
. 'class' . $afterClassToken
|
||||||
. (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '')
|
. (null !== $node->extends ? ' extends ' . $this->p($node->extends) : '')
|
||||||
. $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
|
. (!empty($node->implements) ? ' implements ' . $this->pCommaSeparated($node->implements) : '')
|
||||||
|
. $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function pObjectProperty($node) {
|
protected function pObjectProperty($node) {
|
||||||
@@ -1030,11 +1049,21 @@ class Standard extends PrettyPrinterAbstract
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function pMaybeMultiline(array $nodes, $trailingComma = false) {
|
private function pMaybeMultiline(array $nodes, bool $trailingComma = false) {
|
||||||
if (!$this->hasNodeWithComments($nodes)) {
|
if (!$this->hasNodeWithComments($nodes)) {
|
||||||
return $this->pCommaSeparated($nodes);
|
return $this->pCommaSeparated($nodes);
|
||||||
} else {
|
} else {
|
||||||
return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl;
|
return $this->pCommaSeparatedMultiline($nodes, $trailingComma) . $this->nl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function pAttrGroups(array $nodes, bool $inline = false): string {
|
||||||
|
$result = '';
|
||||||
|
$sep = $inline ? ' ' : $this->nl;
|
||||||
|
foreach ($nodes as $node) {
|
||||||
|
$result .= $this->p($node) . $sep;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1375,6 +1375,7 @@ abstract class PrettyPrinterAbstract
|
|||||||
'Stmt_Unset->vars' => ', ',
|
'Stmt_Unset->vars' => ', ',
|
||||||
'Stmt_Use->uses' => ', ',
|
'Stmt_Use->uses' => ', ',
|
||||||
'MatchArm->conds' => ', ',
|
'MatchArm->conds' => ', ',
|
||||||
|
'AttributeGroup->attrs' => ', ',
|
||||||
|
|
||||||
// statement lists
|
// statement lists
|
||||||
'Expr_Closure->stmts' => "\n",
|
'Expr_Closure->stmts' => "\n",
|
||||||
@@ -1395,6 +1396,17 @@ abstract class PrettyPrinterAbstract
|
|||||||
'Stmt_Function->stmts' => "\n",
|
'Stmt_Function->stmts' => "\n",
|
||||||
'Stmt_If->stmts' => "\n",
|
'Stmt_If->stmts' => "\n",
|
||||||
'Stmt_Namespace->stmts' => "\n",
|
'Stmt_Namespace->stmts' => "\n",
|
||||||
|
'Stmt_Class->attrGroups' => "\n",
|
||||||
|
'Stmt_Interface->attrGroups' => "\n",
|
||||||
|
'Stmt_Trait->attrGroups' => "\n",
|
||||||
|
'Stmt_Function->attrGroups' => "\n",
|
||||||
|
'Stmt_ClassMethod->attrGroups' => "\n",
|
||||||
|
'Stmt_ClassConst->attrGroups' => "\n",
|
||||||
|
'Stmt_Property->attrGroups' => "\n",
|
||||||
|
'Expr_PrintableNewAnonClass->attrGroups' => ' ',
|
||||||
|
'Expr_Closure->attrGroups' => ' ',
|
||||||
|
'Expr_ArrowFunction->attrGroups' => ' ',
|
||||||
|
'Param->attrGroups' => ' ',
|
||||||
'Stmt_Switch->cases' => "\n",
|
'Stmt_Switch->cases' => "\n",
|
||||||
'Stmt_TraitUse->adaptations' => "\n",
|
'Stmt_TraitUse->adaptations' => "\n",
|
||||||
'Stmt_TryCatch->stmts' => "\n",
|
'Stmt_TryCatch->stmts' => "\n",
|
||||||
|
@@ -121,9 +121,11 @@ class ConstExprEvaluatorTest extends \PHPUnit\Framework\TestCase
|
|||||||
'Modulo by zero'
|
'Modulo by zero'
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
new Expr\BinaryOp\Div(new Scalar\LNumber(42), new Scalar\LNumber(0)),
|
new Expr\BinaryOp\Plus(new Scalar\LNumber(42), new Scalar\String_("1foo")),
|
||||||
\ErrorException::class,
|
\ErrorException::class,
|
||||||
'Division by zero'
|
\PHP_VERSION_ID >= 80000
|
||||||
|
? 'A non-numeric value encountered'
|
||||||
|
: 'A non well formed numeric value encountered'
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@@ -275,6 +275,33 @@ class EmulativeTest extends LexerTest
|
|||||||
['?->', [
|
['?->', [
|
||||||
[Tokens::T_NULLSAFE_OBJECT_OPERATOR, '?->'],
|
[Tokens::T_NULLSAFE_OBJECT_OPERATOR, '?->'],
|
||||||
]],
|
]],
|
||||||
|
['#[Attr]', [
|
||||||
|
[Tokens::T_ATTRIBUTE, '#['],
|
||||||
|
[Tokens::T_STRING, 'Attr'],
|
||||||
|
[ord(']'), ']'],
|
||||||
|
]],
|
||||||
|
["#[\nAttr\n]", [
|
||||||
|
[Tokens::T_ATTRIBUTE, '#['],
|
||||||
|
[Tokens::T_STRING, 'Attr'],
|
||||||
|
[ord(']'), ']'],
|
||||||
|
]],
|
||||||
|
// Test interaction of two patch-based emulators
|
||||||
|
["<<<LABEL\n LABEL, #[Attr]", [
|
||||||
|
[Tokens::T_START_HEREDOC, "<<<LABEL\n"],
|
||||||
|
[Tokens::T_END_HEREDOC, " LABEL"],
|
||||||
|
[ord(','), ','],
|
||||||
|
[Tokens::T_ATTRIBUTE, '#['],
|
||||||
|
[Tokens::T_STRING, 'Attr'],
|
||||||
|
[ord(']'), ']'],
|
||||||
|
]],
|
||||||
|
["#[Attr] <<<LABEL\n LABEL,", [
|
||||||
|
[Tokens::T_ATTRIBUTE, '#['],
|
||||||
|
[Tokens::T_STRING, 'Attr'],
|
||||||
|
[ord(']'), ']'],
|
||||||
|
[Tokens::T_START_HEREDOC, "<<<LABEL\n"],
|
||||||
|
[Tokens::T_END_HEREDOC, " LABEL"],
|
||||||
|
[ord(','), ','],
|
||||||
|
]],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,6 +320,22 @@ class EmulativeTest extends LexerTest
|
|||||||
['7.4', 'match', [[Tokens::T_STRING, 'match']]],
|
['7.4', 'match', [[Tokens::T_STRING, 'match']]],
|
||||||
['7.4', 'fn', [[Tokens::T_FN, 'fn']]],
|
['7.4', 'fn', [[Tokens::T_FN, 'fn']]],
|
||||||
['7.3', 'fn', [[Tokens::T_STRING, 'fn']]],
|
['7.3', 'fn', [[Tokens::T_STRING, 'fn']]],
|
||||||
|
// Tested here to skip testLeaveStuffAloneInStrings.
|
||||||
|
['8.0', '"$foo?->bar"', [
|
||||||
|
[ord('"'), '"'],
|
||||||
|
[Tokens::T_VARIABLE, '$foo'],
|
||||||
|
[Tokens::T_NULLSAFE_OBJECT_OPERATOR, '?->'],
|
||||||
|
[Tokens::T_STRING, 'bar'],
|
||||||
|
[ord('"'), '"'],
|
||||||
|
]],
|
||||||
|
['8.0', '"$foo?->bar baz"', [
|
||||||
|
[ord('"'), '"'],
|
||||||
|
[Tokens::T_VARIABLE, '$foo'],
|
||||||
|
[Tokens::T_NULLSAFE_OBJECT_OPERATOR, '?->'],
|
||||||
|
[Tokens::T_STRING, 'bar'],
|
||||||
|
[Tokens::T_ENCAPSED_AND_WHITESPACE, ' baz'],
|
||||||
|
[ord('"'), '"'],
|
||||||
|
]],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -248,6 +248,7 @@ PHP;
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags": 0,
|
"flags": 0,
|
||||||
|
"attrGroups": [],
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"startLine": 4,
|
"startLine": 4,
|
||||||
"endLine": 4
|
"endLine": 4
|
||||||
@@ -275,6 +276,7 @@ PHP;
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags": 0,
|
"flags": 0,
|
||||||
|
"attrGroups": [],
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"startLine": 4,
|
"startLine": 4,
|
||||||
"endLine": 4
|
"endLine": 4
|
||||||
@@ -302,6 +304,7 @@ PHP;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"attrGroups": [],
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"startLine": 4,
|
"startLine": 4,
|
||||||
"comments": [
|
"comments": [
|
||||||
|
@@ -165,13 +165,8 @@ namespace Baz {
|
|||||||
}
|
}
|
||||||
EOC;
|
EOC;
|
||||||
|
|
||||||
$parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative);
|
|
||||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||||
$traverser = new PhpParser\NodeTraverser;
|
$stmts = $this->parseAndResolve($code);
|
||||||
$traverser->addVisitor(new NameResolver);
|
|
||||||
|
|
||||||
$stmts = $parser->parse($code);
|
|
||||||
$stmts = $traverser->traverse($stmts);
|
|
||||||
|
|
||||||
$this->assertSame(
|
$this->assertSame(
|
||||||
$this->canonicalize($expectedCode),
|
$this->canonicalize($expectedCode),
|
||||||
@@ -187,33 +182,43 @@ EOC;
|
|||||||
<?php
|
<?php
|
||||||
namespace NS;
|
namespace NS;
|
||||||
|
|
||||||
|
#[X]
|
||||||
class A extends B implements C, D {
|
class A extends B implements C, D {
|
||||||
use E, F, G {
|
use E, F, G {
|
||||||
f as private g;
|
f as private g;
|
||||||
E::h as i;
|
E::h as i;
|
||||||
E::j insteadof F, G;
|
E::j insteadof F, G;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[X]
|
||||||
|
public float $php = 7.4;
|
||||||
|
public ?Foo $person;
|
||||||
|
protected static ?bool $probability;
|
||||||
|
public A|B|int $prop;
|
||||||
|
|
||||||
|
#[X]
|
||||||
|
const C = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[X]
|
||||||
interface A extends C, D {
|
interface A extends C, D {
|
||||||
public function a(A $a) : A;
|
public function a(A $a) : A;
|
||||||
public function b(A|B|int $a): A|B|int;
|
public function b(A|B|int $a): A|B|int;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClassWithTypeProperties {
|
#[X]
|
||||||
public float $php = 7.4;
|
trait A {}
|
||||||
public ?Foo $person;
|
|
||||||
protected static ?bool $probability;
|
|
||||||
public A|B|int $prop;
|
|
||||||
}
|
|
||||||
|
|
||||||
function f(A $a) : A {}
|
#[X]
|
||||||
|
function f(#[X] A $a) : A {}
|
||||||
function f2(array $a) : array {}
|
function f2(array $a) : array {}
|
||||||
function(A $a) : A {};
|
|
||||||
|
|
||||||
function fn3(?A $a) : ?A {}
|
function fn3(?A $a) : ?A {}
|
||||||
function fn4(?array $a) : ?array {}
|
function fn4(?array $a) : ?array {}
|
||||||
|
|
||||||
|
#[X]
|
||||||
|
function(A $a) : A {};
|
||||||
|
|
||||||
|
#[X]
|
||||||
fn(array $a): array => $a;
|
fn(array $a): array => $a;
|
||||||
fn(A $a): A => $a;
|
fn(A $a): A => $a;
|
||||||
fn(?A $a): ?A => $a;
|
fn(?A $a): ?A => $a;
|
||||||
@@ -236,6 +241,7 @@ EOC;
|
|||||||
$expectedCode = <<<'EOC'
|
$expectedCode = <<<'EOC'
|
||||||
namespace NS;
|
namespace NS;
|
||||||
|
|
||||||
|
#[\NS\X]
|
||||||
class A extends \NS\B implements \NS\C, \NS\D
|
class A extends \NS\B implements \NS\C, \NS\D
|
||||||
{
|
{
|
||||||
use \NS\E, \NS\F, \NS\G {
|
use \NS\E, \NS\F, \NS\G {
|
||||||
@@ -243,34 +249,40 @@ class A extends \NS\B implements \NS\C, \NS\D
|
|||||||
\NS\E::h as i;
|
\NS\E::h as i;
|
||||||
\NS\E::j insteadof \NS\F, \NS\G;
|
\NS\E::j insteadof \NS\F, \NS\G;
|
||||||
}
|
}
|
||||||
|
#[\NS\X]
|
||||||
|
public float $php = 7.4;
|
||||||
|
public ?\NS\Foo $person;
|
||||||
|
protected static ?bool $probability;
|
||||||
|
public \NS\A|\NS\B|int $prop;
|
||||||
|
#[\NS\X]
|
||||||
|
const C = 1;
|
||||||
}
|
}
|
||||||
|
#[\NS\X]
|
||||||
interface A extends \NS\C, \NS\D
|
interface A extends \NS\C, \NS\D
|
||||||
{
|
{
|
||||||
public function a(\NS\A $a) : \NS\A;
|
public function a(\NS\A $a) : \NS\A;
|
||||||
public function b(\NS\A|\NS\B|int $a) : \NS\A|\NS\B|int;
|
public function b(\NS\A|\NS\B|int $a) : \NS\A|\NS\B|int;
|
||||||
}
|
}
|
||||||
class ClassWithTypeProperties
|
#[\NS\X]
|
||||||
|
trait A
|
||||||
{
|
{
|
||||||
public float $php = 7.4;
|
|
||||||
public ?\NS\Foo $person;
|
|
||||||
protected static ?bool $probability;
|
|
||||||
public \NS\A|\NS\B|int $prop;
|
|
||||||
}
|
}
|
||||||
function f(\NS\A $a) : \NS\A
|
#[\NS\X]
|
||||||
|
function f(#[\NS\X] \NS\A $a) : \NS\A
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
function f2(array $a) : array
|
function f2(array $a) : array
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
function (\NS\A $a) : \NS\A {
|
|
||||||
};
|
|
||||||
function fn3(?\NS\A $a) : ?\NS\A
|
function fn3(?\NS\A $a) : ?\NS\A
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
function fn4(?array $a) : ?array
|
function fn4(?array $a) : ?array
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
fn(array $a): array => $a;
|
#[\NS\X] function (\NS\A $a) : \NS\A {
|
||||||
|
};
|
||||||
|
#[\NS\X] fn(array $a): array => $a;
|
||||||
fn(\NS\A $a): \NS\A => $a;
|
fn(\NS\A $a): \NS\A => $a;
|
||||||
fn(?\NS\A $a): ?\NS\A => $a;
|
fn(?\NS\A $a): ?\NS\A => $a;
|
||||||
\NS\A::b();
|
\NS\A::b();
|
||||||
@@ -287,13 +299,8 @@ try {
|
|||||||
}
|
}
|
||||||
EOC;
|
EOC;
|
||||||
|
|
||||||
$parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative);
|
|
||||||
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
$prettyPrinter = new PhpParser\PrettyPrinter\Standard;
|
||||||
$traverser = new PhpParser\NodeTraverser;
|
$stmts = $this->parseAndResolve($code);
|
||||||
$traverser->addVisitor(new NameResolver);
|
|
||||||
|
|
||||||
$stmts = $parser->parse($code);
|
|
||||||
$stmts = $traverser->traverse($stmts);
|
|
||||||
|
|
||||||
$this->assertSame(
|
$this->assertSame(
|
||||||
$this->canonicalize($expectedCode),
|
$this->canonicalize($expectedCode),
|
||||||
@@ -512,4 +519,14 @@ EOC;
|
|||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
new Name\FullyQualified('Foo\bar'), $n2->getAttribute('namespacedName'));
|
new Name\FullyQualified('Foo\bar'), $n2->getAttribute('namespacedName'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function parseAndResolve(string $code): array
|
||||||
|
{
|
||||||
|
$parser = new PhpParser\Parser\Php7(new PhpParser\Lexer\Emulative);
|
||||||
|
$traverser = new PhpParser\NodeTraverser;
|
||||||
|
$traverser->addVisitor(new NameResolver);
|
||||||
|
|
||||||
|
$stmts = $parser->parse($code);
|
||||||
|
return $traverser->traverse($stmts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
179
test/code/formatPreservation/attributes.test
Normal file
179
test/code/formatPreservation/attributes.test
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
Attributes
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
#[A]
|
||||||
|
class X {
|
||||||
|
#[A]
|
||||||
|
public function m(#[A] & $p) {}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
public
|
||||||
|
$prop;
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
const
|
||||||
|
X = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
trait X {}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
interface X {}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
function f() {}
|
||||||
|
|
||||||
|
new #[A] class {};
|
||||||
|
#[A] function() {};
|
||||||
|
#[A] fn()
|
||||||
|
=> 42;
|
||||||
|
-----
|
||||||
|
$attrGroup = new Node\AttributeGroup([
|
||||||
|
new Node\Attribute(new Node\Name('B'), []),
|
||||||
|
]);
|
||||||
|
$stmts[0]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[0]->stmts[0]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[0]->stmts[0]->params[0]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[0]->stmts[1]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[0]->stmts[2]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[1]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[2]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[3]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[4]->expr->class->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[5]->expr->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[6]->expr->attrGroups[] = $attrGroup;
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
#[A]
|
||||||
|
#[B]
|
||||||
|
class X {
|
||||||
|
#[A]
|
||||||
|
#[B]
|
||||||
|
public function m(#[A] #[B] & $p) {}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
#[B]
|
||||||
|
public
|
||||||
|
$prop;
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
#[B]
|
||||||
|
const
|
||||||
|
X = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
#[B]
|
||||||
|
trait X {}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
#[B]
|
||||||
|
interface X {}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
#[B]
|
||||||
|
function f() {}
|
||||||
|
|
||||||
|
new #[A] #[B] class {};
|
||||||
|
#[A] #[B] function() {};
|
||||||
|
#[A] #[B] fn()
|
||||||
|
=> 42;
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
class X {
|
||||||
|
public function m() {}
|
||||||
|
|
||||||
|
public
|
||||||
|
$prop;
|
||||||
|
|
||||||
|
const
|
||||||
|
X = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
trait X {}
|
||||||
|
|
||||||
|
interface X {}
|
||||||
|
|
||||||
|
function f() {}
|
||||||
|
|
||||||
|
new class {};
|
||||||
|
function() {};
|
||||||
|
fn()
|
||||||
|
=> 42;
|
||||||
|
-----
|
||||||
|
// TODO: Currently we lose formatting for this case.
|
||||||
|
$attrGroup = new Node\AttributeGroup([
|
||||||
|
new Node\Attribute(new Node\Name('A'), []),
|
||||||
|
]);
|
||||||
|
$stmts[0]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[0]->stmts[0]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[0]->stmts[1]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[0]->stmts[2]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[1]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[2]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[3]->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[4]->expr->class->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[5]->expr->attrGroups[] = $attrGroup;
|
||||||
|
$stmts[6]->expr->attrGroups[] = $attrGroup;
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
#[A]
|
||||||
|
class X
|
||||||
|
{
|
||||||
|
#[A]
|
||||||
|
public function m()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#[A]
|
||||||
|
public $prop;
|
||||||
|
#[A]
|
||||||
|
const X = 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
trait X
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
interface X
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A]
|
||||||
|
function f()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
new #[A] class
|
||||||
|
{
|
||||||
|
};
|
||||||
|
#[A] function () {
|
||||||
|
};
|
||||||
|
#[A] fn() => 42;
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
|
||||||
|
#[ A, B]
|
||||||
|
class X {};
|
||||||
|
#[
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
]
|
||||||
|
class X {};
|
||||||
|
-----
|
||||||
|
$attr = new Node\Attribute(new Node\Name('C'), []);
|
||||||
|
$stmts[0]->attrGroups[0]->attrs[] = $attr;
|
||||||
|
$stmts[1]->attrGroups[0]->attrs[] = $attr;
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
|
||||||
|
#[ A, B, C]
|
||||||
|
class X {};
|
||||||
|
#[
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
]
|
||||||
|
class X {};
|
@@ -8,6 +8,8 @@ class MyClass {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: MyClass
|
name: MyClass
|
||||||
@@ -17,6 +19,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PROTECTED (2)
|
flags: MODIFIER_PROTECTED (2)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
|
@@ -161,6 +161,8 @@ function test() {
|
|||||||
Syntax error, unexpected '}' from 4:1 to 4:1
|
Syntax error, unexpected '}' from 4:1 to 4:1
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test
|
name: test
|
||||||
@@ -306,6 +308,8 @@ function foo() {
|
|||||||
Syntax error, unexpected '}', expecting T_STRING or T_VARIABLE or '{' or '$' from 4:1 to 4:1
|
Syntax error, unexpected '}', expecting T_STRING or T_VARIABLE or '{' or '$' from 4:1 to 4:1
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function[2:1 - 4:1](
|
0: Stmt_Function[2:1 - 4:1](
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier[2:10 - 2:12](
|
name: Identifier[2:10 - 2:12](
|
||||||
name: foo
|
name: foo
|
||||||
@@ -683,6 +687,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
4: Stmt_Class(
|
4: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: X
|
name: X
|
||||||
@@ -736,6 +742,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_ClassConst(
|
2: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -749,6 +757,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
3: Stmt_Property(
|
3: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -763,6 +773,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
5: Stmt_Interface(
|
5: Stmt_Interface(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: I
|
name: I
|
||||||
)
|
)
|
||||||
@@ -895,6 +907,8 @@ class Foo {
|
|||||||
Syntax error, unexpected T_STRING from 4:5 to 4:9
|
Syntax error, unexpected T_STRING from 4:5 to 4:9
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Foo
|
name: Foo
|
||||||
@@ -904,6 +918,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -998,12 +1014,16 @@ Syntax error, unexpected ')', expecting T_VARIABLE from 22:21 to 22:21
|
|||||||
Syntax error, unexpected ')', expecting T_VARIABLE from 25:13 to 25:13
|
Syntax error, unexpected ')', expecting T_VARIABLE from 25:13 to 25:13
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: foo
|
name: foo
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
@@ -1027,12 +1047,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Function(
|
1: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: foo
|
name: foo
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
@@ -1047,6 +1071,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
@@ -1070,12 +1096,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_Function(
|
2: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: foo
|
name: foo
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -1095,12 +1125,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
3: Stmt_Function(
|
3: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: foo
|
name: foo
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: true
|
byRef: true
|
||||||
@@ -1120,12 +1154,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
4: Stmt_Function(
|
4: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: foo
|
name: foo
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
@@ -1144,6 +1182,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
5: Stmt_Class(
|
5: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Bar
|
name: Bar
|
||||||
@@ -1153,6 +1193,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -1160,6 +1202,8 @@ array(
|
|||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
@@ -1181,10 +1225,14 @@ array(
|
|||||||
)
|
)
|
||||||
6: Stmt_Expression(
|
6: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
@@ -1219,9 +1267,9 @@ $array = [
|
|||||||
];
|
];
|
||||||
-----
|
-----
|
||||||
!!php7
|
!!php7
|
||||||
Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 3:18 to 3:34
|
Syntax error, unexpected T_VARIABLE, expecting ',' or ']' or ')' from 3:18 to 3:34
|
||||||
Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 6:12 to 6:28
|
Syntax error, unexpected T_VARIABLE, expecting ',' or ']' or ')' from 6:12 to 6:28
|
||||||
Syntax error, unexpected T_VARIABLE, expecting ',' or ')' or ']' from 9:21 to 9:37
|
Syntax error, unexpected T_VARIABLE, expecting ',' or ']' or ')' from 9:21 to 9:37
|
||||||
array(
|
array(
|
||||||
0: Stmt_Expression(
|
0: Stmt_Expression(
|
||||||
expr: Expr_Assign(
|
expr: Expr_Assign(
|
||||||
@@ -1330,6 +1378,8 @@ function foo() :
|
|||||||
Syntax error, unexpected '{' from 3:1 to 3:1
|
Syntax error, unexpected '{' from 3:1 to 3:1
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: foo
|
name: foo
|
||||||
@@ -1351,4 +1401,4 @@ array(
|
|||||||
$a = ["a "thing"];
|
$a = ["a "thing"];
|
||||||
-----
|
-----
|
||||||
!!php7
|
!!php7
|
||||||
Syntax error, unexpected T_STRING, expecting ',' or ')' or ']' from 2:11 to 2:15
|
Syntax error, unexpected T_STRING, expecting ',' or ']' or ')' from 2:11 to 2:15
|
@@ -59,6 +59,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Function(
|
1: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: getArr
|
name: getArr
|
||||||
@@ -92,6 +94,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_Function(
|
2: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: arrGen
|
name: arrGen
|
||||||
|
@@ -12,10 +12,14 @@ fn(): int => $x;
|
|||||||
array(
|
array(
|
||||||
0: Stmt_Expression(
|
0: Stmt_Expression(
|
||||||
expr: Expr_ArrowFunction(
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: bool
|
name: bool
|
||||||
@@ -36,10 +40,14 @@ array(
|
|||||||
)
|
)
|
||||||
1: Stmt_Expression(
|
1: Stmt_Expression(
|
||||||
expr: Expr_ArrowFunction(
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -60,10 +68,14 @@ array(
|
|||||||
)
|
)
|
||||||
2: Stmt_Expression(
|
2: Stmt_Expression(
|
||||||
expr: Expr_ArrowFunction(
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: true
|
static: true
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: true
|
byRef: true
|
||||||
@@ -82,10 +94,14 @@ array(
|
|||||||
)
|
)
|
||||||
3: Stmt_Expression(
|
3: Stmt_Expression(
|
||||||
expr: Expr_ArrowFunction(
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: true
|
byRef: true
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -104,10 +120,14 @@ array(
|
|||||||
)
|
)
|
||||||
4: Stmt_Expression(
|
4: Stmt_Expression(
|
||||||
expr: Expr_ArrowFunction(
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -118,6 +138,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -136,6 +158,8 @@ array(
|
|||||||
)
|
)
|
||||||
5: Stmt_Expression(
|
5: Stmt_Expression(
|
||||||
expr: Expr_ArrowFunction(
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
|
@@ -12,10 +12,14 @@ function() use($a) : \Foo\Bar {};
|
|||||||
array(
|
array(
|
||||||
0: Stmt_Expression(
|
0: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -40,10 +44,14 @@ array(
|
|||||||
)
|
)
|
||||||
1: Stmt_Expression(
|
1: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -69,6 +77,8 @@ array(
|
|||||||
)
|
)
|
||||||
2: Stmt_Expression(
|
2: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
@@ -94,10 +104,14 @@ array(
|
|||||||
)
|
)
|
||||||
3: Stmt_Expression(
|
3: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: true
|
byRef: true
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -117,6 +131,8 @@ array(
|
|||||||
)
|
)
|
||||||
4: Stmt_Expression(
|
4: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: true
|
static: true
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
@@ -130,10 +146,14 @@ array(
|
|||||||
)
|
)
|
||||||
5: Stmt_Expression(
|
5: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -155,6 +175,8 @@ array(
|
|||||||
)
|
)
|
||||||
6: Stmt_Expression(
|
6: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
|
@@ -7,6 +7,8 @@ function() use($a,) {};
|
|||||||
array(
|
array(
|
||||||
0: Stmt_Expression(
|
0: Stmt_Expression(
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
|
@@ -71,11 +71,13 @@ array(
|
|||||||
4: Stmt_Expression(
|
4: Stmt_Expression(
|
||||||
expr: Scalar_Encapsed(
|
expr: Scalar_Encapsed(
|
||||||
parts: array(
|
parts: array(
|
||||||
0: Expr_Variable(
|
0: Expr_NullsafePropertyFetch(
|
||||||
name: a
|
var: Expr_Variable(
|
||||||
)
|
name: a
|
||||||
1: Scalar_EncapsedStringPart(
|
)
|
||||||
value: ?->b
|
name: Identifier(
|
||||||
|
name: b
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@@ -204,10 +204,14 @@ array(
|
|||||||
name: Expr_FuncCall(
|
name: Expr_FuncCall(
|
||||||
name: Expr_FuncCall(
|
name: Expr_FuncCall(
|
||||||
name: Expr_Closure(
|
name: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -274,10 +278,14 @@ array(
|
|||||||
name: f
|
name: f
|
||||||
)
|
)
|
||||||
expr: Expr_Closure(
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
|
@@ -54,6 +54,8 @@ class Foo {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Test
|
name: Test
|
||||||
@@ -63,6 +65,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -75,6 +79,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_ClassMethod(
|
1: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -87,6 +93,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_ClassMethod(
|
2: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -99,6 +107,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
3: Stmt_ClassMethod(
|
3: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -111,6 +121,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
4: Stmt_Property(
|
4: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -123,6 +135,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
5: Stmt_Property(
|
5: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -135,6 +149,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
6: Stmt_ClassConst(
|
6: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -156,6 +172,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
7: Stmt_ClassConst(
|
7: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -344,6 +362,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
10: Stmt_Class(
|
10: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Foo
|
name: Foo
|
||||||
|
388
test/code/parser/stmt/attributes.test
Normal file
388
test/code/parser/stmt/attributes.test
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
Attributes
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
|
||||||
|
#[
|
||||||
|
A1,
|
||||||
|
A2(),
|
||||||
|
A3(0),
|
||||||
|
A4(x: 1),
|
||||||
|
]
|
||||||
|
function a() {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A5]
|
||||||
|
class C {
|
||||||
|
#[A6]
|
||||||
|
public function m(
|
||||||
|
#[A7] $param,
|
||||||
|
) {}
|
||||||
|
#[A14]
|
||||||
|
public $prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A8]
|
||||||
|
interface I {}
|
||||||
|
#[A9]
|
||||||
|
trait T {}
|
||||||
|
|
||||||
|
$x = #[A10] function() {};
|
||||||
|
$y = #[A11] fn() => 0;
|
||||||
|
$a = #[A12] static function() {};
|
||||||
|
$b = #[A13] static fn() => 0;
|
||||||
|
-----
|
||||||
|
!!php7
|
||||||
|
array(
|
||||||
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
1: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A2
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
2: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A3
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
0: Arg(
|
||||||
|
name: null
|
||||||
|
value: Scalar_LNumber(
|
||||||
|
value: 0
|
||||||
|
)
|
||||||
|
byRef: false
|
||||||
|
unpack: false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
3: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A4
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
0: Arg(
|
||||||
|
name: Identifier(
|
||||||
|
name: x
|
||||||
|
)
|
||||||
|
value: Scalar_LNumber(
|
||||||
|
value: 1
|
||||||
|
)
|
||||||
|
byRef: false
|
||||||
|
unpack: false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
byRef: false
|
||||||
|
name: Identifier(
|
||||||
|
name: a
|
||||||
|
)
|
||||||
|
params: array(
|
||||||
|
)
|
||||||
|
returnType: null
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
1: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A5
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flags: 0
|
||||||
|
name: Identifier(
|
||||||
|
name: C
|
||||||
|
)
|
||||||
|
extends: null
|
||||||
|
implements: array(
|
||||||
|
)
|
||||||
|
stmts: array(
|
||||||
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A6
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flags: MODIFIER_PUBLIC (1)
|
||||||
|
byRef: false
|
||||||
|
name: Identifier(
|
||||||
|
name: m
|
||||||
|
)
|
||||||
|
params: array(
|
||||||
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A7
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flags: 0
|
||||||
|
type: null
|
||||||
|
byRef: false
|
||||||
|
variadic: false
|
||||||
|
var: Expr_Variable(
|
||||||
|
name: param
|
||||||
|
)
|
||||||
|
default: null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
returnType: null
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
1: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A14
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
flags: MODIFIER_PUBLIC (1)
|
||||||
|
type: null
|
||||||
|
props: array(
|
||||||
|
0: Stmt_PropertyProperty(
|
||||||
|
name: VarLikeIdentifier(
|
||||||
|
name: prop
|
||||||
|
)
|
||||||
|
default: null
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
2: Stmt_Interface(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A8
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
name: Identifier(
|
||||||
|
name: I
|
||||||
|
)
|
||||||
|
extends: array(
|
||||||
|
)
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
3: Stmt_Trait(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A9
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
name: Identifier(
|
||||||
|
name: T
|
||||||
|
)
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
4: Stmt_Expression(
|
||||||
|
expr: Expr_Assign(
|
||||||
|
var: Expr_Variable(
|
||||||
|
name: x
|
||||||
|
)
|
||||||
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A10
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
static: false
|
||||||
|
byRef: false
|
||||||
|
params: array(
|
||||||
|
)
|
||||||
|
uses: array(
|
||||||
|
)
|
||||||
|
returnType: null
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
5: Stmt_Expression(
|
||||||
|
expr: Expr_Assign(
|
||||||
|
var: Expr_Variable(
|
||||||
|
name: y
|
||||||
|
)
|
||||||
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A11
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
static: false
|
||||||
|
byRef: false
|
||||||
|
params: array(
|
||||||
|
)
|
||||||
|
returnType: null
|
||||||
|
expr: Scalar_LNumber(
|
||||||
|
value: 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
6: Stmt_Expression(
|
||||||
|
expr: Expr_Assign(
|
||||||
|
var: Expr_Variable(
|
||||||
|
name: a
|
||||||
|
)
|
||||||
|
expr: Expr_Closure(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A12
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
static: true
|
||||||
|
byRef: false
|
||||||
|
params: array(
|
||||||
|
)
|
||||||
|
uses: array(
|
||||||
|
)
|
||||||
|
returnType: null
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
7: Stmt_Expression(
|
||||||
|
expr: Expr_Assign(
|
||||||
|
var: Expr_Variable(
|
||||||
|
name: b
|
||||||
|
)
|
||||||
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
0: AttributeGroup(
|
||||||
|
attrs: array(
|
||||||
|
0: Attribute(
|
||||||
|
name: Name(
|
||||||
|
parts: array(
|
||||||
|
0: A13
|
||||||
|
)
|
||||||
|
)
|
||||||
|
args: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
static: true
|
||||||
|
byRef: false
|
||||||
|
params: array(
|
||||||
|
)
|
||||||
|
returnType: null
|
||||||
|
expr: Scalar_LNumber(
|
||||||
|
value: 0
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
@@ -9,6 +9,8 @@ abstract class A {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_ABSTRACT (16)
|
flags: MODIFIER_ABSTRACT (16)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -18,6 +20,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -30,6 +34,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_ClassMethod(
|
1: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC | MODIFIER_ABSTRACT (17)
|
flags: MODIFIER_PUBLIC | MODIFIER_ABSTRACT (17)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
|
@@ -25,6 +25,8 @@ array(
|
|||||||
0: Stmt_Expression(
|
0: Stmt_Expression(
|
||||||
expr: Expr_New(
|
expr: Expr_New(
|
||||||
class: Stmt_Class(
|
class: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: null
|
name: null
|
||||||
extends: null
|
extends: null
|
||||||
@@ -32,6 +34,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -52,6 +56,8 @@ array(
|
|||||||
1: Stmt_Expression(
|
1: Stmt_Expression(
|
||||||
expr: Expr_New(
|
expr: Expr_New(
|
||||||
class: Stmt_Class(
|
class: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: null
|
name: null
|
||||||
extends: Name(
|
extends: Name(
|
||||||
@@ -81,6 +87,8 @@ array(
|
|||||||
2: Stmt_Expression(
|
2: Stmt_Expression(
|
||||||
expr: Expr_New(
|
expr: Expr_New(
|
||||||
class: Stmt_Class(
|
class: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: null
|
name: null
|
||||||
extends: null
|
extends: null
|
||||||
@@ -88,6 +96,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -108,6 +118,8 @@ array(
|
|||||||
3: Stmt_Expression(
|
3: Stmt_Expression(
|
||||||
expr: Expr_New(
|
expr: Expr_New(
|
||||||
class: Stmt_Class(
|
class: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: null
|
name: null
|
||||||
extends: Name(
|
extends: Name(
|
||||||
@@ -152,6 +164,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
4: Stmt_Class(
|
4: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -161,6 +175,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -173,6 +189,8 @@ array(
|
|||||||
0: Stmt_Return(
|
0: Stmt_Return(
|
||||||
expr: Expr_New(
|
expr: Expr_New(
|
||||||
class: Stmt_Class(
|
class: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: null
|
name: null
|
||||||
extends: Name(
|
extends: Name(
|
||||||
@@ -184,6 +202,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassConst(
|
0: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
|
66
test/code/parser/stmt/class/class_position.test
Normal file
66
test/code/parser/stmt/class/class_position.test
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
Class position
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class A {
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
class B {
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
-----
|
||||||
|
!!positions
|
||||||
|
array(
|
||||||
|
0: Stmt_Class[3:1 - 4:1](
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
|
flags: 0
|
||||||
|
name: Identifier[3:7 - 3:7](
|
||||||
|
name: A
|
||||||
|
)
|
||||||
|
extends: null
|
||||||
|
implements: array(
|
||||||
|
)
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
1: Stmt_TryCatch[6:1 - 8:1](
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
catches: array(
|
||||||
|
0: Stmt_Catch[7:3 - 8:1](
|
||||||
|
types: array(
|
||||||
|
0: Name[7:10 - 7:18](
|
||||||
|
parts: array(
|
||||||
|
0: Exception
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
var: Expr_Variable[7:20 - 7:21](
|
||||||
|
name: e
|
||||||
|
)
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
finally: null
|
||||||
|
)
|
||||||
|
2: Stmt_Class[10:1 - 11:1](
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
|
flags: 0
|
||||||
|
name: Identifier[10:7 - 10:7](
|
||||||
|
name: B
|
||||||
|
)
|
||||||
|
extends: null
|
||||||
|
implements: array(
|
||||||
|
)
|
||||||
|
stmts: array(
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
@@ -17,6 +17,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
|
@@ -9,6 +9,8 @@ class A {
|
|||||||
Cannot use 'static' as constant modifier from 3:5 to 3:10
|
Cannot use 'static' as constant modifier from 3:5 to 3:10
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -18,6 +20,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassConst(
|
0: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -43,6 +47,8 @@ class A {
|
|||||||
Cannot use 'abstract' as constant modifier from 3:5 to 3:12
|
Cannot use 'abstract' as constant modifier from 3:5 to 3:12
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -52,6 +58,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassConst(
|
0: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_ABSTRACT (16)
|
flags: MODIFIER_ABSTRACT (16)
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -77,6 +85,8 @@ class A {
|
|||||||
Cannot use 'final' as constant modifier from 3:5 to 3:9
|
Cannot use 'final' as constant modifier from 3:5 to 3:9
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -86,6 +96,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassConst(
|
0: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_FINAL (32)
|
flags: MODIFIER_FINAL (32)
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -111,6 +123,8 @@ class A {
|
|||||||
Multiple access type modifiers are not allowed from 3:12 to 3:17
|
Multiple access type modifiers are not allowed from 3:12 to 3:17
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -120,6 +134,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassConst(
|
0: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
|
@@ -12,6 +12,8 @@ class Foo {
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Foo
|
name: Foo
|
||||||
@@ -21,6 +23,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassConst(
|
0: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -34,6 +38,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_ClassConst(
|
1: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -47,6 +53,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_ClassConst(
|
2: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PROTECTED (2)
|
flags: MODIFIER_PROTECTED (2)
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -60,6 +68,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
3: Stmt_ClassConst(
|
3: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PRIVATE (4)
|
flags: MODIFIER_PRIVATE (4)
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
|
@@ -6,6 +6,8 @@ final class A {}
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_FINAL (32)
|
flags: MODIFIER_FINAL (32)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
|
@@ -14,6 +14,8 @@ abstract class A {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_ABSTRACT (16)
|
flags: MODIFIER_ABSTRACT (16)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -23,6 +25,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -35,6 +39,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Property(
|
1: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -47,6 +53,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_ClassMethod(
|
2: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_ABSTRACT (16)
|
flags: MODIFIER_ABSTRACT (16)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -58,6 +66,8 @@ array(
|
|||||||
stmts: null
|
stmts: null
|
||||||
)
|
)
|
||||||
3: Stmt_ClassMethod(
|
3: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_FINAL (32)
|
flags: MODIFIER_FINAL (32)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -70,6 +80,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
4: Stmt_ClassMethod(
|
4: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -82,6 +94,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
5: Stmt_ClassMethod(
|
5: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC | MODIFIER_FINAL (40)
|
flags: MODIFIER_STATIC | MODIFIER_FINAL (40)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -94,6 +108,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
6: Stmt_ClassMethod(
|
6: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
|
@@ -8,6 +8,8 @@ interface A extends C, D {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Interface(
|
0: Stmt_Interface(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
)
|
)
|
||||||
@@ -25,6 +27,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
|
@@ -5,6 +5,8 @@ Invalid modifier combination
|
|||||||
Multiple access type modifiers are not allowed from 1:24 to 1:29
|
Multiple access type modifiers are not allowed from 1:24 to 1:29
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -14,6 +16,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -34,6 +38,8 @@ array(
|
|||||||
Multiple access type modifiers are not allowed from 1:24 to 1:32
|
Multiple access type modifiers are not allowed from 1:24 to 1:32
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -43,6 +49,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC | MODIFIER_PROTECTED (3)
|
flags: MODIFIER_PUBLIC | MODIFIER_PROTECTED (3)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -63,6 +71,8 @@ array(
|
|||||||
Multiple abstract modifiers are not allowed from 1:26 to 1:33
|
Multiple abstract modifiers are not allowed from 1:26 to 1:33
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -72,6 +82,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_ABSTRACT (16)
|
flags: MODIFIER_ABSTRACT (16)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -91,6 +103,8 @@ array(
|
|||||||
Multiple static modifiers are not allowed from 1:24 to 1:29
|
Multiple static modifiers are not allowed from 1:24 to 1:29
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -100,6 +114,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -120,6 +136,8 @@ array(
|
|||||||
Multiple final modifiers are not allowed from 1:23 to 1:27
|
Multiple final modifiers are not allowed from 1:23 to 1:27
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -129,6 +147,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_FINAL (32)
|
flags: MODIFIER_FINAL (32)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -149,6 +169,8 @@ array(
|
|||||||
Cannot use the final modifier on an abstract class member from 1:26 to 1:30
|
Cannot use the final modifier on an abstract class member from 1:26 to 1:30
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -158,6 +180,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_ABSTRACT | MODIFIER_FINAL (48)
|
flags: MODIFIER_ABSTRACT | MODIFIER_FINAL (48)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -178,6 +202,8 @@ array(
|
|||||||
Syntax error, unexpected T_FINAL, expecting T_CLASS from 1:16 to 1:20
|
Syntax error, unexpected T_FINAL, expecting T_CLASS from 1:16 to 1:20
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_FINAL (32)
|
flags: MODIFIER_FINAL (32)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -200,6 +226,8 @@ array(
|
|||||||
Properties cannot be declared abstract from 1:17 to 1:24
|
Properties cannot be declared abstract from 1:17 to 1:24
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -209,6 +237,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_ABSTRACT (16)
|
flags: MODIFIER_ABSTRACT (16)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -229,6 +259,8 @@ array(
|
|||||||
Properties cannot be declared final from 1:17 to 1:21
|
Properties cannot be declared final from 1:17 to 1:21
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -238,6 +270,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_FINAL (32)
|
flags: MODIFIER_FINAL (32)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
|
@@ -5,6 +5,8 @@ Invalid class name
|
|||||||
Cannot use 'self' as class name as it is reserved from 1:13 to 1:16
|
Cannot use 'self' as class name as it is reserved from 1:13 to 1:16
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: self
|
name: self
|
||||||
@@ -22,6 +24,8 @@ array(
|
|||||||
Cannot use 'PARENT' as class name as it is reserved from 1:13 to 1:18
|
Cannot use 'PARENT' as class name as it is reserved from 1:13 to 1:18
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: PARENT
|
name: PARENT
|
||||||
@@ -45,6 +49,8 @@ array(
|
|||||||
Cannot use 'self' as class name as it is reserved from 1:23 to 1:26
|
Cannot use 'self' as class name as it is reserved from 1:23 to 1:26
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -66,6 +72,8 @@ array(
|
|||||||
Cannot use 'PARENT' as class name as it is reserved from 1:23 to 1:28
|
Cannot use 'PARENT' as class name as it is reserved from 1:23 to 1:28
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -87,6 +95,8 @@ array(
|
|||||||
Cannot use 'static' as class name as it is reserved from 1:23 to 1:28
|
Cannot use 'static' as class name as it is reserved from 1:23 to 1:28
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -108,6 +118,8 @@ array(
|
|||||||
Cannot use 'self' as interface name as it is reserved from 1:26 to 1:29
|
Cannot use 'self' as interface name as it is reserved from 1:26 to 1:29
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -130,6 +142,8 @@ array(
|
|||||||
Cannot use 'PARENT' as interface name as it is reserved from 1:26 to 1:31
|
Cannot use 'PARENT' as interface name as it is reserved from 1:26 to 1:31
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -152,6 +166,8 @@ array(
|
|||||||
Cannot use 'static' as interface name as it is reserved from 1:26 to 1:31
|
Cannot use 'static' as interface name as it is reserved from 1:26 to 1:31
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -174,6 +190,8 @@ array(
|
|||||||
Cannot use 'self' as class name as it is reserved from 1:17 to 1:20
|
Cannot use 'self' as class name as it is reserved from 1:17 to 1:20
|
||||||
array(
|
array(
|
||||||
0: Stmt_Interface(
|
0: Stmt_Interface(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: self
|
name: self
|
||||||
)
|
)
|
||||||
@@ -189,6 +207,8 @@ array(
|
|||||||
Cannot use 'PARENT' as class name as it is reserved from 1:17 to 1:22
|
Cannot use 'PARENT' as class name as it is reserved from 1:17 to 1:22
|
||||||
array(
|
array(
|
||||||
0: Stmt_Interface(
|
0: Stmt_Interface(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: PARENT
|
name: PARENT
|
||||||
)
|
)
|
||||||
@@ -210,6 +230,8 @@ array(
|
|||||||
Cannot use 'self' as interface name as it is reserved from 1:27 to 1:30
|
Cannot use 'self' as interface name as it is reserved from 1:27 to 1:30
|
||||||
array(
|
array(
|
||||||
0: Stmt_Interface(
|
0: Stmt_Interface(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
)
|
)
|
||||||
@@ -230,6 +252,8 @@ array(
|
|||||||
Cannot use 'PARENT' as interface name as it is reserved from 1:27 to 1:32
|
Cannot use 'PARENT' as interface name as it is reserved from 1:27 to 1:32
|
||||||
array(
|
array(
|
||||||
0: Stmt_Interface(
|
0: Stmt_Interface(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
)
|
)
|
||||||
@@ -250,6 +274,8 @@ array(
|
|||||||
Cannot use 'static' as interface name as it is reserved from 1:27 to 1:32
|
Cannot use 'static' as interface name as it is reserved from 1:27 to 1:32
|
||||||
array(
|
array(
|
||||||
0: Stmt_Interface(
|
0: Stmt_Interface(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
)
|
)
|
||||||
|
@@ -10,6 +10,8 @@ class A {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -19,6 +21,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -31,6 +35,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_ClassMethod(
|
1: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -43,6 +49,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_ClassMethod(
|
2: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_ABSTRACT | MODIFIER_STATIC (24)
|
flags: MODIFIER_ABSTRACT | MODIFIER_STATIC (24)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
|
@@ -11,6 +11,8 @@ class A {
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -20,6 +22,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: string
|
name: string
|
||||||
@@ -34,6 +38,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Property(
|
1: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PROTECTED | MODIFIER_STATIC (10)
|
flags: MODIFIER_PROTECTED | MODIFIER_STATIC (10)
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
@@ -50,6 +56,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_Property(
|
2: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PRIVATE (4)
|
flags: MODIFIER_PRIVATE (4)
|
||||||
type: NullableType(
|
type: NullableType(
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
|
@@ -13,6 +13,8 @@ class Point {
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Point
|
name: Point
|
||||||
@@ -22,6 +24,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -29,6 +33,8 @@ array(
|
|||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: float
|
name: float
|
||||||
@@ -43,6 +49,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PROTECTED (2)
|
flags: MODIFIER_PROTECTED (2)
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: array
|
name: array
|
||||||
@@ -58,6 +66,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Param(
|
2: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PRIVATE (4)
|
flags: MODIFIER_PRIVATE (4)
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: string
|
name: string
|
||||||
|
@@ -18,6 +18,8 @@ class A extends B implements C, D {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -41,6 +43,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassConst(
|
0: Stmt_ClassConst(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
consts: array(
|
consts: array(
|
||||||
0: Const(
|
0: Const(
|
||||||
@@ -62,6 +66,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Property(
|
1: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -84,6 +90,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_Property(
|
2: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PROTECTED (2)
|
flags: MODIFIER_PROTECTED (2)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -96,6 +104,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
3: Stmt_Property(
|
3: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PRIVATE (4)
|
flags: MODIFIER_PRIVATE (4)
|
||||||
type: null
|
type: null
|
||||||
props: array(
|
props: array(
|
||||||
@@ -108,6 +118,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
4: Stmt_ClassMethod(
|
4: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -120,6 +132,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
5: Stmt_ClassMethod(
|
5: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC | MODIFIER_STATIC (9)
|
flags: MODIFIER_PUBLIC | MODIFIER_STATIC (9)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -127,6 +141,8 @@ array(
|
|||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -142,6 +158,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
6: Stmt_ClassMethod(
|
6: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC | MODIFIER_FINAL (33)
|
flags: MODIFIER_PUBLIC | MODIFIER_FINAL (33)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -158,6 +176,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
7: Stmt_ClassMethod(
|
7: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PROTECTED (2)
|
flags: MODIFIER_PROTECTED (2)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -170,6 +190,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
8: Stmt_ClassMethod(
|
8: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PRIVATE (4)
|
flags: MODIFIER_PRIVATE (4)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
|
@@ -5,6 +5,8 @@ Some special methods cannot be static
|
|||||||
Constructor __construct() cannot be static from 1:17 to 1:22
|
Constructor __construct() cannot be static from 1:17 to 1:22
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -14,6 +16,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -34,6 +38,8 @@ array(
|
|||||||
Destructor __destruct() cannot be static from 1:17 to 1:22
|
Destructor __destruct() cannot be static from 1:17 to 1:22
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -43,6 +49,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -63,6 +71,8 @@ array(
|
|||||||
Clone method __clone() cannot be static from 1:17 to 1:22
|
Clone method __clone() cannot be static from 1:17 to 1:22
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -72,6 +82,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -92,6 +104,8 @@ array(
|
|||||||
Constructor __CONSTRUCT() cannot be static from 1:17 to 1:22
|
Constructor __CONSTRUCT() cannot be static from 1:17 to 1:22
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -101,6 +115,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -121,6 +137,8 @@ array(
|
|||||||
Destructor __Destruct() cannot be static from 1:17 to 1:22
|
Destructor __Destruct() cannot be static from 1:17 to 1:22
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -130,6 +148,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -150,6 +170,8 @@ array(
|
|||||||
Clone method __cLoNe() cannot be static from 1:17 to 1:22
|
Clone method __cLoNe() cannot be static from 1:17 to 1:22
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
@@ -159,6 +181,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_STATIC (8)
|
flags: MODIFIER_STATIC (8)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
|
@@ -8,6 +8,8 @@ class Test {
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Test
|
name: Test
|
||||||
@@ -17,6 +19,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC | MODIFIER_STATIC (9)
|
flags: MODIFIER_PUBLIC | MODIFIER_STATIC (9)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
|
@@ -23,11 +23,15 @@ class B {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Trait(
|
0: Stmt_Trait(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -42,6 +46,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Class(
|
1: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: B
|
name: B
|
||||||
|
@@ -6,12 +6,16 @@ function test(bool $a, Int $b, FLOAT $c, StRiNg $d, iterable $e, object $f, mixe
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test
|
name: test
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: bool
|
name: bool
|
||||||
@@ -24,6 +28,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: int
|
name: int
|
||||||
@@ -36,6 +42,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
2: Param(
|
2: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: float
|
name: float
|
||||||
@@ -48,6 +56,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
3: Param(
|
3: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: string
|
name: string
|
||||||
@@ -60,6 +70,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
4: Param(
|
4: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: iterable
|
name: iterable
|
||||||
@@ -72,6 +84,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
5: Param(
|
5: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: object
|
name: object
|
||||||
@@ -84,6 +98,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
6: Param(
|
6: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: mixed
|
name: mixed
|
||||||
|
@@ -7,12 +7,16 @@ function &a($b) {}
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: a
|
name: a
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: true
|
byRef: true
|
||||||
@@ -28,12 +32,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Function(
|
1: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: true
|
byRef: true
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: a
|
name: a
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
|
@@ -17,6 +17,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: A
|
name: A
|
||||||
|
@@ -16,12 +16,16 @@ function a(
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: a
|
name: a
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -38,6 +42,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -50,6 +56,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Param(
|
2: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -69,6 +77,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
3: Param(
|
3: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -83,6 +93,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
4: Param(
|
4: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -97,6 +109,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
5: Param(
|
5: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -110,6 +124,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
6: Param(
|
6: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -123,6 +139,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
7: Param(
|
7: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -144,6 +162,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
8: Param(
|
8: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
|
@@ -8,12 +8,16 @@ function test(?Foo $bar, ?string $foo) : ?Baz {
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test
|
name: test
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: NullableType(
|
type: NullableType(
|
||||||
type: Name(
|
type: Name(
|
||||||
@@ -30,6 +34,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: NullableType(
|
type: NullableType(
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
|
@@ -8,12 +8,16 @@ function foo($bar, ) {
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: foo
|
name: foo
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -42,6 +46,8 @@ class Foo
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Foo
|
name: Foo
|
||||||
@@ -51,6 +57,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_ClassMethod(
|
0: Stmt_ClassMethod(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
@@ -58,6 +66,8 @@ array(
|
|||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -68,6 +78,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -93,10 +105,14 @@ fn($foo, ) => $bar;
|
|||||||
array(
|
array(
|
||||||
0: Stmt_Expression(
|
0: Stmt_Expression(
|
||||||
expr: Expr_ArrowFunction(
|
expr: Expr_ArrowFunction(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
static: false
|
static: false
|
||||||
byRef: false
|
byRef: false
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
|
@@ -9,6 +9,8 @@ function test4() : Foo\Bar {}
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test1
|
name: test1
|
||||||
@@ -20,6 +22,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Function(
|
1: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test2
|
name: test2
|
||||||
@@ -33,6 +37,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_Function(
|
2: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test3
|
name: test3
|
||||||
@@ -46,6 +52,8 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
3: Stmt_Function(
|
3: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test4
|
name: test4
|
||||||
|
@@ -9,6 +9,8 @@ function a() {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: a
|
name: a
|
||||||
|
@@ -6,12 +6,16 @@ function a($b, array $c, callable $d, E $f) {}
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: a
|
name: a
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -22,6 +26,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: array
|
name: array
|
||||||
@@ -34,6 +40,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
2: Param(
|
2: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Identifier(
|
type: Identifier(
|
||||||
name: callable
|
name: callable
|
||||||
@@ -46,6 +54,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
3: Param(
|
3: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
|
@@ -11,6 +11,8 @@ function test(A|B $a): int|false {}
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Class(
|
0: Stmt_Class(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: Test
|
name: Test
|
||||||
@@ -20,6 +22,8 @@ array(
|
|||||||
)
|
)
|
||||||
stmts: array(
|
stmts: array(
|
||||||
0: Stmt_Property(
|
0: Stmt_Property(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: MODIFIER_PUBLIC (1)
|
flags: MODIFIER_PUBLIC (1)
|
||||||
type: UnionType(
|
type: UnionType(
|
||||||
types: array(
|
types: array(
|
||||||
@@ -48,12 +52,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Function(
|
1: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test
|
name: test
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: UnionType(
|
type: UnionType(
|
||||||
types: array(
|
types: array(
|
||||||
|
@@ -8,12 +8,16 @@ function test($a, Type &... $b) {}
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test
|
name: test
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -24,6 +28,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -39,12 +45,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
1: Stmt_Function(
|
1: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test
|
name: test
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -55,6 +65,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: true
|
byRef: true
|
||||||
@@ -70,12 +82,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
2: Stmt_Function(
|
2: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test
|
name: test
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -86,6 +102,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
@@ -105,12 +123,16 @@ array(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
3: Stmt_Function(
|
3: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: test
|
name: test
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
@@ -121,6 +143,8 @@ array(
|
|||||||
default: null
|
default: null
|
||||||
)
|
)
|
||||||
1: Param(
|
1: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: Name(
|
type: Name(
|
||||||
parts: array(
|
parts: array(
|
||||||
|
@@ -6,12 +6,16 @@ function foo(...$foo = []) {}
|
|||||||
Variadic parameter cannot have a default value from 2:24 to 2:25
|
Variadic parameter cannot have a default value from 2:24 to 2:25
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: foo
|
name: foo
|
||||||
)
|
)
|
||||||
params: array(
|
params: array(
|
||||||
0: Param(
|
0: Param(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
flags: 0
|
flags: 0
|
||||||
type: null
|
type: null
|
||||||
byRef: false
|
byRef: false
|
||||||
|
@@ -33,6 +33,8 @@ function gen() {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: gen
|
name: gen
|
||||||
|
@@ -17,6 +17,8 @@ function gen() {
|
|||||||
!!php7
|
!!php7
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: gen
|
name: gen
|
||||||
|
@@ -10,6 +10,8 @@ function gen() {
|
|||||||
-----
|
-----
|
||||||
array(
|
array(
|
||||||
0: Stmt_Function(
|
0: Stmt_Function(
|
||||||
|
attrGroups: array(
|
||||||
|
)
|
||||||
byRef: false
|
byRef: false
|
||||||
name: Identifier(
|
name: Identifier(
|
||||||
name: gen
|
name: gen
|
||||||
|
@@ -19,4 +19,4 @@ $a?->b($c)?->d;
|
|||||||
$a?->b($c)();
|
$a?->b($c)();
|
||||||
new $a?->b();
|
new $a?->b();
|
||||||
"{$a?->b}";
|
"{$a?->b}";
|
||||||
"{$a}?->b";
|
"{$a?->b}";
|
61
test/code/prettyPrinter/stmt/attributes.test
Normal file
61
test/code/prettyPrinter/stmt/attributes.test
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
Attributes
|
||||||
|
-----
|
||||||
|
<?php
|
||||||
|
|
||||||
|
#[
|
||||||
|
A1,
|
||||||
|
A2(),
|
||||||
|
A3(0),
|
||||||
|
A4(x: 1),
|
||||||
|
]
|
||||||
|
function a() {
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A5]
|
||||||
|
class C {
|
||||||
|
#[A6]
|
||||||
|
public function m(
|
||||||
|
#[A7] $param,
|
||||||
|
) {}
|
||||||
|
#[A12]
|
||||||
|
public $prop;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[A8]
|
||||||
|
interface I {}
|
||||||
|
#[A9]
|
||||||
|
trait T {}
|
||||||
|
|
||||||
|
$x = #[A10] function() {};
|
||||||
|
$y = #[A11] fn() => 0;
|
||||||
|
new #[A13] class {};
|
||||||
|
-----
|
||||||
|
!!php7
|
||||||
|
#[A1, A2, A3(0), A4(x: 1)]
|
||||||
|
function a()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#[A5]
|
||||||
|
class C
|
||||||
|
{
|
||||||
|
#[A6]
|
||||||
|
public function m(#[A7] $param)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#[A12]
|
||||||
|
public $prop;
|
||||||
|
}
|
||||||
|
#[A8]
|
||||||
|
interface I
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#[A9]
|
||||||
|
trait T
|
||||||
|
{
|
||||||
|
}
|
||||||
|
$x = #[A10] function () {
|
||||||
|
};
|
||||||
|
$y = #[A11] fn() => 0;
|
||||||
|
new #[A13] class
|
||||||
|
{
|
||||||
|
};
|
@@ -101,6 +101,7 @@ switch ($testType) {
|
|||||||
| Zend.tests.bug74947
|
| Zend.tests.bug74947
|
||||||
# pretty print differences due to negative LNumbers
|
# pretty print differences due to negative LNumbers
|
||||||
| Zend.tests.neg_num_string
|
| Zend.tests.neg_num_string
|
||||||
|
| Zend.tests.numeric_strings.neg_num_string
|
||||||
| Zend.tests.bug72918
|
| Zend.tests.bug72918
|
||||||
# pretty print difference due to nop statements
|
# pretty print difference due to nop statements
|
||||||
| ext.mbstring.tests.htmlent
|
| ext.mbstring.tests.htmlent
|
||||||
|
Reference in New Issue
Block a user