]> Cypherpunks repositories - gostls13.git/commitdiff
implement .repeats for maps.
authorRob Pike <r@golang.org>
Wed, 23 Dec 2009 20:41:56 +0000 (07:41 +1100)
committerRob Pike <r@golang.org>
Wed, 23 Dec 2009 20:41:56 +0000 (07:41 +1100)
Fixes #309.

R=rsc
CC=golang-dev
https://golang.org/cl/181044

src/pkg/template/template.go
src/pkg/template/template_test.go

index b46d28613c6fba05ca6ab724d1389e289ec6871c..ef694b24b0e48aa4a5a3085c428e625e55f9b965 100644 (file)
@@ -833,41 +833,35 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
        }
        first := true
 
-       if array, ok := field.(reflect.ArrayOrSliceValue); ok {
-               for j := 0; j < array.Len(); j++ {
-                       newst := st.clone(array.Elem(j))
-
-                       // .alternates between elements
-                       if !first && r.altstart >= 0 {
-                               for i := r.altstart; i < r.altend; {
-                                       i = t.executeElement(i, newst)
-                               }
-                       }
-                       first = false
-
-                       for i := start; i < end; {
+       // Code common to all the loops.
+       loopBody := func(newst *state) {
+               // .alternates between elements
+               if !first && r.altstart >= 0 {
+                       for i := r.altstart; i < r.altend; {
                                i = t.executeElement(i, newst)
                        }
                }
+               first = false
+               for i := start; i < end; {
+                       i = t.executeElement(i, newst)
+               }
+       }
+
+       if array, ok := field.(reflect.ArrayOrSliceValue); ok {
+               for j := 0; j < array.Len(); j++ {
+                       loopBody(st.clone(array.Elem(j)))
+               }
+       } else if m, ok := field.(*reflect.MapValue); ok {
+               for _, key := range m.Keys() {
+                       loopBody(st.clone(m.Elem(key)))
+               }
        } else if ch := iter(field); ch != nil {
                for {
                        e := ch.Recv()
                        if ch.Closed() {
                                break
                        }
-                       newst := st.clone(e)
-
-                       // .alternates between elements
-                       if !first && r.altstart >= 0 {
-                               for i := r.altstart; i < r.altend; {
-                                       i = t.executeElement(i, newst)
-                               }
-                       }
-                       first = false
-
-                       for i := start; i < end; {
-                               i = t.executeElement(i, newst)
-                       }
+                       loopBody(st.clone(e))
                }
        } else {
                t.execError(st, r.linenum, ".repeated: cannot repeat %s (type %s)",
index c2bc5125fa142bad59fc624ed1a2faa64c0aa2ef..65dae3a4903bbcef6ac18ee6aa7bc59378376438 100644 (file)
@@ -42,6 +42,7 @@ type S struct {
        false         bool
        mp            map[string]string
        innermap      U
+       stringmap     map[string]string
        bytes         []byte
 }
 
@@ -314,12 +315,24 @@ var tests = []*Test{
 
                out: "Ahoy!\n",
        },
-
        &Test{
                in: "{innermap.mp.innerkey}\n",
 
                out: "55\n",
        },
+       &Test{
+               in: "{stringmap.stringkey1}\n",
+
+               out: "stringresult\n",
+       },
+       &Test{
+               in: "{.repeated section stringmap}\n" +
+                       "{@}\n" +
+                       "{.end}",
+
+               out: "stringresult\n" +
+                       "stringresult\n",
+       },
 }
 
 func TestAll(t *testing.T) {
@@ -342,6 +355,9 @@ func TestAll(t *testing.T) {
        s.mp["mapkey"] = "Ahoy!"
        s.innermap.mp = make(map[string]int)
        s.innermap.mp["innerkey"] = 55
+       s.stringmap = make(map[string]string)
+       s.stringmap["stringkey1"] = "stringresult" // the same value so repeated section is order-independent
+       s.stringmap["stringkey2"] = "stringresult"
        s.bytes = strings.Bytes("hello")
 
        var buf bytes.Buffer