Skip to content

Commit 3faa47c

Browse files
authored
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
1 parent 896bfeb commit 3faa47c

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

_test/struct56.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
)
7+
8+
type A struct {
9+
IA InnerA
10+
}
11+
12+
type InnerA struct {
13+
Timestamp int64
14+
}
15+
16+
func main() {
17+
a := &A{}
18+
b, _ := json.Marshal(a)
19+
fmt.Println(string(b))
20+
}
21+
22+
// Output:
23+
// {"IA":{"Timestamp":0}}

_test/struct57.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
)
7+
8+
type A struct {
9+
InnerA
10+
}
11+
12+
type InnerA struct {
13+
Timestamp int64
14+
}
15+
16+
func main() {
17+
a := &A{}
18+
b, _ := json.Marshal(a)
19+
fmt.Println(string(b))
20+
}
21+
22+
// Output:
23+
// {"Timestamp":0}

interp/type.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,7 +1222,7 @@ func (t *itype) lookupMethod(name string) (*node, []int) {
12221222
}
12231223

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

0 commit comments

Comments
 (0)