use pointer-wrapping for slices and maps

This is important because named slice types might have a custom decoder
that doesn't allow null.
master
Felix Lange 7 years ago
parent 55422dcc4d
commit cd4d995e32
  1. 60
      internal/tests/mapconv/output.go
  2. 72
      internal/tests/sliceconv/output.go
  3. 2
      typeutil.go

@ -43,32 +43,32 @@ func (x X) MarshalJSON() ([]byte, error) {
func (x *X) UnmarshalJSON(input []byte) error { func (x *X) UnmarshalJSON(input []byte) error {
type X struct { type X struct {
Map map[replacedString]replacedInt Map *map[replacedString]replacedInt
Named namedMap2 Named *namedMap2
NoConv map[string]int NoConv *map[string]int
NoConvNamed namedMap NoConvNamed *namedMap
} }
var dec X var dec X
if err := json.Unmarshal(input, &dec); err != nil { if err := json.Unmarshal(input, &dec); err != nil {
return err return err
} }
if dec.Map != nil { if dec.Map != nil {
x.Map = make(map[string]int, len(dec.Map)) x.Map = make(map[string]int, len(*dec.Map))
for k, v := range dec.Map { for k, v := range *dec.Map {
x.Map[string(k)] = int(v) x.Map[string(k)] = int(v)
} }
} }
if dec.Named != nil { if dec.Named != nil {
x.Named = make(namedMap, len(dec.Named)) x.Named = make(namedMap, len(*dec.Named))
for k, v := range dec.Named { for k, v := range *dec.Named {
x.Named[string(k)] = int(v) x.Named[string(k)] = int(v)
} }
} }
if dec.NoConv != nil { if dec.NoConv != nil {
x.NoConv = dec.NoConv x.NoConv = *dec.NoConv
} }
if dec.NoConvNamed != nil { if dec.NoConvNamed != nil {
x.NoConvNamed = dec.NoConvNamed x.NoConvNamed = *dec.NoConvNamed
} }
return nil return nil
} }
@ -108,32 +108,32 @@ func (x X) MarshalYAML() (interface{}, error) {
func (x *X) UnmarshalYAML(unmarshal func(interface{}) error) error { func (x *X) UnmarshalYAML(unmarshal func(interface{}) error) error {
type X struct { type X struct {
Map map[replacedString]replacedInt Map *map[replacedString]replacedInt
Named namedMap2 Named *namedMap2
NoConv map[string]int NoConv *map[string]int
NoConvNamed namedMap NoConvNamed *namedMap
} }
var dec X var dec X
if err := unmarshal(&dec); err != nil { if err := unmarshal(&dec); err != nil {
return err return err
} }
if dec.Map != nil { if dec.Map != nil {
x.Map = make(map[string]int, len(dec.Map)) x.Map = make(map[string]int, len(*dec.Map))
for k, v := range dec.Map { for k, v := range *dec.Map {
x.Map[string(k)] = int(v) x.Map[string(k)] = int(v)
} }
} }
if dec.Named != nil { if dec.Named != nil {
x.Named = make(namedMap, len(dec.Named)) x.Named = make(namedMap, len(*dec.Named))
for k, v := range dec.Named { for k, v := range *dec.Named {
x.Named[string(k)] = int(v) x.Named[string(k)] = int(v)
} }
} }
if dec.NoConv != nil { if dec.NoConv != nil {
x.NoConv = dec.NoConv x.NoConv = *dec.NoConv
} }
if dec.NoConvNamed != nil { if dec.NoConvNamed != nil {
x.NoConvNamed = dec.NoConvNamed x.NoConvNamed = *dec.NoConvNamed
} }
return nil return nil
} }
@ -173,32 +173,32 @@ func (x X) MarshalTOML() (interface{}, error) {
func (x *X) UnmarshalTOML(unmarshal func(interface{}) error) error { func (x *X) UnmarshalTOML(unmarshal func(interface{}) error) error {
type X struct { type X struct {
Map map[replacedString]replacedInt Map *map[replacedString]replacedInt
Named namedMap2 Named *namedMap2
NoConv map[string]int NoConv *map[string]int
NoConvNamed namedMap NoConvNamed *namedMap
} }
var dec X var dec X
if err := unmarshal(&dec); err != nil { if err := unmarshal(&dec); err != nil {
return err return err
} }
if dec.Map != nil { if dec.Map != nil {
x.Map = make(map[string]int, len(dec.Map)) x.Map = make(map[string]int, len(*dec.Map))
for k, v := range dec.Map { for k, v := range *dec.Map {
x.Map[string(k)] = int(v) x.Map[string(k)] = int(v)
} }
} }
if dec.Named != nil { if dec.Named != nil {
x.Named = make(namedMap, len(dec.Named)) x.Named = make(namedMap, len(*dec.Named))
for k, v := range dec.Named { for k, v := range *dec.Named {
x.Named[string(k)] = int(v) x.Named[string(k)] = int(v)
} }
} }
if dec.NoConv != nil { if dec.NoConv != nil {
x.NoConv = dec.NoConv x.NoConv = *dec.NoConv
} }
if dec.NoConvNamed != nil { if dec.NoConvNamed != nil {
x.NoConvNamed = dec.NoConvNamed x.NoConvNamed = *dec.NoConvNamed
} }
return nil return nil
} }

@ -45,36 +45,36 @@ func (x X) MarshalJSON() ([]byte, error) {
func (x *X) UnmarshalJSON(input []byte) error { func (x *X) UnmarshalJSON(input []byte) error {
type X struct { type X struct {
Slice []replacedInt Slice *[]replacedInt
Named namedSlice2 Named *namedSlice2
ByteString []byte ByteString *[]byte
NoConv []int NoConv *[]int
NoConvNamed namedSlice NoConvNamed *namedSlice
} }
var dec X var dec X
if err := json.Unmarshal(input, &dec); err != nil { if err := json.Unmarshal(input, &dec); err != nil {
return err return err
} }
if dec.Slice != nil { if dec.Slice != nil {
x.Slice = make([]int, len(dec.Slice)) x.Slice = make([]int, len(*dec.Slice))
for k, v := range dec.Slice { for k, v := range *dec.Slice {
x.Slice[k] = int(v) x.Slice[k] = int(v)
} }
} }
if dec.Named != nil { if dec.Named != nil {
x.Named = make(namedSlice, len(dec.Named)) x.Named = make(namedSlice, len(*dec.Named))
for k, v := range dec.Named { for k, v := range *dec.Named {
x.Named[k] = int(v) x.Named[k] = int(v)
} }
} }
if dec.ByteString != nil { if dec.ByteString != nil {
x.ByteString = string(dec.ByteString) x.ByteString = string(*dec.ByteString)
} }
if dec.NoConv != nil { if dec.NoConv != nil {
x.NoConv = dec.NoConv x.NoConv = *dec.NoConv
} }
if dec.NoConvNamed != nil { if dec.NoConvNamed != nil {
x.NoConvNamed = dec.NoConvNamed x.NoConvNamed = *dec.NoConvNamed
} }
return nil return nil
} }
@ -116,36 +116,36 @@ func (x X) MarshalYAML() (interface{}, error) {
func (x *X) UnmarshalYAML(unmarshal func(interface{}) error) error { func (x *X) UnmarshalYAML(unmarshal func(interface{}) error) error {
type X struct { type X struct {
Slice []replacedInt Slice *[]replacedInt
Named namedSlice2 Named *namedSlice2
ByteString []byte ByteString *[]byte
NoConv []int NoConv *[]int
NoConvNamed namedSlice NoConvNamed *namedSlice
} }
var dec X var dec X
if err := unmarshal(&dec); err != nil { if err := unmarshal(&dec); err != nil {
return err return err
} }
if dec.Slice != nil { if dec.Slice != nil {
x.Slice = make([]int, len(dec.Slice)) x.Slice = make([]int, len(*dec.Slice))
for k, v := range dec.Slice { for k, v := range *dec.Slice {
x.Slice[k] = int(v) x.Slice[k] = int(v)
} }
} }
if dec.Named != nil { if dec.Named != nil {
x.Named = make(namedSlice, len(dec.Named)) x.Named = make(namedSlice, len(*dec.Named))
for k, v := range dec.Named { for k, v := range *dec.Named {
x.Named[k] = int(v) x.Named[k] = int(v)
} }
} }
if dec.ByteString != nil { if dec.ByteString != nil {
x.ByteString = string(dec.ByteString) x.ByteString = string(*dec.ByteString)
} }
if dec.NoConv != nil { if dec.NoConv != nil {
x.NoConv = dec.NoConv x.NoConv = *dec.NoConv
} }
if dec.NoConvNamed != nil { if dec.NoConvNamed != nil {
x.NoConvNamed = dec.NoConvNamed x.NoConvNamed = *dec.NoConvNamed
} }
return nil return nil
} }
@ -187,36 +187,36 @@ func (x X) MarshalTOML() (interface{}, error) {
func (x *X) UnmarshalTOML(unmarshal func(interface{}) error) error { func (x *X) UnmarshalTOML(unmarshal func(interface{}) error) error {
type X struct { type X struct {
Slice []replacedInt Slice *[]replacedInt
Named namedSlice2 Named *namedSlice2
ByteString []byte ByteString *[]byte
NoConv []int NoConv *[]int
NoConvNamed namedSlice NoConvNamed *namedSlice
} }
var dec X var dec X
if err := unmarshal(&dec); err != nil { if err := unmarshal(&dec); err != nil {
return err return err
} }
if dec.Slice != nil { if dec.Slice != nil {
x.Slice = make([]int, len(dec.Slice)) x.Slice = make([]int, len(*dec.Slice))
for k, v := range dec.Slice { for k, v := range *dec.Slice {
x.Slice[k] = int(v) x.Slice[k] = int(v)
} }
} }
if dec.Named != nil { if dec.Named != nil {
x.Named = make(namedSlice, len(dec.Named)) x.Named = make(namedSlice, len(*dec.Named))
for k, v := range dec.Named { for k, v := range *dec.Named {
x.Named[k] = int(v) x.Named[k] = int(v)
} }
} }
if dec.ByteString != nil { if dec.ByteString != nil {
x.ByteString = string(dec.ByteString) x.ByteString = string(*dec.ByteString)
} }
if dec.NoConv != nil { if dec.NoConv != nil {
x.NoConv = dec.NoConv x.NoConv = *dec.NoConv
} }
if dec.NoConvNamed != nil { if dec.NoConvNamed != nil {
x.NoConvNamed = dec.NoConvNamed x.NoConvNamed = *dec.NoConvNamed
} }
return nil return nil
} }

@ -102,7 +102,7 @@ func ensureNilCheckable(typ types.Type) types.Type {
switch typ.(type) { switch typ.(type) {
case *types.Named: case *types.Named:
typ = typ.Underlying() typ = typ.Underlying()
case *types.Map, *types.Slice, *types.Pointer, *types.Interface: case *types.Pointer, *types.Interface:
return orig return orig
default: default:
return types.NewPointer(orig) return types.NewPointer(orig)

Loading…
Cancel
Save