Commit 990f9f4c authored by Russ Cox's avatar Russ Cox

encoding/json: disable anonymous fields

We should, after Go 1, make them work the same as
package xml, that is, make them appear in the outer
struct.  For now turn them off so that people do not
depend on the old behavior.

Fixing them is issue 3069.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5656102
parent 89b075cc
...@@ -496,6 +496,12 @@ func (d *decodeState) object(v reflect.Value) { ...@@ -496,6 +496,12 @@ func (d *decodeState) object(v reflect.Value) {
// Pretend this field doesn't exist. // Pretend this field doesn't exist.
continue continue
} }
if sf.Anonymous {
// Pretend this field doesn't exist,
// so that we can do a good job with
// these in a later version.
continue
}
// First, tag match // First, tag match
tagName, _ := parseTag(tag) tagName, _ := parseTag(tag)
if tagName == key { if tagName == key {
...@@ -963,3 +969,11 @@ func unquoteBytes(s []byte) (t []byte, ok bool) { ...@@ -963,3 +969,11 @@ func unquoteBytes(s []byte) (t []byte, ok bool) {
} }
return b[0:w], true return b[0:w], true
} }
// The following is issue 3069.
// BUG(rsc): This package ignores anonymous (embedded) struct fields
// during encoding and decoding. A future version may assign meaning
// to them. To force an anonymous field to be ignored in all future
// versions of this package, use an explicit `json:"-"` tag in the struct
// definition.
...@@ -619,3 +619,32 @@ func TestRefUnmarshal(t *testing.T) { ...@@ -619,3 +619,32 @@ func TestRefUnmarshal(t *testing.T) {
t.Errorf("got %+v, want %+v", got, want) t.Errorf("got %+v, want %+v", got, want)
} }
} }
// Test that anonymous fields are ignored.
// We may assign meaning to them later.
func TestAnonymous(t *testing.T) {
type S struct {
T
N int
}
data, err := Marshal(new(S))
if err != nil {
t.Fatalf("Marshal: %v", err)
}
want := `{"N":0}`
if string(data) != want {
t.Fatalf("Marshal = %#q, want %#q", string(data), want)
}
var s S
if err := Unmarshal([]byte(`{"T": 1, "T": {"Y": 1}, "N": 2}`), &s); err != nil {
t.Fatalf("Unmarshal: %v", err)
}
if s.N != 2 {
t.Fatal("Unmarshal: did not set N")
}
if s.T.Y != 0 {
t.Fatal("Unmarshal: did set T.Y")
}
}
...@@ -538,6 +538,11 @@ func encodeFields(t reflect.Type) []encodeField { ...@@ -538,6 +538,11 @@ func encodeFields(t reflect.Type) []encodeField {
if f.PkgPath != "" { if f.PkgPath != "" {
continue continue
} }
if f.Anonymous {
// We want to do a better job with these later,
// so for now pretend they don't exist.
continue
}
var ef encodeField var ef encodeField
ef.i = i ef.i = i
ef.tag = f.Name ef.tag = f.Name
......
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