Commit a33cc423 authored by Rob Pike's avatar Rob Pike

exp/template: allow an empty interface value to be the target of range, etc.

We extract the concrete value inside.

R=golang-dev, adg
CC=golang-dev
https://golang.org/cl/4677041
parent 381a555f
...@@ -183,6 +183,10 @@ func (s *state) evalPipeline(data reflect.Value, pipe []*commandNode) reflect.Va ...@@ -183,6 +183,10 @@ func (s *state) evalPipeline(data reflect.Value, pipe []*commandNode) reflect.Va
value := reflect.Value{} value := reflect.Value{}
for _, cmd := range pipe { for _, cmd := range pipe {
value = s.evalCommand(data, cmd, value) // previous value is this one's final arg. value = s.evalCommand(data, cmd, value) // previous value is this one's final arg.
// If the object has type interface{}, dig down one level to the thing inside.
if value.Kind() == reflect.Interface && value.Type().NumMethod() == 0 {
value = reflect.ValueOf(value.Interface()) // lovely!
}
} }
return value return value
} }
......
...@@ -31,6 +31,8 @@ type T struct { ...@@ -31,6 +31,8 @@ type T struct {
MSI map[string]int MSI map[string]int
MSIone map[string]int // one element, for deterministic output MSIone map[string]int // one element, for deterministic output
MSIEmpty map[string]int MSIEmpty map[string]int
// Empty interface; used to see if we can dig inside one.
EmptyInterface interface{}
} }
// Simple methods with and without arguments. // Simple methods with and without arguments.
...@@ -79,14 +81,15 @@ type U struct { ...@@ -79,14 +81,15 @@ type U struct {
} }
var tVal = &T{ var tVal = &T{
I: 17, I: 17,
U16: 16, U16: 16,
X: "x", X: "x",
U: &U{"v"}, U: &U{"v"},
SI: []int{3, 4, 5}, SI: []int{3, 4, 5},
SB: []bool{true, false}, SB: []bool{true, false},
MSI: map[string]int{"one": 1, "two": 2, "three": 3}, MSI: map[string]int{"one": 1, "two": 2, "three": 3},
MSIone: map[string]int{"one": 1}, MSIone: map[string]int{"one": 1},
EmptyInterface: []int{7, 8},
} }
type execTest struct { type execTest struct {
...@@ -187,6 +190,7 @@ var execTests = []execTest{ ...@@ -187,6 +190,7 @@ var execTests = []execTest{
{"range empty map no else", "{{range .MSIEmpty}}-{{.}}-{{end}}", "", tVal, true}, {"range empty map no else", "{{range .MSIEmpty}}-{{.}}-{{end}}", "", tVal, true},
{"range map else", "{{range .MSI | .MSort}}-{{.}}-{{else}}EMPTY{{end}}", "-one--three--two-", tVal, true}, {"range map else", "{{range .MSI | .MSort}}-{{.}}-{{else}}EMPTY{{end}}", "-one--three--two-", tVal, true},
{"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true}, {"range empty map else", "{{range .MSIEmpty}}-{{.}}-{{else}}EMPTY{{end}}", "EMPTY", tVal, true},
{"range empty interface", "{{range .EmptyInterface}}-{{.}}-{{else}}EMPTY{{end}}", "-7--8-", tVal, true},
// Error handling. // Error handling.
{"error method, error", "{{.EPERM true}}", "", tVal, false}, {"error method, error", "{{.EPERM true}}", "", tVal, false},
{"error method, no error", "{{.EPERM false}}", "false", tVal, true}, {"error method, no error", "{{.EPERM false}}", "false", tVal, true},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment