-
Notifications
You must be signed in to change notification settings - Fork 63
/
json_dumper.go
145 lines (116 loc) · 3.37 KB
/
json_dumper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Package visitor contains walker.visitor implementations
package visitor
import (
"fmt"
"io"
"reflect"
"sort"
"github.com/z7zmey/php-parser/freefloating"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/walker"
)
type JsonDumper struct {
Writer io.Writer
NsResolver *NamespaceResolver
isChildNode bool
isNotFirstNode bool
}
// EnterNode is invoked at every node in hierarchy
func (d *JsonDumper) EnterNode(w walker.Walkable) bool {
n := w.(node.Node)
nodeType := reflect.TypeOf(n).String()
if d.isChildNode {
d.isChildNode = false
} else if d.isNotFirstNode {
fmt.Fprint(d.Writer, ",")
} else {
d.isNotFirstNode = true
}
fmt.Fprintf(d.Writer, "{%q:%q", "type", nodeType)
if p := n.GetPosition(); p != nil {
p := n.GetPosition()
fmt.Fprintf(d.Writer, ",%q:{%q:%d,%q:%d,%q:%d,%q:%d}",
"position",
"startPos", p.StartPos,
"endPos", p.EndPos,
"startLine", p.StartLine,
"endLine", p.EndLine)
}
if d.NsResolver != nil {
if namespacedName, ok := d.NsResolver.ResolvedNames[n]; ok {
fmt.Fprintf(d.Writer, ",%q:%q", "namespacedName", namespacedName)
}
}
if !n.GetFreeFloating().IsEmpty() {
fmt.Fprintf(d.Writer, ",%q:{", "freefloating")
var freefloatingStringsKeys []int
for key := range *n.GetFreeFloating() {
freefloatingStringsKeys = append(freefloatingStringsKeys, int(key))
}
sort.Ints(freefloatingStringsKeys)
i := 0
for _, k := range freefloatingStringsKeys {
key := freefloating.Position(k)
freeFloatingStrings := (*n.GetFreeFloating())[key]
if i != 0 {
fmt.Fprint(d.Writer, ",")
}
i++
fmt.Fprintf(d.Writer, "%q: [", key.String())
j := 0
for _, freeFloatingString := range freeFloatingStrings {
if j != 0 {
fmt.Fprint(d.Writer, ",")
}
j++
switch freeFloatingString.StringType {
case freefloating.CommentType:
fmt.Fprintf(d.Writer, "{%q:%q,%q:%q}", "type", "freefloating.CommentType", "value", freeFloatingString.Value)
case freefloating.WhiteSpaceType:
fmt.Fprintf(d.Writer, "{%q:%q,%q:%q}", "type", "freefloating.WhiteSpaceType", "value", freeFloatingString.Value)
case freefloating.TokenType:
fmt.Fprintf(d.Writer, "{%q:%q,%q:%q}", "type", "freefloating.TokenType", "value", freeFloatingString.Value)
}
}
fmt.Fprint(d.Writer, "]")
}
fmt.Fprint(d.Writer, "}")
}
if a := n.Attributes(); len(a) > 0 {
var attributes []string
for key := range n.Attributes() {
attributes = append(attributes, key)
}
sort.Strings(attributes)
for _, attributeName := range attributes {
attr := a[attributeName]
switch attr.(type) {
case string:
fmt.Fprintf(d.Writer, ",\"%s\":%q", attributeName, attr)
default:
fmt.Fprintf(d.Writer, ",\"%s\":%v", attributeName, attr)
}
}
}
return true
}
// LeaveNode is invoked after node process
func (d *JsonDumper) LeaveNode(n walker.Walkable) {
fmt.Fprint(d.Writer, "}")
d.isNotFirstNode = true
d.isChildNode = false
}
func (d *JsonDumper) EnterChildNode(key string, w walker.Walkable) {
fmt.Fprintf(d.Writer, ",%q:", key)
d.isChildNode = true
}
func (d *JsonDumper) LeaveChildNode(key string, w walker.Walkable) {
// do nothing
}
func (d *JsonDumper) EnterChildList(key string, w walker.Walkable) {
fmt.Fprintf(d.Writer, ",%q:[", key)
d.isNotFirstNode = false
}
func (d *JsonDumper) LeaveChildList(key string, w walker.Walkable) {
fmt.Fprint(d.Writer, "]")
}