#31 dump to native golang struct
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/z7zmey/php-parser/comment"
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
@@ -24,7 +25,7 @@ type Dumper struct {
|
||||
}
|
||||
|
||||
// EnterNode is invoked at every node in hierarchy
|
||||
func (d Dumper) EnterNode(w walker.Walkable) bool {
|
||||
func (d *Dumper) EnterNode(w walker.Walkable) bool {
|
||||
n := w.(node.Node)
|
||||
|
||||
fmt.Fprintf(d.Writer, "%v[%v]\n", d.Indent, reflect.TypeOf(n))
|
||||
@@ -59,13 +60,26 @@ func (d Dumper) EnterNode(w walker.Walkable) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetChildrenVisitor is invoked at every node parameter that contains children nodes
|
||||
func (d Dumper) GetChildrenVisitor(key string) walker.Visitor {
|
||||
fmt.Fprintf(d.Writer, "%v%q:\n", d.Indent+" ", key)
|
||||
return Dumper{d.Writer, d.Indent + " ", d.Comments, d.Positions, d.NsResolver}
|
||||
}
|
||||
|
||||
// LeaveNode is invoked after node process
|
||||
func (d Dumper) LeaveNode(n walker.Walkable) {
|
||||
func (d *Dumper) LeaveNode(n walker.Walkable) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
// GetChildrenVisitor is invoked at every node parameter that contains children nodes
|
||||
func (d *Dumper) EnterChildNode(key string, w walker.Walkable) {
|
||||
fmt.Fprintf(d.Writer, "%v%q:\n", d.Indent+" ", key)
|
||||
d.Indent = d.Indent + " "
|
||||
}
|
||||
|
||||
func (d *Dumper) LeaveChildNode(key string, w walker.Walkable) {
|
||||
d.Indent = strings.TrimSuffix(d.Indent, " ")
|
||||
}
|
||||
|
||||
func (d *Dumper) EnterChildList(key string, w walker.Walkable) {
|
||||
fmt.Fprintf(d.Writer, "%v%q:\n", d.Indent+" ", key)
|
||||
d.Indent = d.Indent + " "
|
||||
}
|
||||
|
||||
func (d *Dumper) LeaveChildList(key string, w walker.Walkable) {
|
||||
d.Indent = strings.TrimSuffix(d.Indent, " ")
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ func ExampleDumper() {
|
||||
nsResolver := visitor.NewNamespaceResolver()
|
||||
nodes.Walk(nsResolver)
|
||||
|
||||
dumper := visitor.Dumper{
|
||||
dumper := &visitor.Dumper{
|
||||
Writer: os.Stdout,
|
||||
Indent: "| ",
|
||||
Comments: php7parser.GetComments(),
|
||||
|
||||
93
visitor/go_dumper.go
Normal file
93
visitor/go_dumper.go
Normal file
@@ -0,0 +1,93 @@
|
||||
// Package visitor contains walker.visitor implementations
|
||||
package visitor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
|
||||
"github.com/z7zmey/php-parser/walker"
|
||||
)
|
||||
|
||||
// GoDumper writes ast hierarchy to an io.Writer as native Golang struct
|
||||
type GoDumper struct {
|
||||
Writer io.Writer
|
||||
depth int
|
||||
isChildNode bool
|
||||
}
|
||||
|
||||
func printIndent(w io.Writer, d int) {
|
||||
for i := 0; i < d; i++ {
|
||||
io.WriteString(w, "\t")
|
||||
}
|
||||
}
|
||||
|
||||
// EnterNode is invoked at every node in hierarchy
|
||||
func (d *GoDumper) EnterNode(w walker.Walkable) bool {
|
||||
n := w.(node.Node)
|
||||
|
||||
nodeType := reflect.TypeOf(n).String()
|
||||
nodeType = strings.Replace(nodeType, "*", "&", 1)
|
||||
|
||||
if d.isChildNode {
|
||||
d.isChildNode = false
|
||||
} else {
|
||||
printIndent(d.Writer, d.depth)
|
||||
}
|
||||
|
||||
io.WriteString(d.Writer, nodeType+"{\n")
|
||||
|
||||
d.depth++
|
||||
|
||||
if a := n.Attributes(); len(a) > 0 {
|
||||
for key, attr := range a {
|
||||
printIndent(d.Writer, d.depth)
|
||||
switch attr.(type) {
|
||||
case string:
|
||||
fmt.Fprintf(d.Writer, "%s: %q,\n", key, attr)
|
||||
default:
|
||||
fmt.Fprintf(d.Writer, "%s: %v,\n", key, attr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// LeaveNode is invoked after node process
|
||||
func (d *GoDumper) LeaveNode(n walker.Walkable) {
|
||||
d.depth--
|
||||
printIndent(d.Writer, d.depth)
|
||||
if d.depth != 0 {
|
||||
io.WriteString(d.Writer, "},\n")
|
||||
} else {
|
||||
io.WriteString(d.Writer, "}\n")
|
||||
}
|
||||
}
|
||||
|
||||
func (d *GoDumper) EnterChildNode(key string, w walker.Walkable) {
|
||||
printIndent(d.Writer, d.depth)
|
||||
io.WriteString(d.Writer, key+": ")
|
||||
d.isChildNode = true
|
||||
}
|
||||
|
||||
func (d *GoDumper) LeaveChildNode(key string, w walker.Walkable) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
func (d *GoDumper) EnterChildList(key string, w walker.Walkable) {
|
||||
printIndent(d.Writer, d.depth)
|
||||
io.WriteString(d.Writer, key+": []node.Node{\n")
|
||||
d.depth++
|
||||
}
|
||||
|
||||
func (d *GoDumper) LeaveChildList(key string, w walker.Walkable) {
|
||||
d.depth--
|
||||
printIndent(d.Writer, d.depth)
|
||||
if d.depth != 0 {
|
||||
io.WriteString(d.Writer, "},\n")
|
||||
}
|
||||
}
|
||||
111
visitor/go_dumper_test.go
Normal file
111
visitor/go_dumper_test.go
Normal file
@@ -0,0 +1,111 @@
|
||||
//Package visitor contains walker.visitor implementations
|
||||
package visitor_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
|
||||
"github.com/z7zmey/php-parser/php7"
|
||||
"github.com/z7zmey/php-parser/visitor"
|
||||
)
|
||||
|
||||
func ExampleGoDumper() {
|
||||
src := `<?php
|
||||
|
||||
namespace Foo {
|
||||
class Bar {
|
||||
public function FunctionName(Type $var = null)
|
||||
{
|
||||
//some comment
|
||||
$var;
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
|
||||
php7parser.Parse()
|
||||
nodes := php7parser.GetRootNode()
|
||||
|
||||
nsResolver := visitor.NewNamespaceResolver()
|
||||
nodes.Walk(nsResolver)
|
||||
|
||||
dumper := &visitor.GoDumper{
|
||||
Writer: os.Stdout,
|
||||
}
|
||||
nodes.Walk(dumper)
|
||||
|
||||
// Unordered output:
|
||||
//&node.Root{
|
||||
// Stmts: []node.Node{
|
||||
// &stmt.Namespace{
|
||||
// NamespaceName: &name.Name{
|
||||
// Parts: []node.Node{
|
||||
// &name.NamePart{
|
||||
// Value: "Foo",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// Stmts: []node.Node{
|
||||
// &stmt.Class{
|
||||
// PhpDocComment: "",
|
||||
// ClassName: &node.Identifier{
|
||||
// Value: "Bar",
|
||||
// },
|
||||
// Stmts: []node.Node{
|
||||
// &stmt.ClassMethod{
|
||||
// ReturnsRef: false,
|
||||
// PhpDocComment: "",
|
||||
// MethodName: &node.Identifier{
|
||||
// Value: "FunctionName",
|
||||
// },
|
||||
// Modifiers: []node.Node{
|
||||
// &node.Identifier{
|
||||
// Value: "public",
|
||||
// },
|
||||
// },
|
||||
// Params: []node.Node{
|
||||
// &node.Parameter{
|
||||
// ByRef: false,
|
||||
// Variadic: false,
|
||||
// VariableType: &name.Name{
|
||||
// Parts: []node.Node{
|
||||
// &name.NamePart{
|
||||
// Value: "Type",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// Variable: &expr.Variable{
|
||||
// VarName: &node.Identifier{
|
||||
// Value: "var",
|
||||
// },
|
||||
// },
|
||||
// DefaultValue: &expr.ConstFetch{
|
||||
// Constant: &name.Name{
|
||||
// Parts: []node.Node{
|
||||
// &name.NamePart{
|
||||
// Value: "null",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// Stmt: &stmt.StmtList{
|
||||
// Stmts: []node.Node{
|
||||
// &stmt.Expression{
|
||||
// Expr: &expr.Variable{
|
||||
// VarName: &node.Identifier{
|
||||
// Value: "var",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
//}
|
||||
}
|
||||
@@ -181,11 +181,6 @@ func (nsr *NamespaceResolver) EnterNode(w walker.Walkable) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// GetChildrenVisitor is invoked at every node parameter that contains children nodes
|
||||
func (nsr *NamespaceResolver) GetChildrenVisitor(key string) walker.Visitor {
|
||||
return nsr
|
||||
}
|
||||
|
||||
// LeaveNode is invoked after node process
|
||||
func (nsr *NamespaceResolver) LeaveNode(w walker.Walkable) {
|
||||
switch n := w.(type) {
|
||||
@@ -196,6 +191,22 @@ func (nsr *NamespaceResolver) LeaveNode(w walker.Walkable) {
|
||||
}
|
||||
}
|
||||
|
||||
func (nsr *NamespaceResolver) EnterChildNode(key string, w walker.Walkable) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
func (nsr *NamespaceResolver) LeaveChildNode(key string, w walker.Walkable) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
func (nsr *NamespaceResolver) EnterChildList(key string, w walker.Walkable) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
func (nsr *NamespaceResolver) LeaveChildList(key string, w walker.Walkable) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
// AddAlias adds a new alias
|
||||
func (nsr *NamespaceResolver) AddAlias(useType string, nn node.Node, prefix []node.Node) {
|
||||
switch use := nn.(type) {
|
||||
|
||||
Reference in New Issue
Block a user