Adjust list and yield parsing, update prettyprinter

* nested list()s will now create nested List nodes (instead of just
   nested arrays)
 * yield $k => $v was parsed with key and value swapped. This is now fixed
 * the pretty printer now works with the newly added language constructs
This commit is contained in:
nikic 2012-09-07 23:21:23 +02:00
parent 4259b44a84
commit f6c1ab6657
6 changed files with 553 additions and 540 deletions

View File

@ -1,6 +1,11 @@
Version 0.9.3-dev Version 0.9.3-dev
----------------- -----------------
* [BC] As `list()` in `foreach` is not supported the structure of list assignments changed:
1. There is no longer a dedicated `AssignList` node; instead a normal `Assign` node is used with a `List` as `var`.
2. Nested lists are now `List` nodes too, instead of just arrays.
* [PHP 5.5] Add support for constant array / string dereferencing. * [PHP 5.5] Add support for constant array / string dereferencing.
Examples: `"foo"[2]`, `[1, 2, 3][2]` Examples: `"foo"[2]`, `[1, 2, 3][2]`
@ -10,17 +15,14 @@ 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 * [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`. finally clause it will be `null`.
* [BC] [PHP 5.5] Add support for `list()` destructuring of `foreach` values. * [PHP 5.5] Add support for `list()` destructuring of `foreach` values.
Example: `foreach ($coords as list($x, $y)) { ... }` Example: `foreach ($coords as list($x, $y)) { ... }`
This changes the node structure for the previously existing `list(...) = $foo` assignments. Those no longer have a
dedicated `AssignList` node; instead they are parsed as a normal `Assign` node with a `List` as `var`. Similarly the
use in `foreach` will generate a `List` for `valueVar`.
* Fix parsing of `$foo =& new Bar`. It is now properly parsed as `AssignRef` (instead of `Assign`). * Fix parsing of `$foo =& new Bar`. It is now properly parsed as `AssignRef` (instead of `Assign`).
Version 0.9.2 (07.07.2012) Version 0.9.2 (07.07.2012)
-------------------------- --------------------------
* Add `Class->getMethods()` function, which returns all methods contained in the `stmts` array of the class node. This * Add `Class->getMethods()` function, which returns all methods contained in the `stmts` array of the class node. This
does not take inherited methods into account. does not take inherited methods into account.

View File

@ -600,7 +600,7 @@ parentheses_expr:
yield_expr: yield_expr:
T_YIELD expr { $$ = Expr_Yield[$2, null]; } T_YIELD expr { $$ = Expr_Yield[$2, null]; }
| T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr_Yield[$2, $4]; } | T_YIELD expr T_DOUBLE_ARROW expr { $$ = Expr_Yield[$4, $2]; }
; ;
array_expr: array_expr:
@ -620,10 +620,6 @@ new_expr:
T_NEW class_name_reference ctor_arguments { $$ = Expr_New[$2, $3]; } T_NEW class_name_reference ctor_arguments { $$ = Expr_New[$2, $3]; }
; ;
list_expr:
T_LIST '(' assignment_list ')' { $$ = Expr_List[$3]; }
;
lexical_vars: lexical_vars:
/* empty */ { $$ = array(); } /* empty */ { $$ = array(); }
| T_USE '(' lexical_var_list ')' { $$ = $3; } | T_USE '(' lexical_var_list ')' { $$ = $3; }
@ -845,14 +841,18 @@ object_property:
| variable_without_objects { $$ = $1; } | variable_without_objects { $$ = $1; }
; ;
assignment_list: list_expr:
assignment_list ',' assignment_list_element { push($1, $3); } T_LIST '(' list_expr_elements ')' { $$ = Expr_List[$3]; }
| assignment_list_element { init($1); }
; ;
assignment_list_element: list_expr_elements:
list_expr_elements ',' list_expr_element { push($1, $3); }
| list_expr_element { init($1); }
;
list_expr_element:
variable { $$ = $1; } variable { $$ = $1; }
| T_LIST '(' assignment_list ')' { $$ = $3; } | list_expr { $$ = $1; }
| /* empty */ { $$ = null; } | /* empty */ { $$ = null; }
; ;

File diff suppressed because it is too large Load Diff

View File

@ -142,10 +142,6 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
return $this->p($node->var) . ' >>= ' . $this->p($node->expr); return $this->p($node->var) . ' >>= ' . $this->p($node->expr);
} }
public function pExpr_AssignList(PHPParser_Node_Expr_AssignList $node) {
return $this->pAssignList($node->vars) . ' = ' . $this->p($node->expr);
}
// Binary expressions // Binary expressions
public function pExpr_Plus(PHPParser_Node_Expr_Plus $node) { public function pExpr_Plus(PHPParser_Node_Expr_Plus $node) {
@ -365,6 +361,19 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
return $map[$node->type] . ' ' . $this->p($node->expr); return $map[$node->type] . ' ' . $this->p($node->expr);
} }
public function pExpr_List(PHPParser_Node_Expr_List $node) {
$pList = array();
foreach ($node->vars as $var) {
if (null === $var) {
$pList[] = '';
} else {
$pList[] = $this->p($var);
}
}
return 'list(' . implode(', ', $pList) . ')';
}
// Other // Other
public function pExpr_Variable(PHPParser_Node_Expr_Variable $node) { public function pExpr_Variable(PHPParser_Node_Expr_Variable $node) {
@ -439,6 +448,18 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
return 'die' . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : ''); return 'die' . (null !== $node->expr ? '(' . $this->p($node->expr) . ')' : '');
} }
public function pExpr_Yield(PHPParser_Node_Expr_Yield $node) {
if ($node->value === null) {
return 'yield';
} else {
// this is a bit ugly, but currently there is no way to detect whether the parentheses are necessary
return '(yield '
. ($node->key !== null ? $this->p($node->key) . ' => ' : '')
. $this->p($node->value)
. ')';
}
}
// Declarations // Declarations
public function pStmt_Namespace(PHPParser_Node_Stmt_Namespace $node) { public function pStmt_Namespace(PHPParser_Node_Stmt_Namespace $node) {
@ -585,7 +606,10 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
public function pStmt_TryCatch(PHPParser_Node_Stmt_TryCatch $node) { public function pStmt_TryCatch(PHPParser_Node_Stmt_TryCatch $node) {
return 'try {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}' return 'try {' . "\n" . $this->pStmts($node->stmts) . "\n" . '}'
. $this->pImplode($node->catches); . $this->pImplode($node->catches)
. ($node->finallyStmts !== null
? ' finally {' . "\n" . $this->pStmts($node->finallyStmts) . "\n" . '}'
: '');
} }
public function pStmt_Catch(PHPParser_Node_Stmt_Catch $node) { public function pStmt_Catch(PHPParser_Node_Stmt_Catch $node) {
@ -688,21 +712,6 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
return $return; return $return;
} }
public function pAssignList(array $elements) {
$pAssignList = array();
foreach ($elements as $element) {
if (null === $element) {
$pAssignList[] = '';
} elseif (is_array($element)) {
$pAssignList[] = $this->pAssignList($element);
} else {
$pAssignList[] = $this->p($element);
}
}
return 'list(' . implode(', ', $pAssignList) . ')';
}
public function pVarOrNewExpr(PHPParser_Node $node) { public function pVarOrNewExpr(PHPParser_Node $node) {
if ($node instanceof PHPParser_Node_Expr_New) { if ($node instanceof PHPParser_Node_Expr_New) {
return '(' . $this->p($node) . ')'; return '(' . $this->p($node) . ')';

View File

@ -185,10 +185,12 @@ array(
0: Expr_Variable( 0: Expr_Variable(
name: a name: a
) )
1: array( 1: Expr_List(
0: null vars: array(
1: Expr_Variable( 0: null
name: c 1: Expr_Variable(
name: c
)
) )
) )
2: Expr_Variable( 2: Expr_Variable(

View File

@ -45,10 +45,10 @@ array(
) )
2: Expr_Yield( 2: Expr_Yield(
key: Expr_Variable( key: Expr_Variable(
name: value name: key
) )
value: Expr_Variable( value: Expr_Variable(
name: key name: value
) )
) )
3: Expr_Assign( 3: Expr_Assign(
@ -77,10 +77,10 @@ array(
) )
expr: Expr_Yield( expr: Expr_Yield(
key: Expr_Variable( key: Expr_Variable(
name: value name: key
) )
value: Expr_Variable( value: Expr_Variable(
name: key name: value
) )
) )
) )