-
Notifications
You must be signed in to change notification settings - Fork 1
/
parse.go
80 lines (68 loc) · 2 KB
/
parse.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
package html
import (
"fmt"
"html/template"
"text/template/parse"
)
const (
rootTemplateName = ""
dummyTemplateName = "__dummy__"
)
func createTemplate(parsedTrees []*parse.Tree, funcs map[string]interface{}) (*template.Template, error) {
tmpl, _ := template.New(dummyTemplateName).Funcs(funcs).Parse("")
for _, tree := range parsedTrees {
var err error
tmpl, err = tmpl.AddParseTree(tree.Name, tree)
if err != nil {
return nil, err
}
}
err := validateTemplate(tmpl)
if err != nil {
return nil, err
}
return tmpl, nil
}
func validateTemplate(root *template.Template) error {
if root.Lookup(rootTemplateName) == nil {
return fmt.Errorf("html/template: missing root template")
}
needTemplates := []string{}
haveTemplates := make(map[string]bool)
for _, tmpl := range root.Templates() {
tmplName := tmpl.Tree.Name
if tmplName != "" {
haveTemplates[tmplName] = true
}
needTemplates = append(needTemplates, requiredTemplates(tmpl.Tree.Root)...)
}
var missingTemplates []string
for _, tmplName := range needTemplates {
if found := haveTemplates[tmplName]; !found {
missingTemplates = append(missingTemplates, tmplName)
}
}
if len(missingTemplates) > 0 {
return fmt.Errorf("html/template: missing template(s) %q", missingTemplates)
}
return nil
}
func requiredTemplates(root *parse.ListNode) (names []string) {
if root == nil {
return
}
for _, node := range root.Nodes {
if tnode, ok := node.(*parse.TemplateNode); ok {
names = append(names, tnode.Name)
} else if lnode, ok := node.(*parse.ListNode); ok {
names = append(names, requiredTemplates(lnode)...)
} else if bnode, ok := node.(*parse.IfNode); ok {
names = append(names, requiredTemplates(bnode.BranchNode.List)...)
names = append(names, requiredTemplates(bnode.BranchNode.ElseList)...)
} else if bnode, ok := node.(*parse.RangeNode); ok {
names = append(names, requiredTemplates(bnode.BranchNode.List)...)
names = append(names, requiredTemplates(bnode.BranchNode.ElseList)...)
}
}
return
}