From d229c2a2c721179e1df6932a520099073ff10dbd Mon Sep 17 00:00:00 2001 From: Nicholas Wiersma Date: Fri, 3 Jul 2020 12:25:04 +0200 Subject: [PATCH] fix: handle Func Value in genFunctionWrapper params * fix: handle Func value in func wrapper params * fix: lint --- interp/interp_eval_test.go | 19 +++++++++++++++++++ interp/run.go | 12 ++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/interp/interp_eval_test.go b/interp/interp_eval_test.go index 45ec5a65..7dd99ed1 100644 --- a/interp/interp_eval_test.go +++ b/interp/interp_eval_test.go @@ -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() diff --git a/interp/run.go b/interp/run.go index 2ee2b4c0..9bb8da82 100644 --- a/interp/run.go +++ b/interp/run.go @@ -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 {