mirror of
https://github.com/golang/go
synced 2024-11-12 07:00:21 -07:00
json: fix []unmarshaler case
Now that reflect has v.Addr(), we can use it. R=golang-dev, dsymonds, r CC=golang-dev https://golang.org/cl/4860041
This commit is contained in:
parent
c9cf04a9f6
commit
83c734601c
@ -251,6 +251,12 @@ func (d *decodeState) value(v reflect.Value) {
|
|||||||
// if it encounters an Unmarshaler, indirect stops and returns that.
|
// if it encounters an Unmarshaler, indirect stops and returns that.
|
||||||
// if wantptr is true, indirect stops at the last pointer.
|
// if wantptr is true, indirect stops at the last pointer.
|
||||||
func (d *decodeState) indirect(v reflect.Value, wantptr bool) (Unmarshaler, reflect.Value) {
|
func (d *decodeState) indirect(v reflect.Value, wantptr bool) (Unmarshaler, reflect.Value) {
|
||||||
|
// If v is a named type and is addressable,
|
||||||
|
// start with its address, so that if the type has pointer methods,
|
||||||
|
// we find them.
|
||||||
|
if v.Kind() != reflect.Ptr && v.Type().Name() != "" && v.CanAddr() {
|
||||||
|
v = v.Addr()
|
||||||
|
}
|
||||||
for {
|
for {
|
||||||
var isUnmarshaler bool
|
var isUnmarshaler bool
|
||||||
if v.Type().NumMethod() > 0 {
|
if v.Type().NumMethod() > 0 {
|
||||||
|
@ -34,10 +34,17 @@ func (u *unmarshaler) UnmarshalJSON(b []byte) os.Error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ustruct struct {
|
||||||
|
M unmarshaler
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
um0, um1 unmarshaler // target2 of unmarshaling
|
um0, um1 unmarshaler // target2 of unmarshaling
|
||||||
ump = &um1
|
ump = &um1
|
||||||
umtrue = unmarshaler{true}
|
umtrue = unmarshaler{true}
|
||||||
|
umslice = []unmarshaler{unmarshaler{true}}
|
||||||
|
umslicep = new([]unmarshaler)
|
||||||
|
umstruct = ustruct{unmarshaler{true}}
|
||||||
)
|
)
|
||||||
|
|
||||||
type unmarshalTest struct {
|
type unmarshalTest struct {
|
||||||
@ -77,6 +84,9 @@ var unmarshalTests = []unmarshalTest{
|
|||||||
// unmarshal interface test
|
// unmarshal interface test
|
||||||
{`{"T":false}`, &um0, umtrue, nil}, // use "false" so test will fail if custom unmarshaler is not called
|
{`{"T":false}`, &um0, umtrue, nil}, // use "false" so test will fail if custom unmarshaler is not called
|
||||||
{`{"T":false}`, &ump, &umtrue, nil},
|
{`{"T":false}`, &ump, &umtrue, nil},
|
||||||
|
{`[{"T":false}]`, &umslice, umslice, nil},
|
||||||
|
{`[{"T":false}]`, &umslicep, &umslice, nil},
|
||||||
|
{`{"M":{"T":false}}`, &umstruct, umstruct, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMarshal(t *testing.T) {
|
func TestMarshal(t *testing.T) {
|
||||||
@ -140,7 +150,6 @@ func TestUnmarshal(t *testing.T) {
|
|||||||
println(string(data))
|
println(string(data))
|
||||||
data, _ = Marshal(tt.out)
|
data, _ = Marshal(tt.out)
|
||||||
println(string(data))
|
println(string(data))
|
||||||
return
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user