[5.4] Add direct dereferencing of new expression

(new A)->b(), (new A)->b, (new A)[0]. The feature is not implemented fully compliant (implemented as a `variable`, not `expr_without_variable`: Awaiting input on that on internals@.
This commit is contained in:
nikic 2011-11-21 18:43:35 +01:00
parent 6ed2f43098
commit adfa67cdcf
4 changed files with 769 additions and 707 deletions

View File

@ -481,10 +481,8 @@ expr:
| T_LIST '(' assignment_list ')' '=' expr { $$ = Expr_AssignList[$3, $6]; }
| variable '=' expr { $$ = Expr_Assign[$1, $3]; }
| variable '=' '&' variable { $$ = Expr_AssignRef[$1, $4]; }
| variable '=' '&' T_NEW class_name_reference ctor_arguments
{ $$ = Expr_Assign[$1, Expr_New[$5, $6]]; }
/* reference dropped intentially */
| T_NEW class_name_reference ctor_arguments { $$ = Expr_New[$2, $3]; }
| variable '=' '&' new_expr { $$ = Expr_Assign[$1, $4]; } /* reference dropped intentially */
| new_expr { $$ = $1; }
| T_CLONE expr { $$ = Expr_Clone[$2]; }
| variable T_PLUS_EQUAL expr { $$ = Expr_AssignPlus [$1, $3]; }
| variable T_MINUS_EQUAL expr { $$ = Expr_AssignMinus [$1, $3]; }
@ -560,6 +558,10 @@ expr:
{ $$ = Expr_Closure[[static: true, byRef: $3, params: $5, uses: $7, stmts: $9]]; }
;
new_expr:
T_NEW class_name_reference ctor_arguments { $$ = Expr_New[$2, $3]; }
;
lexical_vars:
/* empty */ { $$ = array(); }
| T_USE '(' lexical_var_list ')' { $$ = $3; }
@ -712,17 +714,29 @@ variable:
object_access { $$ = $1; }
| base_variable { $$ = $1; }
| function_call { $$ = $1; }
| new_expr_array_deref { $$ = $1; }
;
new_expr_array_deref:
'(' new_expr ')' '[' dim_offset ']' { $$ = Expr_ArrayDimFetch[$2, $5]; }
| new_expr_array_deref '[' dim_offset ']' { $$ = Expr_ArrayDimFetch[$1, $3]; }
;
object_access:
variable T_OBJECT_OPERATOR object_property { $$ = Expr_PropertyFetch[$1, $3]; }
| variable T_OBJECT_OPERATOR object_property '(' function_call_argument_list ')'
variable_or_new_expr T_OBJECT_OPERATOR object_property
{ $$ = Expr_PropertyFetch[$1, $3]; }
| variable_or_new_expr T_OBJECT_OPERATOR object_property '(' function_call_argument_list ')'
{ $$ = Expr_MethodCall[$1, $3, $5]; }
| object_access '(' function_call_argument_list ')' { $$ = Expr_FuncCall[$1, $3]; }
| object_access '[' dim_offset ']' { $$ = Expr_ArrayDimFetch[$1, $3]; }
| object_access '{' expr '}' { $$ = Expr_ArrayDimFetch[$1, $3]; }
;
variable_or_new_expr:
variable { $$ = $1; }
| '(' new_expr ')' { $$ = $2; }
;
variable_without_objects:
reference_variable { $$ = $1; }
| '$' variable_without_objects { $$ = Expr_Variable[$2]; }

File diff suppressed because it is too large Load Diff

View File

@ -182,8 +182,8 @@ class PHPParser_Parser_Debug extends PHPParser_Parser
"expr : T_LIST '(' assignment_list ')' '=' expr",
"expr : variable '=' expr",
"expr : variable '=' '&' variable",
"expr : variable '=' '&' T_NEW class_name_reference ctor_arguments",
"expr : T_NEW class_name_reference ctor_arguments",
"expr : variable '=' '&' new_expr",
"expr : new_expr",
"expr : T_CLONE expr",
"expr : variable T_PLUS_EQUAL expr",
"expr : variable T_MINUS_EQUAL expr",
@ -255,6 +255,7 @@ class PHPParser_Parser_Debug extends PHPParser_Parser
"expr : T_PRINT expr",
"expr : T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars '{' inner_statement_list '}'",
"expr : T_STATIC T_FUNCTION optional_ref '(' parameter_list ')' lexical_vars '{' inner_statement_list '}'",
"new_expr : T_NEW class_name_reference ctor_arguments",
"lexical_vars : /* empty */",
"lexical_vars : T_USE '(' lexical_var_list ')'",
"lexical_var_list : lexical_var_list ',' optional_ref T_VARIABLE",
@ -325,11 +326,16 @@ class PHPParser_Parser_Debug extends PHPParser_Parser
"variable : object_access",
"variable : base_variable",
"variable : function_call",
"object_access : variable T_OBJECT_OPERATOR object_property",
"object_access : variable T_OBJECT_OPERATOR object_property '(' function_call_argument_list ')'",
"variable : new_expr_array_deref",
"new_expr_array_deref : '(' new_expr ')' '[' dim_offset ']'",
"new_expr_array_deref : new_expr_array_deref '[' dim_offset ']'",
"object_access : variable_or_new_expr T_OBJECT_OPERATOR object_property",
"object_access : variable_or_new_expr T_OBJECT_OPERATOR object_property '(' function_call_argument_list ')'",
"object_access : object_access '(' function_call_argument_list ')'",
"object_access : object_access '[' dim_offset ']'",
"object_access : object_access '{' expr '}'",
"variable_or_new_expr : variable",
"variable_or_new_expr : '(' new_expr ')'",
"variable_without_objects : reference_variable",
"variable_without_objects : '$' variable_without_objects",
"base_variable : variable_without_objects",

View File

@ -323,7 +323,7 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
}
public function pExpr_MethodCall(PHPParser_Node_Expr_MethodCall $node) {
return $this->p($node->var) . '->' . $this->pObjectProperty($node->name)
return $this->pVarOrNewExpr($node->var) . '->' . $this->pObjectProperty($node->name)
. '(' . $this->pCommaSeparated($node->args) . ')';
}
@ -385,7 +385,8 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
}
public function pExpr_ArrayDimFetch(PHPParser_Node_Expr_ArrayDimFetch $node) {
return $this->p($node->var) . '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
return $this->pVarOrNewExpr($node->var)
. '[' . (null !== $node->dim ? $this->p($node->dim) : '') . ']';
}
public function pExpr_ConstFetch(PHPParser_Node_Expr_ConstFetch $node) {
@ -397,7 +398,7 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
}
public function pExpr_PropertyFetch(PHPParser_Node_Expr_PropertyFetch $node) {
return $this->p($node->var) . '->' . $this->pObjectProperty($node->name);
return $this->pVarOrNewExpr($node->var) . '->' . $this->pObjectProperty($node->name);
}
public function pExpr_StaticPropertyFetch(PHPParser_Node_Expr_StaticPropertyFetch $node) {
@ -701,4 +702,12 @@ class PHPParser_PrettyPrinter_Zend extends PHPParser_PrettyPrinterAbstract
return 'list(' . implode(', ', $pAssignList) . ')';
}
public function pVarOrNewExpr(PHPParser_Node $node) {
if ($node instanceof PHPParser_Node_Expr_New) {
return '(' . $this->p($node) . ')';
} else {
return $this->p($node);
}
}
}