]> Cypherpunks repositories - gostls13.git/commitdiff
template: move the empty check into parse, which needs it when constructing
authorRob Pike <r@golang.org>
Fri, 2 Dec 2011 01:24:54 +0000 (17:24 -0800)
committerRob Pike <r@golang.org>
Fri, 2 Dec 2011 01:24:54 +0000 (17:24 -0800)
tree sets.

R=golang-dev, gri
CC=golang-dev
https://golang.org/cl/5449062

src/pkg/text/template/multi_test.go
src/pkg/text/template/parse/parse.go
src/pkg/text/template/parse/parse_test.go
src/pkg/text/template/template.go

index 7b35d2633d5786953fed16142593694de282ecc0..3abb51f3383b9d9c8a074108269517331e031117 100644 (file)
@@ -13,35 +13,6 @@ import (
        "text/template/parse"
 )
 
-type isEmptyTest struct {
-       name  string
-       input string
-       empty bool
-}
-
-var isEmptyTests = []isEmptyTest{
-       {"empty", ``, true},
-       {"nonempty", `hello`, false},
-       {"spaces only", " \t\n \t\n", true},
-       {"definition", `{{define "x"}}something{{end}}`, true},
-       {"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true},
-       {"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n}}", false},
-       {"definition and action", "{{define `x`}}something{{end}}{{if 3}}foo{{end}}", false},
-}
-
-func TestIsEmpty(t *testing.T) {
-       for _, test := range isEmptyTests {
-               template, err := New("root").Parse(test.input)
-               if err != nil {
-                       t.Errorf("%q: unexpected error: %v", test.name, err)
-                       continue
-               }
-               if empty := isEmpty(template.Root); empty != test.empty {
-                       t.Errorf("%q: expected %t got %t", test.name, test.empty, empty)
-               }
-       }
-}
-
 const (
        noError  = true
        hasError = false
index 346f613b048398e8bda870c62a6998a73085c45b..4da756657d5201c152a42b13050c628407603bce 100644 (file)
@@ -7,6 +7,7 @@
 package parse
 
 import (
+       "bytes"
        "fmt"
        "runtime"
        "strconv"
@@ -177,10 +178,37 @@ func (t *Tree) Parse(s, leftDelim, rightDelim string, treeSet map[string]*Tree,
 
 // add adds tree to the treeSet.
 func (t *Tree) add(treeSet map[string]*Tree) {
-       if _, present := treeSet[t.Name]; present {
+       tree := treeSet[t.Name]
+       if tree == nil || IsEmptyTree(tree.Root) {
+               treeSet[t.Name] = t
+               return
+       }
+       if !IsEmptyTree(t.Root) {
                t.errorf("template: multiple definition of template %q", t.Name)
        }
-       treeSet[t.Name] = t
+}
+
+// IsEmptyTree reports whether this tree (node) is empty of everything but space.
+func IsEmptyTree(n Node) bool {
+       switch n := n.(type) {
+       case *ActionNode:
+       case *IfNode:
+       case *ListNode:
+               for _, node := range n.Nodes {
+                       if !IsEmptyTree(node) {
+                               return false
+                       }
+               }
+               return true
+       case *RangeNode:
+       case *TemplateNode:
+       case *TextNode:
+               return len(bytes.TrimSpace(n.Text)) == 0
+       case *WithNode:
+       default:
+               panic("unknown node: " + n.String())
+       }
+       return false
 }
 
 // parse is the top-level parser for a template, essentially the same
index fc93455ecbc1fbc1781356745ba857e478d82dec..b70c2143d3de186bd900e8213fa49a864fa1327e 100644 (file)
@@ -257,3 +257,32 @@ func TestParse(t *testing.T) {
                }
        }
 }
+
+type isEmptyTest struct {
+       name  string
+       input string
+       empty bool
+}
+
+var isEmptyTests = []isEmptyTest{
+       {"empty", ``, true},
+       {"nonempty", `hello`, false},
+       {"spaces only", " \t\n \t\n", true},
+       {"definition", `{{define "x"}}something{{end}}`, true},
+       {"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true},
+       {"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n}}", false},
+       {"definition and action", "{{define `x`}}something{{end}}{{if 3}}foo{{end}}", false},
+}
+
+func TestIsEmpty(t *testing.T) {
+       for _, test := range isEmptyTests {
+               tree, err := New("root").Parse(test.input, "", "", make(map[string]*Tree), nil)
+               if err != nil {
+                       t.Errorf("%q: unexpected error: %v", test.name, err)
+                       continue
+               }
+               if empty := IsEmptyTree(tree.Root); empty != test.empty {
+                       t.Errorf("%q: expected %t got %t", test.name, test.empty, empty)
+               }
+       }
+}
index 04fca407c10783b2469d4246edfc66391289589d..cbc68081748e46650ca5e3d8cad7ee0c41cc01d0 100644 (file)
@@ -5,7 +5,6 @@
 package template
 
 import (
-       "bytes"
        "fmt"
        "reflect"
        "text/template/parse"
@@ -198,8 +197,8 @@ func (t *Template) associate(new *Template) error {
        }
        name := new.name
        if old := t.tmpl[name]; old != nil {
-               oldIsEmpty := isEmpty(old.Root)
-               newIsEmpty := isEmpty(new.Root)
+               oldIsEmpty := parse.IsEmptyTree(old.Root)
+               newIsEmpty := parse.IsEmptyTree(new.Root)
                if !oldIsEmpty && !newIsEmpty {
                        return fmt.Errorf("template: redefinition of template %q", name)
                }
@@ -211,26 +210,3 @@ func (t *Template) associate(new *Template) error {
        t.tmpl[name] = new
        return nil
 }
-
-// isEmpty reports whether this tree (node) is empty of everything but space.
-func isEmpty(n parse.Node) bool {
-       switch n := n.(type) {
-       case *parse.ActionNode:
-       case *parse.IfNode:
-       case *parse.ListNode:
-               for _, node := range n.Nodes {
-                       if !isEmpty(node) {
-                               return false
-                       }
-               }
-               return true
-       case *parse.RangeNode:
-       case *parse.TemplateNode:
-       case *parse.TextNode:
-               return len(bytes.TrimSpace(n.Text)) == 0
-       case *parse.WithNode:
-       default:
-               panic("unknown node: " + n.String())
-       }
-       return false
-}