1
0
mirror of https://github.com/golang/go synced 2024-11-25 06:47:56 -07:00

implement .repeats for maps.

Fixes #309.

R=rsc
CC=golang-dev
https://golang.org/cl/181044
This commit is contained in:
Rob Pike 2009-12-24 07:41:56 +11:00
parent 8c557962de
commit 96da3e96c3
2 changed files with 37 additions and 27 deletions

View File

@ -833,10 +833,8 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
} }
first := true first := true
if array, ok := field.(reflect.ArrayOrSliceValue); ok { // Code common to all the loops.
for j := 0; j < array.Len(); j++ { loopBody := func(newst *state) {
newst := st.clone(array.Elem(j))
// .alternates between elements // .alternates between elements
if !first && r.altstart >= 0 { if !first && r.altstart >= 0 {
for i := r.altstart; i < r.altend; { for i := r.altstart; i < r.altend; {
@ -844,30 +842,26 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
} }
} }
first = false first = false
for i := start; i < end; { for i := start; i < end; {
i = t.executeElement(i, newst) 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 { } else if ch := iter(field); ch != nil {
for { for {
e := ch.Recv() e := ch.Recv()
if ch.Closed() { if ch.Closed() {
break break
} }
newst := st.clone(e) loopBody(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)
}
} }
} else { } else {
t.execError(st, r.linenum, ".repeated: cannot repeat %s (type %s)", t.execError(st, r.linenum, ".repeated: cannot repeat %s (type %s)",

View File

@ -42,6 +42,7 @@ type S struct {
false bool false bool
mp map[string]string mp map[string]string
innermap U innermap U
stringmap map[string]string
bytes []byte bytes []byte
} }
@ -314,12 +315,24 @@ var tests = []*Test{
out: "Ahoy!\n", out: "Ahoy!\n",
}, },
&Test{ &Test{
in: "{innermap.mp.innerkey}\n", in: "{innermap.mp.innerkey}\n",
out: "55\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) { func TestAll(t *testing.T) {
@ -342,6 +355,9 @@ func TestAll(t *testing.T) {
s.mp["mapkey"] = "Ahoy!" s.mp["mapkey"] = "Ahoy!"
s.innermap.mp = make(map[string]int) s.innermap.mp = make(map[string]int)
s.innermap.mp["innerkey"] = 55 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") s.bytes = strings.Bytes("hello")
var buf bytes.Buffer var buf bytes.Buffer