changing ClosureUse node purpose

Now ClosureUse is a container node for variable and reference nodes
This commit is contained in:
z7zmey 2018-05-25 09:38:44 +03:00
parent ec0ef26bd6
commit 6ccca996a8
13 changed files with 1225 additions and 1252 deletions

View File

@ -11,19 +11,19 @@ type Closure struct {
Static bool
PhpDocComment string
Params []node.Node
Uses []node.Node
ClosureUse *ClosureUse
ReturnType node.Node
Stmts []node.Node
}
// NewClosure node constructor
func NewClosure(Params []node.Node, Uses []node.Node, ReturnType node.Node, Stmts []node.Node, Static bool, ReturnsRef bool, PhpDocComment string) *Closure {
func NewClosure(Params []node.Node, ClosureUse *ClosureUse, ReturnType node.Node, Stmts []node.Node, Static bool, ReturnsRef bool, PhpDocComment string) *Closure {
return &Closure{
ReturnsRef,
Static,
PhpDocComment,
Params,
Uses,
ClosureUse,
ReturnType,
Stmts,
}
@ -54,13 +54,9 @@ func (n *Closure) Walk(v walker.Visitor) {
}
}
if n.Uses != nil {
vv := v.GetChildrenVisitor("Uses")
for _, nn := range n.Uses {
if nn != nil {
nn.Walk(vv)
}
}
if n.ClosureUse != nil {
vv := v.GetChildrenVisitor("ClosureUse")
n.ClosureUse.Walk(vv)
}
if n.ReturnType != nil {

View File

@ -7,13 +7,13 @@ import (
// ClosureUse node
type ClosureUse struct {
Variable node.Node
Uses []node.Node
}
// NewClosureUse node constructor
func NewClosureUse(Variable node.Node) *ClosureUse {
func NewClosureUse(Uses []node.Node) *ClosureUse {
return &ClosureUse{
Variable,
Uses,
}
}
@ -29,9 +29,13 @@ func (n *ClosureUse) Walk(v walker.Visitor) {
return
}
if n.Variable != nil {
vv := v.GetChildrenVisitor("Variable")
n.Variable.Walk(vv)
if n.Uses != nil {
vv := v.GetChildrenVisitor("Uses")
for _, nn := range n.Uses {
if nn != nil {
nn.Walk(vv)
}
}
}
v.LeaveNode(n)

View File

@ -24,7 +24,6 @@ func TestClosure(t *testing.T) {
ReturnsRef: false,
Static: false,
PhpDocComment: "",
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -64,12 +63,10 @@ func TestClosureUse(t *testing.T) {
Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
Uses: []node.Node{
&expr.ClosureUse{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
},
&expr.ClosureUse{
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
ClosureUse: &expr.ClosureUse{
Uses: []node.Node{
&expr.Variable{VarName: &node.Identifier{Value: "c"}},
&expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
},
},
Stmts: []node.Node{},
@ -111,12 +108,10 @@ func TestClosureUse2(t *testing.T) {
Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
Uses: []node.Node{
&expr.ClosureUse{
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}},
},
&expr.ClosureUse{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
ClosureUse: &expr.ClosureUse{
Uses: []node.Node{
&expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}},
&expr.Variable{VarName: &node.Identifier{Value: "d"}},
},
},
Stmts: []node.Node{},
@ -146,7 +141,6 @@ func TestClosureReturnType(t *testing.T) {
ReturnsRef: false,
Static: false,
PhpDocComment: "",
Uses: []node.Node{},
ReturnType: &name.Name{
Parts: []node.Node{&name.NamePart{Value: "void"}},
},

View File

@ -81,9 +81,11 @@ var nodesToTest = []struct {
},
{
&expr.ClosureUse{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}},
Uses: []node.Node{
&expr.Variable{VarName: &node.Identifier{Value: "a"}},
},
},
[]string{"Variable"},
[]string{"Uses"},
map[string]interface{}{},
},
{
@ -92,11 +94,11 @@ var nodesToTest = []struct {
Static: false,
PhpDocComment: "",
Params: []node.Node{&node.Parameter{}},
Uses: []node.Node{&expr.ClosureUse{}},
ClosureUse: &expr.ClosureUse{},
ReturnType: &name.Name{},
Stmts: []node.Node{&stmt.Nop{}},
},
[]string{"Params", "Uses", "ReturnType", "Stmts"},
[]string{"Params", "ClosureUse", "ReturnType", "Stmts"},
map[string]interface{}{"ReturnsRef": true, "Static": false, "PhpDocComment": ""},
},
{

View File

@ -298,7 +298,6 @@ func TestPhp7ParameterNode(t *testing.T) {
&stmt.Expression{
Expr: &expr.Closure{
Params: expectedParams,
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -306,7 +305,6 @@ func TestPhp7ParameterNode(t *testing.T) {
Expr: &expr.Closure{
Static: true,
Params: expectedParams,
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -368,7 +366,6 @@ func TestPhp5ParameterNode(t *testing.T) {
&stmt.Expression{
Expr: &expr.Closure{
Params: expectedParams,
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -376,7 +373,6 @@ func TestPhp5ParameterNode(t *testing.T) {
Expr: &expr.Closure{
Static: true,
Params: expectedParams,
Uses: []node.Node{},
Stmts: []node.Node{},
},
},

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,7 @@ import (
ClassExtends *stmt.ClassExtends
ClassImplements *stmt.ClassImplements
InterfaceExtends *stmt.InterfaceExtends
ClosureUse *expr.ClosureUse
}
%type <token> $unk
@ -252,10 +253,11 @@ import (
%type <ClassExtends> extends_from
%type <ClassImplements> implements_list
%type <InterfaceExtends> interface_extends_list
%type <ClosureUse> lexical_vars
%type <list> top_statement_list namespace_name use_declarations use_function_declarations use_const_declarations
%type <list> inner_statement_list global_var_list static_var_list encaps_list isset_variables non_empty_array_pair_list
%type <list> array_pair_list assignment_list lexical_var_list lexical_vars elseif_list new_elseif_list non_empty_for_expr
%type <list> array_pair_list assignment_list lexical_var_list elseif_list new_elseif_list non_empty_for_expr
%type <list> for_expr case_list echo_expr_list unset_variables declare_list catch_statement additional_catches
%type <list> non_empty_additional_catches parameter_list non_empty_parameter_list class_statement_list
%type <list> class_statement_list variable_modifiers method_modifiers class_variable_declaration
@ -2589,9 +2591,13 @@ function:
lexical_vars:
/* empty */
{ $$ = []node.Node{} }
{ $$ = nil }
| T_USE '(' lexical_var_list ')'
{ $$ = $3; }
{
$$ = expr.NewClosureUse($3)
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4))
}
;
lexical_var_list:
@ -2605,11 +2611,7 @@ lexical_var_list:
yylex.(*Parser).positions.AddPosition(variable, yylex.(*Parser).positionBuilder.NewTokenPosition($3))
yylex.(*Parser).comments.AddComments(variable, $3.Comments())
use := expr.NewClosureUse(variable)
yylex.(*Parser).positions.AddPosition(use, yylex.(*Parser).positionBuilder.NewTokenPosition($3))
yylex.(*Parser).comments.AddComments(use, $3.Comments())
$$ = append($1, use)
$$ = append($1, variable)
}
| lexical_var_list ',' '&' T_VARIABLE
{
@ -2623,11 +2625,7 @@ lexical_var_list:
reference := expr.NewReference(variable)
use := expr.NewClosureUse(reference)
yylex.(*Parser).positions.AddPosition(use, yylex.(*Parser).positionBuilder.NewTokensPosition($3, $4))
yylex.(*Parser).comments.AddComments(use, $3.Comments())
$$ = append($1, use)
$$ = append($1, reference)
}
| T_VARIABLE
{
@ -2639,11 +2637,7 @@ lexical_var_list:
yylex.(*Parser).positions.AddPosition(variable, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
yylex.(*Parser).comments.AddComments(variable, $1.Comments())
use := expr.NewClosureUse(variable)
yylex.(*Parser).positions.AddPosition(use, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
yylex.(*Parser).comments.AddComments(use, $1.Comments())
$$ = []node.Node{use}
$$ = []node.Node{variable}
}
| '&' T_VARIABLE
{
@ -2657,11 +2651,7 @@ lexical_var_list:
reference := expr.NewReference(variable)
use := expr.NewClosureUse(reference)
yylex.(*Parser).positions.AddPosition(use, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $2))
yylex.(*Parser).comments.AddComments(use, $1.Comments())
$$ = []node.Node{use}
$$ = []node.Node{reference}
}
;

View File

@ -523,7 +523,6 @@ func TestPhp5(t *testing.T) {
&stmt.Expression{
Expr: &expr.Closure{
Params: expectedParams,
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -531,7 +530,6 @@ func TestPhp5(t *testing.T) {
Expr: &expr.Closure{
Static: true,
Params: expectedParams,
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -1987,7 +1985,6 @@ func TestPhp5(t *testing.T) {
ReturnsRef: false,
Static: false,
PhpDocComment: "",
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -2008,12 +2005,10 @@ func TestPhp5(t *testing.T) {
Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
Uses: []node.Node{
&expr.ClosureUse{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
},
&expr.ClosureUse{
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
ClosureUse: &expr.ClosureUse{
Uses: []node.Node{
&expr.Variable{VarName: &node.Identifier{Value: "c"}},
&expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
},
},
Stmts: []node.Node{},
@ -2036,12 +2031,10 @@ func TestPhp5(t *testing.T) {
Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
Uses: []node.Node{
&expr.ClosureUse{
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}},
},
&expr.ClosureUse{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}},
ClosureUse: &expr.ClosureUse{
Uses: []node.Node{
&expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}}},
&expr.Variable{VarName: &node.Identifier{Value: "d"}},
},
},
Stmts: []node.Node{},
@ -2052,7 +2045,6 @@ func TestPhp5(t *testing.T) {
ReturnsRef: false,
Static: false,
PhpDocComment: "",
Uses: []node.Node{},
Stmts: []node.Node{},
},
},

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@ import (
ClassExtends *stmt.ClassExtends
ClassImplements *stmt.ClassImplements
InterfaceExtends *stmt.InterfaceExtends
ClosureUse *expr.ClosureUse
}
%type <token> $unk
@ -271,6 +272,7 @@ import (
%type <ClassExtends> extends_from
%type <ClassImplements> implements_list
%type <InterfaceExtends> interface_extends_list
%type <ClosureUse> lexical_vars
%type <node> member_modifier
%type <node> use_type
@ -281,7 +283,7 @@ import (
%type <list> const_list echo_expr_list for_exprs non_empty_for_exprs global_var_list
%type <list> unprefixed_use_declarations inline_use_declarations property_list static_var_list
%type <list> case_list trait_adaptation_list unset_variables
%type <list> use_declarations lexical_var_list lexical_vars isset_variables non_empty_array_pair_list
%type <list> use_declarations lexical_var_list isset_variables non_empty_array_pair_list
%type <list> array_pair_list non_empty_argument_list top_statement_list
%type <list> inner_statement_list parameter_list non_empty_parameter_list class_statement_list
%type <list> method_modifiers variable_modifiers
@ -3246,9 +3248,19 @@ returns_ref:
lexical_vars:
/* empty */
{ $$ = []node.Node{} }
{ $$ = nil }
| T_USE '(' lexical_var_list ')'
{ $$ = $3; }
{
$$ = expr.NewClosureUse($3)
// save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $4))
// save comments
yylex.(*Parser).comments.AddFromToken($$, $1, comment.UseToken)
yylex.(*Parser).comments.AddFromToken($$, $2, comment.OpenParenthesisToken)
yylex.(*Parser).comments.AddFromToken($$, $4, comment.CloseParenthesisToken)
}
;
lexical_var_list:
@ -3267,23 +3279,20 @@ lexical_var:
T_VARIABLE
{
identifier := node.NewIdentifier(strings.TrimLeft($1.Value, "$"))
variable := expr.NewVariable(identifier)
$$ = expr.NewClosureUse(variable)
$$ = expr.NewVariable(identifier)
// save position
yylex.(*Parser).positions.AddPosition(identifier, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
yylex.(*Parser).positions.AddPosition(variable, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
// save comments
yylex.(*Parser).comments.AddFromToken(variable, $1, comment.VariableToken)
yylex.(*Parser).comments.AddFromToken($$, $1, comment.VariableToken)
}
| '&' T_VARIABLE
{
identifier := node.NewIdentifier(strings.TrimLeft($2.Value, "$"))
variable := expr.NewVariable(identifier)
reference := expr.NewReference(variable)
$$ = expr.NewClosureUse(reference)
$$ = expr.NewReference(variable)
// save position
yylex.(*Parser).positions.AddPosition(identifier, yylex.(*Parser).positionBuilder.NewTokenPosition($2))
@ -3292,7 +3301,7 @@ lexical_var:
// save comments
yylex.(*Parser).comments.AddFromToken($$, $1, comment.AmpersandToken)
yylex.(*Parser).comments.AddFromToken(reference, $2, comment.VariableToken)
yylex.(*Parser).comments.AddFromToken(variable, $2, comment.VariableToken)
}
;

View File

@ -558,7 +558,6 @@ func TestPhp7(t *testing.T) {
&stmt.Expression{
Expr: &expr.Closure{
Params: expectedParams,
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -566,7 +565,6 @@ func TestPhp7(t *testing.T) {
Expr: &expr.Closure{
Static: true,
Params: expectedParams,
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -2118,7 +2116,6 @@ func TestPhp7(t *testing.T) {
ReturnsRef: false,
Static: false,
PhpDocComment: "",
Uses: []node.Node{},
Stmts: []node.Node{},
},
},
@ -2139,12 +2136,10 @@ func TestPhp7(t *testing.T) {
Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
Uses: []node.Node{
&expr.ClosureUse{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "c"}},
},
&expr.ClosureUse{
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
ClosureUse: &expr.ClosureUse{
Uses: []node.Node{
&expr.Variable{VarName: &node.Identifier{Value: "c"}},
&expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "d"}}},
},
},
Stmts: []node.Node{},
@ -2155,7 +2150,6 @@ func TestPhp7(t *testing.T) {
ReturnsRef: false,
Static: false,
PhpDocComment: "",
Uses: []node.Node{},
ReturnType: &name.Name{
Parts: []node.Node{&name.NamePart{Value: "void"}},
},

View File

@ -1006,7 +1006,10 @@ func (p *Printer) printExprClone(n node.Node) {
func (p *Printer) printExprClosureUse(n node.Node) {
nn := n.(*expr.ClosureUse)
p.Print(nn.Variable)
io.WriteString(p.w, "use (")
p.joinPrint(", ", nn.Uses)
io.WriteString(p.w, ")")
}
func (p *Printer) printExprClosure(n node.Node) {
@ -1026,10 +1029,9 @@ func (p *Printer) printExprClosure(n node.Node) {
p.joinPrint(", ", nn.Params)
io.WriteString(p.w, ")")
if nn.Uses != nil {
io.WriteString(p.w, " use (")
p.joinPrint(", ", nn.Uses)
io.WriteString(p.w, ")")
if nn.ClosureUse != nil {
io.WriteString(p.w, " ")
p.Print(nn.ClosureUse)
}
if nn.ReturnType != nil {

View File

@ -1371,10 +1371,13 @@ func TestPrintExprClosureUse(t *testing.T) {
p := printer.NewPrinter(o, " ")
p.Print(&expr.ClosureUse{
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}}},
Uses: []node.Node{
&expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "foo"}}},
&expr.Variable{VarName: &node.Identifier{Value: "bar"}},
},
})
expected := `&$var`
expected := `use (&$foo, $bar)`
actual := o.String()
if expected != actual {
@ -1398,12 +1401,10 @@ func TestPrintExprClosure(t *testing.T) {
Variable: &expr.Variable{VarName: &node.Identifier{Value: "var"}},
},
},
Uses: []node.Node{
&expr.ClosureUse{
Variable: &expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
},
&expr.ClosureUse{
Variable: &expr.Variable{VarName: &node.Identifier{Value: "b"}},
ClosureUse: &expr.ClosureUse{
Uses: []node.Node{
&expr.Reference{Variable: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
&expr.Variable{VarName: &node.Identifier{Value: "b"}},
},
},
ReturnType: &name.FullyQualified{Parts: []node.Node{&name.NamePart{Value: "Foo"}}},