]> Cypherpunks repositories - gostls13.git/commitdiff
json: fix []unmarshaler case
authorRuss Cox <rsc@golang.org>
Wed, 10 Aug 2011 13:26:51 +0000 (09:26 -0400)
committerRuss Cox <rsc@golang.org>
Wed, 10 Aug 2011 13:26:51 +0000 (09:26 -0400)
Now that reflect has v.Addr(), we can use it.

R=golang-dev, dsymonds, r
CC=golang-dev
https://golang.org/cl/4860041

src/pkg/json/decode.go
src/pkg/json/decode_test.go

index 7d474fa7b9327044c76caa6c5285860ecf854e24..4f6562bd552c04f77666c77bac2ecbcffb614551 100644 (file)
@@ -251,6 +251,12 @@ func (d *decodeState) value(v reflect.Value) {
 // if it encounters an Unmarshaler, indirect stops and returns that.
 // if wantptr is true, indirect stops at the last pointer.
 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 {
                var isUnmarshaler bool
                if v.Type().NumMethod() > 0 {
index c0ef5bc3aa1854a983a08150c7e04a9bd3468375..a855d6048663b3eb95d1bbe67662ba00a0c286e0 100644 (file)
@@ -34,10 +34,17 @@ func (u *unmarshaler) UnmarshalJSON(b []byte) os.Error {
        return nil
 }
 
+type ustruct struct {
+       M unmarshaler
+}
+
 var (
        um0, um1 unmarshaler // target2 of unmarshaling
        ump      = &um1
        umtrue   = unmarshaler{true}
+       umslice  = []unmarshaler{unmarshaler{true}}
+       umslicep = new([]unmarshaler)
+       umstruct = ustruct{unmarshaler{true}}
 )
 
 type unmarshalTest struct {
@@ -77,6 +84,9 @@ var unmarshalTests = []unmarshalTest{
        // unmarshal interface test
        {`{"T":false}`, &um0, umtrue, nil}, // use "false" so test will fail if custom unmarshaler is not called
        {`{"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) {
@@ -140,7 +150,6 @@ func TestUnmarshal(t *testing.T) {
                        println(string(data))
                        data, _ = Marshal(tt.out)
                        println(string(data))
-                       return
                        continue
                }
        }