mirror of
https://github.com/golang/go
synced 2024-11-25 04:17:57 -07:00
implement .repeats for maps.
Fixes #309. R=rsc CC=golang-dev https://golang.org/cl/181044
This commit is contained in:
parent
8c557962de
commit
96da3e96c3
@ -833,41 +833,35 @@ 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
|
||||||
|
if !first && r.altstart >= 0 {
|
||||||
// .alternates between elements
|
for i := r.altstart; i < r.altend; {
|
||||||
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)
|
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 {
|
} 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)",
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user