pretty printer: printing alternative statements
This commit is contained in:
parent
c84c8b2106
commit
240efb20e5
@ -3,6 +3,8 @@ package printer
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/z7zmey/php-parser/node/stmt"
|
||||
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
"github.com/z7zmey/php-parser/node/expr"
|
||||
"github.com/z7zmey/php-parser/node/expr/assign"
|
||||
@ -27,6 +29,14 @@ func printComaSeparated(o io.Writer, nn []node.Node) {
|
||||
}
|
||||
}
|
||||
|
||||
func printNodes(o io.Writer, nn []node.Node) {
|
||||
// TODO: handle indentations
|
||||
for _, n := range nn {
|
||||
Print(o, n)
|
||||
io.WriteString(o, ";\n")
|
||||
}
|
||||
}
|
||||
|
||||
func getPrintFuncByNode(n node.Node) func(o io.Writer, n node.Node) {
|
||||
switch n.(type) {
|
||||
|
||||
@ -256,6 +266,29 @@ func getPrintFuncByNode(n node.Node) func(o io.Writer, n node.Node) {
|
||||
return printExprYieldFrom
|
||||
case *expr.Yield:
|
||||
return printExprYield
|
||||
|
||||
// stmt
|
||||
|
||||
case *stmt.AltElseIf:
|
||||
return printStmtAltElseIf
|
||||
case *stmt.AltElse:
|
||||
return printStmtAltElse
|
||||
case *stmt.AltFor:
|
||||
return printStmtAltFor
|
||||
case *stmt.AltForeach:
|
||||
return printStmtAltForeach
|
||||
case *stmt.AltIf:
|
||||
return printStmtAltIf
|
||||
case *stmt.AltSwitch:
|
||||
return printStmtAltSwitch
|
||||
case *stmt.AltWhile:
|
||||
return printStmtAltWhile
|
||||
case *stmt.Case:
|
||||
return printStmtCase
|
||||
case *stmt.StmtList:
|
||||
return printStmtStmtList
|
||||
case *stmt.Expression:
|
||||
return printStmtExpression
|
||||
}
|
||||
|
||||
panic("printer is missing for the node")
|
||||
@ -1132,3 +1165,131 @@ func printExprYield(o io.Writer, n node.Node) {
|
||||
|
||||
Print(o, nn.Value)
|
||||
}
|
||||
|
||||
// smtm
|
||||
|
||||
func printStmtAltElseIf(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.AltElseIf)
|
||||
|
||||
io.WriteString(o, "elseif (")
|
||||
Print(o, nn.Cond)
|
||||
io.WriteString(o, ") :\n")
|
||||
|
||||
Print(o, nn.Stmt)
|
||||
}
|
||||
|
||||
func printStmtAltElse(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.AltElse)
|
||||
|
||||
io.WriteString(o, "else :\n")
|
||||
|
||||
Print(o, nn.Stmt)
|
||||
}
|
||||
|
||||
func printStmtAltFor(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.AltFor)
|
||||
|
||||
io.WriteString(o, "for (")
|
||||
printComaSeparated(o, nn.Init)
|
||||
io.WriteString(o, "; ")
|
||||
printComaSeparated(o, nn.Cond)
|
||||
io.WriteString(o, "; ")
|
||||
printComaSeparated(o, nn.Loop)
|
||||
io.WriteString(o, ") :\n")
|
||||
|
||||
Print(o, nn.Stmt)
|
||||
|
||||
io.WriteString(o, "endfor;\n")
|
||||
}
|
||||
|
||||
func printStmtAltForeach(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.AltForeach)
|
||||
|
||||
io.WriteString(o, "foreach (")
|
||||
Print(o, nn.Expr)
|
||||
io.WriteString(o, " as ")
|
||||
|
||||
if nn.Key != nil {
|
||||
Print(o, nn.Key)
|
||||
io.WriteString(o, " => ")
|
||||
}
|
||||
|
||||
if nn.ByRef {
|
||||
io.WriteString(o, "&")
|
||||
}
|
||||
|
||||
Print(o, nn.Variable)
|
||||
|
||||
io.WriteString(o, ") :\n")
|
||||
|
||||
Print(o, nn.Stmt)
|
||||
|
||||
io.WriteString(o, "endforeach;\n")
|
||||
}
|
||||
|
||||
func printStmtAltIf(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.AltIf)
|
||||
|
||||
io.WriteString(o, "if (")
|
||||
Print(o, nn.Cond)
|
||||
io.WriteString(o, ") :\n")
|
||||
|
||||
Print(o, nn.Stmt)
|
||||
|
||||
for _, elseif := range nn.ElseIf {
|
||||
Print(o, elseif)
|
||||
}
|
||||
|
||||
if nn.Else != nil {
|
||||
Print(o, nn.Else)
|
||||
}
|
||||
|
||||
io.WriteString(o, "endif;\n")
|
||||
}
|
||||
|
||||
func printStmtAltSwitch(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.AltSwitch)
|
||||
|
||||
io.WriteString(o, "switch (")
|
||||
Print(o, nn.Cond)
|
||||
io.WriteString(o, ") :\n")
|
||||
|
||||
for _, c := range nn.Cases {
|
||||
Print(o, c)
|
||||
}
|
||||
|
||||
io.WriteString(o, "endswitch;\n")
|
||||
}
|
||||
|
||||
func printStmtAltWhile(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.AltWhile)
|
||||
|
||||
io.WriteString(o, "while (")
|
||||
Print(o, nn.Cond)
|
||||
io.WriteString(o, ") :\n")
|
||||
|
||||
Print(o, nn.Stmt)
|
||||
|
||||
io.WriteString(o, "endwhile;\n")
|
||||
}
|
||||
|
||||
func printStmtCase(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.Case)
|
||||
|
||||
io.WriteString(o, "case ")
|
||||
Print(o, nn.Cond)
|
||||
io.WriteString(o, ":\n")
|
||||
printNodes(o, nn.Stmts)
|
||||
}
|
||||
|
||||
func printStmtStmtList(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.StmtList)
|
||||
|
||||
printNodes(o, nn.Stmts)
|
||||
}
|
||||
|
||||
func printStmtExpression(o io.Writer, n node.Node) {
|
||||
nn := n.(*stmt.Expression)
|
||||
|
||||
Print(o, nn.Expr)
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"github.com/z7zmey/php-parser/node/expr/cast"
|
||||
"github.com/z7zmey/php-parser/node/name"
|
||||
"github.com/z7zmey/php-parser/node/scalar"
|
||||
"github.com/z7zmey/php-parser/node/stmt"
|
||||
"github.com/z7zmey/php-parser/printer"
|
||||
"github.com/z7zmey/php-parser/walker"
|
||||
)
|
||||
@ -1816,3 +1817,248 @@ func TestPrintYieldFull(t *testing.T) {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
// stmt
|
||||
|
||||
func TestPrintAltElseIf(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.AltElseIf{
|
||||
Cond: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
|
||||
Stmt: &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expected := "elseif ($a) :\n$b;\n"
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintAltElse(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.AltElse{
|
||||
Stmt: &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expected := "else :\n$b;\n"
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintAltFor(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.AltFor{
|
||||
Init: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
|
||||
},
|
||||
Cond: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
|
||||
},
|
||||
Loop: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "c"}}},
|
||||
},
|
||||
Stmt: &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expected := "for ($a; $b; $c) :\n$d;\nendfor;\n"
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintAltForeach(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &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"}},
|
||||
Stmt: &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expected := "foreach ($var as $key => &$val) :\n$d;\nendforeach;\n"
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintAltIf(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.AltIf{
|
||||
Cond: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
|
||||
Stmt: &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
|
||||
},
|
||||
},
|
||||
ElseIf: []node.Node{
|
||||
&stmt.AltElseIf{
|
||||
Cond: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
|
||||
Stmt: &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
&stmt.AltElseIf{
|
||||
Cond: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
|
||||
Stmt: &stmt.StmtList{},
|
||||
},
|
||||
},
|
||||
Else: &stmt.AltElse{
|
||||
Stmt: &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expected := `if ($a) :
|
||||
$d;
|
||||
elseif ($b) :
|
||||
$b;
|
||||
elseif ($c) :
|
||||
else :
|
||||
$b;
|
||||
endif;
|
||||
`
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintStmtAltSwitch(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.AltSwitch{
|
||||
Cond: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
|
||||
Cases: []node.Node{
|
||||
&stmt.Case{
|
||||
Cond: &scalar.String{Value: "a"},
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
|
||||
},
|
||||
},
|
||||
&stmt.Case{
|
||||
Cond: &scalar.String{Value: "b"},
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expected := `switch ($var) :
|
||||
case 'a':
|
||||
$a;
|
||||
case 'b':
|
||||
$b;
|
||||
endswitch;
|
||||
`
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintAltWhile(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.AltWhile{
|
||||
Cond: &stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
|
||||
Stmt: &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
expected := "while ($a) :\n$b;\nendwhile;\n"
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintStmtCase(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.Case{
|
||||
Cond: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
|
||||
},
|
||||
})
|
||||
|
||||
expected := "case $a:\n$a;\n"
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintStmtList(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.StmtList{
|
||||
Stmts: []node.Node{
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
|
||||
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "b"}}},
|
||||
},
|
||||
})
|
||||
|
||||
expected := "$a;\n$b;\n"
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrintExpression(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
|
||||
printer.Print(o, &stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}})
|
||||
|
||||
expected := "$a"
|
||||
actual := o.String()
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user