mirror of https://github.com/goccy/go-json.git
fix: fixed an issue that could not set the correct NextField for fields in the embedded structure (#438)
fix #391
This commit is contained in:
parent
7be58ac89d
commit
6f969b6d5f
|
@ -2630,6 +2630,40 @@ func TestCustomMarshalForMapKey(t *testing.T) {
|
|||
assertEq(t, "custom map key", string(expected), string(got))
|
||||
}
|
||||
|
||||
func TestIssue391(t *testing.T) {
|
||||
type A struct {
|
||||
X string `json:"x,omitempty"`
|
||||
}
|
||||
type B struct {
|
||||
A
|
||||
}
|
||||
type C struct {
|
||||
X []int `json:"x,omitempty"`
|
||||
}
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
in interface{}
|
||||
out string
|
||||
}{
|
||||
{in: struct{ B }{}, out: "{}"},
|
||||
{in: struct {
|
||||
B
|
||||
Y string `json:"y"`
|
||||
}{}, out: `{"y":""}`},
|
||||
{in: struct {
|
||||
Y string `json:"y"`
|
||||
B
|
||||
}{}, out: `{"y":""}`},
|
||||
{in: struct{ C }{}, out: "{}"},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
b, err := json.Marshal(tc.in)
|
||||
assertErr(t, err)
|
||||
assertEq(t, "unexpected result", tc.out, string(b))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIssue417(t *testing.T) {
|
||||
x := map[string]string{
|
||||
"b": "b",
|
||||
|
|
|
@ -397,7 +397,10 @@ func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *
|
|||
func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
|
||||
// firstField is special StructHead operation for anonymous structure.
|
||||
// So, StructHead's next operation is truly struct head operation.
|
||||
lastField := firstField.Next
|
||||
for firstField.Op == OpStructHead {
|
||||
firstField = firstField.Next
|
||||
}
|
||||
lastField := firstField
|
||||
for lastField.NextField != nil {
|
||||
lastField = lastField.NextField
|
||||
}
|
||||
|
@ -437,11 +440,6 @@ func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
|
|||
}
|
||||
if isEndField {
|
||||
endField := fieldCodes.Last()
|
||||
if isEmbeddedStruct(field) {
|
||||
firstField.End = endField
|
||||
lastField := c.lastAnonymousFieldCode(firstField)
|
||||
lastField.NextField = endField
|
||||
}
|
||||
if len(codes) > 0 {
|
||||
codes.First().End = endField
|
||||
} else {
|
||||
|
@ -698,7 +696,15 @@ func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) O
|
|||
Indent: ctx.indent,
|
||||
}
|
||||
codes.Last().Next = end
|
||||
codes.First().NextField = end
|
||||
code := codes.First()
|
||||
for code.Op == OpStructField || code.Op == OpStructHead {
|
||||
code = code.Next
|
||||
}
|
||||
for code.NextField != nil {
|
||||
code = code.NextField
|
||||
}
|
||||
code.NextField = end
|
||||
|
||||
codes = codes.Add(end)
|
||||
ctx.incOpcodeIndex()
|
||||
return codes
|
||||
|
|
Loading…
Reference in New Issue