#50: nodes stmt.Exit and stmt.Die was merged

This commit is contained in:
z7zmey 2018-07-10 00:51:02 +03:00
parent a69e899f04
commit 18d6d59292
17 changed files with 605 additions and 572 deletions

4
.gitignore vendored
View File

@ -1,8 +1,8 @@
.vscode .vscode
php-parser php-parser
**/*.test
*example.php *example.php
cpu.pprof cpu.pprof
mem.pprof mem.pprof
php7.test
php5.test

View File

@ -1,61 +0,0 @@
package expr
import (
"github.com/z7zmey/php-parser/meta"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/position"
"github.com/z7zmey/php-parser/walker"
)
// Die node
type Die struct {
Meta []meta.Meta
Position *position.Position
Expr node.Node
}
// NewDie node constructor
func NewDie(Expr node.Node) *Die {
return &Die{
Expr: Expr,
}
}
// SetPosition sets node position
func (n *Die) SetPosition(p *position.Position) {
n.Position = p
}
// GetPosition returns node positions
func (n *Die) GetPosition() *position.Position {
return n.Position
}
func (n *Die) AddMeta(m []meta.Meta) {
n.Meta = append(n.Meta, m...)
}
func (n *Die) GetMeta() []meta.Meta {
return n.Meta
}
// Attributes returns node attributes as map
func (n *Die) Attributes() map[string]interface{} {
return nil
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Die) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Expr != nil {
v.EnterChildNode("Expr", n)
n.Expr.Walk(v)
v.LeaveChildNode("Expr", n)
}
v.LeaveNode(n)
}

View File

@ -10,6 +10,7 @@ import (
// Exit node // Exit node
type Exit struct { type Exit struct {
Meta []meta.Meta Meta []meta.Meta
Die bool
Position *position.Position Position *position.Position
Expr node.Node Expr node.Node
} }
@ -41,7 +42,9 @@ func (n *Exit) GetMeta() []meta.Meta {
// Attributes returns node attributes as map // Attributes returns node attributes as map
func (n *Exit) Attributes() map[string]interface{} { func (n *Exit) Attributes() map[string]interface{} {
return nil return map[string]interface{}{
"Die": n.Die,
}
} }
// Walk traverses nodes // Walk traverses nodes

View File

@ -32,6 +32,7 @@ func TestExit(t *testing.T) {
EndPos: 8, EndPos: 8,
}, },
Expr: &expr.Exit{ Expr: &expr.Exit{
Die: false,
Position: &position.Position{ Position: &position.Position{
StartLine: 1, StartLine: 1,
EndLine: 1, EndLine: 1,
@ -54,6 +55,48 @@ func TestExit(t *testing.T) {
assertEqual(t, expected, actual) assertEqual(t, expected, actual)
} }
func TestExitEmpty(t *testing.T) {
src := `<? exit();`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 10,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 10,
},
Expr: &expr.Exit{
Die: false,
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 9,
},
},
},
},
}
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)
}
func TestExitExpr(t *testing.T) { func TestExitExpr(t *testing.T) {
src := `<? exit($a);` src := `<? exit($a);`
@ -73,6 +116,7 @@ func TestExitExpr(t *testing.T) {
EndPos: 12, EndPos: 12,
}, },
Expr: &expr.Exit{ Expr: &expr.Exit{
Die: false,
Position: &position.Position{ Position: &position.Position{
StartLine: 1, StartLine: 1,
EndLine: 1, EndLine: 1,
@ -130,7 +174,8 @@ func TestDie(t *testing.T) {
StartPos: 4, StartPos: 4,
EndPos: 7, EndPos: 7,
}, },
Expr: &expr.Die{ Expr: &expr.Exit{
Die: true,
Position: &position.Position{ Position: &position.Position{
StartLine: 1, StartLine: 1,
EndLine: 1, EndLine: 1,
@ -153,6 +198,48 @@ func TestDie(t *testing.T) {
assertEqual(t, expected, actual) assertEqual(t, expected, actual)
} }
func TestDieEmpty(t *testing.T) {
src := `<? die();`
expected := &node.Root{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 9,
},
Stmts: []node.Node{
&stmt.Expression{
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 9,
},
Expr: &expr.Exit{
Die: true,
Position: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 4,
EndPos: 8,
},
},
},
},
}
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)
}
func TestDieExpr(t *testing.T) { func TestDieExpr(t *testing.T) {
src := `<? die($a);` src := `<? die($a);`
@ -171,7 +258,8 @@ func TestDieExpr(t *testing.T) {
StartPos: 4, StartPos: 4,
EndPos: 11, EndPos: 11,
}, },
Expr: &expr.Die{ Expr: &expr.Exit{
Die: true,
Position: &position.Position{ Position: &position.Position{
StartLine: 1, StartLine: 1,
EndLine: 1, EndLine: 1,

View File

@ -21,7 +21,6 @@ var nodes = []node.Node{
&expr.ClosureUse{}, &expr.ClosureUse{},
&expr.Closure{}, &expr.Closure{},
&expr.ConstFetch{}, &expr.ConstFetch{},
&expr.Die{},
&expr.Empty{}, &expr.Empty{},
&expr.ErrorSuppress{}, &expr.ErrorSuppress{},
&expr.Eval{}, &expr.Eval{},

View File

@ -128,17 +128,11 @@ var nodesToTest = []struct {
}, },
{ {
&expr.Exit{ &expr.Exit{
Die: true,
Expr: &expr.Variable{}, Expr: &expr.Variable{},
}, },
[]string{"Expr"}, []string{"Expr"},
map[string]interface{}{}, map[string]interface{}{"Die": true},
},
{
&expr.Die{
Expr: &expr.Variable{},
},
[]string{"Expr"},
map[string]interface{}{},
}, },
{ {
&expr.FunctionCall{ &expr.FunctionCall{

File diff suppressed because it is too large Load Diff

View File

@ -4026,23 +4026,22 @@ expr_without_variable:
} }
| T_EXIT exit_expr | T_EXIT exit_expr
{ {
if (strings.EqualFold($1.Value, "die")) { var e *expr.Exit;
$$ = expr.NewDie(nil)
if $2 != nil { if $2 != nil {
$$.(*expr.Die).Expr = $2.(*expr.Exit).Expr e = $2.(*expr.Exit)
}
} else { } else {
$$ = expr.NewExit(nil) e = expr.NewExit(nil)
if $2 != nil {
$$.(*expr.Exit).Expr = $2.(*expr.Exit).Expr
} }
$$ = e
if (strings.EqualFold($1.Value, "die")) {
e.Die = true
} }
// save position // save position
if $2 == nil { if $2 == nil {
$$.SetPosition(yylex.(*Parser).positionBuilder.NewTokenPosition($1)) $$.SetPosition(yylex.(*Parser).positionBuilder.NewTokenPosition($1))
} else if yylex.(*Parser).currentToken.Value == ")" {
$$.SetPosition(yylex.(*Parser).positionBuilder.NewTokensPosition($1, yylex.(*Parser).currentToken))
} else { } else {
$$.SetPosition(yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2)) $$.SetPosition(yylex.(*Parser).positionBuilder.NewTokenNodePosition($1, $2))
} }
@ -4696,7 +4695,11 @@ exit_expr:
$$ = expr.NewExit($1); $$ = expr.NewExit($1);
// save position // save position
if yylex.(*Parser).currentToken.Value == ")" {
$$.SetPosition(yylex.(*Parser).positionBuilder.NewTokenPosition(yylex.(*Parser).currentToken))
} else {
$$.SetPosition(yylex.(*Parser).positionBuilder.NewNodePosition($1)) $$.SetPosition(yylex.(*Parser).positionBuilder.NewNodePosition($1))
}
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL) yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
} }

View File

@ -9151,6 +9151,7 @@ func TestPhp5(t *testing.T) {
EndPos: 4137, EndPos: 4137,
}, },
Expr: &expr.Exit{ Expr: &expr.Exit{
Die: false,
Position: &position.Position{ Position: &position.Position{
StartLine: 191, StartLine: 191,
EndLine: 191, EndLine: 191,
@ -9167,6 +9168,7 @@ func TestPhp5(t *testing.T) {
EndPos: 4149, EndPos: 4149,
}, },
Expr: &expr.Exit{ Expr: &expr.Exit{
Die: false,
Position: &position.Position{ Position: &position.Position{
StartLine: 192, StartLine: 192,
EndLine: 192, EndLine: 192,
@ -9199,7 +9201,8 @@ func TestPhp5(t *testing.T) {
StartPos: 4153, StartPos: 4153,
EndPos: 4158, EndPos: 4158,
}, },
Expr: &expr.Die{ Expr: &expr.Exit{
Die: true,
Position: &position.Position{ Position: &position.Position{
StartLine: 193, StartLine: 193,
EndLine: 193, EndLine: 193,
@ -9215,7 +9218,8 @@ func TestPhp5(t *testing.T) {
StartPos: 4162, StartPos: 4162,
EndPos: 4169, EndPos: 4169,
}, },
Expr: &expr.Die{ Expr: &expr.Exit{
Die: true,
Position: &position.Position{ Position: &position.Position{
StartLine: 194, StartLine: 194,
EndLine: 194, EndLine: 194,

File diff suppressed because it is too large Load Diff

View File

@ -3802,16 +3802,17 @@ expr_without_variable:
} }
| T_EXIT exit_expr | T_EXIT exit_expr
{ {
if (strings.EqualFold($1.Value, "die")) { var e *expr.Exit;
$$ = expr.NewDie(nil)
if $2 != nil { if $2 != nil {
$$.(*expr.Die).Expr = $2.(*expr.Exit).Expr e = $2.(*expr.Exit)
}
} else { } else {
$$ = expr.NewExit(nil) e = expr.NewExit(nil)
if $2 != nil {
$$.(*expr.Exit).Expr = $2.(*expr.Exit).Expr
} }
$$ = e
if (strings.EqualFold($1.Value, "die")) {
e.Die = true
} }
// save position // save position
@ -4151,8 +4152,8 @@ exit_expr:
$$.SetPosition(yylex.(*Parser).positionBuilder.NewTokensPosition($1, $3)) $$.SetPosition(yylex.(*Parser).positionBuilder.NewTokensPosition($1, $3))
// save comments // save comments
addMeta($2, $1.Meta, meta.OpenParenthesisToken) addMeta($$, $1.Meta, meta.OpenParenthesisToken)
addMeta($2, $3.Meta, meta.CloseParenthesisToken) addMeta($$, $3.Meta, meta.CloseParenthesisToken)
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL) yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
} }

View File

@ -9650,6 +9650,7 @@ func TestPhp7(t *testing.T) {
EndPos: 4286, EndPos: 4286,
}, },
Expr: &expr.Exit{ Expr: &expr.Exit{
Die: false,
Position: &position.Position{ Position: &position.Position{
StartLine: 200, StartLine: 200,
EndLine: 200, EndLine: 200,
@ -9666,6 +9667,7 @@ func TestPhp7(t *testing.T) {
EndPos: 4298, EndPos: 4298,
}, },
Expr: &expr.Exit{ Expr: &expr.Exit{
Die: false,
Position: &position.Position{ Position: &position.Position{
StartLine: 201, StartLine: 201,
EndLine: 201, EndLine: 201,
@ -9698,7 +9700,8 @@ func TestPhp7(t *testing.T) {
StartPos: 4302, StartPos: 4302,
EndPos: 4305, EndPos: 4305,
}, },
Expr: &expr.Die{ Expr: &expr.Exit{
Die: true,
Position: &position.Position{ Position: &position.Position{
StartLine: 202, StartLine: 202,
EndLine: 202, EndLine: 202,
@ -9714,7 +9717,8 @@ func TestPhp7(t *testing.T) {
StartPos: 4309, StartPos: 4309,
EndPos: 4316, EndPos: 4316,
}, },
Expr: &expr.Die{ Expr: &expr.Exit{
Die: true,
Position: &position.Position{ Position: &position.Position{
StartLine: 203, StartLine: 203,
EndLine: 203, EndLine: 203,

View File

@ -234,8 +234,6 @@ func (p *PrettyPrinter) printNode(n node.Node) {
p.printExprClosure(n) p.printExprClosure(n)
case *expr.ConstFetch: case *expr.ConstFetch:
p.printExprConstFetch(n) p.printExprConstFetch(n)
case *expr.Die:
p.printExprDie(n)
case *expr.Empty: case *expr.Empty:
p.printExprEmpty(n) p.printExprEmpty(n)
case *expr.ErrorSuppress: case *expr.ErrorSuppress:
@ -1067,14 +1065,6 @@ func (p *PrettyPrinter) printExprConstFetch(n node.Node) {
p.Print(nn.Constant) p.Print(nn.Constant)
} }
func (p *PrettyPrinter) printExprDie(n node.Node) {
nn := n.(*expr.Die)
io.WriteString(p.w, "die(")
p.Print(nn.Expr)
io.WriteString(p.w, ")")
}
func (p *PrettyPrinter) printExprEmpty(n node.Node) { func (p *PrettyPrinter) printExprEmpty(n node.Node) {
nn := n.(*expr.Empty) nn := n.(*expr.Empty)
@ -1101,7 +1091,11 @@ func (p *PrettyPrinter) printExprEval(n node.Node) {
func (p *PrettyPrinter) printExprExit(n node.Node) { func (p *PrettyPrinter) printExprExit(n node.Node) {
nn := n.(*expr.Exit) nn := n.(*expr.Exit)
if nn.Die {
io.WriteString(p.w, "die(")
} else {
io.WriteString(p.w, "exit(") io.WriteString(p.w, "exit(")
}
p.Print(nn.Expr) p.Print(nn.Expr)
io.WriteString(p.w, ")") io.WriteString(p.w, ")")
} }

View File

@ -1443,20 +1443,6 @@ func TestPrintExprConstFetch(t *testing.T) {
} }
} }
func TestPrintDie(t *testing.T) {
o := bytes.NewBufferString("")
p := printer.NewPrettyPrinter(o, " ")
p.Print(&expr.Die{Expr: &expr.Variable{VarName: &node.Identifier{Value: "var"}}})
expected := `die($var)`
actual := o.String()
if expected != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
}
}
func TestPrintEmpty(t *testing.T) { func TestPrintEmpty(t *testing.T) {
o := bytes.NewBufferString("") o := bytes.NewBufferString("")
@ -1503,7 +1489,7 @@ func TestPrintExit(t *testing.T) {
o := bytes.NewBufferString("") o := bytes.NewBufferString("")
p := printer.NewPrettyPrinter(o, " ") p := printer.NewPrettyPrinter(o, " ")
p.Print(&expr.Exit{Expr: &expr.Variable{VarName: &node.Identifier{Value: "var"}}}) p.Print(&expr.Exit{Die: false, Expr: &expr.Variable{VarName: &node.Identifier{Value: "var"}}})
expected := `exit($var)` expected := `exit($var)`
actual := o.String() actual := o.String()
@ -1513,6 +1499,20 @@ func TestPrintExit(t *testing.T) {
} }
} }
func TestPrintDie(t *testing.T) {
o := bytes.NewBufferString("")
p := printer.NewPrettyPrinter(o, " ")
p.Print(&expr.Exit{Die: true, Expr: &expr.Variable{VarName: &node.Identifier{Value: "var"}}})
expected := `die($var)`
actual := o.String()
if expected != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
}
}
func TestPrintFunctionCall(t *testing.T) { func TestPrintFunctionCall(t *testing.T) {
o := bytes.NewBufferString("") o := bytes.NewBufferString("")

View File

@ -231,8 +231,6 @@ func (p *Printer) printNode(n node.Node) {
p.printExprClosure(n) p.printExprClosure(n)
case *expr.ConstFetch: case *expr.ConstFetch:
p.printExprConstFetch(n) p.printExprConstFetch(n)
case *expr.Die:
p.printExprDie(n)
case *expr.Empty: case *expr.Empty:
p.printExprEmpty(n) p.printExprEmpty(n)
case *expr.ErrorSuppress: case *expr.ErrorSuppress:
@ -1401,21 +1399,6 @@ func (p *Printer) printExprConstFetch(n node.Node) {
p.printMeta(nn, meta.NodeEnd) p.printMeta(nn, meta.NodeEnd)
} }
func (p *Printer) printExprDie(n node.Node) {
nn := n.(*expr.Die)
p.printMeta(nn, meta.NodeStart)
p.printMeta(nn, meta.ExitToken)
io.WriteString(p.w, "die")
p.printMeta(nn.Expr, meta.OpenParenthesisToken)
io.WriteString(p.w, "(")
p.Print(nn.Expr)
p.printMeta(nn.Expr, meta.CloseParenthesisToken)
io.WriteString(p.w, ")")
p.printMeta(nn, meta.NodeEnd)
}
func (p *Printer) printExprEmpty(n node.Node) { func (p *Printer) printExprEmpty(n node.Node) {
nn := n.(*expr.Empty) nn := n.(*expr.Empty)
p.printMeta(nn, meta.NodeStart) p.printMeta(nn, meta.NodeStart)
@ -1462,11 +1445,15 @@ func (p *Printer) printExprExit(n node.Node) {
p.printMeta(nn, meta.NodeStart) p.printMeta(nn, meta.NodeStart)
p.printMeta(nn, meta.ExitToken) p.printMeta(nn, meta.ExitToken)
if nn.Die {
io.WriteString(p.w, "die")
} else {
io.WriteString(p.w, "exit") io.WriteString(p.w, "exit")
p.printMeta(nn.Expr, meta.OpenParenthesisToken) }
p.printMeta(nn, meta.OpenParenthesisToken)
io.WriteString(p.w, "(") io.WriteString(p.w, "(")
p.Print(nn.Expr) p.Print(nn.Expr)
p.printMeta(nn.Expr, meta.CloseParenthesisToken) p.printMeta(nn, meta.CloseParenthesisToken)
io.WriteString(p.w, ")") io.WriteString(p.w, ")")
p.printMeta(nn, meta.NodeEnd) p.printMeta(nn, meta.NodeEnd)

View File

@ -317,7 +317,7 @@ func TestParseAndPrintYield(t *testing.T) {
} }
} }
func TestParseAndPrintAltIfExitDie(t *testing.T) { func TestParseAndPrintAltIf(t *testing.T) {
src := `<?php src := `<?php
if ( 1 ) : if ( 1 ) :
exit ( 1 ) ; exit ( 1 ) ;
@ -334,6 +334,21 @@ func TestParseAndPrintAltIfExitDie(t *testing.T) {
} }
} }
func TestParseAndPrintExitDie(t *testing.T) {
src := `<?php
exit ( ) ;
exit ( 1 );
die ( ) ;
die ( 1 );
`
actual := print(parse(src))
if src != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", src, actual)
}
}
func TestParseAndPrintAltFor(t *testing.T) { func TestParseAndPrintAltFor(t *testing.T) {
src := `<?php src := `<?php
for ( $a ; $b ; $c ) : for ( $a ; $b ; $c ) :

View File

@ -2102,40 +2102,6 @@ func TestPrinterPrintExprConstFetch(t *testing.T) {
} }
} }
func TestPrinterPrintDie(t *testing.T) {
o := bytes.NewBufferString("")
p := printer.NewPrinter(o)
p.Print(&expr.Die{
Meta: []meta.Meta{
&meta.WhiteSpace{
Value: " ",
TokenName: meta.ExitToken,
},
},
Expr: &expr.Variable{
Meta: []meta.Meta{
&meta.WhiteSpace{
Value: " ",
TokenName: meta.OpenParenthesisToken,
},
&meta.WhiteSpace{
Value: " ",
TokenName: meta.CloseParenthesisToken,
},
},
VarName: &node.Identifier{Value: "var"},
},
})
expected := ` die ($var )`
actual := o.String()
if expected != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
}
}
func TestPrinterPrintEmpty(t *testing.T) { func TestPrinterPrintEmpty(t *testing.T) {
o := bytes.NewBufferString("") o := bytes.NewBufferString("")
@ -2228,9 +2194,6 @@ func TestPrinterPrintExit(t *testing.T) {
Value: " ", Value: " ",
TokenName: meta.ExitToken, TokenName: meta.ExitToken,
}, },
},
Expr: &expr.Variable{
Meta: []meta.Meta{
&meta.WhiteSpace{ &meta.WhiteSpace{
Value: " ", Value: " ",
TokenName: meta.OpenParenthesisToken, TokenName: meta.OpenParenthesisToken,
@ -2240,6 +2203,8 @@ func TestPrinterPrintExit(t *testing.T) {
TokenName: meta.CloseParenthesisToken, TokenName: meta.CloseParenthesisToken,
}, },
}, },
Die: false,
Expr: &expr.Variable{
VarName: &node.Identifier{Value: "var"}, VarName: &node.Identifier{Value: "var"},
}, },
}) })
@ -2252,6 +2217,39 @@ func TestPrinterPrintExit(t *testing.T) {
} }
} }
func TestPrinterPrintDie(t *testing.T) {
o := bytes.NewBufferString("")
p := printer.NewPrinter(o)
p.Print(&expr.Exit{
Die: true,
Meta: []meta.Meta{
&meta.WhiteSpace{
Value: " ",
TokenName: meta.ExitToken,
},
&meta.WhiteSpace{
Value: " ",
TokenName: meta.OpenParenthesisToken,
},
&meta.WhiteSpace{
Value: " ",
TokenName: meta.CloseParenthesisToken,
},
},
Expr: &expr.Variable{
VarName: &node.Identifier{Value: "var"},
},
})
expected := ` die ($var )`
actual := o.String()
if expected != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual)
}
}
func TestPrinterPrintFunctionCall(t *testing.T) { func TestPrinterPrintFunctionCall(t *testing.T) {
o := bytes.NewBufferString("") o := bytes.NewBufferString("")