Commit 83c73460 authored by Russ Cox's avatar Russ Cox

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
parent c9cf04a9
...@@ -251,6 +251,12 @@ func (d *decodeState) value(v reflect.Value) { ...@@ -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 { ...@@ -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{ ...@@ -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) { ...@@ -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
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment