create expr.Reference node

[wip] create expr.Reference node

[wip] create expr.Reference node

[wip] create expr.Reference node

fix
This commit is contained in:
z7zmey 2018-05-14 18:09:11 +03:00
parent ac74ae3225
commit ec0ef26bd6
22 changed files with 1408 additions and 1445 deletions

View File

@ -7,15 +7,13 @@ import (
// ArrayItem node
type ArrayItem struct {
ByRef bool
Key node.Node
Val node.Node
Key node.Node
Val node.Node
}
// NewArrayItem node constructor
func NewArrayItem(Key node.Node, Val node.Node, ByRef bool) *ArrayItem {
func NewArrayItem(Key node.Node, Val node.Node) *ArrayItem {
return &ArrayItem{
ByRef,
Key,
Val,
}
@ -23,9 +21,7 @@ func NewArrayItem(Key node.Node, Val node.Node, ByRef bool) *ArrayItem {
// Attributes returns node attributes as map
func (n *ArrayItem) Attributes() map[string]interface{} {
return map[string]interface{}{
"ByRef": n.ByRef,
}
return nil
}
// Walk traverses nodes

View File

@ -7,23 +7,19 @@ import (
// ClosureUse node
type ClosureUse struct {
ByRef bool
Variable node.Node
}
// NewClosureUse node constructor
func NewClosureUse(Variable node.Node, ByRef bool) *ClosureUse {
func NewClosureUse(Variable node.Node) *ClosureUse {
return &ClosureUse{
ByRef,
Variable,
}
}
// Attributes returns node attributes as map
func (n *ClosureUse) Attributes() map[string]interface{} {
return map[string]interface{}{
"ByRef": n.ByRef,
}
return nil
}
// Walk traverses nodes

38
node/expr/n_reference.go Normal file
View File

@ -0,0 +1,38 @@
package expr
import (
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/walker"
)
// Reference node
type Reference struct {
Variable node.Node
}
// NewReference node constructor
func NewReference(Variable node.Node) *Reference {
return &Reference{
Variable,
}
}
// Attributes returns node attributes as map
func (n *Reference) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Reference) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Variable != nil {
vv := v.GetChildrenVisitor("Variable")
n.Variable.Walk(vv)
}
v.LeaveNode(n)
}

View File

@ -47,8 +47,7 @@ func TestArrayItem(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -76,13 +75,11 @@ func TestArrayItems(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: true,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
},
},

View File

@ -66,12 +66,10 @@ func TestClosureUse(t *testing.T) {
},
Uses: []node.Node{
&expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
},
&expr.ClosureUse{
ByRef: true,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
},
},
Stmts: []node.Node{},
@ -115,11 +113,9 @@ func TestClosureUse2(t *testing.T) {
},
Uses: []node.Node{
&expr.ClosureUse{
ByRef: true,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}},
},
&expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
},
},

View File

@ -51,8 +51,7 @@ func TestList(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},
@ -83,7 +82,6 @@ func TestListArrayIndex(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
@ -117,12 +115,10 @@ func TestListList(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},

View File

@ -0,0 +1,41 @@
package expr_test
import (
"bytes"
"testing"
"github.com/z7zmey/php-parser/node/expr"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/stmt"
"github.com/z7zmey/php-parser/php5"
"github.com/z7zmey/php-parser/php7"
)
func TestForeachWithRef(t *testing.T) {
t.Helper()
src := `<? foreach ($a as $k => &$v) {}`
expected := &node.Root{
Stmts: []node.Node{
&stmt.Foreach{
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}}},
Stmt: &stmt.StmtList{
Stmts: []node.Node{},
},
},
},
}
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
php7parser.Parse()
actual := php7parser.GetRootNode()
assertEqual(t, expected, actual)
php5parser := php5.NewParser(bytes.NewBufferString(src), "test.php")
php5parser.Parse()
actual = php5parser.GetRootNode()
assertEqual(t, expected, actual)
}

View File

@ -47,8 +47,7 @@ func TestShortArrayItem(t *testing.T) {
Expr: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -76,13 +75,11 @@ func TestShortArrayItems(t *testing.T) {
Expr: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: true,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
},
},

View File

@ -23,8 +23,7 @@ func TestShortList(t *testing.T) {
Variable: &expr.ShortList{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},
@ -50,7 +49,6 @@ func TestShortListArrayIndex(t *testing.T) {
Variable: &expr.ShortList{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
@ -79,12 +77,10 @@ func TestShortListList(t *testing.T) {
Variable: &expr.ShortList{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},

View File

@ -32,20 +32,18 @@ var nodesToTest = []struct {
},
{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.String{Value: "key"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.String{Value: "key"},
Val: &scalar.Lnumber{Value: "1"},
},
[]string{"Key", "Val"},
map[string]interface{}{"ByRef": false},
map[string]interface{}{},
},
{
&expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.String{Value: "key"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.String{Value: "key"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -83,11 +81,10 @@ var nodesToTest = []struct {
},
{
&expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
[]string{"Variable"},
map[string]interface{}{"ByRef": false},
map[string]interface{}{},
},
{
&expr.Closure{
@ -252,6 +249,13 @@ var nodesToTest = []struct {
[]string{"Variable", "Property"},
map[string]interface{}{},
},
{
&expr.Reference{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
[]string{"Variable"},
map[string]interface{}{},
},
{
&expr.RequireOnce{
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},

View File

@ -7,7 +7,6 @@ import (
// AltForeach node
type AltForeach struct {
ByRef bool
Expr node.Node
Key node.Node
Variable node.Node
@ -15,9 +14,8 @@ type AltForeach struct {
}
// NewAltForeach node constructor
func NewAltForeach(Expr node.Node, Key node.Node, Variable node.Node, Stmt node.Node, ByRef bool) *AltForeach {
func NewAltForeach(Expr node.Node, Key node.Node, Variable node.Node, Stmt node.Node) *AltForeach {
return &AltForeach{
ByRef,
Expr,
Key,
Variable,
@ -27,9 +25,7 @@ func NewAltForeach(Expr node.Node, Key node.Node, Variable node.Node, Stmt node.
// Attributes returns node attributes as map
func (n *AltForeach) Attributes() map[string]interface{} {
return map[string]interface{}{
"ByRef": n.ByRef,
}
return nil
}
// Walk traverses nodes

View File

@ -7,7 +7,6 @@ import (
// Foreach node
type Foreach struct {
ByRef bool
Expr node.Node
Key node.Node
Variable node.Node
@ -15,9 +14,8 @@ type Foreach struct {
}
// NewForeach node constructor
func NewForeach(Expr node.Node, Key node.Node, Variable node.Node, Stmt node.Node, ByRef bool) *Foreach {
func NewForeach(Expr node.Node, Key node.Node, Variable node.Node, Stmt node.Node) *Foreach {
return &Foreach{
ByRef,
Expr,
Key,
Variable,
@ -27,9 +25,7 @@ func NewForeach(Expr node.Node, Key node.Node, Variable node.Node, Stmt node.Nod
// Attributes returns node attributes as map
func (n *Foreach) Attributes() map[string]interface{} {
return map[string]interface{}{
"ByRef": n.ByRef,
}
return nil
}
// Walk traverses nodes

View File

@ -140,10 +140,9 @@ func TestForeachWithRef(t *testing.T) {
expected := &node.Root{
Stmts: []node.Node{
&stmt.Foreach{
ByRef: true,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}}},
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
},
},
@ -166,14 +165,12 @@ func TestForeachWithList(t *testing.T) {
expected := &node.Root{
Stmts: []node.Node{
&stmt.Foreach{
ByRef: false,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
},
},
},

View File

@ -224,25 +224,23 @@ var nodesToTest = []struct {
},
{
&stmt.Foreach{
ByRef: true,
Expr: &stmt.Expression{},
Key: &expr.Variable{},
Variable: &expr.Variable{},
Stmt: &stmt.StmtList{},
},
[]string{"Expr", "Key", "Variable", "Stmt"},
map[string]interface{}{"ByRef": true},
map[string]interface{}{},
},
{
&stmt.AltForeach{
ByRef: true,
Expr: &stmt.Expression{},
Key: &expr.Variable{},
Variable: &expr.Variable{},
Stmt: &stmt.StmtList{},
},
[]string{"Expr", "Key", "Variable", "Stmt"},
map[string]interface{}{"ByRef": true},
map[string]interface{}{},
},
{
&stmt.Function{

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,6 @@ import (
node node.Node
token *scanner.Token
list []node.Node
foreachVariable foreachVariable
simpleIndirectReference simpleIndirectReference
ClassExtends *stmt.ClassExtends
@ -248,6 +247,8 @@ import (
%type <node> switch_case_list
%type <node> method_body
%type <node> foreach_statement for_statement while_statement
%type <node> foreach_variable foreach_optional_arg
%type <ClassExtends> extends_from
%type <ClassImplements> implements_list
%type <InterfaceExtends> interface_extends_list
@ -266,7 +267,6 @@ import (
%type <list> dynamic_class_name_variable_properties variable_properties
%type <simpleIndirectReference> simple_indirect_reference
%type <foreachVariable> foreach_variable foreach_optional_arg
%type <token> is_reference is_variadic
%%
@ -801,29 +801,25 @@ unticked_statement:
}
| T_FOREACH '(' variable T_AS foreach_variable foreach_optional_arg ')' foreach_statement
{
if $6.node == nil {
if $6 == nil {
switch n := $8.(type) {
case *stmt.Foreach :
n.Expr = $3
n.ByRef = $5.byRef
n.Variable = $5.node
n.Variable = $5
case *stmt.AltForeach :
n.Expr = $3
n.ByRef = $5.byRef
n.Variable = $5.node
n.Variable = $5
}
} else {
switch n := $8.(type) {
case *stmt.Foreach :
n.Expr = $3
n.Key = $5.node
n.ByRef = $6.byRef
n.Variable = $6.node
n.Key = $5
n.Variable = $6
case *stmt.AltForeach :
n.Expr = $3
n.Key = $5.node
n.ByRef = $6.byRef
n.Variable = $6.node
n.Key = $5
n.Variable = $6
}
}
@ -834,29 +830,25 @@ unticked_statement:
}
| T_FOREACH '(' expr_without_variable T_AS foreach_variable foreach_optional_arg ')' foreach_statement
{
if $6.node == nil {
if $6 == nil {
switch n := $8.(type) {
case *stmt.Foreach :
n.Expr = $3
n.ByRef = $5.byRef
n.Variable = $5.node
n.Variable = $5
case *stmt.AltForeach :
n.Expr = $3
n.ByRef = $5.byRef
n.Variable = $5.node
n.Variable = $5
}
} else {
switch n := $8.(type) {
case *stmt.Foreach :
n.Expr = $3
n.Key = $5.node
n.ByRef = $6.byRef
n.Variable = $6.node
n.Key = $5
n.Variable = $6
case *stmt.AltForeach :
n.Expr = $3
n.Key = $5.node
n.ByRef = $6.byRef
n.Variable = $6.node
n.Key = $5
n.Variable = $6
}
}
@ -1138,21 +1130,21 @@ interface_list:
foreach_optional_arg:
/* empty */
{ $$ = foreachVariable{nil, false} }
{ $$ = nil }
| T_DOUBLE_ARROW foreach_variable
{ $$ = $2 }
;
foreach_variable:
variable
{ $$ = foreachVariable{$1, false} }
{ $$ = $1 }
| '&' variable
{ $$ = foreachVariable{$2, true} }
{ $$ = expr.NewReference($2) }
| T_LIST '(' assignment_list ')'
{
list := expr.NewList($3)
yylex.(*Parser).positions.AddPosition(list, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4))
$$ = foreachVariable{list, false}
$$ = list
yylex.(*Parser).comments.AddComments(list, $1.Comments())
}
;
@ -1177,13 +1169,13 @@ for_statement:
foreach_statement:
statement
{
$$ = stmt.NewForeach(nil, nil, nil, $1, false)
$$ = stmt.NewForeach(nil, nil, nil, $1)
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition($1))
}
| ':' inner_statement_list T_ENDFOREACH ';'
{
stmtList := stmt.NewStmtList($2)
$$ = stmt.NewAltForeach(nil, nil, nil, stmtList, false)
$$ = stmt.NewAltForeach(nil, nil, nil, stmtList)
yylex.(*Parser).positions.AddPosition(stmtList, yylex.(*Parser).positionBuilder.NewNodeListPosition($2))
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4))
@ -2613,7 +2605,7 @@ lexical_var_list:
yylex.(*Parser).positions.AddPosition(variable, yylex.(*Parser).positionBuilder.NewTokenPosition($3))
yylex.(*Parser).comments.AddComments(variable, $3.Comments())
use := expr.NewClosureUse(variable, false)
use := expr.NewClosureUse(variable)
yylex.(*Parser).positions.AddPosition(use, yylex.(*Parser).positionBuilder.NewTokenPosition($3))
yylex.(*Parser).comments.AddComments(use, $3.Comments())
@ -2629,7 +2621,9 @@ lexical_var_list:
yylex.(*Parser).positions.AddPosition(variable, yylex.(*Parser).positionBuilder.NewTokenPosition($4))
yylex.(*Parser).comments.AddComments(variable, $3.Comments())
use := expr.NewClosureUse(variable, true)
reference := expr.NewReference(variable)
use := expr.NewClosureUse(reference)
yylex.(*Parser).positions.AddPosition(use, yylex.(*Parser).positionBuilder.NewTokensPosition($3, $4))
yylex.(*Parser).comments.AddComments(use, $3.Comments())
@ -2645,7 +2639,7 @@ lexical_var_list:
yylex.(*Parser).positions.AddPosition(variable, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
yylex.(*Parser).comments.AddComments(variable, $1.Comments())
use := expr.NewClosureUse(variable, false)
use := expr.NewClosureUse(variable)
yylex.(*Parser).positions.AddPosition(use, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
yylex.(*Parser).comments.AddComments(use, $1.Comments())
@ -2661,7 +2655,9 @@ lexical_var_list:
yylex.(*Parser).positions.AddPosition(variable, yylex.(*Parser).positionBuilder.NewTokenPosition($2))
yylex.(*Parser).comments.AddComments(variable, $1.Comments())
use := expr.NewClosureUse(variable, true)
reference := expr.NewReference(variable)
use := expr.NewClosureUse(reference)
yylex.(*Parser).positions.AddPosition(use, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $2))
yylex.(*Parser).comments.AddComments(use, $1.Comments())
@ -3307,7 +3303,7 @@ possible_comma:
non_empty_static_array_pair_list:
non_empty_static_array_pair_list ',' static_scalar_value T_DOUBLE_ARROW static_scalar_value
{
arrayItem := expr.NewArrayItem($3, $5, false)
arrayItem := expr.NewArrayItem($3, $5)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodesPosition($3, $5))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$3])
@ -3315,7 +3311,7 @@ non_empty_static_array_pair_list:
}
| non_empty_static_array_pair_list ',' static_scalar_value
{
arrayItem := expr.NewArrayItem(nil, $3, false)
arrayItem := expr.NewArrayItem(nil, $3)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodePosition($3))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$3])
@ -3323,7 +3319,7 @@ non_empty_static_array_pair_list:
}
| static_scalar_value T_DOUBLE_ARROW static_scalar_value
{
arrayItem := expr.NewArrayItem($1, $3, false)
arrayItem := expr.NewArrayItem($1, $3)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $3))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$1])
@ -3331,7 +3327,7 @@ non_empty_static_array_pair_list:
}
| static_scalar_value
{
arrayItem := expr.NewArrayItem(nil, $1, false)
arrayItem := expr.NewArrayItem(nil, $1)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodePosition($1))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$1])
@ -3689,7 +3685,7 @@ assignment_list:
assignment_list_element:
variable
{
$$ = expr.NewArrayItem(nil, $1, false)
$$ = expr.NewArrayItem(nil, $1)
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition($1))
yylex.(*Parser).comments.AddComments($$, yylex.(*Parser).comments[$1])
}
@ -3699,7 +3695,7 @@ assignment_list_element:
yylex.(*Parser).positions.AddPosition(item, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4))
yylex.(*Parser).comments.AddComments(item, $1.Comments())
$$ = expr.NewArrayItem(nil, item, false)
$$ = expr.NewArrayItem(nil, item)
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition(item))
yylex.(*Parser).comments.AddComments($$, yylex.(*Parser).comments[item])
}
@ -3718,7 +3714,7 @@ array_pair_list:
non_empty_array_pair_list:
non_empty_array_pair_list ',' expr T_DOUBLE_ARROW expr
{
arrayItem := expr.NewArrayItem($3, $5, false)
arrayItem := expr.NewArrayItem($3, $5)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodesPosition($3, $5))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$3])
@ -3726,7 +3722,7 @@ non_empty_array_pair_list:
}
| non_empty_array_pair_list ',' expr
{
arrayItem := expr.NewArrayItem(nil, $3, false)
arrayItem := expr.NewArrayItem(nil, $3)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodePosition($3))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$3])
@ -3734,7 +3730,7 @@ non_empty_array_pair_list:
}
| expr T_DOUBLE_ARROW expr
{
arrayItem := expr.NewArrayItem($1, $3, false)
arrayItem := expr.NewArrayItem($1, $3)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $3))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$1])
@ -3742,7 +3738,7 @@ non_empty_array_pair_list:
}
| expr
{
arrayItem := expr.NewArrayItem(nil, $1, false)
arrayItem := expr.NewArrayItem(nil, $1)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodePosition($1))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$1])
@ -3750,7 +3746,8 @@ non_empty_array_pair_list:
}
| non_empty_array_pair_list ',' expr T_DOUBLE_ARROW '&' w_variable
{
arrayItem := expr.NewArrayItem($3, $6, true)
reference := expr.NewReference($6)
arrayItem := expr.NewArrayItem($3, reference)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodesPosition($3, $6))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$3])
@ -3758,7 +3755,8 @@ non_empty_array_pair_list:
}
| non_empty_array_pair_list ',' '&' w_variable
{
arrayItem := expr.NewArrayItem(nil, $4, true)
reference := expr.NewReference($4)
arrayItem := expr.NewArrayItem(nil, reference)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewTokenNodePosition($3, $4))
yylex.(*Parser).comments.AddComments(arrayItem, $3.Comments())
@ -3766,7 +3764,8 @@ non_empty_array_pair_list:
}
| expr T_DOUBLE_ARROW '&' w_variable
{
arrayItem := expr.NewArrayItem($1, $4, true)
reference := expr.NewReference($4)
arrayItem := expr.NewArrayItem($1, reference)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $4))
yylex.(*Parser).comments.AddComments(arrayItem, yylex.(*Parser).comments[$1])
@ -3774,7 +3773,8 @@ non_empty_array_pair_list:
}
| '&' w_variable
{
arrayItem := expr.NewArrayItem(nil, $2, true)
reference := expr.NewReference($2)
arrayItem := expr.NewArrayItem(nil, reference)
yylex.(*Parser).positions.AddPosition(arrayItem, yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2))
yylex.(*Parser).comments.AddComments(arrayItem, $1.Comments())
@ -4014,11 +4014,6 @@ class_name_scalar:
%%
type foreachVariable struct {
node node.Node
byRef bool
}
type simpleIndirectReference struct {
all []*expr.Variable
last *expr.Variable

View File

@ -1065,21 +1065,20 @@ func TestPhp5(t *testing.T) {
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
},
&stmt.Foreach{
ByRef: true,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.Reference{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
},
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
},
&stmt.Foreach{
ByRef: false,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
},
},
},
@ -1905,8 +1904,7 @@ func TestPhp5(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -1915,13 +1913,11 @@ func TestPhp5(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: true,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
},
},
@ -1930,9 +1926,8 @@ func TestPhp5(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: true,
Key: &scalar.Lnumber{Value: "3"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Key: &scalar.Lnumber{Value: "3"},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
},
},
@ -1941,22 +1936,18 @@ func TestPhp5(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: true,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: true,
Key: &scalar.Lnumber{Value: "3"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Key: &scalar.Lnumber{Value: "3"},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
},
},
@ -2019,12 +2010,10 @@ func TestPhp5(t *testing.T) {
},
Uses: []node.Node{
&expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
},
&expr.ClosureUse{
ByRef: true,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
},
},
Stmts: []node.Node{},
@ -2049,11 +2038,9 @@ func TestPhp5(t *testing.T) {
},
Uses: []node.Node{
&expr.ClosureUse{
ByRef: true,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}},
},
&expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
},
},
@ -2286,12 +2273,10 @@ func TestPhp5(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
},
@ -2303,7 +2288,6 @@ func TestPhp5(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
@ -2318,12 +2302,10 @@ func TestPhp5(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},
@ -2450,8 +2432,7 @@ func TestPhp5(t *testing.T) {
Expr: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -2460,13 +2441,11 @@ func TestPhp5(t *testing.T) {
Expr: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: true,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
},
},
@ -3025,12 +3004,10 @@ func TestPhp5(t *testing.T) {
Variable: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "0"},
Val: &scalar.Lnumber{Value: "0"},
},
},
},
@ -3127,8 +3104,7 @@ func TestPhp5(t *testing.T) {
Variable: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -3578,13 +3554,11 @@ func TestPhp5(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "2"},
Val: &scalar.Lnumber{Value: "2"},
},
},
},
@ -3599,13 +3573,11 @@ func TestPhp5(t *testing.T) {
Variable: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "2"},
Val: &scalar.Lnumber{Value: "2"},
Key: &scalar.Lnumber{Value: "2"},
Val: &scalar.Lnumber{Value: "2"},
},
},
},

File diff suppressed because it is too large Load Diff

View File

@ -23,7 +23,6 @@ import (
node node.Node
token *scanner.Token
list []node.Node
foreachVariable foreachVariable
str string
ClassExtends *stmt.ClassExtends
@ -275,7 +274,7 @@ import (
%type <node> member_modifier
%type <node> use_type
%type <foreachVariable> foreach_variable
%type <node> foreach_variable
%type <list> encaps_list backticks_expr namespace_name catch_name_list catch_list class_const_list
@ -963,12 +962,10 @@ statement:
switch n := $7.(type) {
case *stmt.Foreach :
n.Expr = $3
n.ByRef = $5.byRef
n.Variable = $5.node
n.Variable = $5
case *stmt.AltForeach :
n.Expr = $3
n.ByRef = $5.byRef
n.Variable = $5.node
n.Variable = $5
}
$$ = $7
@ -988,13 +985,11 @@ statement:
case *stmt.Foreach :
n.Expr = $3
n.Key = $5
n.ByRef = $7.byRef
n.Variable = $7.node
n.Variable = $7
case *stmt.AltForeach :
n.Expr = $3
n.Key = $5
n.ByRef = $7.byRef
n.Variable = $7.node
n.Variable = $7
}
$$ = $9
@ -1339,41 +1334,41 @@ implements_list:
foreach_variable:
variable
{ $$ = foreachVariable{$1, false} }
{
$$ = $1
}
| '&' variable
{
$$ = foreachVariable{$2, true}
$$ = expr.NewReference($2)
// save position
yylex.(*Parser).positions.AddPosition($2, yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2))
// save comments
yylex.(*Parser).comments.AddFromToken($2, $1, comment.AmpersandToken)
yylex.(*Parser).comments.AddFromToken($$, $1, comment.AmpersandToken)
}
| T_LIST '(' array_pair_list ')'
{
list := expr.NewList($3)
$$ = foreachVariable{list, false}
$$ = expr.NewList($3)
// save position
yylex.(*Parser).positions.AddPosition(list, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4))
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4))
// save comments
yylex.(*Parser).comments.AddFromToken(list, $1, comment.ListToken)
yylex.(*Parser).comments.AddFromToken(list, $2, comment.OpenParenthesisToken)
yylex.(*Parser).comments.AddFromToken(list, $4, comment.CloseParenthesisToken)
yylex.(*Parser).comments.AddFromToken($$, $1, comment.ListToken)
yylex.(*Parser).comments.AddFromToken($$, $2, comment.OpenParenthesisToken)
yylex.(*Parser).comments.AddFromToken($$, $4, comment.CloseParenthesisToken)
}
| '[' array_pair_list ']'
{
list := expr.NewShortList($2)
$$ = foreachVariable{list, false}
$$ = expr.NewShortList($2)
// save position
yylex.(*Parser).positions.AddPosition(list, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $3))
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $3))
// save comments
yylex.(*Parser).comments.AddFromToken(list, $1, comment.OpenSquareBracket)
yylex.(*Parser).comments.AddFromToken(list, $3, comment.CloseSquareBracket)
yylex.(*Parser).comments.AddFromToken($$, $1, comment.OpenSquareBracket)
yylex.(*Parser).comments.AddFromToken($$, $3, comment.CloseSquareBracket)
}
;
@ -1404,7 +1399,7 @@ for_statement:
foreach_statement:
statement
{
$$ = stmt.NewForeach(nil, nil, nil, $1, false)
$$ = stmt.NewForeach(nil, nil, nil, $1)
// save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition($1))
@ -1412,7 +1407,7 @@ foreach_statement:
| ':' inner_statement_list T_ENDFOREACH ';'
{
stmtList := stmt.NewStmtList($2)
$$ = stmt.NewAltForeach(nil, nil, nil, stmtList, false)
$$ = stmt.NewAltForeach(nil, nil, nil, stmtList)
// save position
yylex.(*Parser).positions.AddPosition(stmtList, yylex.(*Parser).positionBuilder.NewNodeListPosition($2))
@ -3273,7 +3268,7 @@ lexical_var:
{
identifier := node.NewIdentifier(strings.TrimLeft($1.Value, "$"))
variable := expr.NewVariable(identifier)
$$ = expr.NewClosureUse(variable, false)
$$ = expr.NewClosureUse(variable)
// save position
yylex.(*Parser).positions.AddPosition(identifier, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
@ -3287,7 +3282,8 @@ lexical_var:
{
identifier := node.NewIdentifier(strings.TrimLeft($2.Value, "$"))
variable := expr.NewVariable(identifier)
$$ = expr.NewClosureUse(variable, true)
reference := expr.NewReference(variable)
$$ = expr.NewClosureUse(reference)
// save position
yylex.(*Parser).positions.AddPosition(identifier, yylex.(*Parser).positionBuilder.NewTokenPosition($2))
@ -3296,7 +3292,7 @@ lexical_var:
// save comments
yylex.(*Parser).comments.AddFromToken($$, $1, comment.AmpersandToken)
yylex.(*Parser).comments.AddFromToken(variable, $2, comment.VariableToken)
yylex.(*Parser).comments.AddFromToken(reference, $2, comment.VariableToken)
}
;
@ -3915,7 +3911,7 @@ non_empty_array_pair_list:
array_pair:
expr T_DOUBLE_ARROW expr
{
$$ = expr.NewArrayItem($1, $3, false)
$$ = expr.NewArrayItem($1, $3)
// save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $3))
@ -3925,37 +3921,39 @@ array_pair:
}
| expr
{
$$ = expr.NewArrayItem(nil, $1, false)
$$ = expr.NewArrayItem(nil, $1)
// save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition($1))
}
| expr T_DOUBLE_ARROW '&' variable
{
$$ = expr.NewArrayItem($1, $4, true)
reference := expr.NewReference($4)
$$ = expr.NewArrayItem($1, reference)
// save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $4))
// save comments
yylex.(*Parser).comments.AddFromToken($$, $2, comment.DoubleArrowToken)
yylex.(*Parser).comments.AddFromToken($$, $3, comment.AmpersandToken)
yylex.(*Parser).comments.AddFromToken(reference, $3, comment.AmpersandToken)
}
| '&' variable
{
$$ = expr.NewArrayItem(nil, $2, true)
reference := expr.NewReference($2)
$$ = expr.NewArrayItem(nil, reference)
// save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2))
// save comments
yylex.(*Parser).comments.AddFromToken($$, $1, comment.AmpersandToken)
yylex.(*Parser).comments.AddFromToken(reference, $1, comment.AmpersandToken)
}
| expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')'
{
// TODO: Cannot use list() as standalone expression
list := expr.NewList($5)
$$ = expr.NewArrayItem($1, list, false)
$$ = expr.NewArrayItem($1, list)
// save position
yylex.(*Parser).positions.AddPosition(list, yylex.(*Parser).positionBuilder.NewTokensPosition($3, $6))
@ -3971,7 +3969,7 @@ array_pair:
{
// TODO: Cannot use list() as standalone expression
list := expr.NewList($3)
$$ = expr.NewArrayItem(nil, list, false)
$$ = expr.NewArrayItem(nil, list)
// save position
yylex.(*Parser).positions.AddPosition(list, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4))
@ -4279,8 +4277,3 @@ isset_variable:
/////////////////////////////////////////////////////////////////////////
%%
type foreachVariable struct {
node node.Node
byRef bool
}

View File

@ -1155,35 +1155,32 @@ func TestPhp7(t *testing.T) {
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
},
&stmt.Foreach{
ByRef: true,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.Reference{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
},
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
},
&stmt.Foreach{
ByRef: false,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
},
},
},
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
},
&stmt.Foreach{
ByRef: false,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.ShortList{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
},
},
},
@ -2062,8 +2059,7 @@ func TestPhp7(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -2072,13 +2068,11 @@ func TestPhp7(t *testing.T) {
Expr: &expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: true,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
},
},
@ -2147,12 +2141,10 @@ func TestPhp7(t *testing.T) {
},
Uses: []node.Node{
&expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
},
&expr.ClosureUse{
ByRef: true,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
},
},
Stmts: []node.Node{},
@ -2339,8 +2331,7 @@ func TestPhp7(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},
@ -2352,7 +2343,6 @@ func TestPhp7(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
@ -2367,12 +2357,10 @@ func TestPhp7(t *testing.T) {
Variable: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},
@ -2478,8 +2466,7 @@ func TestPhp7(t *testing.T) {
Expr: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -2488,13 +2475,11 @@ func TestPhp7(t *testing.T) {
Expr: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
&expr.ArrayItem{
ByRef: true,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
},
},
},
@ -2504,8 +2489,7 @@ func TestPhp7(t *testing.T) {
Variable: &expr.ShortList{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},
@ -2517,7 +2501,6 @@ func TestPhp7(t *testing.T) {
Variable: &expr.ShortList{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
@ -2532,12 +2515,10 @@ func TestPhp7(t *testing.T) {
Variable: &expr.ShortList{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
},
@ -3133,8 +3114,7 @@ func TestPhp7(t *testing.T) {
Variable: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
},
},
},
@ -3169,8 +3149,7 @@ func TestPhp7(t *testing.T) {
Variable: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
},
},
},
@ -3227,18 +3206,15 @@ func TestPhp7(t *testing.T) {
Expr: &expr.ShortArray{
Items: []node.Node{
&expr.ArrayItem{
ByRef: true,
Key: &scalar.Lnumber{Value: "1"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &scalar.Lnumber{Value: "1"},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
},
&expr.ArrayItem{
ByRef: false,
Key: &scalar.Lnumber{Value: "2"},
Key: &scalar.Lnumber{Value: "2"},
Val: &expr.List{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
},

View File

@ -272,6 +272,8 @@ func (p *Printer) printNode(n node.Node) {
p.printExprPrint(n)
case *expr.PropertyFetch:
p.printExprPropertyFetch(n)
case *expr.Reference:
p.printExprReference(n)
case *expr.Require:
p.printExprRequire(n)
case *expr.RequireOnce:
@ -964,10 +966,6 @@ func (p *Printer) printExprArrayItem(n node.Node) {
io.WriteString(p.w, " => ")
}
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.Print(nn.Val)
}
@ -1008,11 +1006,6 @@ func (p *Printer) printExprClone(n node.Node) {
func (p *Printer) printExprClosureUse(n node.Node) {
nn := n.(*expr.ClosureUse)
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.Print(nn.Variable)
}
@ -1211,6 +1204,13 @@ func (p *Printer) printExprPropertyFetch(n node.Node) {
p.Print(nn.Property)
}
func (p *Printer) printExprReference(n node.Node) {
nn := n.(*expr.Reference)
io.WriteString(p.w, "&")
p.Print(nn.Variable)
}
func (p *Printer) printExprRequire(n node.Node) {
nn := n.(*expr.Require)
@ -1382,10 +1382,6 @@ func (p *Printer) printStmtAltForeach(n node.Node) {
io.WriteString(p.w, " => ")
}
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.Print(nn.Variable)
io.WriteString(p.w, ") :\n")
@ -1769,9 +1765,6 @@ func (p *Printer) printStmtForeach(n node.Node) {
io.WriteString(p.w, " => ")
}
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.Print(nn.Variable)
io.WriteString(p.w, ")")

View File

@ -1245,9 +1245,8 @@ func TestPrintExprArrayItemWithKey(t *testing.T) {
p := printer.NewPrinter(o, " ")
p.Print(&expr.ArrayItem{
ByRef: false,
Key: &scalar.String{Value: "'Hello'"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
Key: &scalar.String{Value: "'Hello'"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
})
expected := `'Hello' => $world`
@ -1263,8 +1262,7 @@ func TestPrintExprArrayItem(t *testing.T) {
p := printer.NewPrinter(o, " ")
p.Print(&expr.ArrayItem{
ByRef: true,
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "world"}}},
})
expected := `&$world`
@ -1282,18 +1280,15 @@ func TestPrintExprArray(t *testing.T) {
p.Print(&expr.Array{
Items: []node.Node{
&expr.ArrayItem{
ByRef: false,
Key: &scalar.String{Value: "'Hello'"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
Key: &scalar.String{Value: "'Hello'"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
},
&expr.ArrayItem{
ByRef: true,
Key: &scalar.Lnumber{Value: "2"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
Key: &scalar.Lnumber{Value: "2"},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}}},
},
&expr.ArrayItem{
ByRef: false,
Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
},
},
})
@ -1376,8 +1371,7 @@ func TestPrintExprClosureUse(t *testing.T) {
p := printer.NewPrinter(o, " ")
p.Print(&expr.ClosureUse{
ByRef: true,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}}},
})
expected := `&$var`
@ -1406,11 +1400,9 @@ func TestPrintExprClosure(t *testing.T) {
},
Uses: []node.Node{
&expr.ClosureUse{
ByRef: true,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
},
&expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
@ -1795,6 +1787,22 @@ func TestPrintPropertyFetch(t *testing.T) {
}
}
func TestPrintExprReference(t *testing.T) {
o := bytes.NewBufferString("")
p := printer.NewPrinter(o, " ")
p.Print(&expr.Reference{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "foo"}},
})
expected := `&$foo`
actual := o.String()
if expected != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
}
}
func TestPrintRequire(t *testing.T) {
o := bytes.NewBufferString("")
@ -1854,9 +1862,8 @@ func TestPrintExprShortArray(t *testing.T) {
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
},
&expr.ArrayItem{
ByRef: true,
Key: &scalar.Lnumber{Value: "2"},
Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
Key: &scalar.Lnumber{Value: "2"},
Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}}},
},
&expr.ArrayItem{
Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
@ -2200,10 +2207,9 @@ func TestPrintAltForeach(t *testing.T) {
p.Print(&stmt.Namespace{
Stmts: []node.Node{
&stmt.AltForeach{
ByRef: true,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "key"}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "val"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "val"}}},
Stmt: &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
@ -3141,10 +3147,9 @@ func TestPrintStmtForeachNop(t *testing.T) {
p := printer.NewPrinter(o, " ")
p.Print(&stmt.Foreach{
ByRef: true,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}}},
Stmt: &stmt.Nop{},
})