Commit fe59d86d authored by David Symonds's avatar David Symonds

exp/template: fix implementation of printValue.

R=r
CC=golang-dev
https://golang.org/cl/4878042
parent 3cca9e0b
...@@ -620,19 +620,23 @@ func indirect(v reflect.Value) (rv reflect.Value, isNil bool) { ...@@ -620,19 +620,23 @@ func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
// printValue writes the textual representation of the value to the output of // printValue writes the textual representation of the value to the output of
// the template. // the template.
func (s *state) printValue(n parse.Node, v reflect.Value) { func (s *state) printValue(n parse.Node, v reflect.Value) {
if v.Kind() == reflect.Ptr {
v, _ = indirect(v) // fmt.Fprint handles nil.
}
if !v.IsValid() { if !v.IsValid() {
fmt.Fprint(s.wr, "<no value>") fmt.Fprint(s.wr, "<no value>")
return return
} }
if !v.Type().Implements(fmtStringerType) {
if v.CanAddr() && reflect.PtrTo(v.Type()).Implements(fmtStringerType) {
v = v.Addr()
} else {
switch v.Kind() { switch v.Kind() {
case reflect.Ptr: case reflect.Chan, reflect.Func:
v, _ = indirect(v) // fmt.Fprint handles nil.
case reflect.Chan, reflect.Func, reflect.Interface:
s.errorf("can't print %s of type %s", n, v.Type()) s.errorf("can't print %s of type %s", n, v.Type())
} }
// If it's a value but the pointer implements Stringer, use the pointer. }
if v.Kind() != reflect.Ptr && v.CanAddr() && reflect.PtrTo(v.Type()).Implements(fmtStringerType) {
v = v.Addr()
} }
fmt.Fprint(s.wr, v.Interface()) fmt.Fprint(s.wr, v.Interface())
} }
...@@ -48,6 +48,8 @@ type T struct { ...@@ -48,6 +48,8 @@ type T struct {
Empty4 interface{} Empty4 interface{}
// Non-empty interface. // Non-empty interface.
NonEmptyInterface I NonEmptyInterface I
// Stringer.
Str fmt.Stringer
// Pointers // Pointers
PI *int PI *int
PSI *[]int PSI *[]int
...@@ -92,6 +94,7 @@ var tVal = &T{ ...@@ -92,6 +94,7 @@ var tVal = &T{
Empty3: []int{7, 8}, Empty3: []int{7, 8},
Empty4: &U{"UinEmpty"}, Empty4: &U{"UinEmpty"},
NonEmptyInterface: new(T), NonEmptyInterface: new(T),
Str: os.NewError("foozle"),
PI: newInt(23), PI: newInt(23),
PSI: newIntSlice(21, 22, 23), PSI: newIntSlice(21, 22, 23),
Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X Tmpl: Must(New("x").Parse("test template")), // "x" is the value of .X
...@@ -396,6 +399,8 @@ var execTests = []execTest{ ...@@ -396,6 +399,8 @@ var execTests = []execTest{
{"bug3", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true}, {"bug3", "{{with $}}{{.Method0}}{{end}}", "M0", tVal, true},
// Nil interface values in if. // Nil interface values in if.
{"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true}, {"bug4", "{{if .Empty0}}non-nil{{else}}nil{{end}}", "nil", tVal, true},
// Stringer.
{"bug5", "{{.Str}}", "foozle", tVal, true},
} }
func zeroArgs() string { func zeroArgs() string {
......
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