[8.4] Add support for new deref without parens

RFC: https://wiki.php.net/rfc/new_without_parentheses
This commit is contained in:
Nikita Popov 2024-05-25 16:02:08 +02:00
parent d57da64d7c
commit 7b0384cdbe
5 changed files with 1766 additions and 1366 deletions

View File

@ -1,3 +1,10 @@
Version 5.1.0-dev
-----------------
### Added
* [8.4] Added support for dereferenceing `new` expressions without parentheses.
Version 5.0.2 (2024-03-05) Version 5.0.2 (2024-03-05)
-------------------------- --------------------------

View File

@ -1069,12 +1069,21 @@ anonymous_class:
$this->checkClass($$[0], -1); } $this->checkClass($$[0], -1); }
; ;
new_expr: new_dereferenceable:
T_NEW class_name_reference ctor_arguments { $$ = Expr\New_[$2, $3]; } T_NEW class_name_reference argument_list { $$ = Expr\New_[$2, $3]; }
| T_NEW anonymous_class | T_NEW anonymous_class
{ list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; } { list($class, $ctorArgs) = $2; $$ = Expr\New_[$class, $ctorArgs]; }
; ;
new_non_dereferenceable:
T_NEW class_name_reference { $$ = Expr\New_[$2, []]; }
;
new_expr:
new_dereferenceable
| new_non_dereferenceable
;
lexical_vars: lexical_vars:
/* empty */ { $$ = array(); } /* empty */ { $$ = array(); }
| T_USE '(' lexical_var_list ')' { $$ = $3; } | T_USE '(' lexical_var_list ')' { $$ = $3; }
@ -1213,6 +1222,7 @@ fully_dereferencable:
| '(' expr ')' { $$ = $2; } | '(' expr ')' { $$ = $2; }
| dereferencable_scalar | dereferencable_scalar
| class_constant | class_constant
| new_dereferenceable
; ;
array_object_dereferencable: array_object_dereferencable:
@ -1224,6 +1234,7 @@ callable_expr:
callable_variable callable_variable
| '(' expr ')' { $$ = $2; } | '(' expr ')' { $$ = $2; }
| dereferencable_scalar | dereferencable_scalar
| new_dereferenceable
; ;
callable_variable: callable_variable:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,318 @@
New dereference without parentheses
-----
<?php
new A()->foo;
new A()->foo();
new A()::FOO;
new A()::foo();
new A()::$foo;
new A()[0];
new A(){0};
new A()();
new class {}->foo;
new class {}->foo();
new class {}::FOO;
new class {}::foo();
new class {}::$foo;
new class {}[0];
new class {}{0};
new class {}();
-----
array(
0: Stmt_Expression(
expr: Expr_PropertyFetch(
var: Expr_New(
class: Name(
name: A
)
args: array(
)
)
name: Identifier(
name: foo
)
)
)
1: Stmt_Expression(
expr: Expr_MethodCall(
var: Expr_New(
class: Name(
name: A
)
args: array(
)
)
name: Identifier(
name: foo
)
args: array(
)
)
)
2: Stmt_Expression(
expr: Expr_ClassConstFetch(
class: Expr_New(
class: Name(
name: A
)
args: array(
)
)
name: Identifier(
name: FOO
)
)
)
3: Stmt_Expression(
expr: Expr_StaticCall(
class: Expr_New(
class: Name(
name: A
)
args: array(
)
)
name: Identifier(
name: foo
)
args: array(
)
)
)
4: Stmt_Expression(
expr: Expr_StaticPropertyFetch(
class: Expr_New(
class: Name(
name: A
)
args: array(
)
)
name: VarLikeIdentifier(
name: foo
)
)
)
5: Stmt_Expression(
expr: Expr_ArrayDimFetch(
var: Expr_New(
class: Name(
name: A
)
args: array(
)
)
dim: Scalar_Int(
value: 0
)
)
)
6: Stmt_Expression(
expr: Expr_ArrayDimFetch(
var: Expr_New(
class: Name(
name: A
)
args: array(
)
)
dim: Scalar_Int(
value: 0
)
)
)
7: Stmt_Expression(
expr: Expr_FuncCall(
name: Expr_New(
class: Name(
name: A
)
args: array(
)
)
args: array(
)
)
)
8: Stmt_Expression(
expr: Expr_PropertyFetch(
var: Expr_New(
class: Stmt_Class(
attrGroups: array(
)
flags: 0
name: null
extends: null
implements: array(
)
stmts: array(
)
)
args: array(
)
)
name: Identifier(
name: foo
)
)
)
9: Stmt_Expression(
expr: Expr_MethodCall(
var: Expr_New(
class: Stmt_Class(
attrGroups: array(
)
flags: 0
name: null
extends: null
implements: array(
)
stmts: array(
)
)
args: array(
)
)
name: Identifier(
name: foo
)
args: array(
)
)
)
10: Stmt_Expression(
expr: Expr_ClassConstFetch(
class: Expr_New(
class: Stmt_Class(
attrGroups: array(
)
flags: 0
name: null
extends: null
implements: array(
)
stmts: array(
)
)
args: array(
)
)
name: Identifier(
name: FOO
)
)
)
11: Stmt_Expression(
expr: Expr_StaticCall(
class: Expr_New(
class: Stmt_Class(
attrGroups: array(
)
flags: 0
name: null
extends: null
implements: array(
)
stmts: array(
)
)
args: array(
)
)
name: Identifier(
name: foo
)
args: array(
)
)
)
12: Stmt_Expression(
expr: Expr_StaticPropertyFetch(
class: Expr_New(
class: Stmt_Class(
attrGroups: array(
)
flags: 0
name: null
extends: null
implements: array(
)
stmts: array(
)
)
args: array(
)
)
name: VarLikeIdentifier(
name: foo
)
)
)
13: Stmt_Expression(
expr: Expr_ArrayDimFetch(
var: Expr_New(
class: Stmt_Class(
attrGroups: array(
)
flags: 0
name: null
extends: null
implements: array(
)
stmts: array(
)
)
args: array(
)
)
dim: Scalar_Int(
value: 0
)
)
)
14: Stmt_Expression(
expr: Expr_ArrayDimFetch(
var: Expr_New(
class: Stmt_Class(
attrGroups: array(
)
flags: 0
name: null
extends: null
implements: array(
)
stmts: array(
)
)
args: array(
)
)
dim: Scalar_Int(
value: 0
)
)
)
15: Stmt_Expression(
expr: Expr_FuncCall(
name: Expr_New(
class: Stmt_Class(
attrGroups: array(
)
flags: 0
name: null
extends: null
implements: array(
)
stmts: array(
)
)
args: array(
)
)
args: array(
)
)
)
)