aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/text/template
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2011-12-01 17:24:54 -0800
committerRob Pike <r@golang.org>2011-12-01 17:24:54 -0800
commite6b3371781d4f7b07c2c7c4e2f2ef4c4e7233225 (patch)
tree6bd8ed831f3f50f11c37133827bdc282aa0610e7 /src/pkg/text/template
parenta5d300862b683e6a6d0e503c213d191155d1f63b (diff)
downloadgo-e6b3371781d4f7b07c2c7c4e2f2ef4c4e7233225.tar.xz
template: move the empty check into parse, which needs it when constructing
tree sets. R=golang-dev, gri CC=golang-dev https://golang.org/cl/5449062
Diffstat (limited to 'src/pkg/text/template')
-rw-r--r--src/pkg/text/template/multi_test.go29
-rw-r--r--src/pkg/text/template/parse/parse.go32
-rw-r--r--src/pkg/text/template/parse/parse_test.go29
-rw-r--r--src/pkg/text/template/template.go28
4 files changed, 61 insertions, 57 deletions
diff --git a/src/pkg/text/template/multi_test.go b/src/pkg/text/template/multi_test.go
index 7b35d2633d..3abb51f338 100644
--- a/src/pkg/text/template/multi_test.go
+++ b/src/pkg/text/template/multi_test.go
@@ -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
diff --git a/src/pkg/text/template/parse/parse.go b/src/pkg/text/template/parse/parse.go
index 346f613b04..4da756657d 100644
--- a/src/pkg/text/template/parse/parse.go
+++ b/src/pkg/text/template/parse/parse.go
@@ -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
diff --git a/src/pkg/text/template/parse/parse_test.go b/src/pkg/text/template/parse/parse_test.go
index fc93455ecb..b70c2143d3 100644
--- a/src/pkg/text/template/parse/parse_test.go
+++ b/src/pkg/text/template/parse/parse_test.go
@@ -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)
+ }
+ }
+}
diff --git a/src/pkg/text/template/template.go b/src/pkg/text/template/template.go
index 04fca407c1..cbc6808174 100644
--- a/src/pkg/text/template/template.go
+++ b/src/pkg/text/template/template.go
@@ -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
-}