Commit a733f0bc authored by Rob Pike's avatar Rob Pike

exp/template: use MethodByName, add to build.

R=rsc, adg, r
CC=golang-dev
https://golang.org/cl/4641081
parent 22484e22
...@@ -82,6 +82,7 @@ DIRS=\ ...@@ -82,6 +82,7 @@ DIRS=\
exp/gui\ exp/gui\
exp/gui/x11\ exp/gui/x11\
exp/regexp/syntax\ exp/regexp/syntax\
exp/template\
expvar\ expvar\
flag\ flag\
fmt\ fmt\
......
...@@ -134,10 +134,7 @@ func (s *state) evalFieldNode(data reflect.Value, field *fieldNode, args []node, ...@@ -134,10 +134,7 @@ func (s *state) evalFieldNode(data reflect.Value, field *fieldNode, args []node,
} }
func (s *state) evalField(data reflect.Value, fieldName string) reflect.Value { func (s *state) evalField(data reflect.Value, fieldName string) reflect.Value {
for { for data.Kind() == reflect.Ptr {
if data.Kind() != reflect.Ptr {
break
}
data = reflect.Indirect(data) data = reflect.Indirect(data)
} }
switch data.Kind() { switch data.Kind() {
...@@ -162,12 +159,8 @@ func (s *state) evalMethodOrField(data reflect.Value, fieldName string, args []n ...@@ -162,12 +159,8 @@ func (s *state) evalMethodOrField(data reflect.Value, fieldName string, args []n
ptr, data = data, reflect.Indirect(data) ptr, data = data, reflect.Indirect(data)
} }
// Is it a method? We use the pointer because it has value methods too. // Is it a method? We use the pointer because it has value methods too.
// TODO: reflect.Type could use a MethodByName. if method, ok := ptr.Type().MethodByName(fieldName); ok {
for i := 0; i < ptr.Type().NumMethod(); i++ { return s.evalMethod(ptr, method, args, final)
method := ptr.Type().Method(i)
if method.Name == fieldName {
return s.evalMethod(ptr, i, args, final)
}
} }
if len(args) > 1 || final.IsValid() { if len(args) > 1 || final.IsValid() {
s.errorf("%s is not a method but has arguments", fieldName) s.errorf("%s is not a method but has arguments", fieldName)
...@@ -185,8 +178,7 @@ var ( ...@@ -185,8 +178,7 @@ var (
osErrorType = reflect.TypeOf(new(os.Error)).Elem() osErrorType = reflect.TypeOf(new(os.Error)).Elem()
) )
func (s *state) evalMethod(v reflect.Value, i int, args []node, final reflect.Value) reflect.Value { func (s *state) evalMethod(v reflect.Value, method reflect.Method, args []node, final reflect.Value) reflect.Value {
method := v.Type().Method(i)
typ := method.Type typ := method.Type
fun := method.Func fun := method.Func
numIn := len(args) numIn := len(args)
......
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