2018-06-19 20:55:12 +00:00
|
|
|
// Package visitor contains walker.visitor implementations
|
|
|
|
package visitor
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"reflect"
|
|
|
|
|
2019-02-13 20:18:07 +00:00
|
|
|
"github.com/z7zmey/php-parser/freefloating"
|
2018-06-19 20:55:12 +00:00
|
|
|
"github.com/z7zmey/php-parser/node"
|
|
|
|
"github.com/z7zmey/php-parser/walker"
|
|
|
|
)
|
|
|
|
|
|
|
|
type PrettyJsonDumper struct {
|
2018-06-29 21:51:11 +00:00
|
|
|
Writer io.Writer
|
|
|
|
NsResolver *NamespaceResolver
|
|
|
|
depth int
|
|
|
|
isChildNode bool
|
|
|
|
isNotFirstNode bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPrettyJsonDumper(Writer io.Writer, NsResolver *NamespaceResolver) *PrettyJsonDumper {
|
|
|
|
return &PrettyJsonDumper{
|
|
|
|
Writer: Writer,
|
|
|
|
NsResolver: NsResolver,
|
|
|
|
depth: 0,
|
|
|
|
isChildNode: false,
|
|
|
|
isNotFirstNode: false,
|
|
|
|
}
|
2018-06-19 20:55:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *PrettyJsonDumper) printIndent(w io.Writer) {
|
|
|
|
for i := 0; i < d.depth; i++ {
|
|
|
|
fmt.Fprint(d.Writer, " ")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// EnterNode is invoked at every node in hierarchy
|
|
|
|
func (d *PrettyJsonDumper) EnterNode(w walker.Walkable) bool {
|
|
|
|
n := w.(node.Node)
|
|
|
|
|
|
|
|
nodeType := reflect.TypeOf(n).String()
|
|
|
|
|
|
|
|
if d.isChildNode {
|
|
|
|
d.isChildNode = false
|
2018-06-29 21:51:11 +00:00
|
|
|
} else if d.isNotFirstNode {
|
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
|
|
|
d.printIndent(d.Writer)
|
2018-06-19 20:55:12 +00:00
|
|
|
} else {
|
|
|
|
d.printIndent(d.Writer)
|
2018-06-29 21:51:11 +00:00
|
|
|
d.isNotFirstNode = true
|
2018-06-19 20:55:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Fprint(d.Writer, "{\n")
|
|
|
|
d.depth++
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %q", "type", nodeType)
|
|
|
|
|
2018-06-24 07:19:44 +00:00
|
|
|
if p := n.GetPosition(); p != nil {
|
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: {\n", "position")
|
|
|
|
d.depth++
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %d,\n", "startPos", p.StartPos)
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %d,\n", "endPos", p.EndPos)
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %d,\n", "startLine", p.StartLine)
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %d\n", "endLine", p.EndLine)
|
|
|
|
d.depth--
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprint(d.Writer, "}")
|
2018-06-19 20:55:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if d.NsResolver != nil {
|
|
|
|
if namespacedName, ok := d.NsResolver.ResolvedNames[n]; ok {
|
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "\"namespacedName\": %q", namespacedName)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-13 20:18:07 +00:00
|
|
|
if !n.GetFreeFloating().IsEmpty() {
|
2018-06-25 12:38:31 +00:00
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
|
|
|
d.printIndent(d.Writer)
|
2019-02-13 20:18:07 +00:00
|
|
|
fmt.Fprint(d.Writer, "\"freefloating\": {\n")
|
2018-06-25 12:38:31 +00:00
|
|
|
d.depth++
|
2019-02-13 20:18:07 +00:00
|
|
|
i := 0
|
|
|
|
for key, freeFloatingStrings := range *n.GetFreeFloating() {
|
|
|
|
if i != 0 {
|
2018-06-25 12:38:31 +00:00
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
2018-06-19 20:55:12 +00:00
|
|
|
}
|
2019-02-13 20:18:07 +00:00
|
|
|
i++
|
2018-06-29 21:51:11 +00:00
|
|
|
|
|
|
|
d.printIndent(d.Writer)
|
2019-02-13 20:18:07 +00:00
|
|
|
fmt.Fprintf(d.Writer, "%q: [\n", key)
|
2018-06-29 21:51:11 +00:00
|
|
|
d.depth++
|
2019-02-13 20:18:07 +00:00
|
|
|
|
|
|
|
j := 0
|
|
|
|
for _, freeFloatingString := range freeFloatingStrings {
|
|
|
|
if j != 0 {
|
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
|
|
|
}
|
|
|
|
j++
|
|
|
|
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprint(d.Writer, "{\n")
|
|
|
|
d.depth++
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
switch freeFloatingString.StringType {
|
|
|
|
case freefloating.CommentType:
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %q,\n", "type", "freefloating.CommentType")
|
|
|
|
case freefloating.WhiteSpaceType:
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %q,\n", "type", "freefloating.WhiteSpaceType")
|
|
|
|
case freefloating.TokenType:
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %q,\n", "type", "freefloating.TokenType")
|
|
|
|
}
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: %q\n", "value", freeFloatingString.Value)
|
|
|
|
d.depth--
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprint(d.Writer, "}")
|
2018-06-29 21:51:11 +00:00
|
|
|
}
|
2019-02-13 20:18:07 +00:00
|
|
|
|
2018-06-29 21:51:11 +00:00
|
|
|
d.depth--
|
2019-02-13 20:18:07 +00:00
|
|
|
fmt.Fprint(d.Writer, "\n")
|
2018-06-29 21:51:11 +00:00
|
|
|
d.printIndent(d.Writer)
|
2019-02-13 20:18:07 +00:00
|
|
|
fmt.Fprint(d.Writer, "]")
|
2018-06-19 20:55:12 +00:00
|
|
|
}
|
2018-06-25 12:38:31 +00:00
|
|
|
d.depth--
|
|
|
|
fmt.Fprint(d.Writer, "\n")
|
|
|
|
d.printIndent(d.Writer)
|
2019-02-13 20:18:07 +00:00
|
|
|
fmt.Fprint(d.Writer, "}")
|
2018-06-19 20:55:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if a := n.Attributes(); len(a) > 0 {
|
|
|
|
for key, attr := range a {
|
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
switch attr.(type) {
|
|
|
|
case string:
|
|
|
|
fmt.Fprintf(d.Writer, "\"%s\": %q", key, attr)
|
|
|
|
default:
|
|
|
|
fmt.Fprintf(d.Writer, "\"%s\": %v", key, attr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
// LeaveNode is invoked after node process
|
|
|
|
func (d *PrettyJsonDumper) LeaveNode(n walker.Walkable) {
|
|
|
|
d.depth--
|
|
|
|
fmt.Fprint(d.Writer, "\n")
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprint(d.Writer, "}")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *PrettyJsonDumper) EnterChildNode(key string, w walker.Walkable) {
|
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: ", key)
|
|
|
|
d.isChildNode = true
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *PrettyJsonDumper) LeaveChildNode(key string, w walker.Walkable) {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *PrettyJsonDumper) EnterChildList(key string, w walker.Walkable) {
|
|
|
|
fmt.Fprint(d.Writer, ",\n")
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprintf(d.Writer, "%q: [\n", key)
|
|
|
|
d.depth++
|
2018-06-29 21:51:11 +00:00
|
|
|
|
|
|
|
d.isNotFirstNode = false
|
2018-06-19 20:55:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (d *PrettyJsonDumper) LeaveChildList(key string, w walker.Walkable) {
|
|
|
|
d.depth--
|
|
|
|
fmt.Fprint(d.Writer, "\n")
|
|
|
|
d.printIndent(d.Writer)
|
|
|
|
fmt.Fprint(d.Writer, "]")
|
|
|
|
}
|