fix: lookup embedded binary fields in struct (#207)
This commit is contained in:
committed by
Ludovic Fernandez
parent
264782408a
commit
67ba2888d7
20
_test/struct18.go
Normal file
20
_test/struct18.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type AuthenticatedRequest struct {
|
||||
http.Request
|
||||
Username string
|
||||
}
|
||||
|
||||
func main() {
|
||||
a := &AuthenticatedRequest{}
|
||||
|
||||
fmt.Printf("%v %T\n", a.Header, a.Header)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// map[] http.Header
|
||||
@@ -1129,6 +1129,12 @@ func (interp *Interpreter) Cfg(root *Node) ([]*Node, error) {
|
||||
n.typ = &Type{cat: ValueT, rtype: rtype}
|
||||
}
|
||||
}
|
||||
} else if s, lind, ok := n.typ.lookupBinField(n.child[1].ident); ok {
|
||||
// Handle an embedded binary field into a struct field
|
||||
n.gen = getIndexSeqField
|
||||
lind = append(lind, s.Index...)
|
||||
n.val = lind
|
||||
n.typ = &Type{cat: ValueT, rtype: s.Type}
|
||||
} else {
|
||||
err = n.cfgError("undefined selector: %s", n.child[1].ident)
|
||||
}
|
||||
|
||||
@@ -1086,6 +1086,25 @@ func getPtrIndexSeq(n *Node) {
|
||||
}
|
||||
}
|
||||
|
||||
func getIndexSeqField(n *Node) {
|
||||
value := genValue(n.child[0])
|
||||
index := n.val.([]int)
|
||||
i := n.findex
|
||||
next := getExec(n.tnext)
|
||||
|
||||
if n.child[0].typ.TypeOf().Kind() == reflect.Ptr {
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
f.data[i] = value(f).Elem().FieldByIndex(index)
|
||||
return next
|
||||
}
|
||||
} else {
|
||||
n.exec = func(f *Frame) Builtin {
|
||||
f.data[i] = value(f).FieldByIndex(index)
|
||||
return next
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getIndexSeqMethod(n *Node) {
|
||||
value := genValue(n.child[0])
|
||||
index := n.val.([]int)
|
||||
|
||||
@@ -528,6 +528,26 @@ func (t *Type) lookupField(name string) []int {
|
||||
return nil
|
||||
}
|
||||
|
||||
// lookupBinField returns a structfield and a path to access an embedded binary field in a struct object
|
||||
func (t *Type) lookupBinField(name string) (reflect.StructField, []int, bool) {
|
||||
if t.cat == PtrT {
|
||||
return t.val.lookupBinField(name)
|
||||
}
|
||||
var index []int
|
||||
s, ok := t.TypeOf().FieldByName(name)
|
||||
if !ok {
|
||||
for i, f := range t.field {
|
||||
if f.embed {
|
||||
if s2, index2, ok2 := f.typ.lookupBinField(name); ok2 {
|
||||
index = append([]int{i}, index2...)
|
||||
return s2, index, ok2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return s, index, ok
|
||||
}
|
||||
|
||||
// getMethod returns a pointer to the method definition
|
||||
func (t *Type) getMethod(name string) *Node {
|
||||
for _, m := range t.method {
|
||||
|
||||
Reference in New Issue
Block a user