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
-----------------
* [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.
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
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)) { ... }`
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`).
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
does not take inherited methods into account.

View File

@ -600,7 +600,7 @@ parentheses_expr:
yield_expr:
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:
@ -620,10 +620,6 @@ new_expr:
T_NEW class_name_reference ctor_arguments { $$ = Expr_New[$2, $3]; }
;
list_expr:
T_LIST '(' assignment_list ')' { $$ = Expr_List[$3]; }
;
lexical_vars:
/* empty */ { $$ = array(); }
| T_USE '(' lexical_var_list ')' { $$ = $3; }
@ -845,14 +841,18 @@ object_property:
| variable_without_objects { $$ = $1; }
;
assignment_list:
assignment_list ',' assignment_list_element { push($1, $3); }
| assignment_list_element { init($1); }
list_expr:
T_LIST '(' list_expr_elements ')' { $$ = Expr_List[$3]; }
;
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; }
| T_LIST '(' assignment_list ')' { $$ = $3; }
| list_expr { $$ = $1; }
| /* 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);
}
public function pExpr_AssignList(PHPParser_Node_Expr_AssignList $node) {
return $this->pAssignList($node->vars) . ' = ' . $this->p($node->expr);
}
// Binary expressions
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);
}
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
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) . ')' : '');
}
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
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) {
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) {
@ -688,21 +712,6 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
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) {
if ($node instanceof PHPParser_Node_Expr_New) {
return '(' . $this->p($node) . ')';

View File

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

View File

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