mirror of
https://github.com/nikic/PHP-Parser.git
synced 2025-01-17 15:18:17 +01:00
[PHP 8.0] Add match expressions (#672)
RFC: https://wiki.php.net/rfc/match_expression_v2 Upstream implementation: php/php-src#5371 Closes #671.
This commit is contained in:
parent
6ec527bce7
commit
69c5d48afd
@ -1,7 +1,10 @@
|
||||
Version 4.6.1-dev
|
||||
-----------------
|
||||
|
||||
Nothing yet.
|
||||
### Added
|
||||
|
||||
* [PHP 8.0] Added support for match expressions. These are represented using a new `Expr\Match_`
|
||||
containing `MatchArm`s.
|
||||
|
||||
Version 4.6.0 (2020-07-02)
|
||||
--------------------------
|
||||
|
@ -28,6 +28,7 @@ reserved_non_modifiers:
|
||||
| T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT
|
||||
| T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
|
||||
| T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER | T_FN
|
||||
| T_MATCH
|
||||
;
|
||||
|
||||
semi_reserved:
|
||||
|
@ -28,6 +28,7 @@ reserved_non_modifiers:
|
||||
| T_FUNCTION | T_CONST | T_RETURN | T_PRINT | T_YIELD | T_LIST | T_SWITCH | T_ENDSWITCH | T_CASE | T_DEFAULT
|
||||
| T_BREAK | T_ARRAY | T_CALLABLE | T_EXTENDS | T_IMPLEMENTS | T_NAMESPACE | T_TRAIT | T_INTERFACE | T_CLASS
|
||||
| T_CLASS_C | T_TRAIT_C | T_FUNC_C | T_METHOD_C | T_LINE | T_FILE | T_DIR | T_NS_C | T_HALT_COMPILER | T_FN
|
||||
| T_MATCH
|
||||
;
|
||||
|
||||
semi_reserved:
|
||||
@ -399,6 +400,25 @@ case_separator:
|
||||
| ';'
|
||||
;
|
||||
|
||||
match:
|
||||
T_MATCH '(' expr ')' '{' match_arm_list '}' { $$ = Expr\Match_[$3, $6]; }
|
||||
;
|
||||
|
||||
match_arm_list:
|
||||
/* empty */ { $$ = []; }
|
||||
| non_empty_match_arm_list optional_comma { $$ = $1; }
|
||||
;
|
||||
|
||||
non_empty_match_arm_list:
|
||||
match_arm { init($1); }
|
||||
| non_empty_match_arm_list ',' match_arm { push($1, $3); }
|
||||
;
|
||||
|
||||
match_arm:
|
||||
expr_list_allow_comma T_DOUBLE_ARROW expr { $$ = Node\MatchArm[$1, $3]; }
|
||||
| T_DEFAULT optional_comma T_DOUBLE_ARROW expr { $$ = Node\MatchArm[null, $4]; }
|
||||
;
|
||||
|
||||
while_statement:
|
||||
statement { $$ = toArray($1); }
|
||||
| ':' inner_statement_list T_ENDWHILE ';' { $$ = $2; }
|
||||
@ -666,6 +686,7 @@ expr:
|
||||
| variable '=' expr { $$ = Expr\Assign[$1, $3]; }
|
||||
| variable '=' '&' variable { $$ = Expr\AssignRef[$1, $4]; }
|
||||
| new_expr { $$ = $1; }
|
||||
| match { $$ = $1; }
|
||||
| T_CLONE expr { $$ = Expr\Clone_[$2]; }
|
||||
| variable T_PLUS_EQUAL expr { $$ = Expr\AssignOp\Plus [$1, $3]; }
|
||||
| variable T_MINUS_EQUAL expr { $$ = Expr\AssignOp\Minus [$1, $3]; }
|
||||
@ -967,14 +988,14 @@ new_variable:
|
||||
|
||||
member_name:
|
||||
identifier_ex { $$ = $1; }
|
||||
| '{' expr '}' { $$ = $2; }
|
||||
| simple_variable { $$ = Expr\Variable[$1]; }
|
||||
| '{' expr '}' { $$ = $2; }
|
||||
| simple_variable { $$ = Expr\Variable[$1]; }
|
||||
;
|
||||
|
||||
property_name:
|
||||
identifier { $$ = $1; }
|
||||
| '{' expr '}' { $$ = $2; }
|
||||
| simple_variable { $$ = Expr\Variable[$1]; }
|
||||
| '{' expr '}' { $$ = $2; }
|
||||
| simple_variable { $$ = Expr\Variable[$1]; }
|
||||
| error { $$ = Expr\Error[]; $this->errorState = 2; }
|
||||
;
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
%token T_ENDDECLARE
|
||||
%token T_AS
|
||||
%token T_SWITCH
|
||||
%token T_MATCH
|
||||
%token T_ENDSWITCH
|
||||
%token T_CASE
|
||||
%token T_DEFAULT
|
||||
|
@ -7,6 +7,7 @@ use PhpParser\ErrorHandler;
|
||||
use PhpParser\Lexer;
|
||||
use PhpParser\Lexer\TokenEmulator\CoaleseEqualTokenEmulator;
|
||||
use PhpParser\Lexer\TokenEmulator\FnTokenEmulator;
|
||||
use PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
|
||||
use PhpParser\Lexer\TokenEmulator\NumericLiteralSeparatorEmulator;
|
||||
use PhpParser\Lexer\TokenEmulator\TokenEmulatorInterface;
|
||||
use PhpParser\Parser\Tokens;
|
||||
@ -15,9 +16,11 @@ class Emulative extends Lexer
|
||||
{
|
||||
const PHP_7_3 = '7.3.0dev';
|
||||
const PHP_7_4 = '7.4.0dev';
|
||||
const PHP_8_0 = '8.0.0dev';
|
||||
|
||||
const T_COALESCE_EQUAL = 1007;
|
||||
const T_FN = 1008;
|
||||
const T_MATCH = 1009;
|
||||
|
||||
const FLEXIBLE_DOC_STRING_REGEX = <<<'REGEX'
|
||||
/<<<[ \t]*(['"]?)([a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)\1\r?\n
|
||||
@ -39,11 +42,13 @@ REGEX;
|
||||
parent::__construct($options);
|
||||
|
||||
$this->tokenEmulators[] = new FnTokenEmulator();
|
||||
$this->tokenEmulators[] = new MatchTokenEmulator();
|
||||
$this->tokenEmulators[] = new CoaleseEqualTokenEmulator();
|
||||
$this->tokenEmulators[] = new NumericLiteralSeparatorEmulator();
|
||||
|
||||
$this->tokenMap[self::T_COALESCE_EQUAL] = Tokens::T_COALESCE_EQUAL;
|
||||
$this->tokenMap[self::T_FN] = Tokens::T_FN;
|
||||
$this->tokenMap[self::T_MATCH] = Tokens::T_MATCH;
|
||||
}
|
||||
|
||||
public function startLexing(string $code, ErrorHandler $errorHandler = null) {
|
||||
|
@ -18,10 +18,8 @@ final class FnTokenEmulator implements TokenEmulatorInterface
|
||||
|
||||
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
|
||||
foreach ($tokens as $i => $token) {
|
||||
if ($token[0] === T_STRING && $token[1] === 'fn') {
|
||||
if ($token[0] === T_STRING && strtolower($token[1]) === 'fn') {
|
||||
$previousNonSpaceToken = $this->getPreviousNonSpaceToken($tokens, $i);
|
||||
if ($previousNonSpaceToken !== null && $previousNonSpaceToken[0] === T_OBJECT_OPERATOR) {
|
||||
continue;
|
||||
|
51
lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php
Normal file
51
lib/PhpParser/Lexer/TokenEmulator/MatchTokenEmulator.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Lexer\TokenEmulator;
|
||||
|
||||
use PhpParser\Lexer\Emulative;
|
||||
|
||||
final class MatchTokenEmulator implements TokenEmulatorInterface
|
||||
{
|
||||
public function isEmulationNeeded(string $code) : bool
|
||||
{
|
||||
// skip version where this is supported
|
||||
if (version_compare(\PHP_VERSION, Emulative::PHP_8_0, '>=')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return strpos($code, 'match') !== false;
|
||||
}
|
||||
|
||||
public function emulate(string $code, array $tokens): array
|
||||
{
|
||||
foreach ($tokens as $i => $token) {
|
||||
if ($token[0] === T_STRING && strtolower($token[1]) === 'match') {
|
||||
$previousNonSpaceToken = $this->getPreviousNonSpaceToken($tokens, $i);
|
||||
if ($previousNonSpaceToken !== null && $previousNonSpaceToken[0] === T_OBJECT_OPERATOR) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tokens[$i][0] = Emulative::T_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
return $tokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $tokens
|
||||
* @return mixed[]|null
|
||||
*/
|
||||
private function getPreviousNonSpaceToken(array $tokens, int $start)
|
||||
{
|
||||
for ($i = $start - 1; $i >= 0; --$i) {
|
||||
if ($tokens[$i][0] === T_WHITESPACE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
return $tokens[$i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
31
lib/PhpParser/Node/Expr/Match_.php
Normal file
31
lib/PhpParser/Node/Expr/Match_.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node\Expr;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\MatchArm;
|
||||
|
||||
class Match_ extends Node\Expr
|
||||
{
|
||||
/** @var Node\Expr */
|
||||
public $cond;
|
||||
/** @var MatchArm[] */
|
||||
public $arms;
|
||||
|
||||
/**
|
||||
* @param MatchArm[] $arms
|
||||
*/
|
||||
public function __construct(Node\Expr $cond, array $arms = [], array $attributes = []) {
|
||||
$this->attributes = $attributes;
|
||||
$this->cond = $cond;
|
||||
$this->arms = $arms;
|
||||
}
|
||||
|
||||
public function getSubNodeNames() : array {
|
||||
return ['cond', 'arms'];
|
||||
}
|
||||
|
||||
public function getType() : string {
|
||||
return 'Expr_Match';
|
||||
}
|
||||
}
|
31
lib/PhpParser/Node/MatchArm.php
Normal file
31
lib/PhpParser/Node/MatchArm.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
namespace PhpParser\Node;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeAbstract;
|
||||
|
||||
class MatchArm extends NodeAbstract
|
||||
{
|
||||
/** @var null|Node\Expr[] */
|
||||
public $conds;
|
||||
/** @var Node\Expr */
|
||||
public $body;
|
||||
|
||||
/**
|
||||
* @param null|Node\Expr[] $conds
|
||||
*/
|
||||
public function __construct($conds, Node\Expr $body, array $attributes = []) {
|
||||
$this->conds = $conds;
|
||||
$this->body = $body;
|
||||
$this->attributes = $attributes;
|
||||
}
|
||||
|
||||
public function getSubNodeNames() : array {
|
||||
return ['conds', 'body'];
|
||||
}
|
||||
|
||||
public function getType() : string {
|
||||
return 'MatchArm';
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -84,63 +84,64 @@ final class Tokens
|
||||
const T_ENDDECLARE = 332;
|
||||
const T_AS = 333;
|
||||
const T_SWITCH = 334;
|
||||
const T_ENDSWITCH = 335;
|
||||
const T_CASE = 336;
|
||||
const T_DEFAULT = 337;
|
||||
const T_BREAK = 338;
|
||||
const T_CONTINUE = 339;
|
||||
const T_GOTO = 340;
|
||||
const T_FUNCTION = 341;
|
||||
const T_FN = 342;
|
||||
const T_CONST = 343;
|
||||
const T_RETURN = 344;
|
||||
const T_TRY = 345;
|
||||
const T_CATCH = 346;
|
||||
const T_FINALLY = 347;
|
||||
const T_THROW = 348;
|
||||
const T_USE = 349;
|
||||
const T_INSTEADOF = 350;
|
||||
const T_GLOBAL = 351;
|
||||
const T_STATIC = 352;
|
||||
const T_ABSTRACT = 353;
|
||||
const T_FINAL = 354;
|
||||
const T_PRIVATE = 355;
|
||||
const T_PROTECTED = 356;
|
||||
const T_PUBLIC = 357;
|
||||
const T_VAR = 358;
|
||||
const T_UNSET = 359;
|
||||
const T_ISSET = 360;
|
||||
const T_EMPTY = 361;
|
||||
const T_HALT_COMPILER = 362;
|
||||
const T_CLASS = 363;
|
||||
const T_TRAIT = 364;
|
||||
const T_INTERFACE = 365;
|
||||
const T_EXTENDS = 366;
|
||||
const T_IMPLEMENTS = 367;
|
||||
const T_OBJECT_OPERATOR = 368;
|
||||
const T_LIST = 369;
|
||||
const T_ARRAY = 370;
|
||||
const T_CALLABLE = 371;
|
||||
const T_CLASS_C = 372;
|
||||
const T_TRAIT_C = 373;
|
||||
const T_METHOD_C = 374;
|
||||
const T_FUNC_C = 375;
|
||||
const T_LINE = 376;
|
||||
const T_FILE = 377;
|
||||
const T_COMMENT = 378;
|
||||
const T_DOC_COMMENT = 379;
|
||||
const T_OPEN_TAG = 380;
|
||||
const T_OPEN_TAG_WITH_ECHO = 381;
|
||||
const T_CLOSE_TAG = 382;
|
||||
const T_WHITESPACE = 383;
|
||||
const T_START_HEREDOC = 384;
|
||||
const T_END_HEREDOC = 385;
|
||||
const T_DOLLAR_OPEN_CURLY_BRACES = 386;
|
||||
const T_CURLY_OPEN = 387;
|
||||
const T_PAAMAYIM_NEKUDOTAYIM = 388;
|
||||
const T_NAMESPACE = 389;
|
||||
const T_NS_C = 390;
|
||||
const T_DIR = 391;
|
||||
const T_NS_SEPARATOR = 392;
|
||||
const T_ELLIPSIS = 393;
|
||||
const T_MATCH = 335;
|
||||
const T_ENDSWITCH = 336;
|
||||
const T_CASE = 337;
|
||||
const T_DEFAULT = 338;
|
||||
const T_BREAK = 339;
|
||||
const T_CONTINUE = 340;
|
||||
const T_GOTO = 341;
|
||||
const T_FUNCTION = 342;
|
||||
const T_FN = 343;
|
||||
const T_CONST = 344;
|
||||
const T_RETURN = 345;
|
||||
const T_TRY = 346;
|
||||
const T_CATCH = 347;
|
||||
const T_FINALLY = 348;
|
||||
const T_THROW = 349;
|
||||
const T_USE = 350;
|
||||
const T_INSTEADOF = 351;
|
||||
const T_GLOBAL = 352;
|
||||
const T_STATIC = 353;
|
||||
const T_ABSTRACT = 354;
|
||||
const T_FINAL = 355;
|
||||
const T_PRIVATE = 356;
|
||||
const T_PROTECTED = 357;
|
||||
const T_PUBLIC = 358;
|
||||
const T_VAR = 359;
|
||||
const T_UNSET = 360;
|
||||
const T_ISSET = 361;
|
||||
const T_EMPTY = 362;
|
||||
const T_HALT_COMPILER = 363;
|
||||
const T_CLASS = 364;
|
||||
const T_TRAIT = 365;
|
||||
const T_INTERFACE = 366;
|
||||
const T_EXTENDS = 367;
|
||||
const T_IMPLEMENTS = 368;
|
||||
const T_OBJECT_OPERATOR = 369;
|
||||
const T_LIST = 370;
|
||||
const T_ARRAY = 371;
|
||||
const T_CALLABLE = 372;
|
||||
const T_CLASS_C = 373;
|
||||
const T_TRAIT_C = 374;
|
||||
const T_METHOD_C = 375;
|
||||
const T_FUNC_C = 376;
|
||||
const T_LINE = 377;
|
||||
const T_FILE = 378;
|
||||
const T_COMMENT = 379;
|
||||
const T_DOC_COMMENT = 380;
|
||||
const T_OPEN_TAG = 381;
|
||||
const T_OPEN_TAG_WITH_ECHO = 382;
|
||||
const T_CLOSE_TAG = 383;
|
||||
const T_WHITESPACE = 384;
|
||||
const T_START_HEREDOC = 385;
|
||||
const T_END_HEREDOC = 386;
|
||||
const T_DOLLAR_OPEN_CURLY_BRACES = 387;
|
||||
const T_CURLY_OPEN = 388;
|
||||
const T_PAAMAYIM_NEKUDOTAYIM = 389;
|
||||
const T_NAMESPACE = 390;
|
||||
const T_NS_C = 391;
|
||||
const T_DIR = 392;
|
||||
const T_NS_SEPARATOR = 393;
|
||||
const T_ELLIPSIS = 394;
|
||||
}
|
||||
|
@ -594,6 +594,18 @@ class Standard extends PrettyPrinterAbstract
|
||||
. ' {' . $this->pStmts($node->stmts) . $this->nl . '}';
|
||||
}
|
||||
|
||||
protected function pExpr_Match(Expr\Match_ $node) {
|
||||
return 'match (' . $this->p($node->cond) . ') {'
|
||||
. $this->pCommaSeparatedMultiline($node->arms, true)
|
||||
. $this->nl
|
||||
. '}';
|
||||
}
|
||||
|
||||
protected function pMatchArm(Node\MatchArm $node) {
|
||||
return ($node->conds ? $this->pCommaSeparated($node->conds) : 'default')
|
||||
. ' => ' . $this->p($node->body);
|
||||
}
|
||||
|
||||
protected function pExpr_ArrowFunction(Expr\ArrowFunction $node) {
|
||||
return ($node->static ? 'static ' : '')
|
||||
. 'fn' . ($node->byRef ? '&' : '')
|
||||
|
@ -1320,12 +1320,14 @@ abstract class PrettyPrinterAbstract
|
||||
'Stmt_Global->vars' => ', ',
|
||||
'Stmt_GroupUse->uses' => ', ',
|
||||
'Stmt_Interface->extends' => ', ',
|
||||
'Stmt_Match->arms' => ', ',
|
||||
'Stmt_Property->props' => ', ',
|
||||
'Stmt_StaticVar->vars' => ', ',
|
||||
'Stmt_TraitUse->traits' => ', ',
|
||||
'Stmt_TraitUseAdaptation_Precedence->insteadof' => ', ',
|
||||
'Stmt_Unset->vars' => ', ',
|
||||
'Stmt_Use->uses' => ', ',
|
||||
'MatchArm->conds' => ', ',
|
||||
|
||||
// statement lists
|
||||
'Expr_Closure->stmts' => "\n",
|
||||
|
89
test/code/formatPreservation/matche.test
Normal file
89
test/code/formatPreservation/matche.test
Normal file
@ -0,0 +1,89 @@
|
||||
Matches
|
||||
-----
|
||||
<?php
|
||||
$value = match (1) {
|
||||
1
|
||||
=>
|
||||
'one'
|
||||
};
|
||||
-----
|
||||
$stmts[0]->expr->expr->arms[] = new Node\MatchArm(null, new Scalar\String_('two'));
|
||||
-----
|
||||
<?php
|
||||
$value = match (1) {
|
||||
1
|
||||
=>
|
||||
'one',
|
||||
default => 'two',
|
||||
};
|
||||
-----
|
||||
<?php
|
||||
$value = match (1) {
|
||||
1, 2 =>
|
||||
'test',
|
||||
};
|
||||
-----
|
||||
$stmts[0]->expr->expr->arms[0]->conds[] = new Scalar\LNumber(3);
|
||||
-----
|
||||
<?php
|
||||
$value = match (1) {
|
||||
1, 2, 3 =>
|
||||
'test',
|
||||
};
|
||||
-----
|
||||
<?php
|
||||
$value = match (1) {
|
||||
1
|
||||
=>
|
||||
'one',
|
||||
2
|
||||
=>
|
||||
'two',
|
||||
3
|
||||
=>
|
||||
'three',
|
||||
};
|
||||
-----
|
||||
array_splice($stmts[0]->expr->expr->arms, 1, 1, []);
|
||||
-----
|
||||
<?php
|
||||
$value = match (1) {
|
||||
1
|
||||
=>
|
||||
'one',
|
||||
3
|
||||
=>
|
||||
'three',
|
||||
};
|
||||
-----
|
||||
<?php
|
||||
// TODO: Preserve formatting?
|
||||
$value = match (1) {
|
||||
default
|
||||
=>
|
||||
'test',
|
||||
};
|
||||
-----
|
||||
$stmts[0]->expr->expr->arms[0]->conds = [new Scalar\LNumber(1)];
|
||||
-----
|
||||
<?php
|
||||
// TODO: Preserve formatting?
|
||||
$value = match (1) {
|
||||
1 => 'test',
|
||||
};
|
||||
-----
|
||||
<?php
|
||||
// TODO: Preserve formatting?
|
||||
$value = match (1) {
|
||||
1
|
||||
=>
|
||||
'test',
|
||||
};
|
||||
-----
|
||||
$stmts[0]->expr->expr->arms[0]->conds = null;
|
||||
-----
|
||||
<?php
|
||||
// TODO: Preserve formatting?
|
||||
$value = match (1) {
|
||||
default => 'test',
|
||||
};
|
218
test/code/parser/expr/match.test
Normal file
218
test/code/parser/expr/match.test
Normal file
@ -0,0 +1,218 @@
|
||||
Match
|
||||
-----
|
||||
<?php
|
||||
|
||||
echo match (1) {
|
||||
0 => 'Foo',
|
||||
1 => 'Bar',
|
||||
};
|
||||
-----
|
||||
!!php7
|
||||
array(
|
||||
0: Stmt_Echo(
|
||||
exprs: array(
|
||||
0: Expr_Match(
|
||||
cond: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
arms: array(
|
||||
0: MatchArm(
|
||||
conds: array(
|
||||
0: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
)
|
||||
body: Scalar_String(
|
||||
value: Foo
|
||||
)
|
||||
)
|
||||
1: MatchArm(
|
||||
conds: array(
|
||||
0: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
)
|
||||
body: Scalar_String(
|
||||
value: Bar
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
-----
|
||||
<?php
|
||||
|
||||
$value = match (1) {
|
||||
// list of conditions
|
||||
0, 1 => 'Foo',
|
||||
};
|
||||
-----
|
||||
!!php7
|
||||
array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_Assign(
|
||||
var: Expr_Variable(
|
||||
name: value
|
||||
)
|
||||
expr: Expr_Match(
|
||||
cond: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
arms: array(
|
||||
0: MatchArm(
|
||||
conds: array(
|
||||
0: Scalar_LNumber(
|
||||
value: 0
|
||||
comments: array(
|
||||
0: // list of conditions
|
||||
)
|
||||
)
|
||||
1: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
)
|
||||
body: Scalar_String(
|
||||
value: Foo
|
||||
)
|
||||
comments: array(
|
||||
0: // list of conditions
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
-----
|
||||
<?php
|
||||
|
||||
$result = match ($operator) {
|
||||
BinaryOperator::ADD => $lhs + $rhs,
|
||||
};
|
||||
-----
|
||||
!!php7
|
||||
array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_Assign(
|
||||
var: Expr_Variable(
|
||||
name: result
|
||||
)
|
||||
expr: Expr_Match(
|
||||
cond: Expr_Variable(
|
||||
name: operator
|
||||
)
|
||||
arms: array(
|
||||
0: MatchArm(
|
||||
conds: array(
|
||||
0: Expr_ClassConstFetch(
|
||||
class: Name(
|
||||
parts: array(
|
||||
0: BinaryOperator
|
||||
)
|
||||
)
|
||||
name: Identifier(
|
||||
name: ADD
|
||||
)
|
||||
)
|
||||
)
|
||||
body: Expr_BinaryOp_Plus(
|
||||
left: Expr_Variable(
|
||||
name: lhs
|
||||
)
|
||||
right: Expr_Variable(
|
||||
name: rhs
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
-----
|
||||
<?php
|
||||
|
||||
$value = match ($char) {
|
||||
1 => '1',
|
||||
default => 'default'
|
||||
};
|
||||
-----
|
||||
!!php7
|
||||
array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_Assign(
|
||||
var: Expr_Variable(
|
||||
name: value
|
||||
)
|
||||
expr: Expr_Match(
|
||||
cond: Expr_Variable(
|
||||
name: char
|
||||
)
|
||||
arms: array(
|
||||
0: MatchArm(
|
||||
conds: array(
|
||||
0: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
)
|
||||
body: Scalar_String(
|
||||
value: 1
|
||||
)
|
||||
)
|
||||
1: MatchArm(
|
||||
conds: null
|
||||
body: Scalar_String(
|
||||
value: default
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
-----
|
||||
<?php
|
||||
|
||||
$value = match (1) {
|
||||
0, 1, => 'Foo',
|
||||
default, => 'Bar',
|
||||
};
|
||||
-----
|
||||
!!php7
|
||||
array(
|
||||
0: Stmt_Expression(
|
||||
expr: Expr_Assign(
|
||||
var: Expr_Variable(
|
||||
name: value
|
||||
)
|
||||
expr: Expr_Match(
|
||||
cond: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
arms: array(
|
||||
0: MatchArm(
|
||||
conds: array(
|
||||
0: Scalar_LNumber(
|
||||
value: 0
|
||||
)
|
||||
1: Scalar_LNumber(
|
||||
value: 1
|
||||
)
|
||||
)
|
||||
body: Scalar_String(
|
||||
value: Foo
|
||||
)
|
||||
)
|
||||
1: MatchArm(
|
||||
conds: null
|
||||
body: Scalar_String(
|
||||
value: Bar
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
18
test/code/prettyPrinter/expr/match.test
Normal file
18
test/code/prettyPrinter/expr/match.test
Normal file
@ -0,0 +1,18 @@
|
||||
Match
|
||||
-----
|
||||
<?php
|
||||
|
||||
echo match (1) {
|
||||
0, 1 => 'Foo',
|
||||
// Comment
|
||||
2 => 'Bar',
|
||||
default => 'Foo',
|
||||
};
|
||||
-----
|
||||
!!php7
|
||||
echo match (1) {
|
||||
0, 1 => 'Foo',
|
||||
// Comment
|
||||
2 => 'Bar',
|
||||
default => 'Foo',
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
wget -q https://github.com/php/php-src/archive/PHP-7.4.tar.gz
|
||||
VERSION="master"
|
||||
wget -q https://github.com/php/php-src/archive/$VERSION.tar.gz
|
||||
mkdir -p ./data/php-src
|
||||
tar -xzf ./PHP-7.4.tar.gz -C ./data/php-src --strip-components=1
|
||||
tar -xzf ./$VERSION.tar.gz -C ./data/php-src --strip-components=1
|
||||
php -n test_old/run.php --verbose --no-progress PHP7 ./data/php-src
|
||||
|
Loading…
x
Reference in New Issue
Block a user