Compare commits

..

5 Commits

Author SHA1 Message Date
Nikita Popov
c346bbfafe Release PHP-Parser 4.6.0 2020-07-02 19:12:47 +02:00
Nikita Popov
4abc531213 Canonicalize to PHP 8 comment token format
The trailing newline is no longer part of the comment token.
2020-06-27 18:53:09 +02:00
TomasVotruba
b58b19ed1d Add constructor promotion support 2020-06-27 17:57:47 +02:00
Nikita Popov
0d2d8f95a1 FPPP: Support catch without variable 2020-06-27 17:42:46 +02:00
TomasVotruba
244db65dd1 [PHP 8.0] Add trailing comma in parameter list 2020-06-12 20:24:25 +02:00
33 changed files with 1327 additions and 938 deletions

View File

@@ -1,8 +1,25 @@
Version 4.5.1-dev
Version 4.6.1-dev
-----------------
Nothing yet.
Version 4.6.0 (2020-07-02)
--------------------------
### Added
* [PHP 8.0] Added support for trailing commas in parameter lists.
* [PHP 8.0] Added support for constructor promotion. The parameter visibility is stored in
`Node\Param::$flags`.
### Fixed
* Comment tokens now always follow the PHP 8 interpretation, and do not include trailing
whitespace.
* As a result of the previous change, some whitespace issues when inserting a statement into a
method containing only a comment, and using the formatting-preserving pretty printer, have been
resolved.
Version 4.5.0 (2020-06-03)
--------------------------

View File

@@ -440,7 +440,7 @@ foreach_variable:
;
parameter_list:
non_empty_parameter_list no_comma { $$ = $1; }
non_empty_parameter_list optional_comma { $$ = $1; }
| /* empty */ { $$ = array(); }
;
@@ -449,13 +449,22 @@ non_empty_parameter_list:
| non_empty_parameter_list ',' parameter { push($1, $3); }
;
optional_visibility_modifier:
/* empty */ { $$ = 0; }
| T_PUBLIC { $$ = Stmt\Class_::MODIFIER_PUBLIC; }
| T_PROTECTED { $$ = Stmt\Class_::MODIFIER_PROTECTED; }
| T_PRIVATE { $$ = Stmt\Class_::MODIFIER_PRIVATE; }
;
parameter:
optional_type optional_ref optional_ellipsis plain_variable
{ $$ = Node\Param[$4, null, $1, $2, $3]; $this->checkParam($$); }
| optional_type optional_ref optional_ellipsis plain_variable '=' expr
{ $$ = Node\Param[$4, $6, $1, $2, $3]; $this->checkParam($$); }
| optional_type optional_ref optional_ellipsis error
{ $$ = Node\Param[Expr\Error[], null, $1, $2, $3]; }
optional_visibility_modifier optional_type optional_ref optional_ellipsis plain_variable
{ $$ = new Node\Param($5, null, $2, $3, $4, attributes(), $1);
$this->checkParam($$); }
| optional_visibility_modifier optional_type optional_ref optional_ellipsis plain_variable '=' expr
{ $$ = new Node\Param($5, $7, $2, $3, $4, attributes(), $1);
$this->checkParam($$); }
| optional_visibility_modifier optional_type optional_ref optional_ellipsis error
{ $$ = new Node\Param(Expr\Error[], null, $2, $3, $4, attributes(), $1); }
;
type_expr:

View File

@@ -89,7 +89,7 @@ class Lexer
error_clear_last();
$this->tokens = @token_get_all($code);
$this->handleErrors($errorHandler);
$this->postprocessTokens($errorHandler);
if (false !== $scream) {
ini_set('xdebug.scream', $scream);
@@ -131,40 +131,14 @@ class Lexer
&& substr($token[1], -2) !== '*/';
}
/**
* Check whether an error *may* have occurred during tokenization.
*
* @return bool
*/
private function errorMayHaveOccurred() : bool {
if (defined('HHVM_VERSION')) {
// In HHVM token_get_all() does not throw warnings, so we need to conservatively
// assume that an error occurred
return true;
}
if (PHP_VERSION_ID >= 80000) {
// PHP 8 converts the "bad character" case into a parse error, rather than treating
// it as a lexing warning. To preserve previous behavior, we need to assume that an
// error occurred.
// TODO: We should handle this the same way as PHP 8: Only generate T_BAD_CHARACTER
// token here (for older PHP versions) and leave generationg of the actual parse error
// to the parser. This will also save the full token scan on PHP 8 here.
return true;
}
return null !== error_get_last();
}
protected function handleErrors(ErrorHandler $errorHandler) {
if (!$this->errorMayHaveOccurred()) {
return;
}
protected function postprocessTokens(ErrorHandler $errorHandler) {
// PHP's error handling for token_get_all() is rather bad, so if we want detailed
// error information we need to compute it ourselves. Invalid character errors are
// detected by finding "gaps" in the token array. Unterminated comments are detected
// by checking if a trailing comment has a "*/" at the end.
//
// Additionally, we canonicalize to the PHP 8 comment format here, which does not include
// the trailing whitespace anymore
$filePos = 0;
$line = 1;
@@ -178,6 +152,23 @@ class Lexer
$this->handleInvalidCharacterRange($filePos, $filePos + 1, $line, $errorHandler);
}
if ($token[0] === \T_COMMENT && preg_match('/(\r\n|\n|\r)$/D', $token[1], $matches)) {
$trailingNewline = $matches[0];
$token[1] = substr($token[1], 0, -strlen($trailingNewline));
$this->tokens[$i] = $token;
if (isset($this->tokens[$i + 1]) && $this->tokens[$i + 1][0] === \T_WHITESPACE) {
// Move trailing newline into following T_WHITESPACE token, if it already exists.
$this->tokens[$i + 1][1] = $trailingNewline . $this->tokens[$i + 1][1];
$this->tokens[$i + 1][2]--;
} else {
// Otherwise, we need to create a new T_WHITESPACE token.
array_splice($this->tokens, $i + 1, 0, [
[\T_WHITESPACE, $trailingNewline, $line],
]);
$numTokens++;
}
}
$tokenValue = \is_string($token) ? $token : $token[1];
$tokenLen = \strlen($tokenValue);

View File

@@ -16,6 +16,8 @@ class Param extends NodeAbstract
public $var;
/** @var null|Expr Default value */
public $default;
/** @var int */
public $flags;
/**
* Constructs a parameter node.
@@ -25,11 +27,14 @@ class Param extends NodeAbstract
* @param null|string|Identifier|Name|NullableType|UnionType $type Type declaration
* @param bool $byRef Whether is passed by reference
* @param bool $variadic Whether this is a variadic argument
* @param array $flags Optional visibility flags
* @param array $attributes Additional attributes
*/
public function __construct(
$var, Expr $default = null, $type = null,
bool $byRef = false, bool $variadic = false, array $attributes = []
bool $byRef = false, bool $variadic = false,
array $attributes = [],
int $flags = 0
) {
$this->attributes = $attributes;
$this->type = \is_string($type) ? new Identifier($type) : $type;
@@ -37,10 +42,11 @@ class Param extends NodeAbstract
$this->variadic = $variadic;
$this->var = $var;
$this->default = $default;
$this->flags = $flags;
}
public function getSubNodeNames() : array {
return ['type', 'byRef', 'variadic', 'var', 'default'];
return ['flags', 'type', 'byRef', 'variadic', 'var', 'default'];
}
public function getType() : string {

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,8 @@ class Standard extends PrettyPrinterAbstract
// Special nodes
protected function pParam(Node\Param $node) {
return ($node->type ? $this->p($node->type) . ' ' : '')
return ($this->pModifiers($node->flags))
. ($node->type ? $this->p($node->type) . ' ' : '')
. ($node->byRef ? '&' : '')
. ($node->variadic ? '...' : '')
. $this->p($node->var)
@@ -725,7 +726,7 @@ class Standard extends PrettyPrinterAbstract
protected function pStmt_ClassMethod(Stmt\ClassMethod $node) {
return $this->pModifiers($node->flags)
. 'function ' . ($node->byRef ? '&' : '') . $node->name
. '(' . $this->pCommaSeparated($node->params) . ')'
. '(' . $this->pMaybeMultiline($node->params) . ')'
. (null !== $node->returnType ? ' : ' . $this->p($node->returnType) : '')
. (null !== $node->stmts
? $this->nl . '{' . $this->pStmts($node->stmts) . $this->nl . '}'

View File

@@ -1220,6 +1220,7 @@ abstract class PrettyPrinterAbstract
'Param->type' => $stripRight,
'Param->default' => $stripEquals,
'Stmt_Break->num' => $stripBoth,
'Stmt_Catch->var' => $stripLeft,
'Stmt_ClassMethod->returnType' => $stripColon,
'Stmt_Class->extends' => ['left' => \T_EXTENDS],
'Expr_PrintableNewAnonClass->extends' => ['left' => \T_EXTENDS],
@@ -1257,6 +1258,7 @@ abstract class PrettyPrinterAbstract
'Param->type' => [null, false, null, ' '],
'Param->default' => [null, false, ' = ', null],
'Stmt_Break->num' => [\T_BREAK, false, ' ', null],
'Stmt_Catch->var' => [null, false, ' ', null],
'Stmt_ClassMethod->returnType' => [')', false, ' : ', null],
'Stmt_Class->extends' => [null, false, ' extends ', null],
'Expr_PrintableNewAnonClass->extends' => [null, ' extends ', null],
@@ -1413,6 +1415,7 @@ abstract class PrettyPrinterAbstract
'Stmt_ClassMethod->flags' => \T_FUNCTION,
'Stmt_Class->flags' => \T_CLASS,
'Stmt_Property->flags' => \T_VARIABLE,
'Param->flags' => \T_VARIABLE,
//'Stmt_TraitUseAdaptation_Alias->newModifier' => 0, // TODO
];

View File

@@ -124,12 +124,12 @@ class LexerTest extends \PHPUnit\Framework\TestCase
'comments' => [
new Comment('/* comment */',
1, 6, 1, 1, 18, 1),
new Comment('// comment' . "\n",
1, 20, 3, 2, 30, 3),
new Comment('// comment',
1, 20, 3, 1, 29, 3),
new Comment\Doc('/** docComment 1 */',
2, 31, 4, 2, 49, 4),
2, 31, 5, 2, 49, 5),
new Comment\Doc('/** docComment 2 */',
2, 50, 5, 2, 68, 5),
2, 50, 6, 2, 68, 6),
],
],
['endLine' => 2]
@@ -185,11 +185,11 @@ class LexerTest extends \PHPUnit\Framework\TestCase
],
[
Tokens::T_CONSTANT_ENCAPSED_STRING, '"b"',
['startTokenPos' => 5], ['endTokenPos' => 5]
['startTokenPos' => 6], ['endTokenPos' => 6]
],
[
ord(';'), ';',
['startTokenPos' => 6], ['endTokenPos' => 6]
['startTokenPos' => 7], ['endTokenPos' => 7]
],
]
],
@@ -251,14 +251,17 @@ class LexerTest extends \PHPUnit\Framework\TestCase
}
public function testGetTokens() {
$code = '<?php "a";' . "\n" . '// foo' . "\n" . '"b";';
$code = '<?php "a";' . "\n" . '// foo' . "\n" . '// bar' . "\n\n" . '"b";';
$expectedTokens = [
[T_OPEN_TAG, '<?php ', 1],
[T_CONSTANT_ENCAPSED_STRING, '"a"', 1],
';',
[T_WHITESPACE, "\n", 1],
[T_COMMENT, '// foo' . "\n", 2],
[T_CONSTANT_ENCAPSED_STRING, '"b"', 3],
[T_COMMENT, '// foo', 2],
[T_WHITESPACE, "\n", 2],
[T_COMMENT, '// bar', 3],
[T_WHITESPACE, "\n\n", 3],
[T_CONSTANT_ENCAPSED_STRING, '"b"', 5],
';',
];

View File

@@ -247,6 +247,7 @@ PHP;
"kind": 10
}
},
"flags": 0,
"attributes": {
"startLine": 4,
"endLine": 4
@@ -273,6 +274,7 @@ PHP;
"endLine": 4
}
},
"flags": 0,
"attributes": {
"startLine": 4,
"endLine": 4
@@ -305,12 +307,12 @@ PHP;
"comments": [
{
"nodeType": "Comment",
"text": "\/\/ comment\n",
"text": "\/\/ comment",
"line": 2,
"filePos": 6,
"tokenPos": 1,
"endLine": 3,
"endFilePos": 16,
"endLine": 2,
"endFilePos": 15,
"endTokenPos": 1
},
{
@@ -318,10 +320,10 @@ PHP;
"text": "\/** doc comment *\/",
"line": 3,
"filePos": 17,
"tokenPos": 2,
"tokenPos": 3,
"endLine": 3,
"endFilePos": 34,
"endTokenPos": 2
"endTokenPos": 3
}
],
"endLine": 6

View File

@@ -83,10 +83,10 @@ EOC;
$this->assertInstanceOf(Stmt\Echo_::class, $echo);
$this->assertEquals([
'comments' => [
new Comment("// Line\n",
4, 49, 12, 5, 56, 12),
new Comment("// Comments\n",
5, 61, 14, 6, 72, 14),
new Comment("// Line",
4, 49, 12, 4, 55, 12),
new Comment("// Comments",
5, 61, 14, 5, 71, 14),
],
'startLine' => 6,
'endLine' => 6,

View File

@@ -15,8 +15,8 @@ class Foo {
public function __construct()
{
// I'm just a comment
$foo; }
$foo;
}
}
-----
<?php
@@ -72,5 +72,6 @@ class Foo {
public function __construct()
{
// I'm a new comment
}
}
}

View File

@@ -173,4 +173,22 @@ $stmts[0]->name = new Node\Name('Foo');
<?php
namespace Foo
{ echo 42; }
{ echo 42; }
-----
<?php
try
{
}
catch (Exception)
{
}
-----
$stmts[0]->catches[0]->var = new Expr\Variable('e');
-----
<?php
try
{
}
catch (Exception $e)
{
}

View File

@@ -30,4 +30,28 @@ class Bar {
public final function
foo() {}
}
}
-----
<?php
function test(
public T1 $x
= 'y',
private T2 $y
= 'z',
T3 $z
= 'x',
) {}
-----
$stmts[0]->params[0]->flags = Stmt\Class_::MODIFIER_PRIVATE;
$stmts[0]->params[1]->flags = 0;
$stmts[0]->params[2]->flags = Stmt\Class_::MODIFIER_PUBLIC;
-----
<?php
function test(
private T1 $x
= 'y',
T2 $y
= 'z',
public T3 $z
= 'x',
) {}

View File

@@ -191,4 +191,22 @@ $stmts[0]->name = null;
namespace
{
}
}
-----
<?php
try
{
}
catch (Exception $e)
{
}
-----
$stmts[0]->catches[0]->var = null;
-----
<?php
try
{
}
catch (Exception)
{
}

View File

@@ -594,14 +594,13 @@ isset($x, );
declare(a=42, );
function foo($a, ) {}
foo($a, );
global $a, ;
static $a, ;
echo $a, ;
for ($a, ; $b, ; $c, );
function ($a, ) use ($b, ) {};
function ($a) use ($b, ) {};
-----
!!php7
A trailing comma is not allowed here from 5:6 to 5:6
@@ -614,15 +613,13 @@ A trailing comma is not allowed here from 13:17 to 13:17
A trailing comma is not allowed here from 14:14 to 14:14
A trailing comma is not allowed here from 16:22 to 16:22
A trailing comma is not allowed here from 21:13 to 21:13
A trailing comma is not allowed here from 23:16 to 23:16
A trailing comma is not allowed here from 24:10 to 24:10
A trailing comma is not allowed here from 25:10 to 25:10
A trailing comma is not allowed here from 26:10 to 26:10
A trailing comma is not allowed here from 27:8 to 27:8
A trailing comma is not allowed here from 29:8 to 29:8
A trailing comma is not allowed here from 29:14 to 29:14
A trailing comma is not allowed here from 29:20 to 29:20
A trailing comma is not allowed here from 30:13 to 30:13
A trailing comma is not allowed here from 30:24 to 30:24
A trailing comma is not allowed here from 26:8 to 26:8
A trailing comma is not allowed here from 28:8 to 28:8
A trailing comma is not allowed here from 28:14 to 28:14
A trailing comma is not allowed here from 28:20 to 28:20
A trailing comma is not allowed here from 29:22 to 29:22
array(
0: Stmt_GroupUse(
type: TYPE_UNKNOWN (0)
@@ -811,27 +808,7 @@ array(
)
stmts: null
)
9: Stmt_Function(
byRef: false
name: Identifier(
name: foo
)
params: array(
0: Param(
type: null
byRef: false
variadic: false
var: Expr_Variable(
name: a
)
default: null
)
)
returnType: null
stmts: array(
)
)
10: Stmt_Expression(
9: Stmt_Expression(
expr: Expr_FuncCall(
name: Name(
parts: array(
@@ -849,14 +826,14 @@ array(
)
)
)
11: Stmt_Global(
10: Stmt_Global(
vars: array(
0: Expr_Variable(
name: a
)
)
)
12: Stmt_Static(
11: Stmt_Static(
vars: array(
0: Stmt_StaticVar(
var: Expr_Variable(
@@ -866,14 +843,14 @@ array(
)
)
)
13: Stmt_Echo(
12: Stmt_Echo(
exprs: array(
0: Expr_Variable(
name: a
)
)
)
14: Stmt_For(
13: Stmt_For(
init: array(
0: Expr_Variable(
name: a
@@ -892,12 +869,13 @@ array(
stmts: array(
)
)
15: Stmt_Expression(
14: Stmt_Expression(
expr: Expr_Closure(
static: false
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -1075,6 +1053,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: Name(
parts: array(
0: Type
@@ -1103,6 +1082,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: Name(
parts: array(
0: Type1
@@ -1116,6 +1096,7 @@ array(
default: null
)
1: Param(
flags: 0
type: Name(
parts: array(
0: Type2
@@ -1144,6 +1125,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: true
@@ -1168,6 +1150,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: true
variadic: false
@@ -1192,6 +1175,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: Name(
parts: array(
0: Bar
@@ -1225,6 +1209,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: Name(
parts: array(
0: Baz
@@ -1249,6 +1234,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: Name(
parts: array(
0: Foo

View File

@@ -16,6 +16,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: Identifier(
name: bool
)
@@ -39,6 +40,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -62,6 +64,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: true
variadic: false
@@ -83,6 +86,7 @@ array(
byRef: true
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -104,6 +108,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -113,6 +118,7 @@ array(
default: null
)
1: Param(
flags: 0
type: null
byRef: false
variadic: true
@@ -142,4 +148,4 @@ array(
)
)
)
)
)

View File

@@ -16,6 +16,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -43,6 +44,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -96,6 +98,7 @@ array(
byRef: true
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -131,6 +134,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false

View File

@@ -198,6 +198,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -264,6 +265,7 @@ array(
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false

View File

@@ -67,4 +67,4 @@ array(
)
)
)
)
)

View File

@@ -0,0 +1,81 @@
Property promotion
-----
<?php
class Point {
public function __construct(
public float $x = 0.0,
protected array $y = [],
private string $z = 'hello'
) {}
}
-----
!!php7
array(
0: Stmt_Class(
flags: 0
name: Identifier(
name: Point
)
extends: null
implements: array(
)
stmts: array(
0: Stmt_ClassMethod(
flags: MODIFIER_PUBLIC (1)
byRef: false
name: Identifier(
name: __construct
)
params: array(
0: Param(
flags: MODIFIER_PUBLIC (1)
type: Identifier(
name: float
)
byRef: false
variadic: false
var: Expr_Variable(
name: x
)
default: Scalar_DNumber(
value: 0
)
)
1: Param(
flags: MODIFIER_PROTECTED (2)
type: Identifier(
name: array
)
byRef: false
variadic: false
var: Expr_Variable(
name: y
)
default: Expr_Array(
items: array(
)
)
)
2: Param(
flags: MODIFIER_PRIVATE (4)
type: Identifier(
name: string
)
byRef: false
variadic: false
var: Expr_Variable(
name: z
)
default: Scalar_String(
value: hello
)
)
)
returnType: null
stmts: array(
)
)
)
)
)

View File

@@ -127,6 +127,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false

View File

@@ -12,6 +12,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: Identifier(
name: bool
)
@@ -23,6 +24,7 @@ array(
default: null
)
1: Param(
flags: 0
type: Identifier(
name: int
)
@@ -34,6 +36,7 @@ array(
default: null
)
2: Param(
flags: 0
type: Identifier(
name: float
)
@@ -45,6 +48,7 @@ array(
default: null
)
3: Param(
flags: 0
type: Identifier(
name: string
)
@@ -56,6 +60,7 @@ array(
default: null
)
4: Param(
flags: 0
type: Identifier(
name: iterable
)
@@ -67,6 +72,7 @@ array(
default: null
)
5: Param(
flags: 0
type: Identifier(
name: object
)
@@ -78,6 +84,7 @@ array(
default: null
)
6: Param(
flags: 0
type: Identifier(
name: mixed
)

View File

@@ -13,6 +13,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: true
variadic: false
@@ -33,6 +34,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false

View File

@@ -22,6 +22,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -37,6 +38,7 @@ array(
)
)
1: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -48,6 +50,7 @@ array(
)
)
2: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -66,6 +69,7 @@ array(
)
)
3: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -79,6 +83,7 @@ array(
)
)
4: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -92,6 +97,7 @@ array(
)
)
5: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -104,6 +110,7 @@ array(
)
)
6: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -116,6 +123,7 @@ array(
)
)
7: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -136,6 +144,7 @@ array(
)
)
8: Param(
flags: 0
type: null
byRef: false
variadic: false

View File

@@ -14,6 +14,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: NullableType(
type: Name(
parts: array(
@@ -29,6 +30,7 @@ array(
default: null
)
1: Param(
flags: 0
type: NullableType(
type: Identifier(
name: string

View File

@@ -0,0 +1,116 @@
Trailing comma in parameter list
-----
<?php
function foo($bar, ) {
}
-----
!!php7
array(
0: Stmt_Function(
byRef: false
name: Identifier(
name: foo
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
var: Expr_Variable(
name: bar
)
default: null
)
)
returnType: null
stmts: array(
)
)
)
-----
<?php
class Foo
{
function __construct($name, $value, )
{
}
}
-----
!!php7
array(
0: Stmt_Class(
flags: 0
name: Identifier(
name: Foo
)
extends: null
implements: array(
)
stmts: array(
0: Stmt_ClassMethod(
flags: 0
byRef: false
name: Identifier(
name: __construct
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
var: Expr_Variable(
name: name
)
default: null
)
1: Param(
flags: 0
type: null
byRef: false
variadic: false
var: Expr_Variable(
name: value
)
default: null
)
)
returnType: null
stmts: array(
)
)
)
)
)
-----
<?php
fn($foo, ) => $bar;
-----
!!php7
array(
0: Stmt_Expression(
expr: Expr_ArrowFunction(
static: false
byRef: false
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
var: Expr_Variable(
name: foo
)
default: null
)
)
returnType: null
expr: Expr_Variable(
name: bar
)
)
)
)

View File

@@ -12,6 +12,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -21,6 +22,7 @@ array(
default: null
)
1: Param(
flags: 0
type: Identifier(
name: array
)
@@ -32,6 +34,7 @@ array(
default: null
)
2: Param(
flags: 0
type: Identifier(
name: callable
)
@@ -43,6 +46,7 @@ array(
default: null
)
3: Param(
flags: 0
type: Name(
parts: array(
0: E

View File

@@ -54,6 +54,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: UnionType(
types: array(
0: Name(

View File

@@ -14,6 +14,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -23,6 +24,7 @@ array(
default: null
)
1: Param(
flags: 0
type: null
byRef: false
variadic: true
@@ -43,6 +45,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -52,6 +55,7 @@ array(
default: null
)
1: Param(
flags: 0
type: null
byRef: true
variadic: true
@@ -72,6 +76,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -81,6 +86,7 @@ array(
default: null
)
1: Param(
flags: 0
type: Name(
parts: array(
0: Type
@@ -105,6 +111,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: false
@@ -114,6 +121,7 @@ array(
default: null
)
1: Param(
flags: 0
type: Name(
parts: array(
0: Type

View File

@@ -12,6 +12,7 @@ array(
)
params: array(
0: Param(
flags: 0
type: null
byRef: false
variadic: true

View File

@@ -29,4 +29,4 @@ array(
)
finally: null
)
)
)

View File

@@ -2,7 +2,10 @@ Closures
-----
<?php
$closureWithArgs = function ($arg1, $arg2) {
$closureWithArgs = function (
$arg1,
$arg2
) {
$comment = 'closure body';
};

View File

@@ -0,0 +1,49 @@
Property promotion
-----
<?php
class Point
{
public function __construct(
public float $x = 0.0,
protected array $y = [],
private string $z = 'hello',
) {
}
}
-----
!!php7
class Point
{
public function __construct(public float $x = 0.0, protected array $y = [], private string $z = 'hello')
{
}
}
-----
<?php
class Test
{
public $z;
public function __construct(
public int $x,
/** @SomeAnnotation() */
public string $y = "123",
string $z = "abc"
)
{
}
}
-----
!!php7
class Test
{
public $z;
public function __construct(
public int $x,
/** @SomeAnnotation() */
public string $y = "123",
string $z = "abc"
)
{
}
}