stmt visitor tests

This commit is contained in:
z7zmey 2018-02-06 19:11:47 +02:00
parent b06fd9887d
commit d7d17326b6
12 changed files with 523 additions and 36 deletions

View File

@ -9,7 +9,7 @@ build:
run: build run: build
./php-parser $(PHPFILE) ./php-parser $(PHPFILE)
test: build test:
go test ./... --cover go test ./... --cover
compile: ./php5/php5.go ./php7/php7.go ./scanner/scanner.go compile: ./php5/php5.go ./php7/php7.go ./scanner/scanner.go

View File

@ -71,7 +71,7 @@ func (n *AltIf) Walk(v walker.Visitor) {
} }
if n.Else != nil { if n.Else != nil {
vv := v.GetChildrenVisitor("else") vv := v.GetChildrenVisitor("Else")
n.Else.Walk(vv) n.Else.Walk(vv)
} }

View File

@ -31,15 +31,15 @@ func (n *Do) Walk(v walker.Visitor) {
return return
} }
if n.Cond != nil {
vv := v.GetChildrenVisitor("Cond")
n.Cond.Walk(vv)
}
if n.Stmt != nil { if n.Stmt != nil {
vv := v.GetChildrenVisitor("Stmt") vv := v.GetChildrenVisitor("Stmt")
n.Stmt.Walk(vv) n.Stmt.Walk(vv)
} }
if n.Cond != nil {
vv := v.GetChildrenVisitor("Cond")
n.Cond.Walk(vv)
}
v.LeaveNode(n) v.LeaveNode(n)
} }

View File

@ -8,15 +8,15 @@ import (
// GroupUse node // GroupUse node
type GroupUse struct { type GroupUse struct {
UseType node.Node UseType node.Node
pRefix node.Node Prefix node.Node
UseList []node.Node UseList []node.Node
} }
// NewGroupUse node constuctor // NewGroupUse node constuctor
func NewGroupUse(UseType node.Node, pRefix node.Node, UseList []node.Node) *GroupUse { func NewGroupUse(UseType node.Node, Prefix node.Node, UseList []node.Node) *GroupUse {
return &GroupUse{ return &GroupUse{
UseType, UseType,
pRefix, Prefix,
UseList, UseList,
} }
} }
@ -43,9 +43,9 @@ func (n *GroupUse) Walk(v walker.Visitor) {
n.UseType.Walk(vv) n.UseType.Walk(vv)
} }
if n.pRefix != nil { if n.Prefix != nil {
vv := v.GetChildrenVisitor("pRefix") vv := v.GetChildrenVisitor("Prefix")
n.pRefix.Walk(vv) n.Prefix.Walk(vv)
} }
if n.UseList != nil { if n.UseList != nil {

View File

@ -71,7 +71,7 @@ func (n *If) Walk(v walker.Visitor) {
} }
if n.Else != nil { if n.Else != nil {
vv := v.GetChildrenVisitor("else") vv := v.GetChildrenVisitor("Else")
n.Else.Walk(vv) n.Else.Walk(vv)
} }

View File

@ -2,23 +2,20 @@ package stmt
import ( import (
"github.com/z7zmey/php-parser/node" "github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/token"
"github.com/z7zmey/php-parser/walker" "github.com/z7zmey/php-parser/walker"
) )
// Switch node // Switch node
type Switch struct { type Switch struct {
token token.Token
Cond node.Node Cond node.Node
cases []node.Node Cases []node.Node
} }
// NewSwitch node constuctor // NewSwitch node constuctor
func NewSwitch(token token.Token, Cond node.Node, cases []node.Node) *Switch { func NewSwitch(Cond node.Node, Cases []node.Node) *Switch {
return &Switch{ return &Switch{
token,
Cond, Cond,
cases, Cases,
} }
} }
@ -39,9 +36,9 @@ func (n *Switch) Walk(v walker.Visitor) {
n.Cond.Walk(vv) n.Cond.Walk(vv)
} }
if n.cases != nil { if n.Cases != nil {
vv := v.GetChildrenVisitor("cases") vv := v.GetChildrenVisitor("Cases")
for _, nn := range n.cases { for _, nn := range n.Cases {
if nn != nil { if nn != nil {
nn.Walk(vv) nn.Walk(vv)
} }

View File

@ -2,21 +2,18 @@ package stmt
import ( import (
"github.com/z7zmey/php-parser/node" "github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/token"
"github.com/z7zmey/php-parser/walker" "github.com/z7zmey/php-parser/walker"
) )
// While node // While node
type While struct { type While struct {
Token token.Token
Cond node.Node Cond node.Node
Stmt node.Node Stmt node.Node
} }
// NewWhile node constuctor // NewWhile node constuctor
func NewWhile(Token token.Token, Cond node.Node, Stmt node.Node) *While { func NewWhile(Cond node.Node, Stmt node.Node) *While {
return &While{ return &While{
Token,
Cond, Cond,
Stmt, Stmt,
} }

493
node/stmt/t_visitor_test.go Normal file
View File

@ -0,0 +1,493 @@
package stmt_test
import (
"github.com/z7zmey/php-parser/node/expr"
"github.com/z7zmey/php-parser/node/stmt"
"reflect"
"testing"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/walker"
"github.com/kylelemons/godebug/pretty"
)
var nodesToTest = []struct {
node node.Node // node
expectedVisitedKeys []string // visited keys
expectedAttributes map[string]interface{}
}{
{
&stmt.AltIf{
Cond: &stmt.Expression{},
Stmt: &stmt.StmtList{},
ElseIf: []node.Node{&stmt.ElseIf{}},
Else: &stmt.Else{},
},
[]string{"Cond", "Stmt", "ElseIf", "Else"},
map[string]interface{}{},
},
{
&stmt.AltElse{
Stmt: &stmt.StmtList{},
},
[]string{"Stmt"},
map[string]interface{}{},
},
{
&stmt.AltElseIf{
Cond: &stmt.Expression{},
Stmt: &stmt.StmtList{},
},
[]string{"Cond", "Stmt"},
map[string]interface{}{},
},
{
&stmt.Break{
Expr: &stmt.Expression{},
},
[]string{"Expr"},
map[string]interface{}{},
},
{
&stmt.Case{
Cond: &stmt.Expression{},
Stmts: []node.Node{},
},
[]string{"Cond", "Stmts"},
map[string]interface{}{},
},
{
&stmt.Catch{
Types: []node.Node{},
Variable: &expr.Variable{},
Stmts: []node.Node{},
},
[]string{"Types", "Variable", "Stmts"},
map[string]interface{}{},
},
{
&stmt.ClassConstList{
Modifiers: []node.Node{},
Consts: []node.Node{},
},
[]string{"Modifiers", "Consts"},
map[string]interface{}{},
},
{
&stmt.ClassMethod{
ReturnsRef: true,
PhpDocComment: "/** */",
MethodName: &node.Identifier{},
Modifiers: []node.Node{},
Params: []node.Node{},
ReturnType: &node.Identifier{},
Stmts: []node.Node{},
},
[]string{"MethodName", "Modifiers", "Params", "ReturnType", "Stmts"},
map[string]interface{}{"ReturnsRef": true, "PhpDocComment": "/** */"},
},
{
&stmt.Class{
PhpDocComment: "/** */",
ClassName: &node.Identifier{},
Modifiers: []node.Node{},
Args: []node.Node{},
Extends: &node.Identifier{},
Implements: []node.Node{},
Stmts: []node.Node{},
},
[]string{"ClassName", "Modifiers", "Args", "Extends", "Implements", "Stmts"},
map[string]interface{}{"PhpDocComment": "/** */"},
},
{
&stmt.ConstList{
Consts: []node.Node{},
},
[]string{"Consts"},
map[string]interface{}{},
},
{
&stmt.Constant{
PhpDocComment: "/** */",
ConstantName: &node.Identifier{},
Expr: &stmt.Expression{},
},
[]string{"ConstantName", "Expr"},
map[string]interface{}{"PhpDocComment": "/** */"},
},
{
&stmt.Continue{
Expr: &stmt.Expression{},
},
[]string{"Expr"},
map[string]interface{}{},
},
{
&stmt.Declare{
Consts: []node.Node{},
Stmt: &stmt.StmtList{},
},
[]string{"Consts", "Stmt"},
map[string]interface{}{},
},
{
&stmt.Default{
Stmts: []node.Node{},
},
[]string{"Stmts"},
map[string]interface{}{},
},
{
&stmt.Do{
Stmt: &stmt.StmtList{},
Cond: &expr.Variable{},
},
[]string{"Stmt", "Cond"},
map[string]interface{}{},
},
{
&stmt.Do{
Stmt: &stmt.StmtList{},
Cond: &expr.Variable{},
},
[]string{"Stmt", "Cond"},
map[string]interface{}{},
},
{
&stmt.Echo{
Exprs: []node.Node{},
},
[]string{"Exprs"},
map[string]interface{}{},
},
{
&stmt.If{
Cond: &stmt.Expression{},
Stmt: &stmt.StmtList{},
ElseIf: []node.Node{&stmt.ElseIf{}},
Else: &stmt.Else{},
},
[]string{"Cond", "Stmt", "ElseIf", "Else"},
map[string]interface{}{},
},
{
&stmt.Else{
Stmt: &stmt.StmtList{},
},
[]string{"Stmt"},
map[string]interface{}{},
},
{
&stmt.ElseIf{
Cond: &stmt.Expression{},
Stmt: &stmt.StmtList{},
},
[]string{"Cond", "Stmt"},
map[string]interface{}{},
},
{
&stmt.Expression{
Expr: &stmt.Expression{},
},
[]string{"Expr"},
map[string]interface{}{},
},
{
&stmt.Finally{
Stmts: []node.Node{},
},
[]string{"Stmts"},
map[string]interface{}{},
},
{
&stmt.For{
Init: []node.Node{},
Cond: []node.Node{},
Loop: []node.Node{},
Stmt: &stmt.StmtList{},
},
[]string{"Init", "Cond", "Loop", "Stmt"},
map[string]interface{}{},
},
{
&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},
},
{
&stmt.Function{
ReturnsRef: true,
PhpDocComment: "/** */",
FunctionName: &node.Identifier{},
Params: []node.Node{},
ReturnType: &node.Identifier{},
Stmts: []node.Node{},
},
[]string{"FunctionName", "Params", "ReturnType", "Stmts"},
map[string]interface{}{"ReturnsRef": true, "PhpDocComment": "/** */"},
},
{
&stmt.Global{
Vars: []node.Node{},
},
[]string{"Vars"},
map[string]interface{}{},
},
{
&stmt.Goto{
Label: &node.Identifier{},
},
[]string{"Label"},
map[string]interface{}{},
},
{
&stmt.GroupUse{
UseType: &node.Identifier{},
Prefix: &node.Identifier{},
UseList: []node.Node{},
},
[]string{"UseType", "Prefix", "UseList"},
map[string]interface{}{},
},
{
&stmt.HaltCompiler{},
[]string{},
map[string]interface{}{},
},
{
&stmt.InlineHtml{
Value: "hello",
},
[]string{},
map[string]interface{}{"Value": "hello"},
},
{
&stmt.Interface{
PhpDocComment: "/** */",
InterfaceName: &node.Identifier{},
Extends: []node.Node{},
Stmts: []node.Node{},
},
[]string{"InterfaceName", "Extends", "Stmts"},
map[string]interface{}{"PhpDocComment": "/** */"},
},
{
&stmt.Label{
LabelName: &node.Identifier{},
},
[]string{"LabelName"},
map[string]interface{}{},
},
{
&stmt.Namespace{
NamespaceName: &node.Identifier{},
Stmts: []node.Node{},
},
[]string{"NamespaceName", "Stmts"},
map[string]interface{}{},
},
{
&stmt.Nop{},
[]string{},
map[string]interface{}{},
},
{
&stmt.PropertyList{
Modifiers: []node.Node{},
Properties: []node.Node{},
},
[]string{"Modifiers", "Properties"},
map[string]interface{}{},
},
{
&stmt.Property{
PhpDocComment: "/** */",
Variable: &expr.Variable{},
Expr: &stmt.Expression{},
},
[]string{"Variable", "Expr"},
map[string]interface{}{"PhpDocComment": "/** */"},
},
{
&stmt.Return{
Expr: &stmt.Expression{},
},
[]string{"Expr"},
map[string]interface{}{},
},
{
&stmt.StaticVar{
Variable: &expr.Variable{},
Expr: &stmt.Expression{},
},
[]string{"Variable", "Expr"},
map[string]interface{}{},
},
{
&stmt.Static{
Vars: []node.Node{},
},
[]string{"Vars"},
map[string]interface{}{},
},
{
&stmt.Switch{
Cond: &expr.Variable{},
Cases: []node.Node{},
},
[]string{"Cond", "Cases"},
map[string]interface{}{},
},
{
&stmt.Throw{
Expr: &stmt.Expression{},
},
[]string{"Expr"},
map[string]interface{}{},
},
{
&stmt.TraitMethodRef{
Trait: &node.Identifier{},
Method: &node.Identifier{},
},
[]string{"Trait", "Method"},
map[string]interface{}{},
},
{
&stmt.TraitUseAlias{
Ref: &node.Identifier{},
Modifier: &node.Identifier{},
Alias: &node.Identifier{},
},
[]string{"Ref", "Modifier", "Alias"},
map[string]interface{}{},
},
{
&stmt.TraitUsePrecedence{
Ref: &node.Identifier{},
Insteadof: &node.Identifier{},
},
[]string{"Ref", "Insteadof"},
map[string]interface{}{},
},
{
&stmt.TraitUse{
Traits: []node.Node{},
Adaptations: []node.Node{},
},
[]string{"Traits", "Adaptations"},
map[string]interface{}{},
},
{
&stmt.Trait{
PhpDocComment: "/** */",
TraitName: &node.Identifier{},
Stmts: []node.Node{},
},
[]string{"TraitName", "Stmts"},
map[string]interface{}{"PhpDocComment": "/** */"},
},
{
&stmt.Try{
Stmts: []node.Node{},
Catches: []node.Node{},
Finally: &stmt.Finally{},
},
[]string{"Stmts", "Catches", "Finally"},
map[string]interface{}{},
},
{
&stmt.Unset{
Vars: []node.Node{},
},
[]string{"Vars"},
map[string]interface{}{},
},
{
&stmt.UseList{
UseType: &node.Identifier{},
Uses: []node.Node{},
},
[]string{"UseType", "Uses"},
map[string]interface{}{},
},
{
&stmt.Use{
UseType: &node.Identifier{},
Use: &node.Identifier{},
Alias: &node.Identifier{},
},
[]string{"UseType", "Use", "Alias"},
map[string]interface{}{},
},
{
&stmt.While{
Cond: &expr.Variable{},
Stmt: &stmt.StmtList{},
},
[]string{"Cond", "Stmt"},
map[string]interface{}{},
},
}
type visitorMock struct {
visitChildren bool
visitedKeys []string
}
func (v *visitorMock) EnterNode(n walker.Walker) bool { return v.visitChildren }
func (v *visitorMock) GetChildrenVisitor(key string) walker.Visitor {
v.visitedKeys = append(v.visitedKeys, key)
return &visitorMock{v.visitChildren, nil}
}
func (v *visitorMock) LeaveNode(n walker.Walker) {}
func TestVisitorDisableChildren(t *testing.T) {
for _, tt := range nodesToTest {
v := &visitorMock{false, nil}
tt.node.Walk(v)
expected := []string{}
actual := v.visitedKeys
diff := pretty.Compare(expected, actual)
if diff != "" {
t.Errorf("%s diff: (-expected +actual)\n%s", reflect.TypeOf(tt.node), diff)
}
}
}
func TestVisitor(t *testing.T) {
for _, tt := range nodesToTest {
v := &visitorMock{true, nil}
tt.node.Walk(v)
expected := tt.expectedVisitedKeys
actual := v.visitedKeys
diff := pretty.Compare(expected, actual)
if diff != "" {
t.Errorf("%s diff: (-expected +actual)\n%s", reflect.TypeOf(tt.node), diff)
}
}
}
// test Attributes()
func TestNameAttributes(t *testing.T) {
for _, tt := range nodesToTest {
expected := tt.expectedAttributes
actual := tt.node.Attributes()
diff := pretty.Compare(expected, actual)
if diff != "" {
t.Errorf("%s diff: (-expected +actual)\n%s", reflect.TypeOf(tt.node), diff)
}
}
}

View File

@ -2692,7 +2692,7 @@ yydefault:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:605 //line php5/php5.y:605
{ {
yyVAL.node = stmt.NewWhile(yyDollar[1].token, yyDollar[2].node, yyDollar[3].node) yyVAL.node = stmt.NewWhile(yyDollar[2].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[3].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[3].node))
comments.AddComments(yyVAL.node, yyDollar[1].token.Comments()) comments.AddComments(yyVAL.node, yyDollar[1].token.Comments())
} }
@ -2716,7 +2716,7 @@ yydefault:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php5/php5.y:623 //line php5/php5.y:623
{ {
yyVAL.node = stmt.NewSwitch(yyDollar[1].token, yyDollar[2].node, yyDollar[3].nodesWithEndToken.nodes) yyVAL.node = stmt.NewSwitch(yyDollar[2].node, yyDollar[3].nodesWithEndToken.nodes)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].nodesWithEndToken.endToken)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].nodesWithEndToken.endToken))
comments.AddComments(yyVAL.node, yyDollar[1].token.Comments()) comments.AddComments(yyVAL.node, yyDollar[1].token.Comments())
} }

View File

@ -603,7 +603,7 @@ unticked_statement:
} }
| T_WHILE parenthesis_expr while_statement | T_WHILE parenthesis_expr while_statement
{ {
$$ = stmt.NewWhile($1, $2, $3) $$ = stmt.NewWhile($2, $3)
positions.AddPosition($$, positionBuilder.NewTokenNodePosition($1, $3)) positions.AddPosition($$, positionBuilder.NewTokenNodePosition($1, $3))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }
@ -621,7 +621,7 @@ unticked_statement:
} }
| T_SWITCH parenthesis_expr switch_case_list | T_SWITCH parenthesis_expr switch_case_list
{ {
$$ = stmt.NewSwitch($1, $2, $3.nodes) $$ = stmt.NewSwitch($2, $3.nodes)
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3.endToken)) positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3.endToken))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }

View File

@ -2880,7 +2880,7 @@ yydefault:
yyDollar = yyS[yypt-5 : yypt+1] yyDollar = yyS[yypt-5 : yypt+1]
//line php7/php7.y:525 //line php7/php7.y:525
{ {
yyVAL.node = stmt.NewWhile(yyDollar[1].token, yyDollar[3].node, yyDollar[5].node) yyVAL.node = stmt.NewWhile(yyDollar[3].node, yyDollar[5].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[5].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[5].node))
comments.AddComments(yyVAL.node, yyDollar[1].token.Comments()) comments.AddComments(yyVAL.node, yyDollar[1].token.Comments())
} }
@ -2904,7 +2904,7 @@ yydefault:
yyDollar = yyS[yypt-5 : yypt+1] yyDollar = yyS[yypt-5 : yypt+1]
//line php7/php7.y:543 //line php7/php7.y:543
{ {
yyVAL.node = stmt.NewSwitch(yyDollar[1].token, yyDollar[3].node, yyDollar[5].nodesWithEndToken.nodes) yyVAL.node = stmt.NewSwitch(yyDollar[3].node, yyDollar[5].nodesWithEndToken.nodes)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[5].nodesWithEndToken.endToken)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[5].nodesWithEndToken.endToken))
comments.AddComments(yyVAL.node, yyDollar[1].token.Comments()) comments.AddComments(yyVAL.node, yyDollar[1].token.Comments())
} }

View File

@ -523,7 +523,7 @@ statement:
| alt_if_stmt { $$ = $1; } | alt_if_stmt { $$ = $1; }
| T_WHILE '(' expr ')' while_statement | T_WHILE '(' expr ')' while_statement
{ {
$$ = stmt.NewWhile($1, $3, $5) $$ = stmt.NewWhile($3, $5)
positions.AddPosition($$, positionBuilder.NewTokenNodePosition($1, $5)) positions.AddPosition($$, positionBuilder.NewTokenNodePosition($1, $5))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }
@ -541,7 +541,7 @@ statement:
} }
| T_SWITCH '(' expr ')' switch_case_list | T_SWITCH '(' expr ')' switch_case_list
{ {
$$ = stmt.NewSwitch($1, $3, $5.nodes) $$ = stmt.NewSwitch($3, $5.nodes)
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $5.endToken)) positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $5.endToken))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }