fix: correct handling of function in struct field (#226)
This commit is contained in:
committed by
Ludovic Fernandez
parent
cd12274ec6
commit
25ddbbad03
21
_test/struct20.go
Normal file
21
_test/struct20.go
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type SecretProvider func(user, realm string) string
|
||||||
|
|
||||||
|
type BasicAuth struct {
|
||||||
|
Realm string
|
||||||
|
Secrets SecretProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *BasicAuth) CheckAuth() string { return a.Secrets("me", a.Realm) }
|
||||||
|
|
||||||
|
func secretBasic(user, realm string) string { return user + "-" + realm }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
b := &BasicAuth{"test", secretBasic}
|
||||||
|
s := b.CheckAuth()
|
||||||
|
println(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// me-test
|
||||||
22
_test/struct21.go
Normal file
22
_test/struct21.go
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
type SecretProvider func(user, realm string) string
|
||||||
|
|
||||||
|
type BasicAuth struct {
|
||||||
|
Realm string
|
||||||
|
Secrets SecretProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *BasicAuth) CheckAuth() string { return a.Secrets("me", a.Realm) }
|
||||||
|
|
||||||
|
func (a *BasicAuth) secretBasic(user, realm string) string { return a.Realm + "-" + user + "-" + realm }
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
b := &BasicAuth{Realm: "test"}
|
||||||
|
b.Secrets = b.secretBasic
|
||||||
|
s := b.CheckAuth()
|
||||||
|
println(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output:
|
||||||
|
// test-me-test
|
||||||
@@ -1151,6 +1151,11 @@ func (interp *Interpreter) Cfg(root *Node) ([]*Node, error) {
|
|||||||
case PtrT:
|
case PtrT:
|
||||||
n.typ = n.typ.fieldSeq(ti)
|
n.typ = n.typ.fieldSeq(ti)
|
||||||
n.gen = getPtrIndexSeq
|
n.gen = getPtrIndexSeq
|
||||||
|
if n.typ.cat == FuncT {
|
||||||
|
// function in a struct field is always wrapped in reflect.Value
|
||||||
|
rtype := n.typ.TypeOf()
|
||||||
|
n.typ = &Type{cat: ValueT, rtype: rtype}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
n.gen = getIndexSeq
|
n.gen = getIndexSeq
|
||||||
n.typ = n.typ.fieldSeq(ti)
|
n.typ = n.typ.fieldSeq(ti)
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
"reflect"
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() { log.SetFlags(log.Lshortfile) }
|
||||||
|
|
||||||
// Builtin type defines functions which run at CFG execution
|
// Builtin type defines functions which run at CFG execution
|
||||||
type Builtin func(f *Frame) Builtin
|
type Builtin func(f *Frame) Builtin
|
||||||
|
|
||||||
@@ -400,7 +402,11 @@ func _panic(n *Node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func genFunctionWrapper(n *Node) func(*Frame) reflect.Value {
|
func genFunctionWrapper(n *Node) func(*Frame) reflect.Value {
|
||||||
def := n.val.(*Node)
|
var def *Node
|
||||||
|
var ok bool
|
||||||
|
if def, ok = n.val.(*Node); !ok {
|
||||||
|
return genValueAsFunctionWrapper(n)
|
||||||
|
}
|
||||||
setExec(def.child[3].start)
|
setExec(def.child[3].start)
|
||||||
start := def.child[3].start
|
start := def.child[3].start
|
||||||
numRet := len(def.typ.ret)
|
numRet := len(def.typ.ret)
|
||||||
@@ -1446,12 +1452,13 @@ func compositeSparse(n *Node) {
|
|||||||
values := make(map[int]func(*Frame) reflect.Value)
|
values := make(map[int]func(*Frame) reflect.Value)
|
||||||
a, _ := n.typ.zero()
|
a, _ := n.typ.zero()
|
||||||
for _, c := range child {
|
for _, c := range child {
|
||||||
|
c1 := c.child[1]
|
||||||
field := n.typ.fieldIndex(c.child[0].ident)
|
field := n.typ.fieldIndex(c.child[0].ident)
|
||||||
convertLiteralValue(c.child[1], n.typ.field[field].typ.TypeOf())
|
convertLiteralValue(c1, n.typ.field[field].typ.TypeOf())
|
||||||
if c.typ.cat == FuncT {
|
if c1.typ.cat == FuncT {
|
||||||
values[field] = genFunctionWrapper(c.child[1])
|
values[field] = genFunctionWrapper(c1)
|
||||||
} else {
|
} else {
|
||||||
values[field] = genValue(c.child[1])
|
values[field] = genValue(c1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,13 @@ func genValueRecv(n *Node) func(*Frame) reflect.Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func genValueAsFunctionWrapper(n *Node) func(*Frame) reflect.Value {
|
||||||
|
v := genValue(n)
|
||||||
|
return func(f *Frame) reflect.Value {
|
||||||
|
return genFunctionWrapper(v(f).Interface().(*Node))(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func genValueAs(n *Node, t reflect.Type) func(*Frame) reflect.Value {
|
func genValueAs(n *Node, t reflect.Type) func(*Frame) reflect.Value {
|
||||||
v := genValue(n)
|
v := genValue(n)
|
||||||
return func(f *Frame) reflect.Value {
|
return func(f *Frame) reflect.Value {
|
||||||
|
|||||||
Reference in New Issue
Block a user