mirror of https://github.com/goccy/go-json.git
Fix indirect layout
This commit is contained in:
parent
36a91cc8e8
commit
902856929d
|
@ -2004,3 +2004,32 @@ func TestInterfaceWithPointer(t *testing.T) {
|
|||
}
|
||||
assertEq(t, "interface{}", string(expected), string(actual))
|
||||
}
|
||||
|
||||
func TestIssue263(t *testing.T) {
|
||||
type Foo struct {
|
||||
A []string `json:"a"`
|
||||
B int `json:"b"`
|
||||
}
|
||||
|
||||
type MyStruct struct {
|
||||
Foo *Foo `json:"foo,omitempty"`
|
||||
}
|
||||
|
||||
s := MyStruct{
|
||||
Foo: &Foo{
|
||||
A: []string{"ls -lah"},
|
||||
B: 0,
|
||||
},
|
||||
}
|
||||
expected, err := stdjson.Marshal(s)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
actual, err := json.Marshal(s)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(expected, actual) {
|
||||
t.Fatalf("expected:[%s] but got:[%s]", string(expected), string(actual))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1440,8 +1440,10 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
|
|||
// if parent is indirect type, set child indirect property to true
|
||||
valueCode.Flags |= IndirectFlags
|
||||
} else {
|
||||
// if parent is not indirect type and child have only one field, set child indirect property to false
|
||||
if i == 0 && valueCode.NextField != nil && valueCode.NextField.Op == OpStructEnd {
|
||||
// if parent is not indirect type, set child indirect property to false.
|
||||
// but if parent's indirect is false and isPtr is true, then indirect must be true.
|
||||
// Do this only if indirectConversion is enabled at the end of compileStruct.
|
||||
if i == 0 {
|
||||
valueCode.Flags &= ^IndirectFlags
|
||||
}
|
||||
}
|
||||
|
@ -1544,7 +1546,11 @@ func compileStruct(ctx *compileContext, isPtr bool) (*Opcode, error) {
|
|||
delete(ctx.structTypeToCompiledCode, typeptr)
|
||||
|
||||
if !disableIndirectConversion && (head.Flags&IndirectFlags == 0) && isPtr {
|
||||
head.Flags |= IndirectFlags
|
||||
headCode := head
|
||||
for strings.Contains(headCode.Op.String(), "Head") {
|
||||
headCode.Flags |= IndirectFlags
|
||||
headCode = headCode.Next
|
||||
}
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
|
|
|
@ -631,6 +631,56 @@ func TestCoverInt(t *testing.T) {
|
|||
}{A: -1}},
|
||||
},
|
||||
|
||||
// HeadIntNotRootMultiFields
|
||||
{
|
||||
name: "HeadIntNotRootMultiFields",
|
||||
data: struct {
|
||||
A struct {
|
||||
A int `json:"a"`
|
||||
B int `json:"b"`
|
||||
}
|
||||
}{A: struct {
|
||||
A int `json:"a"`
|
||||
B int `json:"b"`
|
||||
}{A: -1, B: 1}},
|
||||
},
|
||||
{
|
||||
name: "HeadIntNotRootOmitEmptyMultiFields",
|
||||
data: struct {
|
||||
A struct {
|
||||
A int `json:"a,omitempty"`
|
||||
B int `json:"b,omitempty"`
|
||||
}
|
||||
}{A: struct {
|
||||
A int `json:"a,omitempty"`
|
||||
B int `json:"b,omitempty"`
|
||||
}{A: -1, B: 1}},
|
||||
},
|
||||
{
|
||||
name: "HeadIntNotRootStringMultiFields",
|
||||
data: struct {
|
||||
A struct {
|
||||
A int `json:"a,string"`
|
||||
B int `json:"b,string"`
|
||||
}
|
||||
}{A: struct {
|
||||
A int `json:"a,string"`
|
||||
B int `json:"b,string"`
|
||||
}{A: -1, B: 1}},
|
||||
},
|
||||
{
|
||||
name: "HeadIntNotRootStringOmitEmptyMultiFields",
|
||||
data: struct {
|
||||
A struct {
|
||||
A int `json:"a,string,omitempty"`
|
||||
B int `json:"b,string,omitempty"`
|
||||
}
|
||||
}{A: struct {
|
||||
A int `json:"a,string,omitempty"`
|
||||
B int `json:"b,string,omitempty"`
|
||||
}{A: -1, B: 1}},
|
||||
},
|
||||
|
||||
// HeadIntPtrNotRoot
|
||||
{
|
||||
name: "HeadIntPtrNotRoot",
|
||||
|
@ -791,6 +841,56 @@ func TestCoverInt(t *testing.T) {
|
|||
}{A: -1})},
|
||||
},
|
||||
|
||||
// PtrHeadIntNotRootMultiFields
|
||||
{
|
||||
name: "PtrHeadIntNotRootMultiFields",
|
||||
data: struct {
|
||||
A *struct {
|
||||
A int `json:"a"`
|
||||
B int `json:"b"`
|
||||
}
|
||||
}{A: &(struct {
|
||||
A int `json:"a"`
|
||||
B int `json:"b"`
|
||||
}{A: -1, B: 1})},
|
||||
},
|
||||
{
|
||||
name: "PtrHeadIntNotRootOmitEmptyMultiFields",
|
||||
data: struct {
|
||||
A *struct {
|
||||
A int `json:"a,omitempty"`
|
||||
B int `json:"b,omitempty"`
|
||||
}
|
||||
}{A: &(struct {
|
||||
A int `json:"a,omitempty"`
|
||||
B int `json:"b,omitempty"`
|
||||
}{A: -1, B: 1})},
|
||||
},
|
||||
{
|
||||
name: "PtrHeadIntNotRootStringMultiFields",
|
||||
data: struct {
|
||||
A *struct {
|
||||
A int `json:"a,string"`
|
||||
B int `json:"b,string"`
|
||||
}
|
||||
}{A: &(struct {
|
||||
A int `json:"a,string"`
|
||||
B int `json:"b,string"`
|
||||
}{A: -1, B: 1})},
|
||||
},
|
||||
{
|
||||
name: "PtrHeadIntNotRootStringOmitEmptyMultiFields",
|
||||
data: struct {
|
||||
A *struct {
|
||||
A int `json:"a,string,omitempty"`
|
||||
B int `json:"b,string,omitempty"`
|
||||
}
|
||||
}{A: &(struct {
|
||||
A int `json:"a,string,omitempty"`
|
||||
B int `json:"b,string,omitempty"`
|
||||
}{A: -1, B: 1})},
|
||||
},
|
||||
|
||||
// PtrHeadIntPtrNotRoot
|
||||
{
|
||||
name: "PtrHeadIntPtrNotRoot",
|
||||
|
|
Loading…
Reference in New Issue