2018-02-20 18:22:15 +00:00
|
|
|
// Package visitor contains walker.visitor implementations
|
|
|
|
package visitor
|
2018-01-12 08:04:31 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2018-03-03 20:51:22 +00:00
|
|
|
"io"
|
2018-01-12 08:04:31 +00:00
|
|
|
"reflect"
|
2018-06-18 20:29:52 +00:00
|
|
|
"strings"
|
2018-01-12 08:04:31 +00:00
|
|
|
|
2018-01-17 16:58:45 +00:00
|
|
|
"github.com/z7zmey/php-parser/node"
|
2018-01-12 08:04:31 +00:00
|
|
|
|
2018-01-17 16:58:45 +00:00
|
|
|
"github.com/z7zmey/php-parser/walker"
|
2018-01-12 08:04:31 +00:00
|
|
|
)
|
|
|
|
|
2018-04-07 19:43:48 +00:00
|
|
|
// Dumper writes ast hierarchy to an io.Writer
|
2018-01-12 08:16:09 +00:00
|
|
|
// Also prints comments and positions attached to nodes
|
2018-01-12 08:04:31 +00:00
|
|
|
type Dumper struct {
|
2018-03-03 20:51:22 +00:00
|
|
|
Writer io.Writer
|
2018-03-01 20:31:36 +00:00
|
|
|
Indent string
|
|
|
|
NsResolver *NamespaceResolver
|
2018-01-12 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
2018-04-07 16:07:02 +00:00
|
|
|
// EnterNode is invoked at every node in hierarchy
|
2018-06-18 20:29:52 +00:00
|
|
|
func (d *Dumper) EnterNode(w walker.Walkable) bool {
|
2018-01-17 16:58:45 +00:00
|
|
|
n := w.(node.Node)
|
2018-01-12 08:04:31 +00:00
|
|
|
|
2018-03-03 20:51:22 +00:00
|
|
|
fmt.Fprintf(d.Writer, "%v[%v]\n", d.Indent, reflect.TypeOf(n))
|
2018-03-01 20:31:36 +00:00
|
|
|
|
2018-06-24 07:19:44 +00:00
|
|
|
if n.GetPosition() != nil {
|
|
|
|
fmt.Fprintf(d.Writer, "%v\"Position\": %s\n", d.Indent+" ", n.GetPosition())
|
2018-01-12 08:04:31 +00:00
|
|
|
}
|
2018-03-01 20:31:36 +00:00
|
|
|
|
|
|
|
if d.NsResolver != nil {
|
|
|
|
if namespacedName, ok := d.NsResolver.ResolvedNames[n]; ok {
|
2018-06-19 20:55:12 +00:00
|
|
|
fmt.Fprintf(d.Writer, "%v\"NamespacedName\": %q\n", d.Indent+" ", namespacedName)
|
2018-02-27 21:57:33 +00:00
|
|
|
}
|
2018-01-12 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
2018-07-29 08:44:38 +00:00
|
|
|
if mm := n.GetMeta(); len(*mm) > 0 {
|
2018-06-29 21:51:11 +00:00
|
|
|
fmt.Fprintf(d.Writer, "%v\"Meta\":\n", d.Indent+" ")
|
2018-07-29 08:44:38 +00:00
|
|
|
for _, m := range *mm {
|
|
|
|
fmt.Fprintf(d.Writer, "%v%q before %q\n", d.Indent+" ", m, m.TokenName.String())
|
2018-03-01 20:31:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if a := n.Attributes(); len(a) > 0 {
|
|
|
|
for key, attr := range a {
|
2018-06-19 20:55:12 +00:00
|
|
|
switch attr.(type) {
|
|
|
|
case string:
|
|
|
|
fmt.Fprintf(d.Writer, "%v\"%v\": %q\n", d.Indent+" ", key, attr)
|
|
|
|
default:
|
|
|
|
fmt.Fprintf(d.Writer, "%v\"%v\": %v\n", d.Indent+" ", key, attr)
|
|
|
|
}
|
2018-01-12 08:04:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2018-06-18 20:29:52 +00:00
|
|
|
// LeaveNode is invoked after node process
|
|
|
|
func (d *Dumper) LeaveNode(n walker.Walkable) {
|
|
|
|
// do nothing
|
|
|
|
}
|
|
|
|
|
2018-01-12 08:16:09 +00:00
|
|
|
// GetChildrenVisitor is invoked at every node parameter that contains children nodes
|
2018-06-18 20:29:52 +00:00
|
|
|
func (d *Dumper) EnterChildNode(key string, w walker.Walkable) {
|
2018-03-03 20:51:22 +00:00
|
|
|
fmt.Fprintf(d.Writer, "%v%q:\n", d.Indent+" ", key)
|
2018-06-18 20:29:52 +00:00
|
|
|
d.Indent = d.Indent + " "
|
2018-01-12 08:04:31 +00:00
|
|
|
}
|
|
|
|
|
2018-06-18 20:29:52 +00:00
|
|
|
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, " ")
|
2018-01-12 08:04:31 +00:00
|
|
|
}
|