1
0
mirror of https://github.com/danog/PHP-Parser.git synced 2024-11-26 20:04:48 +01:00

Add support for finally clauses (PHP 5.5)

This adds a new finallyStmts subnode to the TryCatch node. If there is
no finally clause it will be null.
This commit is contained in:
nikic 2012-09-07 18:06:11 +02:00
parent f8f1e17e41
commit ae3774f0f2
7 changed files with 1511 additions and 1399 deletions

View File

@ -1,6 +1,9 @@
Version 0.9.3-dev
-----------------
* [PHP 5.5] Add support for `finally`. This adds a new `finallyStmts` subnode to the `TryCatch` node. If there is no
finally clause it will be `null`.
* [BC] [PHP 5.5] Add support for `list()` destructuring of `foreach` values.
Example: `foreach ($coords as list($x, $y)) { ... }`

View File

@ -63,6 +63,7 @@
%token T_RETURN
%token T_TRY
%token T_CATCH
%token T_FINALLY
%token T_THROW
%token T_USE
%token T_INSTEADOF
@ -195,14 +196,15 @@ statement:
{ $$ = Stmt_Foreach[$3, $7[0], [keyVar: $5, byRef: $7[1], stmts: $9]]; }
| T_DECLARE '(' declare_list ')' declare_statement { $$ = Stmt_Declare[$3, $5]; }
| ';' { $$ = array(); /* means: no statement */ }
| T_TRY '{' inner_statement_list '}' catches { $$ = Stmt_TryCatch[$3, $5]; }
| T_TRY '{' inner_statement_list '}' catches optional_finally
{ $$ = Stmt_TryCatch[$3, $5, $6]; }
| T_THROW expr ';' { $$ = Stmt_Throw[$2]; }
| T_GOTO T_STRING ';' { $$ = Stmt_Goto[$2]; }
| T_STRING ':' { $$ = Stmt_Label[$1]; }
;
catches:
catch { init($1); }
/* empty */ { init(); }
| catches catch { push($1, $2); }
;
@ -211,6 +213,11 @@ catch:
{ $$ = Stmt_Catch[$3, parseVar($4), $7]; }
;
optional_finally:
/* empty */ { $$ = null; }
| T_FINALLY '{' inner_statement_list '}' { $$ = $3; }
;
variables_list:
variable { init($1); }
| variables_list ',' variable { push($1, $3); }

View File

@ -11,31 +11,32 @@ class PHPParser_Lexer_Emulative extends PHPParser_Lexer
public function __construct() {
parent::__construct();
$newKeywordsPerVersion = array(
'5.5.0-dev' => array(
'finally' => PHPParser_Parser::T_FINALLY,
),
'5.4.0-dev' => array(
'callable' => PHPParser_Parser::T_CALLABLE,
'insteadof' => PHPParser_Parser::T_INSTEADOF,
'trait' => PHPParser_Parser::T_TRAIT,
'__trait__' => PHPParser_Parser::T_TRAIT_C,
),
'5.3.0-dev' => array(
'__dir__' => PHPParser_Parser::T_DIR,
'goto' => PHPParser_Parser::T_GOTO,
'namespace' => PHPParser_Parser::T_NAMESPACE,
'__namespace__' => PHPParser_Parser::T_NS_C,
),
);
$this->newKeywords = array();
foreach ($newKeywordsPerVersion as $version => $newKeywords) {
if (version_compare(PHP_VERSION, $version, '>=')) {
break;
}
if (version_compare(PHP_VERSION, '5.4.0RC1', '>=')) {
return;
$this->newKeywords += $newKeywords;
}
// new PHP 5.4 keywords
$this->newKeywords += array(
'callable' => PHPParser_Parser::T_CALLABLE,
'insteadof' => PHPParser_Parser::T_INSTEADOF,
'trait' => PHPParser_Parser::T_TRAIT,
'__trait__' => PHPParser_Parser::T_TRAIT_C,
);
if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
return;
}
// new PHP 5.3 keywords
$this->newKeywords += array(
'__dir__' => PHPParser_Parser::T_DIR,
'goto' => PHPParser_Parser::T_GOTO,
'namespace' => PHPParser_Parser::T_NAMESPACE,
'__namespace__' => PHPParser_Parser::T_NS_C,
);
}
public function startLexing($code) {

View File

@ -1,23 +1,30 @@
<?php
/**
* @property PHPParser_Node[] $stmts Statements
* @property PHPParser_Node_Stmt_Catch[] $catches Catches
* @property PHPParser_Node[] $stmts Statements
* @property PHPParser_Node_Stmt_Catch[] $catches Catches
* @property PHPParser_Node[] $finallyStmts Finally statements
*/
class PHPParser_Node_Stmt_TryCatch extends PHPParser_Node_Stmt
{
/**
* Constructs a try catch node.
*
* @param PHPParser_Node[] $stmts Statements
* @param PHPParser_Node_Stmt_Catch[] $catches Catches
* @param array $attributes Additional attributes
* @param PHPParser_Node[] $stmts Statements
* @param PHPParser_Node_Stmt_Catch[] $catches Catches
* @param PHPParser_Node[] $finallyStmts Finally statements (null means no finally clause)
* @param array|null $attributes Additional attributes
*/
public function __construct(array $stmts, array $catches, array $attributes = array()) {
public function __construct(array $stmts, array $catches, array $finallyStmts = null, array $attributes = array()) {
if (empty($catches) && null === $finallyStmts) {
throw new PHPParser_Error('Cannot use try without catch or finally');
}
parent::__construct(
array(
'stmts' => $stmts,
'catches' => $catches,
'stmts' => $stmts,
'catches' => $catches,
'finallyStmts' => $finallyStmts,
),
$attributes
);

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,92 @@
Try/catch
-----
<?php
try {
doTry();
} catch (A $b) {
doCatchA();
} catch (B $c) {
doCatchB();
} finally {
doFinally();
}
// no finally
try { }
catch (A $b) { }
// no catch
try { }
finally { }
-----
array(
0: Stmt_TryCatch(
stmts: array(
0: Expr_FuncCall(
name: Name(
parts: array(
0: doTry
)
)
args: array(
)
)
)
catches: array(
0: Stmt_Catch(
type: Name(
parts: array(
0: A
)
)
var: b
stmts: array(
0: Expr_FuncCall(
name: Name(
parts: array(
0: doCatchA
)
)
args: array(
)
)
)
)
1: Stmt_Catch(
type: Name(
parts: array(
0: B
)
)
var: c
stmts: array(
0: Expr_FuncCall(
name: Name(
parts: array(
0: doCatchB
)
)
args: array(
)
)
)
)
)
finallyStmts: array(
0: Expr_FuncCall(
name: Name(
parts: array(
0: doFinally
)
)
args: array(
)
)
)
)
1: Stmt_TryCatch(
stmts: array(
)
catches: array(
@ -24,16 +100,15 @@ array(
stmts: array(
)
)
1: Stmt_Catch(
type: Name(
parts: array(
0: B
)
)
var: c
stmts: array(
)
)
)
finallyStmts: null
)
2: Stmt_TryCatch(
stmts: array(
)
catches: array(
)
finallyStmts: array(
)
)
)

View File

@ -0,0 +1,7 @@
Cannot use try without catch or finally
-----
<?php
try { }
-----
Cannot use try without catch or finally on line 3