]> Cypherpunks repositories - gostls13.git/commitdiff
text/template: evaluate function fields
authorRob Pike <r@golang.org>
Wed, 15 Feb 2012 05:05:34 +0000 (16:05 +1100)
committerRob Pike <r@golang.org>
Wed, 15 Feb 2012 05:05:34 +0000 (16:05 +1100)
Just an oversight they didn't work and easy to address.

Fixes #3025.

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/5656059

src/pkg/text/template/exec.go
src/pkg/text/template/exec_test.go

index 973189a8a62c97de524bab028c4e730f0af023dd..af745286c0bc3f6bc553c2f0e4a55a30be18fcb1 100644 (file)
@@ -419,10 +419,14 @@ func (s *state) evalField(dot reflect.Value, fieldName string, args []parse.Node
                tField, ok := receiver.Type().FieldByName(fieldName)
                if ok {
                        field := receiver.FieldByIndex(tField.Index)
-                       if hasArgs {
-                               s.errorf("%s is not a method but has arguments", fieldName)
-                       }
                        if tField.PkgPath == "" { // field is exported
+                               // If it's a function, we must call it.
+                               if field.Type().Kind() == reflect.Func {
+                                       return s.evalCall(dot, field, fieldName, args, final)
+                               }
+                               if hasArgs {
+                                       s.errorf("%s is not a method or function but has arguments", fieldName)
+                               }
                                return field
                        }
                }
index 9bb55e48aac602df616d5d2edd924a8acbeb06b2..159cf5100d933eaf0217bf685bc6f20e05d0915a 100644 (file)
@@ -59,6 +59,8 @@ type T struct {
        PI  *int
        PSI *[]int
        NIL *int
+       // Function (not method)
+       Func func(...string) string
        // Template to test evaluation of templates.
        Tmpl *Template
 }
@@ -118,6 +120,7 @@ var tVal = &T{
        Err:               errors.New("erroozle"),
        PI:                newInt(23),
        PSI:               newIntSlice(21, 22, 23),
+       Func:              func(s ...string) string { return fmt.Sprint("<", strings.Join(s, "+"), ">") },
        Tmpl:              Must(New("x").Parse("test template")), // "x" is the value of .X
 }
 
@@ -297,8 +300,13 @@ var execTests = []execTest{
                "{{with $x := .}}{{with .SI}}{{$.GetU.TrueFalse $.True}}{{end}}{{end}}",
                "true", tVal, true},
 
+       // Function call
+       {".Func", "-{{.Func}}-", "-<>-", tVal, true},
+       {".Func2", "-{{.Func `he` `llo`}}-", "-<he+llo>-", tVal, true},
+
        // Pipelines.
        {"pipeline", "-{{.Method0 | .Method2 .U16}}-", "-Method2: 16 M0-", tVal, true},
+       {"pipeline func", "-{{.Func `llo` | .Func `he` }}-", "-<he+<llo>>-", tVal, true},
 
        // If.
        {"if true", "{{if true}}TRUE{{end}}", "TRUE", tVal, true},