Skip to content

Commit 3585705

Browse files
stromsvagmpvl
authored andcommitted
internal/core/convert: fix for embedded structs are not honored
Fixes #376. I added [a comment](cuelang/cue#376 (comment)) to #376 with some questions. Would be great if I could get some feedback on that as well as my proposed fix. My experience with cue is very limited. Closes #568 cuelang/cue#568 GitOrigin-RevId: 00851951dfd10dd11489c99f1507d2f2c880183c Change-Id: Ia857cdb14739e232a6028ebc32ee1a6a11494ebf Reviewed-on: https://cue-review.googlesource.com/c/cue/+/7684 Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent c715b94 commit 3585705

File tree

3 files changed

+66
-5
lines changed

3 files changed

+66
-5
lines changed

encoding/gocode/gocodec/codec_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,38 @@ func TestDecode(t *testing.T) {
266266
}{{
267267
in: "str",
268268
want: `"str"`,
269+
}, {
270+
in: func() interface{} {
271+
type T struct {
272+
B int
273+
}
274+
type S struct {
275+
A string
276+
T
277+
}
278+
return S{}
279+
}(),
280+
want: `{
281+
A: ""
282+
B: 0
283+
}`,
284+
}, {
285+
in: func() interface{} {
286+
type T struct {
287+
B int
288+
}
289+
type S struct {
290+
A string
291+
T `json:"t"`
292+
}
293+
return S{}
294+
}(),
295+
want: `{
296+
A: ""
297+
t: {
298+
B: 0
299+
}
300+
}`,
269301
}}
270302
c := New(&cue.Runtime{}, nil)
271303

internal/core/convert/go.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ var tagsWithNames = []string{"json", "yaml", "protobuf"}
9999

100100
func getName(f *reflect.StructField) string {
101101
name := f.Name
102+
if f.Anonymous {
103+
name = ""
104+
}
102105
for _, s := range tagsWithNames {
103106
if tag, ok := f.Tag.Lookup(s); ok {
104107
if p := strings.Index(tag, ","); p >= 0 {
@@ -405,18 +408,18 @@ func convertRec(ctx *adt.OpContext, nilIsTop bool, x interface{}) adt.Value {
405408

406409
t := value.Type()
407410
for i := 0; i < value.NumField(); i++ {
408-
t := t.Field(i)
409-
if t.PkgPath != "" {
411+
sf := t.Field(i)
412+
if sf.PkgPath != "" {
410413
continue
411414
}
412415
val := value.Field(i)
413416
if !nilIsTop && isNil(val) {
414417
continue
415418
}
416-
if tag, _ := t.Tag.Lookup("json"); tag == "-" {
419+
if tag, _ := sf.Tag.Lookup("json"); tag == "-" {
417420
continue
418421
}
419-
if isOmitEmpty(&t) && isZero(val) {
422+
if isOmitEmpty(&sf) && isZero(val) {
420423
continue
421424
}
422425
sub := convertRec(ctx, nilIsTop, val.Interface())
@@ -430,10 +433,21 @@ func convertRec(ctx *adt.OpContext, nilIsTop bool, x interface{}) adt.Value {
430433

431434
// leave errors like we do during normal evaluation or do we
432435
// want to return the error?
433-
name := getName(&t)
436+
name := getName(&sf)
434437
if name == "-" {
435438
continue
436439
}
440+
if sf.Anonymous && name == "" {
441+
arc, ok := sub.(*adt.Vertex)
442+
if ok {
443+
for _, a := range arc.Arcs {
444+
obj.Decls = append(obj.Decls, &adt.Field{Label: a.Label, Value: a.Value})
445+
v.Arcs = append(v.Arcs, a)
446+
}
447+
}
448+
continue
449+
}
450+
437451
f := ctx.StringLabel(name)
438452
obj.Decls = append(obj.Decls, &adt.Field{Label: f, Value: sub})
439453
arc, ok := sub.(*adt.Vertex)

internal/core/convert/go_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,21 @@ func TestConvert(t *testing.T) {
183183
reflect.ValueOf(3), "3",
184184
}, {
185185
time.Date(2019, 4, 1, 0, 0, 0, 0, time.UTC), `(string){ "2019-04-01T00:00:00Z" }`,
186+
}, {
187+
func() interface{} {
188+
type T struct {
189+
B int
190+
}
191+
type S struct {
192+
A string
193+
T
194+
}
195+
return S{}
196+
}(),
197+
`(struct){
198+
A: (string){ "" }
199+
B: (int){ 0 }
200+
}`,
186201
}}
187202
r := runtime.New()
188203
for _, tc := range testCases {

0 commit comments

Comments
 (0)