interp: take into account embedded property of struct field

The trick is that in reflect, the field is called Anonymous, which is
actually a different notion in the Go spec/vocable.

n.b. only works for non-recursive types for now.

Fixes #781
This commit is contained in:
mpl
2020-08-20 14:51:14 +02:00
committed by GitHub
parent 896bfeb5a1
commit 3faa47c61e
3 changed files with 54 additions and 2 deletions

23
_test/struct56.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import (
"encoding/json"
"fmt"
)
type A struct {
IA InnerA
}
type InnerA struct {
Timestamp int64
}
func main() {
a := &A{}
b, _ := json.Marshal(a)
fmt.Println(string(b))
}
// Output:
// {"IA":{"Timestamp":0}}

23
_test/struct57.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import (
"encoding/json"
"fmt"
)
type A struct {
InnerA
}
type InnerA struct {
Timestamp int64
}
func main() {
a := &A{}
b, _ := json.Marshal(a)
fmt.Println(string(b))
}
// Output:
// {"Timestamp":0}

View File

@@ -1222,7 +1222,7 @@ func (t *itype) lookupMethod(name string) (*node, []int) {
}
// LookupBinMethod returns a method and a path to access a field in a struct object (the receiver).
func (t *itype) lookupBinMethod(name string) (m reflect.Method, index []int, isPtr bool, ok bool) {
func (t *itype) lookupBinMethod(name string) (m reflect.Method, index []int, isPtr, ok bool) {
if t.cat == ptrT {
return t.val.lookupBinMethod(name)
}
@@ -1349,8 +1349,14 @@ func (t *itype) refType(defined map[string]*itype, wrapRecursive bool) reflect.T
defined[name] = t
}
var fields []reflect.StructField
// TODO(mpl): make Anonymous work for recursive types too. Maybe not worth the
// effort, and we're better off just waiting for
// https://github.com/golang/go/issues/39717 to land.
for _, f := range t.field {
field := reflect.StructField{Name: exportName(f.name), Type: f.typ.refType(defined, wrapRecursive), Tag: reflect.StructTag(f.tag)}
field := reflect.StructField{
Name: exportName(f.name), Type: f.typ.refType(defined, wrapRecursive),
Tag: reflect.StructTag(f.tag), Anonymous: (f.embed && !recursive),
}
fields = append(fields, field)
}
if recursive && wrapRecursive {