#30 created json dumper
This commit is contained in:
parent
dd572a8fed
commit
09c984ebdb
10
README.md
10
README.md
@ -47,9 +47,17 @@ CLI
|
||||
---
|
||||
|
||||
```
|
||||
php-parser [-php5 -noDump] <path> ...
|
||||
php-parser [flags] <path> ...
|
||||
```
|
||||
|
||||
| flag | type | description |
|
||||
|-------|------|----------------------------------------------|
|
||||
| -d |string| dump format: [custom, go, json, pretty-json] |
|
||||
| -p | bool | show positions |
|
||||
| -c | bool | show comments |
|
||||
| -r | bool | resolve names |
|
||||
| -php5 | bool | parse as PHP5 |
|
||||
|
||||
Dump AST to stdout.
|
||||
|
||||
Example
|
||||
|
55
main.go
55
main.go
@ -17,11 +17,18 @@ import (
|
||||
|
||||
var wg sync.WaitGroup
|
||||
var usePhp5 *bool
|
||||
var noDump *bool
|
||||
var dumpType string
|
||||
var showPositions *bool
|
||||
var showComments *bool
|
||||
var showResolvedNs *bool
|
||||
|
||||
func main() {
|
||||
usePhp5 = flag.Bool("php5", false, "use PHP5 parserWorker")
|
||||
noDump = flag.Bool("noDump", false, "disable dumping to stdout")
|
||||
usePhp5 = flag.Bool("php5", false, "parse as PHP5")
|
||||
showPositions = flag.Bool("p", false, "show positions")
|
||||
showComments = flag.Bool("c", false, "show comments")
|
||||
showResolvedNs = flag.Bool("r", false, "resolve names")
|
||||
flag.StringVar(&dumpType, "d", "", "dump format: [custom, go, json, pretty_json]")
|
||||
|
||||
flag.Parse()
|
||||
|
||||
pathCh := make(chan string)
|
||||
@ -95,19 +102,53 @@ func printer(result <-chan parser.Parser) {
|
||||
fmt.Println(e)
|
||||
}
|
||||
|
||||
if !*noDump {
|
||||
nsResolver := visitor.NewNamespaceResolver()
|
||||
var nsResolver *visitor.NamespaceResolver
|
||||
if *showResolvedNs {
|
||||
nsResolver = visitor.NewNamespaceResolver()
|
||||
parserWorker.GetRootNode().Walk(nsResolver)
|
||||
}
|
||||
|
||||
var comments parser.Comments
|
||||
if *showComments {
|
||||
comments = parserWorker.GetComments()
|
||||
}
|
||||
|
||||
var positions parser.Positions
|
||||
if *showPositions {
|
||||
positions = parserWorker.GetPositions()
|
||||
}
|
||||
|
||||
switch dumpType {
|
||||
case "custom":
|
||||
dumper := &visitor.Dumper{
|
||||
Writer: os.Stdout,
|
||||
Indent: "| ",
|
||||
Comments: parserWorker.GetComments(),
|
||||
Positions: parserWorker.GetPositions(),
|
||||
Comments: comments,
|
||||
Positions: positions,
|
||||
NsResolver: nsResolver,
|
||||
}
|
||||
parserWorker.GetRootNode().Walk(dumper)
|
||||
case "json":
|
||||
dumper := &visitor.JsonDumper{
|
||||
Writer: os.Stdout,
|
||||
Comments: comments,
|
||||
Positions: positions,
|
||||
NsResolver: nsResolver,
|
||||
}
|
||||
parserWorker.GetRootNode().Walk(dumper)
|
||||
case "pretty_json":
|
||||
dumper := &visitor.PrettyJsonDumper{
|
||||
Writer: os.Stdout,
|
||||
Comments: comments,
|
||||
Positions: positions,
|
||||
NsResolver: nsResolver,
|
||||
}
|
||||
parserWorker.GetRootNode().Walk(dumper)
|
||||
case "go":
|
||||
dumper := &visitor.GoDumper{Writer: os.Stdout}
|
||||
parserWorker.GetRootNode().Walk(dumper)
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}
|
||||
}
|
||||
|
@ -32,13 +32,13 @@ func (d *Dumper) EnterNode(w walker.Walkable) bool {
|
||||
|
||||
if d.Positions != nil {
|
||||
if p := d.Positions[n]; p != nil {
|
||||
fmt.Fprintf(d.Writer, "%v\"Position\": %s;\n", d.Indent+" ", *p)
|
||||
fmt.Fprintf(d.Writer, "%v\"Position\": %s\n", d.Indent+" ", *p)
|
||||
}
|
||||
}
|
||||
|
||||
if d.NsResolver != nil {
|
||||
if namespacedName, ok := d.NsResolver.ResolvedNames[n]; ok {
|
||||
fmt.Fprintf(d.Writer, "%v\"NamespacedName\": %s;\n", d.Indent+" ", namespacedName)
|
||||
fmt.Fprintf(d.Writer, "%v\"NamespacedName\": %q\n", d.Indent+" ", namespacedName)
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +53,12 @@ func (d *Dumper) EnterNode(w walker.Walkable) bool {
|
||||
|
||||
if a := n.Attributes(); len(a) > 0 {
|
||||
for key, attr := range a {
|
||||
fmt.Fprintf(d.Writer, "%v\"%v\": %v;\n", d.Indent+" ", key, attr)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,83 +40,83 @@ func ExampleDumper() {
|
||||
|
||||
// Unordered output:
|
||||
// | [*node.Root]
|
||||
//| "Position": Pos{Line: 3-11 Pos: 10-143};
|
||||
// | "Position": Pos{Line: 3-11 Pos: 10-143}
|
||||
// | "Stmts":
|
||||
// | [*stmt.Namespace]
|
||||
//| "Position": Pos{Line: 3-11 Pos: 10-143};
|
||||
// | "Position": Pos{Line: 3-11 Pos: 10-143}
|
||||
// | "NamespaceName":
|
||||
// | [*name.Name]
|
||||
//| "Position": Pos{Line: 3-3 Pos: 20-22};
|
||||
// | "Position": Pos{Line: 3-3 Pos: 20-22}
|
||||
// | "Parts":
|
||||
// | [*name.NamePart]
|
||||
//| "Position": Pos{Line: 3-3 Pos: 20-22};
|
||||
//| "Value": Foo;
|
||||
// | "Position": Pos{Line: 3-3 Pos: 20-22}
|
||||
// | "Value": "Foo"
|
||||
// | "Stmts":
|
||||
// | [*stmt.Class]
|
||||
//| "Position": Pos{Line: 4-10 Pos: 29-139};
|
||||
//| "NamespacedName": Foo\Bar;
|
||||
//| "PhpDocComment": ;
|
||||
// | "Position": Pos{Line: 4-10 Pos: 29-139}
|
||||
// | "NamespacedName": "Foo\\Bar"
|
||||
// | "PhpDocComment": ""
|
||||
// | "ClassName":
|
||||
// | [*node.Identifier]
|
||||
//| "Position": Pos{Line: 4-4 Pos: 35-37};
|
||||
//| "Value": Bar;
|
||||
// | "Position": Pos{Line: 4-4 Pos: 35-37}
|
||||
// | "Value": "Bar"
|
||||
// | "Stmts":
|
||||
// | [*stmt.ClassMethod]
|
||||
//| "Position": Pos{Line: 5-9 Pos: 45-134};
|
||||
//| "ReturnsRef": false;
|
||||
//| "PhpDocComment": ;
|
||||
// | "Position": Pos{Line: 5-9 Pos: 45-134}
|
||||
// | "ReturnsRef": false
|
||||
// | "PhpDocComment": ""
|
||||
// | "MethodName":
|
||||
// | [*node.Identifier]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 61-72};
|
||||
//| "Value": FunctionName;
|
||||
// | "Position": Pos{Line: 5-5 Pos: 61-72}
|
||||
// | "Value": "FunctionName"
|
||||
// | "Modifiers":
|
||||
// | [*node.Identifier]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 45-50};
|
||||
//| "Value": public;
|
||||
// | "Position": Pos{Line: 5-5 Pos: 45-50}
|
||||
// | "Value": "public"
|
||||
// | "Params":
|
||||
// | [*node.Parameter]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 74-89};
|
||||
//| "ByRef": false;
|
||||
//| "Variadic": false;
|
||||
// | "Position": Pos{Line: 5-5 Pos: 74-89}
|
||||
// | "Variadic": false
|
||||
// | "ByRef": false
|
||||
// | "VariableType":
|
||||
// | [*name.Name]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 74-77};
|
||||
//| "NamespacedName": Foo\Type;
|
||||
// | "Position": Pos{Line: 5-5 Pos: 74-77}
|
||||
// | "NamespacedName": "Foo\\Type"
|
||||
// | "Parts":
|
||||
// | [*name.NamePart]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 74-77};
|
||||
//| "Value": Type;
|
||||
// | "Position": Pos{Line: 5-5 Pos: 74-77}
|
||||
// | "Value": "Type"
|
||||
// | "Variable":
|
||||
// | [*expr.Variable]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 79-82};
|
||||
// | "Position": Pos{Line: 5-5 Pos: 79-82}
|
||||
// | "VarName":
|
||||
// | [*node.Identifier]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 79-82};
|
||||
//| "Value": var;
|
||||
// | "Position": Pos{Line: 5-5 Pos: 79-82}
|
||||
// | "Value": "var"
|
||||
// | "DefaultValue":
|
||||
// | [*expr.ConstFetch]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 86-89};
|
||||
// | "Position": Pos{Line: 5-5 Pos: 86-89}
|
||||
// | "Constant":
|
||||
// | [*name.Name]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 86-89};
|
||||
//| "NamespacedName": null;
|
||||
// | "Position": Pos{Line: 5-5 Pos: 86-89}
|
||||
// | "NamespacedName": "null"
|
||||
// | "Parts":
|
||||
// | [*name.NamePart]
|
||||
//| "Position": Pos{Line: 5-5 Pos: 86-89};
|
||||
//| "Value": null;
|
||||
// | "Position": Pos{Line: 5-5 Pos: 86-89}
|
||||
// | "Value": "null"
|
||||
// | "Stmt":
|
||||
// | [*stmt.StmtList]
|
||||
//| "Position": Pos{Line: 6-9 Pos: 96-134};
|
||||
// | "Position": Pos{Line: 6-9 Pos: 96-134}
|
||||
// | "Stmts":
|
||||
// | [*stmt.Expression]
|
||||
//| "Position": Pos{Line: 8-8 Pos: 124-128};
|
||||
// | "Position": Pos{Line: 8-8 Pos: 124-128}
|
||||
// | "Expr":
|
||||
// | [*expr.Variable]
|
||||
//| "Position": Pos{Line: 8-8 Pos: 124-127};
|
||||
// | "Position": Pos{Line: 8-8 Pos: 124-127}
|
||||
// | "Comments":
|
||||
// | "// some comment\n" before "VariableToken"
|
||||
// | "VarName":
|
||||
// | [*node.Identifier]
|
||||
//| "Position": Pos{Line: 8-8 Pos: 124-127};
|
||||
//| "Value": var;
|
||||
// | "Position": Pos{Line: 8-8 Pos: 124-127}
|
||||
// | "Value": "var"
|
||||
}
|
||||
|
97
visitor/json_dumper.go
Normal file
97
visitor/json_dumper.go
Normal file
@ -0,0 +1,97 @@
|
||||
// Package visitor contains walker.visitor implementations
|
||||
package visitor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
"github.com/z7zmey/php-parser/parser"
|
||||
|
||||
"github.com/z7zmey/php-parser/walker"
|
||||
)
|
||||
|
||||
type JsonDumper struct {
|
||||
Writer io.Writer
|
||||
Comments parser.Comments
|
||||
Positions parser.Positions
|
||||
NsResolver *NamespaceResolver
|
||||
}
|
||||
|
||||
// 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()
|
||||
|
||||
fmt.Fprintf(d.Writer, "{%q:%q", "type", nodeType)
|
||||
|
||||
if d.Positions != nil {
|
||||
if p := d.Positions[n]; p != nil {
|
||||
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 d.Comments != nil {
|
||||
if c := d.Comments[n]; len(c) > 0 {
|
||||
fmt.Fprintf(d.Writer, ",%q:[", "comments")
|
||||
|
||||
for k, cc := range c {
|
||||
if k == 0 {
|
||||
fmt.Fprintf(d.Writer, "%q", cc)
|
||||
} else {
|
||||
fmt.Fprintf(d.Writer, ",%q", cc)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprint(d.Writer, "]")
|
||||
}
|
||||
}
|
||||
|
||||
if a := n.Attributes(); len(a) > 0 {
|
||||
for key, attr := range a {
|
||||
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 *JsonDumper) LeaveNode(n walker.Walkable) {
|
||||
fmt.Fprint(d.Writer, "}")
|
||||
}
|
||||
|
||||
func (d *JsonDumper) EnterChildNode(key string, w walker.Walkable) {
|
||||
fmt.Fprintf(d.Writer, ",%q:", key)
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
}
|
||||
|
||||
func (d *JsonDumper) LeaveChildList(key string, w walker.Walkable) {
|
||||
fmt.Fprint(d.Writer, "]")
|
||||
}
|
43
visitor/json_dumper_test.go
Normal file
43
visitor/json_dumper_test.go
Normal file
@ -0,0 +1,43 @@
|
||||
//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 ExampleJsonDumper() {
|
||||
src := `<?php
|
||||
|
||||
namespace Foo {
|
||||
class Bar {
|
||||
public function FunctionName(Type $var = null)
|
||||
{
|
||||
// some comment
|
||||
// second comment
|
||||
$var;
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
|
||||
php7parser.Parse()
|
||||
nodes := php7parser.GetRootNode()
|
||||
|
||||
nsResolver := visitor.NewNamespaceResolver()
|
||||
nodes.Walk(nsResolver)
|
||||
|
||||
dumper := &visitor.JsonDumper{
|
||||
Writer: os.Stdout,
|
||||
Comments: php7parser.GetComments(),
|
||||
Positions: php7parser.GetPositions(),
|
||||
NsResolver: nsResolver,
|
||||
}
|
||||
nodes.Walk(dumper)
|
||||
|
||||
// Unordered output:
|
||||
// {"type":"*node.Root","position":{"startPos":10,"endPos":166,"startLine":3,"endLine":12},"Stmts":[{"type":"*stmt.Namespace","position":{"startPos":10,"endPos":166,"startLine":3,"endLine":12},"NamespaceName":{"type":"*name.Name","position":{"startPos":20,"endPos":22,"startLine":3,"endLine":3},"Parts":[{"type":"*name.NamePart","position":{"startPos":20,"endPos":22,"startLine":3,"endLine":3},"Value":"Foo"}]},"Stmts":[{"type":"*stmt.Class","position":{"startPos":29,"endPos":162,"startLine":4,"endLine":11},"namespacedName":"Foo\\Bar","PhpDocComment":"","ClassName":{"type":"*node.Identifier","position":{"startPos":35,"endPos":37,"startLine":4,"endLine":4},"Value":"Bar"},"Stmts":[{"type":"*stmt.ClassMethod","position":{"startPos":45,"endPos":157,"startLine":5,"endLine":10},"ReturnsRef":false,"PhpDocComment":"","MethodName":{"type":"*node.Identifier","position":{"startPos":61,"endPos":72,"startLine":5,"endLine":5},"Value":"FunctionName"},"Modifiers":[{"type":"*node.Identifier","position":{"startPos":45,"endPos":50,"startLine":5,"endLine":5},"Value":"public"}],"Params":[{"type":"*node.Parameter","position":{"startPos":74,"endPos":89,"startLine":5,"endLine":5},"ByRef":false,"Variadic":false,"VariableType":{"type":"*name.Name","position":{"startPos":74,"endPos":77,"startLine":5,"endLine":5},"namespacedName":"Foo\\Type","Parts":[{"type":"*name.NamePart","position":{"startPos":74,"endPos":77,"startLine":5,"endLine":5},"Value":"Type"}]},"Variable":{"type":"*expr.Variable","position":{"startPos":79,"endPos":82,"startLine":5,"endLine":5},"VarName":{"type":"*node.Identifier","position":{"startPos":79,"endPos":82,"startLine":5,"endLine":5},"Value":"var"}},"DefaultValue":{"type":"*expr.ConstFetch","position":{"startPos":86,"endPos":89,"startLine":5,"endLine":5},"Constant":{"type":"*name.Name","position":{"startPos":86,"endPos":89,"startLine":5,"endLine":5},"namespacedName":"null","Parts":[{"type":"*name.NamePart","position":{"startPos":86,"endPos":89,"startLine":5,"endLine":5},"Value":"null"}]}}}],"Stmt":{"type":"*stmt.StmtList","position":{"startPos":96,"endPos":157,"startLine":6,"endLine":10},"Stmts":[{"type":"*stmt.Expression","position":{"startPos":147,"endPos":151,"startLine":9,"endLine":9},"Expr":{"type":"*expr.Variable","position":{"startPos":147,"endPos":150,"startLine":9,"endLine":9},"comments":["// some comment\n","// second comment\n"],"VarName":{"type":"*node.Identifier","position":{"startPos":147,"endPos":150,"startLine":9,"endLine":9},"Value":"var"}}}]}}]}]}]}
|
||||
}
|
145
visitor/pretty_json_dumper.go
Normal file
145
visitor/pretty_json_dumper.go
Normal file
@ -0,0 +1,145 @@
|
||||
// Package visitor contains walker.visitor implementations
|
||||
package visitor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
|
||||
"github.com/z7zmey/php-parser/node"
|
||||
"github.com/z7zmey/php-parser/parser"
|
||||
|
||||
"github.com/z7zmey/php-parser/walker"
|
||||
)
|
||||
|
||||
type PrettyJsonDumper struct {
|
||||
Writer io.Writer
|
||||
Comments parser.Comments
|
||||
Positions parser.Positions
|
||||
NsResolver *NamespaceResolver
|
||||
depth int
|
||||
isChildNode bool
|
||||
}
|
||||
|
||||
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
|
||||
} else {
|
||||
d.printIndent(d.Writer)
|
||||
}
|
||||
|
||||
fmt.Fprint(d.Writer, "{\n")
|
||||
d.depth++
|
||||
d.printIndent(d.Writer)
|
||||
fmt.Fprintf(d.Writer, "%q: %q", "type", nodeType)
|
||||
|
||||
if d.Positions != nil {
|
||||
if p := d.Positions[n]; 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, "}")
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
if d.Comments != nil {
|
||||
if c := d.Comments[n]; len(c) > 0 {
|
||||
fmt.Fprint(d.Writer, ",\n")
|
||||
d.printIndent(d.Writer)
|
||||
fmt.Fprint(d.Writer, "\"comments\": [\n")
|
||||
d.depth++
|
||||
for k, cc := range c {
|
||||
if k == 0 {
|
||||
d.printIndent(d.Writer)
|
||||
fmt.Fprintf(d.Writer, "%q", cc)
|
||||
} else {
|
||||
fmt.Fprint(d.Writer, ",\n")
|
||||
d.printIndent(d.Writer)
|
||||
fmt.Fprintf(d.Writer, "%q", cc)
|
||||
}
|
||||
}
|
||||
d.depth--
|
||||
fmt.Fprint(d.Writer, "\n")
|
||||
d.printIndent(d.Writer)
|
||||
fmt.Fprint(d.Writer, "]")
|
||||
}
|
||||
}
|
||||
|
||||
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++
|
||||
}
|
||||
|
||||
func (d *PrettyJsonDumper) LeaveChildList(key string, w walker.Walkable) {
|
||||
d.depth--
|
||||
fmt.Fprint(d.Writer, "\n")
|
||||
d.printIndent(d.Writer)
|
||||
fmt.Fprint(d.Writer, "]")
|
||||
}
|
269
visitor/pretty_json_dumper_test.go
Normal file
269
visitor/pretty_json_dumper_test.go
Normal file
@ -0,0 +1,269 @@
|
||||
//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 ExamplePrettyJsonDumper() {
|
||||
src := `<?php
|
||||
|
||||
namespace Foo {
|
||||
class Bar {
|
||||
public function FunctionName(Type $var = null)
|
||||
{
|
||||
// some comment
|
||||
// second comment
|
||||
$var;
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
php7parser := php7.NewParser(bytes.NewBufferString(src), "test.php")
|
||||
php7parser.Parse()
|
||||
nodes := php7parser.GetRootNode()
|
||||
|
||||
nsResolver := visitor.NewNamespaceResolver()
|
||||
nodes.Walk(nsResolver)
|
||||
|
||||
dumper := &visitor.PrettyJsonDumper{
|
||||
Writer: os.Stdout,
|
||||
Comments: php7parser.GetComments(),
|
||||
Positions: php7parser.GetPositions(),
|
||||
NsResolver: nsResolver,
|
||||
}
|
||||
nodes.Walk(dumper)
|
||||
|
||||
// Unordered output:
|
||||
// {
|
||||
// "type": "*node.Root",
|
||||
// "position": {
|
||||
// "startPos": 10,
|
||||
// "endPos": 166,
|
||||
// "startLine": 3,
|
||||
// "endLine": 12
|
||||
// },
|
||||
// "Stmts": [
|
||||
// {
|
||||
// "type": "*stmt.Namespace",
|
||||
// "position": {
|
||||
// "startPos": 10,
|
||||
// "endPos": 166,
|
||||
// "startLine": 3,
|
||||
// "endLine": 12
|
||||
// },
|
||||
// "NamespaceName": {
|
||||
// "type": "*name.Name",
|
||||
// "position": {
|
||||
// "startPos": 20,
|
||||
// "endPos": 22,
|
||||
// "startLine": 3,
|
||||
// "endLine": 3
|
||||
// },
|
||||
// "Parts": [
|
||||
// {
|
||||
// "type": "*name.NamePart",
|
||||
// "position": {
|
||||
// "startPos": 20,
|
||||
// "endPos": 22,
|
||||
// "startLine": 3,
|
||||
// "endLine": 3
|
||||
// },
|
||||
// "Value": "Foo"
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// "Stmts": [
|
||||
// {
|
||||
// "type": "*stmt.Class",
|
||||
// "position": {
|
||||
// "startPos": 29,
|
||||
// "endPos": 162,
|
||||
// "startLine": 4,
|
||||
// "endLine": 11
|
||||
// },
|
||||
// "namespacedName": "Foo\\Bar",
|
||||
// "PhpDocComment": "",
|
||||
// "ClassName": {
|
||||
// "type": "*node.Identifier",
|
||||
// "position": {
|
||||
// "startPos": 35,
|
||||
// "endPos": 37,
|
||||
// "startLine": 4,
|
||||
// "endLine": 4
|
||||
// },
|
||||
// "Value": "Bar"
|
||||
// },
|
||||
// "Stmts": [
|
||||
// {
|
||||
// "type": "*stmt.ClassMethod",
|
||||
// "position": {
|
||||
// "startPos": 45,
|
||||
// "endPos": 157,
|
||||
// "startLine": 5,
|
||||
// "endLine": 10
|
||||
// },
|
||||
// "ReturnsRef": false,
|
||||
// "PhpDocComment": "",
|
||||
// "MethodName": {
|
||||
// "type": "*node.Identifier",
|
||||
// "position": {
|
||||
// "startPos": 61,
|
||||
// "endPos": 72,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "Value": "FunctionName"
|
||||
// },
|
||||
// "Modifiers": [
|
||||
// {
|
||||
// "type": "*node.Identifier",
|
||||
// "position": {
|
||||
// "startPos": 45,
|
||||
// "endPos": 50,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "Value": "public"
|
||||
// }
|
||||
// ],
|
||||
// "Params": [
|
||||
// {
|
||||
// "type": "*node.Parameter",
|
||||
// "position": {
|
||||
// "startPos": 74,
|
||||
// "endPos": 89,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "ByRef": false,
|
||||
// "Variadic": false,
|
||||
// "VariableType": {
|
||||
// "type": "*name.Name",
|
||||
// "position": {
|
||||
// "startPos": 74,
|
||||
// "endPos": 77,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "namespacedName": "Foo\\Type",
|
||||
// "Parts": [
|
||||
// {
|
||||
// "type": "*name.NamePart",
|
||||
// "position": {
|
||||
// "startPos": 74,
|
||||
// "endPos": 77,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "Value": "Type"
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
// "Variable": {
|
||||
// "type": "*expr.Variable",
|
||||
// "position": {
|
||||
// "startPos": 79,
|
||||
// "endPos": 82,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "VarName": {
|
||||
// "type": "*node.Identifier",
|
||||
// "position": {
|
||||
// "startPos": 79,
|
||||
// "endPos": 82,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "Value": "var"
|
||||
// }
|
||||
// },
|
||||
// "DefaultValue": {
|
||||
// "type": "*expr.ConstFetch",
|
||||
// "position": {
|
||||
// "startPos": 86,
|
||||
// "endPos": 89,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "Constant": {
|
||||
// "type": "*name.Name",
|
||||
// "position": {
|
||||
// "startPos": 86,
|
||||
// "endPos": 89,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "namespacedName": "null",
|
||||
// "Parts": [
|
||||
// {
|
||||
// "type": "*name.NamePart",
|
||||
// "position": {
|
||||
// "startPos": 86,
|
||||
// "endPos": 89,
|
||||
// "startLine": 5,
|
||||
// "endLine": 5
|
||||
// },
|
||||
// "Value": "null"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ],
|
||||
// "Stmt": {
|
||||
// "type": "*stmt.StmtList",
|
||||
// "position": {
|
||||
// "startPos": 96,
|
||||
// "endPos": 157,
|
||||
// "startLine": 6,
|
||||
// "endLine": 10
|
||||
// },
|
||||
// "Stmts": [
|
||||
// {
|
||||
// "type": "*stmt.Expression",
|
||||
// "position": {
|
||||
// "startPos": 147,
|
||||
// "endPos": 151,
|
||||
// "startLine": 9,
|
||||
// "endLine": 9
|
||||
// },
|
||||
// "Expr": {
|
||||
// "type": "*expr.Variable",
|
||||
// "position": {
|
||||
// "startPos": 147,
|
||||
// "endPos": 150,
|
||||
// "startLine": 9,
|
||||
// "endLine": 9
|
||||
// },
|
||||
// "comments": [
|
||||
// "// some comment\n",
|
||||
// "// second comment\n"
|
||||
// ],
|
||||
// "VarName": {
|
||||
// "type": "*node.Identifier",
|
||||
// "position": {
|
||||
// "startPos": 147,
|
||||
// "endPos": 150,
|
||||
// "startLine": 9,
|
||||
// "endLine": 9
|
||||
// },
|
||||
// "Value": "var"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
}
|
Loading…
Reference in New Issue
Block a user