text/template: new, simpler API

The Set type is gone. Instead, templates are automatically associated by
being parsed together; nested definitions implicitly create associations.
Only associated templates can invoke one another.

This approach dramatically reduces the breadth of the construction API.

For now, html/template is deleted from src/pkg/Makefile, so this can
be checked in. Nothing in the tree depends on it. It will be updated next.

R=dsymonds, adg, rsc, r, gri, mikesamuel, nigeltao
CC=golang-dev
https://golang.org/cl/5415060
diff --git a/src/pkg/text/template/parse/parse.go b/src/pkg/text/template/parse/parse.go
index c0491e5..36c5403 100644
--- a/src/pkg/text/template/parse/parse.go
+++ b/src/pkg/text/template/parse/parse.go
@@ -97,6 +97,15 @@
 	return token
 }
 
+// expectEither consumes the next token and guarantees it has one of the required types.
+func (t *Tree) expectOneOf(expected1, expected2 itemType, context string) item {
+	token := t.next()
+	if token.typ != expected1 && token.typ != expected2 {
+		t.errorf("expected %s or %s in %s; got %s", expected1, expected2, context, token)
+	}
+	return token
+}
+
 // unexpected complains about the token and terminates processing.
 func (t *Tree) unexpected(token item, context string) {
 	t.errorf("unexpected %s in %s", token, context)
@@ -162,9 +171,18 @@
 	t.startParse(funcs, lex(t.Name, s, leftDelim, rightDelim))
 	t.parse(treeSet)
 	t.stopParse()
+	t.add(treeSet)
 	return t, nil
 }
 
+// add adds tree to the treeSet.
+func (t *Tree) add(treeSet map[string]*Tree) {
+	if _, present := treeSet[t.Name]; present {
+		t.errorf("template: multiple definition of template %q", t.Name)
+	}
+	treeSet[t.Name] = t
+}
+
 // parse is the top-level parser for a template, essentially the same
 // as itemList except it also parses {{define}} actions.
 // It runs to EOF.
@@ -174,7 +192,7 @@
 		if t.peek().typ == itemLeftDelim {
 			delim := t.next()
 			if t.next().typ == itemDefine {
-				newT := New("new definition") // name will be updated once we know it.
+				newT := New("definition") // name will be updated once we know it.
 				newT.startParse(t.funcs, t.lex)
 				newT.parseDefinition(treeSet)
 				continue
@@ -194,11 +212,8 @@
 // installs the definition in the treeSet map.  The "define" keyword has already
 // been scanned.
 func (t *Tree) parseDefinition(treeSet map[string]*Tree) {
-	if treeSet == nil {
-		t.errorf("no set specified for template definition")
-	}
 	const context = "define clause"
-	name := t.expect(itemString, context)
+	name := t.expectOneOf(itemString, itemRawString, context)
 	var err error
 	t.Name, err = strconv.Unquote(name.val)
 	if err != nil {
@@ -211,10 +226,7 @@
 		t.errorf("unexpected %s in %s", end, context)
 	}
 	t.stopParse()
-	if _, present := treeSet[t.Name]; present {
-		t.errorf("template: %q multiply defined", name)
-	}
-	treeSet[t.Name] = t
+	t.add(treeSet)
 }
 
 // itemList:
diff --git a/src/pkg/text/template/parse/parse_test.go b/src/pkg/text/template/parse/parse_test.go
index 5c10086..fc93455 100644
--- a/src/pkg/text/template/parse/parse_test.go
+++ b/src/pkg/text/template/parse/parse_test.go
@@ -236,7 +236,7 @@
 
 func TestParse(t *testing.T) {
 	for _, test := range parseTests {
-		tmpl, err := New(test.name).Parse(test.input, "", "", nil, builtins)
+		tmpl, err := New(test.name).Parse(test.input, "", "", make(map[string]*Tree), builtins)
 		switch {
 		case err == nil && !test.ok:
 			t.Errorf("%q: expected error; got none", test.name)