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))
|
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) {
|
func TestIssue417(t *testing.T) {
|
||||||
x := map[string]string{
|
x := map[string]string{
|
||||||
"b": "b",
|
"b": "b",
|
||||||
|
|
|
@ -397,7 +397,10 @@ func (c *StructCode) lastFieldCode(field *StructFieldCode, firstField *Opcode) *
|
||||||
func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
|
func (c *StructCode) lastAnonymousFieldCode(firstField *Opcode) *Opcode {
|
||||||
// firstField is special StructHead operation for anonymous structure.
|
// firstField is special StructHead operation for anonymous structure.
|
||||||
// So, StructHead's next operation is truly struct head operation.
|
// 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 {
|
for lastField.NextField != nil {
|
||||||
lastField = lastField.NextField
|
lastField = lastField.NextField
|
||||||
}
|
}
|
||||||
|
@ -437,11 +440,6 @@ func (c *StructCode) ToOpcode(ctx *compileContext) Opcodes {
|
||||||
}
|
}
|
||||||
if isEndField {
|
if isEndField {
|
||||||
endField := fieldCodes.Last()
|
endField := fieldCodes.Last()
|
||||||
if isEmbeddedStruct(field) {
|
|
||||||
firstField.End = endField
|
|
||||||
lastField := c.lastAnonymousFieldCode(firstField)
|
|
||||||
lastField.NextField = endField
|
|
||||||
}
|
|
||||||
if len(codes) > 0 {
|
if len(codes) > 0 {
|
||||||
codes.First().End = endField
|
codes.First().End = endField
|
||||||
} else {
|
} else {
|
||||||
|
@ -698,7 +696,15 @@ func (c *StructFieldCode) addStructEndCode(ctx *compileContext, codes Opcodes) O
|
||||||
Indent: ctx.indent,
|
Indent: ctx.indent,
|
||||||
}
|
}
|
||||||
codes.Last().Next = end
|
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)
|
codes = codes.Add(end)
|
||||||
ctx.incOpcodeIndex()
|
ctx.incOpcodeIndex()
|
||||||
return codes
|
return codes
|
||||||
|
|
Loading…
Reference in New Issue