tplimpl: Fix issue with recursive templates

Fixes #2927
This commit is contained in:
Bjørn Erik Pedersen 2017-02-18 09:08:00 +01:00
parent 4493e8ed9f
commit bdc02edfa8
2 changed files with 34 additions and 5 deletions

View file

@ -35,12 +35,21 @@ var paramsPaths = [][]string{
} }
type templateContext struct { type templateContext struct {
decl decl decl decl
templ *template.Template templ *template.Template
visited map[string]bool
}
func (c templateContext) getIfNotVisited(name string) *template.Template {
if c.visited[name] {
return nil
}
c.visited[name] = true
return c.templ.Lookup(name)
} }
func newTemplateContext(templ *template.Template) *templateContext { func newTemplateContext(templ *template.Template) *templateContext {
return &templateContext{templ: templ, decl: make(map[string]string)} return &templateContext{templ: templ, decl: make(map[string]string), visited: make(map[string]bool)}
} }
@ -59,7 +68,6 @@ func applyTemplateTransformers(templ *template.Template) error {
// paramsKeysToLower is made purposely non-generic to make it not so tempting // paramsKeysToLower is made purposely non-generic to make it not so tempting
// to do more of these hard-to-maintain AST transformations. // to do more of these hard-to-maintain AST transformations.
func (c *templateContext) paramsKeysToLower(n parse.Node) { func (c *templateContext) paramsKeysToLower(n parse.Node) {
switch x := n.(type) { switch x := n.(type) {
case *parse.ListNode: case *parse.ListNode:
if x != nil { if x != nil {
@ -74,7 +82,7 @@ func (c *templateContext) paramsKeysToLower(n parse.Node) {
case *parse.RangeNode: case *parse.RangeNode:
c.paramsKeysToLowerForNodes(x.Pipe, x.List, x.ElseList) c.paramsKeysToLowerForNodes(x.Pipe, x.List, x.ElseList)
case *parse.TemplateNode: case *parse.TemplateNode:
subTempl := c.templ.Lookup(x.Name) subTempl := c.getIfNotVisited(x.Name)
if subTempl != nil { if subTempl != nil {
c.paramsKeysToLowerForNodes(subTempl.Tree.Root) c.paramsKeysToLowerForNodes(subTempl.Tree.Root)
} }

View file

@ -267,3 +267,24 @@ P2: {{ .Params.LOWER }}
require.Contains(t, result, "P1: P1L") require.Contains(t, result, "P1: P1L")
require.Contains(t, result, "P2: P1L") require.Contains(t, result, "P2: P1L")
} }
// Issue #2927
func TestTransformRecursiveTemplate(t *testing.T) {
recursive := `
{{ define "menu-nodes" }}
{{ template "menu-node" }}
{{ end }}
{{ define "menu-node" }}
{{ template "menu-node" }}
{{ end }}
{{ template "menu-nodes" }}
`
templ, err := template.New("foo").Parse(recursive)
require.NoError(t, err)
c := newTemplateContext(templ)
c.paramsKeysToLower(templ.Tree.Root)
}