Skip to content

Commit

Permalink
interp: take into account embedded property of struct field
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mpl committed Aug 20, 2020
1 parent 896bfeb commit 3faa47c
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
23 changes: 23 additions & 0 deletions _test/struct56.go
@@ -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 changes: 23 additions & 0 deletions _test/struct57.go
@@ -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}
10 changes: 8 additions & 2 deletions interp/type.go
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 3faa47c

Please sign in to comment.