remove nodesWithEndToken type

This commit is contained in:
z7zmey 2018-06-03 09:35:44 +03:00
parent 2abe1dfb84
commit a488f43496
17 changed files with 1393 additions and 1251 deletions

View File

@ -103,6 +103,7 @@ nodes := &stmt.StmtList{
&stmt.ClassMethod{ &stmt.ClassMethod{
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
MethodName: &node.Identifier{Value: "greet"}, MethodName: &node.Identifier{Value: "greet"},
Stmt: &stmt.StmtList{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.Echo{ &stmt.Echo{
Exprs: []node.Node{ Exprs: []node.Node{
@ -114,6 +115,7 @@ nodes := &stmt.StmtList{
}, },
}, },
}, },
},
} }
file := os.Stdout file := os.Stdout

View File

@ -13,11 +13,11 @@ type ClassMethod struct {
Modifiers []node.Node Modifiers []node.Node
Params []node.Node Params []node.Node
ReturnType node.Node ReturnType node.Node
Stmts []node.Node Stmt node.Node
} }
// NewClassMethod node constructor // NewClassMethod node constructor
func NewClassMethod(MethodName node.Node, Modifiers []node.Node, ReturnsRef bool, Params []node.Node, ReturnType node.Node, Stmts []node.Node, PhpDocComment string) *ClassMethod { func NewClassMethod(MethodName node.Node, Modifiers []node.Node, ReturnsRef bool, Params []node.Node, ReturnType node.Node, Stmt node.Node, PhpDocComment string) *ClassMethod {
return &ClassMethod{ return &ClassMethod{
ReturnsRef, ReturnsRef,
PhpDocComment, PhpDocComment,
@ -25,7 +25,7 @@ func NewClassMethod(MethodName node.Node, Modifiers []node.Node, ReturnsRef bool
Modifiers, Modifiers,
Params, Params,
ReturnType, ReturnType,
Stmts, Stmt,
} }
} }
@ -72,13 +72,9 @@ func (n *ClassMethod) Walk(v walker.Visitor) {
n.ReturnType.Walk(vv) n.ReturnType.Walk(vv)
} }
if n.Stmts != nil { if n.Stmt != nil {
vv := v.GetChildrenVisitor("Stmts") vv := v.GetChildrenVisitor("Stmt")
for _, nn := range n.Stmts { n.Stmt.Walk(vv)
if nn != nil {
nn.Walk(vv)
}
}
} }
v.LeaveNode(n) v.LeaveNode(n)

View File

@ -2,9 +2,10 @@ package stmt_test
import ( import (
"bytes" "bytes"
"github.com/z7zmey/php-parser/node/name"
"testing" "testing"
"github.com/z7zmey/php-parser/node/name"
"github.com/z7zmey/php-parser/node" "github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/stmt" "github.com/z7zmey/php-parser/node/stmt"
"github.com/z7zmey/php-parser/php5" "github.com/z7zmey/php-parser/php5"
@ -22,11 +23,13 @@ func TestSimpleClassMethod(t *testing.T) {
&stmt.ClassMethod{ &stmt.ClassMethod{
PhpDocComment: "", PhpDocComment: "",
MethodName: &node.Identifier{Value: "bar"}, MethodName: &node.Identifier{Value: "bar"},
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
}, },
},
} }
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php") php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
@ -56,8 +59,10 @@ func TestPrivateProtectedClassMethod(t *testing.T) {
&node.Identifier{Value: "final"}, &node.Identifier{Value: "final"},
&node.Identifier{Value: "private"}, &node.Identifier{Value: "private"},
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
},
&stmt.ClassMethod{ &stmt.ClassMethod{
PhpDocComment: "", PhpDocComment: "",
ReturnsRef: false, ReturnsRef: false,
@ -65,11 +70,13 @@ func TestPrivateProtectedClassMethod(t *testing.T) {
Modifiers: []node.Node{ Modifiers: []node.Node{
&node.Identifier{Value: "protected"}, &node.Identifier{Value: "protected"},
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
}, },
},
} }
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php") php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
@ -99,11 +106,13 @@ func TestPhp5ClassMethod(t *testing.T) {
&node.Identifier{Value: "public"}, &node.Identifier{Value: "public"},
&node.Identifier{Value: "static"}, &node.Identifier{Value: "static"},
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
}, },
},
} }
php5parser := php5.NewParser(bytes.NewBufferString(src), "test.php") php5parser := php5.NewParser(bytes.NewBufferString(src), "test.php")
@ -133,11 +142,13 @@ func TestPhp7ClassMethod(t *testing.T) {
&name.NamePart{Value: "void"}, &name.NamePart{Value: "void"},
}, },
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
}, },
},
} }
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php") php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
@ -163,6 +174,7 @@ func TestAbstractClassMethod(t *testing.T) {
&node.Identifier{Value: "abstract"}, &node.Identifier{Value: "abstract"},
&node.Identifier{Value: "public"}, &node.Identifier{Value: "public"},
}, },
Stmt: &stmt.Nop{},
}, },
}, },
}, },
@ -201,6 +213,7 @@ func TestPhp7AbstractClassMethod(t *testing.T) {
&name.NamePart{Value: "void"}, &name.NamePart{Value: "void"},
}, },
}, },
Stmt: &stmt.Nop{},
}, },
}, },
}, },

View File

@ -82,9 +82,9 @@ var nodesToTest = []struct {
Modifiers: []node.Node{&stmt.Expression{}}, Modifiers: []node.Node{&stmt.Expression{}},
Params: []node.Node{&stmt.Expression{}}, Params: []node.Node{&stmt.Expression{}},
ReturnType: &node.Identifier{}, ReturnType: &node.Identifier{},
Stmts: []node.Node{&stmt.Expression{}}, Stmt: &stmt.StmtList{},
}, },
[]string{"MethodName", "Modifiers", "Params", "ReturnType", "Stmts"}, []string{"MethodName", "Modifiers", "Params", "ReturnType", "Stmt"},
map[string]interface{}{"ReturnsRef": true, "PhpDocComment": "/** */"}, map[string]interface{}{"ReturnsRef": true, "PhpDocComment": "/** */"},
}, },
{ {

View File

@ -289,10 +289,12 @@ func TestPhp7ParameterNode(t *testing.T) {
MethodName: &node.Identifier{Value: "foo"}, MethodName: &node.Identifier{Value: "foo"},
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
Params: expectedParams, Params: expectedParams,
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Expression{ &stmt.Expression{
Expr: &expr.Closure{ Expr: &expr.Closure{
Params: expectedParams, Params: expectedParams,
@ -357,10 +359,12 @@ func TestPhp5ParameterNode(t *testing.T) {
MethodName: &node.Identifier{Value: "foo"}, MethodName: &node.Identifier{Value: "foo"},
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
Params: expectedParams, Params: expectedParams,
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Expression{ &stmt.Expression{
Expr: &expr.Closure{ Expr: &expr.Closure{
Params: expectedParams, Params: expectedParams,

View File

@ -174,6 +174,16 @@ func (b *PositionBuilder) NewNodeNodeListPosition(n node.Node, list []node.Node)
) )
} }
// NewNodeListNodePosition returns new Position
func (b *PositionBuilder) NewNodeListNodePosition(list []node.Node, n node.Node) *position.Position {
return position.NewPosition(
b.getListStartPos(list).startLine,
b.getNodeEndPos(n).endLine,
b.getListStartPos(list).startPos,
b.getNodeEndPos(n).endPos,
)
}
// NewOptionalListTokensPosition returns new Position // NewOptionalListTokensPosition returns new Position
func (b *PositionBuilder) NewOptionalListTokensPosition(list []node.Node, t *scanner.Token, endToken *scanner.Token) *position.Position { func (b *PositionBuilder) NewOptionalListTokensPosition(list []node.Node, t *scanner.Token, endToken *scanner.Token) *position.Position {
if list == nil { if list == nil {

View File

@ -259,6 +259,41 @@ func TestNewNodeNodeListPosition(t *testing.T) {
} }
} }
func TestNewNodeListNodePosition(t *testing.T) {
n1 := node.NewIdentifier("test node")
n2 := node.NewIdentifier("test node")
n3 := node.NewIdentifier("test node")
builder := parser.PositionBuilder{
Positions: &parser.Positions{
n1: &position.Position{
StartLine: 1,
EndLine: 1,
StartPos: 0,
EndPos: 8,
},
n2: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 9,
EndPos: 17,
},
n3: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 18,
EndPos: 26,
},
},
}
pos := builder.NewNodeListNodePosition([]node.Node{n1, n2}, n3)
if pos.String() != `Pos{Line: 1-3 Pos: 0-26}` {
t.Errorf("token value is not equal\n")
}
}
func TestNewOptionalListTokensPosition(t *testing.T) { func TestNewOptionalListTokensPosition(t *testing.T) {
builder := parser.PositionBuilder{} builder := parser.PositionBuilder{}

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,6 @@ import (
boolWithToken boolWithToken boolWithToken boolWithToken
list []node.Node list []node.Node
foreachVariable foreachVariable foreachVariable foreachVariable
nodesWithEndToken *nodesWithEndToken
simpleIndirectReference simpleIndirectReference simpleIndirectReference simpleIndirectReference
altSyntaxNode altSyntaxNode altSyntaxNode altSyntaxNode
} }
@ -245,6 +244,7 @@ import (
%type <node> ctor_arguments function_call_parameter_list %type <node> ctor_arguments function_call_parameter_list
%type <node> trait_adaptations %type <node> trait_adaptations
%type <node> switch_case_list %type <node> switch_case_list
%type <node> method_body
%type <list> top_statement_list namespace_name use_declarations use_function_declarations use_const_declarations %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> inner_statement_list global_var_list static_var_list encaps_list isset_variables non_empty_array_pair_list
@ -261,7 +261,6 @@ import (
%type <simpleIndirectReference> simple_indirect_reference %type <simpleIndirectReference> simple_indirect_reference
%type <foreachVariable> foreach_variable foreach_optional_arg %type <foreachVariable> foreach_variable foreach_optional_arg
%type <nodesWithEndToken> method_body
%type <boolWithToken> is_reference is_variadic %type <boolWithToken> is_reference is_variadic
%type <altSyntaxNode> while_statement for_statement foreach_statement %type <altSyntaxNode> while_statement for_statement foreach_statement
@ -1574,8 +1573,14 @@ class_statement:
yylex.(*Parser).positions.AddPosition(name, yylex.(*Parser).positionBuilder.NewTokenPosition($4)) yylex.(*Parser).positions.AddPosition(name, yylex.(*Parser).positionBuilder.NewTokenPosition($4))
yylex.(*Parser).comments.AddComments(name, $4.Comments()) yylex.(*Parser).comments.AddComments(name, $4.Comments())
$$ = stmt.NewClassMethod(name, $1, $3.value, $6, nil, $8.nodes, "") $$ = stmt.NewClassMethod(name, $1, $3.value, $6, nil, $8, "")
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewOptionalListTokensPosition($1, $2, $8.endToken))
if $1 == nil {
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokenNodePosition($2, $8))
} else {
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodeListNodePosition($1, $8))
}
yylex.(*Parser).comments.AddComments($$, yylex.(*Parser).listGetFirstNodeComments($1)) yylex.(*Parser).comments.AddComments($$, yylex.(*Parser).listGetFirstNodeComments($1))
} }
; ;
@ -1712,9 +1717,17 @@ trait_modifiers:
method_body: method_body:
';' /* abstract method */ ';' /* abstract method */
{ $$ = &nodesWithEndToken{nil, $1} } {
$$ = stmt.NewNop()
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
}
| '{' inner_statement_list '}' | '{' inner_statement_list '}'
{ $$ = &nodesWithEndToken{$2, $3} } {
$$ = stmt.NewStmtList($2)
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $3))
}
; ;
variable_modifiers: variable_modifiers:
@ -3926,11 +3939,6 @@ type foreachVariable struct {
byRef bool byRef bool
} }
type nodesWithEndToken struct {
nodes []node.Node
endToken *scanner.Token
}
type boolWithToken struct { type boolWithToken struct {
value bool value bool
token *scanner.Token token *scanner.Token

View File

@ -514,10 +514,12 @@ func TestPhp5(t *testing.T) {
MethodName: &node.Identifier{Value: "foo"}, MethodName: &node.Identifier{Value: "foo"},
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
Params: expectedParams, Params: expectedParams,
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Expression{ &stmt.Expression{
Expr: &expr.Closure{ Expr: &expr.Closure{
Params: expectedParams, Params: expectedParams,
@ -776,10 +778,12 @@ func TestPhp5(t *testing.T) {
&stmt.ClassMethod{ &stmt.ClassMethod{
PhpDocComment: "", PhpDocComment: "",
MethodName: &node.Identifier{Value: "bar"}, MethodName: &node.Identifier{Value: "bar"},
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Class{ &stmt.Class{
ClassName: &node.Identifier{Value: "foo"}, ClassName: &node.Identifier{Value: "foo"},
Stmts: []node.Node{ Stmts: []node.Node{
@ -791,10 +795,12 @@ func TestPhp5(t *testing.T) {
&node.Identifier{Value: "public"}, &node.Identifier{Value: "public"},
&node.Identifier{Value: "static"}, &node.Identifier{Value: "static"},
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Class{ &stmt.Class{
ClassName: &node.Identifier{Value: "foo"}, ClassName: &node.Identifier{Value: "foo"},
Stmts: []node.Node{ Stmts: []node.Node{
@ -806,8 +812,10 @@ func TestPhp5(t *testing.T) {
&node.Identifier{Value: "final"}, &node.Identifier{Value: "final"},
&node.Identifier{Value: "private"}, &node.Identifier{Value: "private"},
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
},
&stmt.ClassMethod{ &stmt.ClassMethod{
PhpDocComment: "", PhpDocComment: "",
ReturnsRef: false, ReturnsRef: false,
@ -815,10 +823,12 @@ func TestPhp5(t *testing.T) {
Modifiers: []node.Node{ Modifiers: []node.Node{
&node.Identifier{Value: "protected"}, &node.Identifier{Value: "protected"},
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Class{ &stmt.Class{
ClassName: &node.Identifier{Value: "foo"}, ClassName: &node.Identifier{Value: "foo"},
Modifiers: []node.Node{ Modifiers: []node.Node{
@ -833,6 +843,7 @@ func TestPhp5(t *testing.T) {
&node.Identifier{Value: "abstract"}, &node.Identifier{Value: "abstract"},
&node.Identifier{Value: "public"}, &node.Identifier{Value: "public"},
}, },
Stmt: &stmt.Nop{},
}, },
}, },
}, },

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,6 @@ import (
boolWithToken boolWithToken boolWithToken boolWithToken
list []node.Node list []node.Node
foreachVariable foreachVariable foreachVariable foreachVariable
nodesWithEndToken *nodesWithEndToken
str string str string
altSyntaxNode altSyntaxNode altSyntaxNode altSyntaxNode
} }
@ -266,12 +265,12 @@ import (
%type <node> argument_list ctor_arguments %type <node> argument_list ctor_arguments
%type <node> trait_adaptations %type <node> trait_adaptations
%type <node> switch_case_list %type <node> switch_case_list
%type <node> method_body
%type <node> member_modifier %type <node> member_modifier
%type <node> use_type %type <node> use_type
%type <foreachVariable> foreach_variable %type <foreachVariable> foreach_variable
%type <nodesWithEndToken> method_body
%type <list> encaps_list backticks_expr namespace_name catch_name_list catch_list class_const_list %type <list> encaps_list backticks_expr namespace_name catch_name_list catch_list class_const_list
%type <list> const_list echo_expr_list for_exprs non_empty_for_exprs global_var_list %type <list> const_list echo_expr_list for_exprs non_empty_for_exprs global_var_list
@ -1945,11 +1944,15 @@ class_statement:
| method_modifiers T_FUNCTION returns_ref identifier backup_doc_comment '(' parameter_list ')' return_type method_body | method_modifiers T_FUNCTION returns_ref identifier backup_doc_comment '(' parameter_list ')' return_type method_body
{ {
name := node.NewIdentifier($4.Value) name := node.NewIdentifier($4.Value)
$$ = stmt.NewClassMethod(name, $1, $3.value, $7, $9, $10.nodes, $5) $$ = stmt.NewClassMethod(name, $1, $3.value, $7, $9, $10, $5)
// save position // save position
yylex.(*Parser).positions.AddPosition(name, yylex.(*Parser).positionBuilder.NewTokenPosition($4)) yylex.(*Parser).positions.AddPosition(name, yylex.(*Parser).positionBuilder.NewTokenPosition($4))
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewOptionalListTokensPosition($1, $2, $10.endToken)) if $1 == nil {
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokenNodePosition($2, $10))
} else {
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewNodeListNodePosition($1, $10))
}
// save comments // save comments
yylex.(*Parser).comments.AddFromToken($$, $2, comment.FunctionToken) yylex.(*Parser).comments.AddFromToken($$, $2, comment.FunctionToken)
@ -2130,8 +2133,27 @@ absolute_trait_method_reference:
; ;
method_body: method_body:
';' /* abstract method */ { $$ = &nodesWithEndToken{nil, $1} } ';' /* abstract method */
| '{' inner_statement_list '}' { $$ = &nodesWithEndToken{$2, $3} } {
$$ = stmt.NewNop()
// save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokenPosition($1))
// save comments
yylex.(*Parser).comments.AddFromToken($$, $1, comment.SemiColonToken)
}
| '{' inner_statement_list '}'
{
$$ = stmt.NewStmtList($2)
// save position
yylex.(*Parser).positions.AddPosition($$, yylex.(*Parser).positionBuilder.NewTokensPosition($1, $3))
// save comments
yylex.(*Parser).comments.AddFromToken($$, $1, comment.OpenCurlyBracesToken)
yylex.(*Parser).comments.AddFromToken($$, $3, comment.CloseCurlyBracesToken)
}
; ;
variable_modifiers: variable_modifiers:
@ -4223,11 +4245,6 @@ type foreachVariable struct {
byRef bool byRef bool
} }
type nodesWithEndToken struct {
nodes []node.Node
endToken *scanner.Token
}
type boolWithToken struct { type boolWithToken struct {
value bool value bool
token *scanner.Token token *scanner.Token

View File

@ -549,10 +549,12 @@ func TestPhp7(t *testing.T) {
MethodName: &node.Identifier{Value: "foo"}, MethodName: &node.Identifier{Value: "foo"},
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
Params: expectedParams, Params: expectedParams,
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Expression{ &stmt.Expression{
Expr: &expr.Closure{ Expr: &expr.Closure{
Params: expectedParams, Params: expectedParams,
@ -866,10 +868,12 @@ func TestPhp7(t *testing.T) {
&stmt.ClassMethod{ &stmt.ClassMethod{
PhpDocComment: "", PhpDocComment: "",
MethodName: &node.Identifier{Value: "bar"}, MethodName: &node.Identifier{Value: "bar"},
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Class{ &stmt.Class{
ClassName: &node.Identifier{Value: "foo"}, ClassName: &node.Identifier{Value: "foo"},
Stmts: []node.Node{ Stmts: []node.Node{
@ -881,10 +885,12 @@ func TestPhp7(t *testing.T) {
&node.Identifier{Value: "public"}, &node.Identifier{Value: "public"},
&node.Identifier{Value: "static"}, &node.Identifier{Value: "static"},
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Class{ &stmt.Class{
ClassName: &node.Identifier{Value: "foo"}, ClassName: &node.Identifier{Value: "foo"},
Stmts: []node.Node{ Stmts: []node.Node{
@ -901,10 +907,12 @@ func TestPhp7(t *testing.T) {
&name.NamePart{Value: "void"}, &name.NamePart{Value: "void"},
}, },
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Class{ &stmt.Class{
ClassName: &node.Identifier{Value: "foo"}, ClassName: &node.Identifier{Value: "foo"},
Modifiers: []node.Node{ Modifiers: []node.Node{
@ -2966,10 +2974,12 @@ func TestPhp7(t *testing.T) {
&stmt.ClassMethod{ &stmt.ClassMethod{
MethodName: &node.Identifier{Value: "class"}, MethodName: &node.Identifier{Value: "class"},
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Expression{ &stmt.Expression{
Expr: &expr.FunctionCall{ Expr: &expr.FunctionCall{
Function: &name.FullyQualified{ Function: &name.FullyQualified{
@ -3072,6 +3082,7 @@ func TestPhp7(t *testing.T) {
&node.Identifier{Value: "protected"}, &node.Identifier{Value: "protected"},
&node.Identifier{Value: "static"}, &node.Identifier{Value: "static"},
}, },
Stmt: &stmt.Nop{},
}, },
&stmt.ClassMethod{ &stmt.ClassMethod{
MethodName: &node.Identifier{Value: "baz"}, MethodName: &node.Identifier{Value: "baz"},
@ -3079,10 +3090,12 @@ func TestPhp7(t *testing.T) {
&node.Identifier{Value: "final"}, &node.Identifier{Value: "final"},
&node.Identifier{Value: "private"}, &node.Identifier{Value: "private"},
}, },
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
}, },
},
&stmt.Expression{ &stmt.Expression{
Expr: &expr.PropertyFetch{ Expr: &expr.PropertyFetch{
Variable: &expr.New{ Variable: &expr.New{

View File

@ -1517,13 +1517,18 @@ func (p *Printer) printStmtClassMethod(n node.Node) {
p.Print(nn.ReturnType) p.Print(nn.ReturnType)
} }
switch s := nn.Stmt.(type) {
case *stmt.StmtList:
io.WriteString(p.w, "\n") io.WriteString(p.w, "\n")
p.printIndent() p.printIndent()
io.WriteString(p.w, "{\n") io.WriteString(p.w, "{\n")
p.printNodes(nn.Stmts) p.printNodes(s.Stmts)
io.WriteString(p.w, "\n") io.WriteString(p.w, "\n")
p.printIndent() p.printIndent()
io.WriteString(p.w, "}") io.WriteString(p.w, "}")
default:
p.Print(s)
}
} }
func (p *Printer) printStmtClass(n node.Node) { func (p *Printer) printStmtClass(n node.Node) {

View File

@ -44,6 +44,7 @@ func TestPrintFile(t *testing.T) {
&stmt.ClassMethod{ &stmt.ClassMethod{
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
MethodName: &node.Identifier{Value: "greet"}, MethodName: &node.Identifier{Value: "greet"},
Stmt: &stmt.StmtList{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.Echo{ &stmt.Echo{
Exprs: []node.Node{ Exprs: []node.Node{
@ -55,6 +56,7 @@ func TestPrintFile(t *testing.T) {
}, },
}, },
}, },
},
}) })
expected := `<?php expected := `<?php
@ -2453,9 +2455,11 @@ func TestPrintStmtClassMethod(t *testing.T) {
}, },
}, },
ReturnType: &name.Name{Parts: []node.Node{&name.NamePart{Value: "void"}}}, ReturnType: &name.Name{Parts: []node.Node{&name.NamePart{Value: "void"}}},
Stmt: &stmt.StmtList{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}}, &stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
}, },
},
}) })
expected := `public function &foo(?int &$a = null, ...$b): void expected := `public function &foo(?int &$a = null, ...$b): void
@ -3387,6 +3391,7 @@ func TestPrintInterface(t *testing.T) {
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
MethodName: &node.Identifier{Value: "foo"}, MethodName: &node.Identifier{Value: "foo"},
Params: []node.Node{}, Params: []node.Node{},
Stmt: &stmt.StmtList{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}}, &stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
}, },
@ -3394,6 +3399,7 @@ func TestPrintInterface(t *testing.T) {
}, },
}, },
}, },
},
}) })
expected := `namespace { expected := `namespace {
@ -3833,6 +3839,7 @@ func TestPrintTrait(t *testing.T) {
Modifiers: []node.Node{&node.Identifier{Value: "public"}}, Modifiers: []node.Node{&node.Identifier{Value: "public"}},
MethodName: &node.Identifier{Value: "foo"}, MethodName: &node.Identifier{Value: "foo"},
Params: []node.Node{}, Params: []node.Node{},
Stmt: &stmt.StmtList{
Stmts: []node.Node{ Stmts: []node.Node{
&stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}}, &stmt.Expression{Expr: &expr.Variable{VarName: &node.Identifier{Value: "a"}}},
}, },
@ -3840,6 +3847,7 @@ func TestPrintTrait(t *testing.T) {
}, },
}, },
}, },
},
}) })
expected := `namespace { expected := `namespace {

View File

@ -63,8 +63,8 @@ func ExampleDumper() {
//| "Stmts": //| "Stmts":
//| [*stmt.ClassMethod] //| [*stmt.ClassMethod]
//| "Position": Pos{Line: 5-9 Pos: 45-134}; //| "Position": Pos{Line: 5-9 Pos: 45-134};
//| "PhpDocComment": ;
//| "ReturnsRef": false; //| "ReturnsRef": false;
//| "PhpDocComment": ;
//| "MethodName": //| "MethodName":
//| [*node.Identifier] //| [*node.Identifier]
//| "Position": Pos{Line: 5-5 Pos: 61-72}; //| "Position": Pos{Line: 5-5 Pos: 61-72};
@ -104,6 +104,9 @@ func ExampleDumper() {
//| [*name.NamePart] //| [*name.NamePart]
//| "Position": Pos{Line: 5-5 Pos: 86-89}; //| "Position": Pos{Line: 5-5 Pos: 86-89};
//| "Value": null; //| "Value": null;
//| "Stmt":
//| [*stmt.StmtList]
//| "Position": Pos{Line: 6-9 Pos: 96-134};
//| "Stmts": //| "Stmts":
//| [*stmt.Expression] //| [*stmt.Expression]
//| "Position": Pos{Line: 8-8 Pos: 124-128}; //| "Position": Pos{Line: 8-8 Pos: 124-128};

View File

@ -544,7 +544,9 @@ func TestResolveMethodName(t *testing.T) {
}, },
}, },
ReturnType: &node.Nullable{Expr: nameBC}, ReturnType: &node.Nullable{Expr: nameBC},
Stmt: &stmt.StmtList{
Stmts: []node.Node{}, Stmts: []node.Node{},
},
} }
expected := map[node.Node]string{ expected := map[node.Node]string{