fix: function created by reflect.MakeFunc using closure had wrong type (#75)
Call genNodeWrapper on interpreted function returned by a closure, itself being wrapped, to ensure that the function can be called from binary, no matter the level of nesting closures.
This commit is contained in:
committed by
Ludovic Fernandez
parent
6fc6560af3
commit
18330ad7f9
17
example/closure/_pkg/src/foo/bar/bar.go
Normal file
17
example/closure/_pkg/src/foo/bar/bar.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package bar
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var version = "v1"
|
||||
|
||||
func NewSample() func(string, string) func(string) string {
|
||||
fmt.Println("in NewSample")
|
||||
return func(val string, name string) func(string) string {
|
||||
fmt.Println("in function", version, val, name)
|
||||
return func(msg string) string {
|
||||
return fmt.Sprint("here", version, val, name, msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
36
example/closure/closure_test.go
Normal file
36
example/closure/closure_test.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package clos1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/containous/dyngo/interp"
|
||||
"github.com/containous/dyngo/stdlib"
|
||||
)
|
||||
|
||||
func TestFunctionCall(t *testing.T) {
|
||||
i := interp.New(interp.Opt{GoPath: "./_pkg"})
|
||||
i.Use(stdlib.Value, stdlib.Type)
|
||||
|
||||
_, err := i.Eval(`import "foo/bar"`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fnv, err := i.Eval(`bar.NewSample()`)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
fn, ok := fnv.Interface().(func(string, string) func(string) string)
|
||||
if !ok {
|
||||
t.Fatal("conversion failed")
|
||||
}
|
||||
|
||||
fn2 := fn("hello", "world")
|
||||
val := fn2("truc")
|
||||
|
||||
expected := "herev1helloworldtruc"
|
||||
if val != expected {
|
||||
t.Errorf("Got: %q, want: %q", val, expected)
|
||||
}
|
||||
}
|
||||
@@ -363,8 +363,13 @@ func genNodeWrapper(n *Node) func(*Frame) reflect.Value {
|
||||
if len(def.child[2].child) > 1 {
|
||||
if fieldList := def.child[2].child[1]; fieldList != nil {
|
||||
result = make([]reflect.Value, len(fieldList.child))
|
||||
for i := range fieldList.child {
|
||||
result[i] = frame.data[i]
|
||||
for i, c := range fieldList.child {
|
||||
if c.typ.cat == FuncT {
|
||||
gv := genNodeWrapper(frame.data[i].Interface().(*Node))
|
||||
result[i] = gv(f)
|
||||
} else {
|
||||
result[i] = frame.data[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user