fix: handle Func Value in genFunctionWrapper params

* fix: handle Func value in func wrapper params

* fix: lint
This commit is contained in:
Nicholas Wiersma
2020-07-03 12:25:04 +02:00
committed by GitHub
parent 2f2df7a0f8
commit d229c2a2c7
2 changed files with 29 additions and 2 deletions

View File

@@ -385,6 +385,25 @@ func TestEvalChan(t *testing.T) {
})
}
func TestEvalFunctionCallWithFunctionParam(t *testing.T) {
i := interp.New(interp.Options{})
eval(t, i, `
func Bar(s string, fn func(string)string) string { return fn(s) }
`)
v := eval(t, i, "Bar")
bar := v.Interface().(func(string, func(string) string) string)
got := bar("hello ", func(s string) string {
return s + "world!"
})
want := "hello world!"
if got != want {
t.Errorf("unexpected result of function eval: got %q, want %q", got, want)
}
}
func TestEvalMissingSymbol(t *testing.T) {
defer func() {
r := recover()

View File

@@ -679,9 +679,13 @@ func genFunctionWrapper(n *node) func(*frame) reflect.Value {
// Copy function input arguments in local frame
for i, arg := range in {
if def.typ.arg[i].cat == interfaceT {
typ := def.typ.arg[i]
switch {
case typ.cat == interfaceT:
d[i].Set(reflect.ValueOf(valueInterface{value: arg.Elem()}))
} else {
case typ.cat == funcT && arg.Kind() == reflect.Func:
d[i].Set(reflect.ValueOf(genFunctionNode(arg)))
default:
d[i].Set(arg)
}
}
@@ -705,6 +709,10 @@ func genFunctionWrapper(n *node) func(*frame) reflect.Value {
}
}
func genFunctionNode(v reflect.Value) *node {
return &node{kind: funcType, action: aNop, rval: v, typ: &itype{cat: valueT, rtype: v.Type()}}
}
func genInterfaceWrapper(n *node, typ reflect.Type) func(*frame) reflect.Value {
value := genValue(n)
if typ == nil || typ.Kind() != reflect.Interface || typ.NumMethod() == 0 || n.typ.cat == valueT {