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

View File

@ -7,23 +7,19 @@ import (
// ClosureUse node // ClosureUse node
type ClosureUse struct { type ClosureUse struct {
ByRef bool
Variable node.Node Variable node.Node
} }
// NewClosureUse node constructor // NewClosureUse node constructor
func NewClosureUse(Variable node.Node, ByRef bool) *ClosureUse { func NewClosureUse(Variable node.Node) *ClosureUse {
return &ClosureUse{ return &ClosureUse{
ByRef,
Variable, Variable,
} }
} }
// Attributes returns node attributes as map // Attributes returns node attributes as map
func (n *ClosureUse) Attributes() map[string]interface{} { func (n *ClosureUse) Attributes() map[string]interface{} {
return map[string]interface{}{ return nil
"ByRef": n.ByRef,
}
} }
// Walk traverses nodes // 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{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
}, },
}, },

View File

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

View File

@ -51,8 +51,7 @@ func TestList(t *testing.T) {
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{ Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
@ -117,12 +115,10 @@ func TestListList(t *testing.T) {
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.List{ Val: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
}, },
}, },

View File

@ -23,8 +23,7 @@ func TestShortList(t *testing.T) {
Variable: &expr.ShortList{ Variable: &expr.ShortList{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Variable: &expr.ShortList{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{ Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
@ -79,12 +77,10 @@ func TestShortListList(t *testing.T) {
Variable: &expr.ShortList{ Variable: &expr.ShortList{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.List{ Val: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ &expr.ArrayItem{
ByRef: false, Key: &scalar.String{Value: "key"},
Key: &scalar.String{Value: "key"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
[]string{"Key", "Val"}, []string{"Key", "Val"},
map[string]interface{}{"ByRef": false}, map[string]interface{}{},
}, },
{ {
&expr.Array{ &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.String{Value: "key"},
Key: &scalar.String{Value: "key"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
}, },
}, },
@ -83,11 +81,10 @@ var nodesToTest = []struct {
}, },
{ {
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
[]string{"Variable"}, []string{"Variable"},
map[string]interface{}{"ByRef": false}, map[string]interface{}{},
}, },
{ {
&expr.Closure{ &expr.Closure{
@ -252,6 +249,13 @@ var nodesToTest = []struct {
[]string{"Variable", "Property"}, []string{"Variable", "Property"},
map[string]interface{}{}, map[string]interface{}{},
}, },
{
&expr.Reference{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
[]string{"Variable"},
map[string]interface{}{},
},
{ {
&expr.RequireOnce{ &expr.RequireOnce{
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},

View File

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

View File

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

View File

@ -140,10 +140,9 @@ func TestForeachWithRef(t *testing.T) {
expected := &node.Root{ expected := &node.Root{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.Foreach{ &stmt.Foreach{
ByRef: true,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}}, 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{}}, Stmt: &stmt.StmtList{Stmts: []node.Node{}},
}, },
}, },
@ -166,14 +165,12 @@ func TestForeachWithList(t *testing.T) {
expected := &node.Root{ expected := &node.Root{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.Foreach{ &stmt.Foreach{
ByRef: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ &stmt.Foreach{
ByRef: true,
Expr: &stmt.Expression{}, Expr: &stmt.Expression{},
Key: &expr.Variable{}, Key: &expr.Variable{},
Variable: &expr.Variable{}, Variable: &expr.Variable{},
Stmt: &stmt.StmtList{}, Stmt: &stmt.StmtList{},
}, },
[]string{"Expr", "Key", "Variable", "Stmt"}, []string{"Expr", "Key", "Variable", "Stmt"},
map[string]interface{}{"ByRef": true}, map[string]interface{}{},
}, },
{ {
&stmt.AltForeach{ &stmt.AltForeach{
ByRef: true,
Expr: &stmt.Expression{}, Expr: &stmt.Expression{},
Key: &expr.Variable{}, Key: &expr.Variable{},
Variable: &expr.Variable{}, Variable: &expr.Variable{},
Stmt: &stmt.StmtList{}, Stmt: &stmt.StmtList{},
}, },
[]string{"Expr", "Key", "Variable", "Stmt"}, []string{"Expr", "Key", "Variable", "Stmt"},
map[string]interface{}{"ByRef": true}, map[string]interface{}{},
}, },
{ {
&stmt.Function{ &stmt.Function{

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1065,21 +1065,20 @@ func TestPhp5(t *testing.T) {
Stmt: &stmt.StmtList{Stmts: []node.Node{}}, Stmt: &stmt.StmtList{Stmts: []node.Node{}},
}, },
&stmt.Foreach{ &stmt.Foreach{
ByRef: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}}, Variable: &expr.Reference{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Stmt: &stmt.StmtList{Stmts: []node.Node{}}, },
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
}, },
&stmt.Foreach{ &stmt.Foreach{
ByRef: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
}, },
}, },
@ -1930,9 +1926,8 @@ func TestPhp5(t *testing.T) {
Expr: &expr.Array{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Key: &scalar.Lnumber{Value: "3"},
Key: &scalar.Lnumber{Value: "3"}, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
}, },
}, },
@ -1941,22 +1936,18 @@ func TestPhp5(t *testing.T) {
Expr: &expr.Array{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Key: &scalar.Lnumber{Value: "3"},
Key: &scalar.Lnumber{Value: "3"}, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
}, },
}, },
@ -2019,12 +2010,10 @@ func TestPhp5(t *testing.T) {
}, },
Uses: []node.Node{ Uses: []node.Node{
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
}, },
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: true, Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
}, },
}, },
Stmts: []node.Node{}, Stmts: []node.Node{},
@ -2049,11 +2038,9 @@ func TestPhp5(t *testing.T) {
}, },
Uses: []node.Node{ Uses: []node.Node{
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: true, Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
}, },
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
}, },
}, },
@ -2286,12 +2273,10 @@ func TestPhp5(t *testing.T) {
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
&expr.ArrayItem{ &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{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{ Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
@ -2318,12 +2302,10 @@ func TestPhp5(t *testing.T) {
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.List{ Val: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
}, },
}, },
@ -3025,12 +3004,10 @@ func TestPhp5(t *testing.T) {
Variable: &expr.Array{ Variable: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.ShortArray{ Val: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Variable: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &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{ Variable: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "2"},
Key: &scalar.Lnumber{Value: "2"}, Val: &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 node node.Node
token *scanner.Token token *scanner.Token
list []node.Node list []node.Node
foreachVariable foreachVariable
str string str string
ClassExtends *stmt.ClassExtends ClassExtends *stmt.ClassExtends
@ -275,7 +274,7 @@ import (
%type <node> member_modifier %type <node> member_modifier
%type <node> use_type %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 %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) { switch n := $7.(type) {
case *stmt.Foreach : case *stmt.Foreach :
n.Expr = $3 n.Expr = $3
n.ByRef = $5.byRef n.Variable = $5
n.Variable = $5.node
case *stmt.AltForeach : case *stmt.AltForeach :
n.Expr = $3 n.Expr = $3
n.ByRef = $5.byRef n.Variable = $5
n.Variable = $5.node
} }
$$ = $7 $$ = $7
@ -988,13 +985,11 @@ statement:
case *stmt.Foreach : case *stmt.Foreach :
n.Expr = $3 n.Expr = $3
n.Key = $5 n.Key = $5
n.ByRef = $7.byRef n.Variable = $7
n.Variable = $7.node
case *stmt.AltForeach : case *stmt.AltForeach :
n.Expr = $3 n.Expr = $3
n.Key = $5 n.Key = $5
n.ByRef = $7.byRef n.Variable = $7
n.Variable = $7.node
} }
$$ = $9 $$ = $9
@ -1339,41 +1334,41 @@ implements_list:
foreach_variable: foreach_variable:
variable variable
{ $$ = foreachVariable{$1, false} } {
$$ = $1
}
| '&' variable | '&' variable
{ {
$$ = foreachVariable{$2, true} $$ = expr.NewReference($2)
// save position // save position
yylex.(*Parser).positions.AddPosition($2, yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2)) yylex.(*Parser).positions.AddPosition($2, yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2))
// save comments // save comments
yylex.(*Parser).comments.AddFromToken($2, $1, comment.AmpersandToken) yylex.(*Parser).comments.AddFromToken($$, $1, comment.AmpersandToken)
} }
| T_LIST '(' array_pair_list ')' | T_LIST '(' array_pair_list ')'
{ {
list := expr.NewList($3) $$ = expr.NewList($3)
$$ = foreachVariable{list, false}
// save position // 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 // save comments
yylex.(*Parser).comments.AddFromToken(list, $1, comment.ListToken) yylex.(*Parser).comments.AddFromToken($$, $1, comment.ListToken)
yylex.(*Parser).comments.AddFromToken(list, $2, comment.OpenParenthesisToken) yylex.(*Parser).comments.AddFromToken($$, $2, comment.OpenParenthesisToken)
yylex.(*Parser).comments.AddFromToken(list, $4, comment.CloseParenthesisToken) yylex.(*Parser).comments.AddFromToken($$, $4, comment.CloseParenthesisToken)
} }
| '[' array_pair_list ']' | '[' array_pair_list ']'
{ {
list := expr.NewShortList($2) $$ = expr.NewShortList($2)
$$ = foreachVariable{list, false}
// save position // 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 // save comments
yylex.(*Parser).comments.AddFromToken(list, $1, comment.OpenSquareBracket) yylex.(*Parser).comments.AddFromToken($$, $1, comment.OpenSquareBracket)
yylex.(*Parser).comments.AddFromToken(list, $3, comment.CloseSquareBracket) yylex.(*Parser).comments.AddFromToken($$, $3, comment.CloseSquareBracket)
} }
; ;
@ -1404,7 +1399,7 @@ for_statement:
foreach_statement: foreach_statement:
statement statement
{ {
$$ = stmt.NewForeach(nil, nil, nil, $1, false) $$ = stmt.NewForeach(nil, nil, nil, $1)
// save position // save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition($1)) yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition($1))
@ -1412,7 +1407,7 @@ foreach_statement:
| ':' inner_statement_list T_ENDFOREACH ';' | ':' inner_statement_list T_ENDFOREACH ';'
{ {
stmtList := stmt.NewStmtList($2) stmtList := stmt.NewStmtList($2)
$$ = stmt.NewAltForeach(nil, nil, nil, stmtList, false) $$ = stmt.NewAltForeach(nil, nil, nil, stmtList)
// save position // save position
yylex.(*Parser).positions.AddPosition(stmtList, yylex.(*Parser).positionBuilder.NewNodeListPosition($2)) yylex.(*Parser).positions.AddPosition(stmtList, yylex.(*Parser).positionBuilder.NewNodeListPosition($2))
@ -3273,7 +3268,7 @@ lexical_var:
{ {
identifier := node.NewIdentifier(strings.TrimLeft($1.Value, "$")) identifier := node.NewIdentifier(strings.TrimLeft($1.Value, "$"))
variable := expr.NewVariable(identifier) variable := expr.NewVariable(identifier)
$$ = expr.NewClosureUse(variable, false) $$ = expr.NewClosureUse(variable)
// save position // save position
yylex.(*Parser).positions.AddPosition(identifier, yylex.(*Parser).positionBuilder.NewTokenPosition($1)) yylex.(*Parser).positions.AddPosition(identifier, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
@ -3287,7 +3282,8 @@ lexical_var:
{ {
identifier := node.NewIdentifier(strings.TrimLeft($2.Value, "$")) identifier := node.NewIdentifier(strings.TrimLeft($2.Value, "$"))
variable := expr.NewVariable(identifier) variable := expr.NewVariable(identifier)
$$ = expr.NewClosureUse(variable, true) reference := expr.NewReference(variable)
$$ = expr.NewClosureUse(reference)
// save position // save position
yylex.(*Parser).positions.AddPosition(identifier, yylex.(*Parser).positionBuilder.NewTokenPosition($2)) yylex.(*Parser).positions.AddPosition(identifier, yylex.(*Parser).positionBuilder.NewTokenPosition($2))
@ -3296,7 +3292,7 @@ lexical_var:
// save comments // save comments
yylex.(*Parser).comments.AddFromToken($$, $1, comment.AmpersandToken) 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: array_pair:
expr T_DOUBLE_ARROW expr expr T_DOUBLE_ARROW expr
{ {
$$ = expr.NewArrayItem($1, $3, false) $$ = expr.NewArrayItem($1, $3)
// save position // save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $3)) yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $3))
@ -3925,37 +3921,39 @@ array_pair:
} }
| expr | expr
{ {
$$ = expr.NewArrayItem(nil, $1, false) $$ = expr.NewArrayItem(nil, $1)
// save position // save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition($1)) yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodePosition($1))
} }
| expr T_DOUBLE_ARROW '&' variable | expr T_DOUBLE_ARROW '&' variable
{ {
$$ = expr.NewArrayItem($1, $4, true) reference := expr.NewReference($4)
$$ = expr.NewArrayItem($1, reference)
// save position // save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $4)) yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodesPosition($1, $4))
// save comments // save comments
yylex.(*Parser).comments.AddFromToken($$, $2, comment.DoubleArrowToken) yylex.(*Parser).comments.AddFromToken($$, $2, comment.DoubleArrowToken)
yylex.(*Parser).comments.AddFromToken($$, $3, comment.AmpersandToken) yylex.(*Parser).comments.AddFromToken(reference, $3, comment.AmpersandToken)
} }
| '&' variable | '&' variable
{ {
$$ = expr.NewArrayItem(nil, $2, true) reference := expr.NewReference($2)
$$ = expr.NewArrayItem(nil, reference)
// save position // save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2)) yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2))
// save comments // 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 ')' | expr T_DOUBLE_ARROW T_LIST '(' array_pair_list ')'
{ {
// TODO: Cannot use list() as standalone expression // TODO: Cannot use list() as standalone expression
list := expr.NewList($5) list := expr.NewList($5)
$$ = expr.NewArrayItem($1, list, false) $$ = expr.NewArrayItem($1, list)
// save position // save position
yylex.(*Parser).positions.AddPosition(list, yylex.(*Parser).positionBuilder.NewTokensPosition($3, $6)) yylex.(*Parser).positions.AddPosition(list, yylex.(*Parser).positionBuilder.NewTokensPosition($3, $6))
@ -3971,7 +3969,7 @@ array_pair:
{ {
// TODO: Cannot use list() as standalone expression // TODO: Cannot use list() as standalone expression
list := expr.NewList($3) list := expr.NewList($3)
$$ = expr.NewArrayItem(nil, list, false) $$ = expr.NewArrayItem(nil, list)
// save position // save position
yylex.(*Parser).positions.AddPosition(list, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4)) 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: &stmt.StmtList{Stmts: []node.Node{}},
}, },
&stmt.Foreach{ &stmt.Foreach{
ByRef: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}}, Variable: &expr.Reference{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "v"}},
Stmt: &stmt.StmtList{Stmts: []node.Node{}}, },
Stmt: &stmt.StmtList{Stmts: []node.Node{}},
}, },
&stmt.Foreach{ &stmt.Foreach{
ByRef: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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: &stmt.StmtList{Stmts: []node.Node{}},
}, },
&stmt.Foreach{ &stmt.Foreach{
ByRef: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}},
Variable: &expr.ShortList{ Variable: &expr.ShortList{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
}, },
}, },
@ -2147,12 +2141,10 @@ func TestPhp7(t *testing.T) {
}, },
Uses: []node.Node{ Uses: []node.Node{
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
}, },
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: true, Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
}, },
}, },
Stmts: []node.Node{}, Stmts: []node.Node{},
@ -2339,8 +2331,7 @@ func TestPhp7(t *testing.T) {
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{ Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
@ -2367,12 +2357,10 @@ func TestPhp7(t *testing.T) {
Variable: &expr.List{ Variable: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.List{ Val: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &scalar.Lnumber{Value: "1"},
Val: &scalar.Lnumber{Value: "1"},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
}, },
}, },
}, },
@ -2504,8 +2489,7 @@ func TestPhp7(t *testing.T) {
Variable: &expr.ShortList{ Variable: &expr.ShortList{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Variable: &expr.ShortList{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.ArrayDimFetch{ Val: &expr.ArrayDimFetch{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
@ -2532,12 +2515,10 @@ func TestPhp7(t *testing.T) {
Variable: &expr.ShortList{ Variable: &expr.ShortList{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false,
Val: &expr.List{ Val: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Variable: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Variable: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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{ Expr: &expr.ShortArray{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Key: &scalar.Lnumber{Value: "1"},
Key: &scalar.Lnumber{Value: "1"}, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.Lnumber{Value: "2"},
Key: &scalar.Lnumber{Value: "2"},
Val: &expr.List{ Val: &expr.List{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &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) p.printExprPrint(n)
case *expr.PropertyFetch: case *expr.PropertyFetch:
p.printExprPropertyFetch(n) p.printExprPropertyFetch(n)
case *expr.Reference:
p.printExprReference(n)
case *expr.Require: case *expr.Require:
p.printExprRequire(n) p.printExprRequire(n)
case *expr.RequireOnce: case *expr.RequireOnce:
@ -964,10 +966,6 @@ func (p *Printer) printExprArrayItem(n node.Node) {
io.WriteString(p.w, " => ") io.WriteString(p.w, " => ")
} }
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.Print(nn.Val) p.Print(nn.Val)
} }
@ -1008,11 +1006,6 @@ func (p *Printer) printExprClone(n node.Node) {
func (p *Printer) printExprClosureUse(n node.Node) { func (p *Printer) printExprClosureUse(n node.Node) {
nn := n.(*expr.ClosureUse) nn := n.(*expr.ClosureUse)
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.Print(nn.Variable) p.Print(nn.Variable)
} }
@ -1211,6 +1204,13 @@ func (p *Printer) printExprPropertyFetch(n node.Node) {
p.Print(nn.Property) 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) { func (p *Printer) printExprRequire(n node.Node) {
nn := n.(*expr.Require) nn := n.(*expr.Require)
@ -1382,10 +1382,6 @@ func (p *Printer) printStmtAltForeach(n node.Node) {
io.WriteString(p.w, " => ") io.WriteString(p.w, " => ")
} }
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.Print(nn.Variable) p.Print(nn.Variable)
io.WriteString(p.w, ") :\n") io.WriteString(p.w, ") :\n")
@ -1769,9 +1765,6 @@ func (p *Printer) printStmtForeach(n node.Node) {
io.WriteString(p.w, " => ") io.WriteString(p.w, " => ")
} }
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.Print(nn.Variable) p.Print(nn.Variable)
io.WriteString(p.w, ")") io.WriteString(p.w, ")")

View File

@ -1245,9 +1245,8 @@ func TestPrintExprArrayItemWithKey(t *testing.T) {
p := printer.NewPrinter(o, " ") p := printer.NewPrinter(o, " ")
p.Print(&expr.ArrayItem{ p.Print(&expr.ArrayItem{
ByRef: false, Key: &scalar.String{Value: "'Hello'"},
Key: &scalar.String{Value: "'Hello'"}, Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
}) })
expected := `'Hello' => $world` expected := `'Hello' => $world`
@ -1263,8 +1262,7 @@ func TestPrintExprArrayItem(t *testing.T) {
p := printer.NewPrinter(o, " ") p := printer.NewPrinter(o, " ")
p.Print(&expr.ArrayItem{ p.Print(&expr.ArrayItem{
ByRef: true, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "world"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
}) })
expected := `&$world` expected := `&$world`
@ -1282,18 +1280,15 @@ func TestPrintExprArray(t *testing.T) {
p.Print(&expr.Array{ p.Print(&expr.Array{
Items: []node.Node{ Items: []node.Node{
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: false, Key: &scalar.String{Value: "'Hello'"},
Key: &scalar.String{Value: "'Hello'"}, Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Key: &scalar.Lnumber{Value: "2"},
Key: &scalar.Lnumber{Value: "2"}, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
}, },
&expr.ArrayItem{ &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 := printer.NewPrinter(o, " ")
p.Print(&expr.ClosureUse{ p.Print(&expr.ClosureUse{
ByRef: true, Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
}) })
expected := `&$var` expected := `&$var`
@ -1406,11 +1400,9 @@ func TestPrintExprClosure(t *testing.T) {
}, },
Uses: []node.Node{ Uses: []node.Node{
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: true, Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
}, },
&expr.ClosureUse{ &expr.ClosureUse{
ByRef: false,
Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}}, 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) { func TestPrintRequire(t *testing.T) {
o := bytes.NewBufferString("") o := bytes.NewBufferString("")
@ -1854,9 +1862,8 @@ func TestPrintExprShortArray(t *testing.T) {
Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}}, Val: &expr.Variable{VarName: &node.Identifier{Value: "world"}},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
ByRef: true, Key: &scalar.Lnumber{Value: "2"},
Key: &scalar.Lnumber{Value: "2"}, Val: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}}},
Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
}, },
&expr.ArrayItem{ &expr.ArrayItem{
Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}}, Val: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
@ -2200,10 +2207,9 @@ func TestPrintAltForeach(t *testing.T) {
p.Print(&stmt.Namespace{ p.Print(&stmt.Namespace{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.AltForeach{ &stmt.AltForeach{
ByRef: true,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "var"}}, Expr: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "key"}}, 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{ Stmt: &stmt.StmtList{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "d"}}}, &stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
@ -3141,10 +3147,9 @@ func TestPrintStmtForeachNop(t *testing.T) {
p := printer.NewPrinter(o, " ") p := printer.NewPrinter(o, " ")
p.Print(&stmt.Foreach{ p.Print(&stmt.Foreach{
ByRef: true,
Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}, Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Key: &expr.Variable{VarName: &node.Identifier{Value: "k"}}, 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{}, Stmt: &stmt.Nop{},
}) })