forked from CloudyKit/jet
-
Notifications
You must be signed in to change notification settings - Fork 0
/
dump.go
108 lines (94 loc) · 2.83 KB
/
dump.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
package jet
import (
"bytes"
"fmt"
"io"
"reflect"
)
// dumpAll returns
// - everything in Runtime.context
// - everything in Runtime.variables
// - everything in Runtime.set.globals
// - everything in Runtime.blocks
func dumpAll(a Arguments, depth int) reflect.Value {
var b bytes.Buffer
var vars VarMap
ctx := a.runtime.context
fmt.Fprintln(&b, "Context:")
fmt.Fprintf(&b, "\t%s %#v\n", ctx.Type(), ctx)
dumpScopeVars(&b, a.runtime.scope, 0)
dumpScopeVarsToDepth(&b, a.runtime.parent, depth)
vars = a.runtime.set.globals
for i, name := range vars.SortedKeys() {
if i == 0 {
fmt.Fprintln(&b, "Globals:")
}
val := vars[name]
fmt.Fprintf(&b, "\t%s:=%#v // %s\n", name, val, val.Type())
}
blockKeys := a.runtime.scope.sortedBlocks()
fmt.Fprintln(&b, "Blocks:")
for _, k := range blockKeys {
block := a.runtime.blocks[k]
dumpBlock(&b, block)
}
return reflect.ValueOf(b.String())
}
// dumpScopeVarsToDepth prints all variables in the scope, and all parent scopes,
// to the limit of maxDepth.
func dumpScopeVarsToDepth(w io.Writer, scope *scope, maxDepth int) {
for i := 1; i <= maxDepth; i++ {
if scope == nil {
break // do not panic if something bad happens
}
dumpScopeVars(w, scope, i)
scope = scope.parent
}
}
// dumpScopeVars prints all variables in the scope.
func dumpScopeVars(w io.Writer, scope *scope, lvl int) {
if scope == nil {
return // do not panic if something bad happens
}
if lvl == 0 {
fmt.Fprint(w, "Variables in current scope:\n")
} else {
fmt.Fprintf(w, "Variables in scope %d level(s) up:\n", lvl)
}
vars := scope.variables
for _, k := range vars.SortedKeys() {
fmt.Fprintf(w, "\t%s=%#v\n", k, vars[k])
}
}
// dumpIdentified accepts a runtime and slice of names.
// Then, it prints all variables and blocks in the runtime, with names equal to one of the names
// in the slice.
func dumpIdentified(rnt *Runtime, ids []string) reflect.Value {
var b bytes.Buffer
for _, id := range ids {
dumpFindVar(&b, rnt, id)
dumpFindBlock(&b, rnt, id)
}
return reflect.ValueOf(b.String())
}
// dumpFindBlock finds the block by name, prints the header of the block, and name of the template in which it was defined.
func dumpFindBlock(w io.Writer, rnt *Runtime, name string) {
if block, ok := rnt.scope.blocks[name]; ok {
dumpBlock(w, block)
}
}
// dumpBlock prints header of the block, and template in which the block was first defined.
func dumpBlock(w io.Writer, block *BlockNode) {
if block == nil {
return
}
fmt.Fprintf(w, "\tblock %s(%s), from %s\n", block.Name, block.Parameters.String(), block.TemplatePath)
}
// dumpFindBlock finds the variable by name, and prints the variable, if it is in the runtime.
func dumpFindVar(w io.Writer, rnt *Runtime, name string) {
val, err := rnt.resolve(name)
if err != nil {
return
}
fmt.Fprintf(w, "\t%s:=%#v // %s\n", name, val, val.Type())
}