refactoring: update ast structure of "Foreach" node

This commit is contained in:
Vadym Slizov
2020-12-26 19:38:45 +02:00
parent b85bae2ec1
commit 8bf1fa822d
12 changed files with 1263 additions and 1734 deletions

View File

@@ -574,6 +574,7 @@ type StmtForeach struct {
AsTkn *token.Token
Key Vertex
DoubleArrowTkn *token.Token
AmpersandTkn *token.Token
Var Vertex
CloseParenthesisTkn *token.Token
ColonTkn *token.Token

View File

@@ -552,6 +552,7 @@ func (v *Dumper) StmtForeach(n *ast.StmtForeach) {
v.dumpToken("AsTkn", n.AsTkn)
v.dumpVertex("Key", n.Key)
v.dumpToken("DoubleArrowTkn", n.DoubleArrowTkn)
v.dumpToken("AmpersandTkn", n.AmpersandTkn)
v.dumpVertex("Var", n.Var)
v.dumpToken("CloseParenthesisTkn", n.CloseParenthesisTkn)
v.dumpToken("ColonTkn", n.ColonTkn)

View File

@@ -557,6 +557,9 @@ func (f *formatter) StmtForeach(n *ast.StmtForeach) {
}
f.addFreeFloating(token.T_WHITESPACE, []byte(" "))
if n.AmpersandTkn != nil {
n.AmpersandTkn = f.newToken('&', []byte("&"))
}
n.Var.Accept(f)
n.CloseParenthesisTkn = f.newToken(')', []byte(")"))

View File

@@ -1372,6 +1372,44 @@ func TestFormatter_StmtForeach(t *testing.T) {
}
}
func TestFormatter_StmtForeach_Reference(t *testing.T) {
o := bytes.NewBufferString("")
n := &ast.StmtForeach{
Expr: &ast.ExprVariable{
VarName: &ast.Identifier{
Value: []byte("$foo"),
},
},
AmpersandTkn: &token.Token{},
Var: &ast.ExprVariable{
VarName: &ast.Identifier{
Value: []byte("$val"),
},
},
Stmt: &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.StmtNop{},
},
},
}
f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1)
n.Accept(f)
p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP)
n.Accept(p)
expected := `foreach($foo as &$val) {
;
}`
actual := o.String()
if expected != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
}
}
func TestFormatter_StmtForeach_Key(t *testing.T) {
o := bytes.NewBufferString("")

View File

@@ -356,6 +356,7 @@ func (p *printer) StmtForeach(n *ast.StmtForeach) {
p.printToken(n.AsTkn, []byte("as"))
p.printNode(n.Key)
p.printToken(n.DoubleArrowTkn, p.ifNode(n.Key, []byte("=>")))
p.printToken(n.AmpersandTkn, nil)
p.printNode(n.Var)
p.printToken(n.CloseParenthesisTkn, []byte(")"))
p.printToken(n.ColonTkn, nil)

View File

@@ -3799,6 +3799,39 @@ func TestPrinterPrintStmtForeach(t *testing.T) {
}
}
func TestPrinterPrintStmtForeach_Reference(t *testing.T) {
o := bytes.NewBufferString("")
p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP)
n := &ast.StmtForeach{
Expr: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$a")},
},
Key: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$k")},
},
AmpersandTkn: &token.Token{
Value: []byte("&"),
},
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$v")},
},
Stmt: &ast.StmtStmtList{
Stmts: []ast.Vertex{
&ast.StmtNop{},
},
},
}
n.Accept(p)
expected := `foreach($a as$k=>&$v){;}`
actual := o.String()
if expected != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
}
}
func TestPrinterPrintStmtFunction(t *testing.T) {
o := bytes.NewBufferString("")