honnef.co/go/tools@v0.4.7/staticcheck/testdata/src/example.com/CheckUnsupportedMarshal/CheckUnsupportedMarshal.go (about)

     1  package pkg
     2  
     3  import (
     4  	"encoding/json"
     5  	"encoding/xml"
     6  	"time"
     7  )
     8  
     9  type T1 struct {
    10  	A int
    11  	B func() `json:"-" xml:"-"`
    12  	c chan int
    13  }
    14  
    15  type T2 struct {
    16  	T1
    17  }
    18  
    19  type T3 struct {
    20  	Ch chan int
    21  }
    22  
    23  type T4 struct {
    24  	C ValueMarshaler
    25  }
    26  
    27  type T5 struct {
    28  	B func() `xml:"-"`
    29  }
    30  
    31  type T6 struct {
    32  	B func() `json:"-"`
    33  }
    34  
    35  type T7 struct {
    36  	A int
    37  	B int
    38  	T3
    39  }
    40  
    41  type T8 struct {
    42  	C int
    43  	*T7
    44  }
    45  
    46  type T9 struct {
    47  	F PointerMarshaler
    48  }
    49  
    50  type T10 struct {
    51  	F *struct {
    52  		PointerMarshaler
    53  	}
    54  }
    55  
    56  type Recursive struct {
    57  	Field *Recursive
    58  }
    59  
    60  type ValueMarshaler chan int
    61  
    62  func (ValueMarshaler) MarshalText() ([]byte, error) { return nil, nil }
    63  
    64  type PointerMarshaler chan int
    65  
    66  func (*PointerMarshaler) MarshalText() ([]byte, error) { return nil, nil }
    67  
    68  func fn() {
    69  	var t1 T1
    70  	var t2 T2
    71  	var t3 T3
    72  	var t4 T4
    73  	var t5 T5
    74  	var t6 T6
    75  	var t8 T8
    76  	var t9 T9
    77  	var t10 T10
    78  	var t11 Recursive
    79  	json.Marshal(t1)
    80  	json.Marshal(t2)
    81  	json.Marshal(t3) //@ diag(`unsupported type chan int, via x.Ch`)
    82  	json.Marshal(t4)
    83  	json.Marshal(t5) //@ diag(`unsupported type func(), via x.B`)
    84  	json.Marshal(t6)
    85  	(*json.Encoder)(nil).Encode(t1)
    86  	(*json.Encoder)(nil).Encode(t2)
    87  	(*json.Encoder)(nil).Encode(t3) //@ diag(`unsupported type chan int, via x.Ch`)
    88  	(*json.Encoder)(nil).Encode(t4)
    89  	(*json.Encoder)(nil).Encode(t5) //@ diag(`unsupported type func(), via x.B`)
    90  	(*json.Encoder)(nil).Encode(t6)
    91  
    92  	xml.Marshal(t1)
    93  	xml.Marshal(t2)
    94  	xml.Marshal(t3) //@ diag(`unsupported type chan int, via x.Ch`)
    95  	xml.Marshal(t4)
    96  	xml.Marshal(t5)
    97  	xml.Marshal(t6) //@ diag(`unsupported type func(), via x.B`)
    98  	(*xml.Encoder)(nil).Encode(t1)
    99  	(*xml.Encoder)(nil).Encode(t2)
   100  	(*xml.Encoder)(nil).Encode(t3) //@ diag(`unsupported type chan int, via x.C`)
   101  	(*xml.Encoder)(nil).Encode(t4)
   102  	(*xml.Encoder)(nil).Encode(t5)
   103  	(*xml.Encoder)(nil).Encode(t6) //@ diag(`unsupported type func(), via x.B`)
   104  
   105  	json.Marshal(t8)  //@ diag(`unsupported type chan int, via x.T7.T3.Ch`)
   106  	json.Marshal(t9)  //@ diag(`unsupported type PointerMarshaler, via x.F`)
   107  	json.Marshal(&t9) // this is fine, t9 is addressable, therefore T9.D is, too
   108  	json.Marshal(t10) // this is fine, T10.F.D is addressable
   109  
   110  	xml.Marshal(t8)  //@ diag(`unsupported type chan int, via x.T7.T3.Ch`)
   111  	xml.Marshal(t9)  //@ diag(`unsupported type PointerMarshaler, via x.F`)
   112  	xml.Marshal(&t9) // this is fine, t9 is addressable, therefore T9.D is, too
   113  	xml.Marshal(t10) // this is fine, T10.F.D is addressable
   114  
   115  	json.Marshal(t11)
   116  	xml.Marshal(t11)
   117  }
   118  
   119  func addressabilityJSON() {
   120  	var a PointerMarshaler
   121  	var b []PointerMarshaler
   122  	var c struct {
   123  		F PointerMarshaler
   124  	}
   125  	var d [4]PointerMarshaler
   126  	json.Marshal(a) //@ diag(re`unsupported type PointerMarshaler$`)
   127  	json.Marshal(&a)
   128  	json.Marshal(b)
   129  	json.Marshal(&b)
   130  	json.Marshal(c) //@ diag(`unsupported type PointerMarshaler, via x.F`)
   131  	json.Marshal(&c)
   132  	json.Marshal(d) //@ diag(`unsupported type PointerMarshaler, via x[0]`)
   133  	json.Marshal(&d)
   134  
   135  	var m1 map[string]PointerMarshaler
   136  	json.Marshal(m1)                                //@ diag(`unsupported type PointerMarshaler, via x[k]`)
   137  	json.Marshal(&m1)                               //@ diag(`unsupported type PointerMarshaler, via x[k]`)
   138  	json.Marshal([]map[string]PointerMarshaler{m1}) //@ diag(`unsupported type PointerMarshaler, via x[0][k]`)
   139  
   140  	var m2 map[string]*PointerMarshaler
   141  	json.Marshal(m2)
   142  	json.Marshal(&m2)
   143  	json.Marshal([]map[string]*PointerMarshaler{m2})
   144  }
   145  
   146  func addressabilityXML() {
   147  	var a PointerMarshaler
   148  	var b []PointerMarshaler
   149  	var c struct {
   150  		XMLName xml.Name `json:"foo"`
   151  		F       PointerMarshaler
   152  	}
   153  	var d [4]PointerMarshaler
   154  	xml.Marshal(a) //@ diag(re`unsupported type PointerMarshaler$`)
   155  	xml.Marshal(&a)
   156  	xml.Marshal(b)
   157  	xml.Marshal(&b)
   158  	xml.Marshal(c) //@ diag(`unsupported type PointerMarshaler, via x.F`)
   159  	xml.Marshal(&c)
   160  	xml.Marshal(d) //@ diag(`unsupported type PointerMarshaler, via x[0]`)
   161  	xml.Marshal(&d)
   162  }
   163  
   164  func mapsJSON() {
   165  	var good map[int]string
   166  	var bad map[interface{}]string
   167  	// the map key has to be statically known good; it must be a number or a string
   168  	json.Marshal(good)
   169  	json.Marshal(bad) //@ diag(`unsupported type map[interface{}]string`)
   170  
   171  	var m1 map[string]PointerMarshaler
   172  	json.Marshal(m1)                                //@ diag(`unsupported type PointerMarshaler, via x[k]`)
   173  	json.Marshal(&m1)                               //@ diag(`unsupported type PointerMarshaler, via x[k]`)
   174  	json.Marshal([]map[string]PointerMarshaler{m1}) //@ diag(`unsupported type PointerMarshaler, via x[0][k]`)
   175  
   176  	var m2 map[string]*PointerMarshaler
   177  	json.Marshal(m2)
   178  	json.Marshal(&m2)
   179  	json.Marshal([]map[string]*PointerMarshaler{m2})
   180  
   181  	var m3 map[string]ValueMarshaler
   182  	json.Marshal(m3)
   183  	json.Marshal(&m3)
   184  	json.Marshal([]map[string]ValueMarshaler{m3})
   185  
   186  	var m4 map[string]*ValueMarshaler
   187  	json.Marshal(m4)
   188  	json.Marshal(&m4)
   189  	json.Marshal([]map[string]*ValueMarshaler{m4})
   190  
   191  	var m5 map[ValueMarshaler]string
   192  	var m6 map[*ValueMarshaler]string
   193  	var m7 map[PointerMarshaler]string
   194  	var m8 map[*PointerMarshaler]string
   195  
   196  	json.Marshal(m5)
   197  	json.Marshal(m6)
   198  	json.Marshal(m7) //@ diag(`unsupported type map[PointerMarshaler]string`)
   199  	json.Marshal(m8)
   200  }
   201  
   202  func mapsXML() {
   203  	// encoding/xml doesn't support any maps
   204  	var bad map[string]string
   205  	xml.Marshal(bad) //@ diag(`unsupported type`)
   206  }
   207  
   208  func fieldPriorityJSON() {
   209  	// In this example, the channel doesn't matter, because T1.F has higher priority than T1.T2.F
   210  	type lT2 struct {
   211  		F chan int
   212  	}
   213  	type lT1 struct {
   214  		F int
   215  		lT2
   216  	}
   217  	json.Marshal(lT1{})
   218  
   219  	// In this example, it does matter
   220  	type lT4 struct {
   221  		C chan int
   222  	}
   223  	type lT3 struct {
   224  		F int
   225  		lT4
   226  	}
   227  	json.Marshal(lT3{}) //@ diag(`unsupported type chan int, via x.lT4.C`)
   228  }
   229  
   230  func fieldPriorityXML() {
   231  	// In this example, the channel doesn't matter, because T1.F has higher priority than T1.T2.F
   232  	type lT2 struct {
   233  		F chan int
   234  	}
   235  	type lT1 struct {
   236  		F int
   237  		lT2
   238  	}
   239  	xml.Marshal(lT1{})
   240  
   241  	// In this example, it does matter
   242  	type lT4 struct {
   243  		C chan int
   244  	}
   245  	type lT3 struct {
   246  		F int
   247  		lT4
   248  	}
   249  	xml.Marshal(lT3{}) //@ diag(`unsupported type chan int, via x.lT4.C`)
   250  }
   251  
   252  func longPathJSON() {
   253  	var foo struct {
   254  		Field struct {
   255  			Field2 []struct {
   256  				Map map[string]chan int
   257  			}
   258  		}
   259  	}
   260  	json.Marshal(foo) //@ diag(`unsupported type chan int, via x.Field.Field2[0].Map[k]`)
   261  }
   262  
   263  func otherPackageJSON() {
   264  	var x time.Ticker
   265  	json.Marshal(x) //@ diag(`unsupported type <-chan time.Time, via x.C`)
   266  }
   267  
   268  func longPathXML() {
   269  	var foo struct {
   270  		Field struct {
   271  			Field2 []struct {
   272  				Map map[string]chan int
   273  			}
   274  		}
   275  	}
   276  	xml.Marshal(foo) //@ diag(`unsupported type map[string]chan int, via x.Field.Field2[0].Map`)
   277  }
   278  
   279  func otherPackageXML() {
   280  	var x time.Ticker
   281  	xml.Marshal(x) //@ diag(`unsupported type <-chan time.Time, via x.C`)
   282  }
   283  
   284  type ToplevelPointerMarshalerXML struct {
   285  	Field map[string]string
   286  }
   287  
   288  func (*ToplevelPointerMarshalerXML) MarshalXML(*xml.Encoder, xml.StartElement) error {
   289  	return nil
   290  }
   291  
   292  type ToplevelPointerMarshalerText struct {
   293  	Field map[string]string
   294  }
   295  
   296  func (*ToplevelPointerMarshalerText) MarshalText() ([]byte, error) {
   297  	return nil, nil
   298  }
   299  
   300  func toplevelPointer() {
   301  	xml.Marshal(&ToplevelPointerMarshalerXML{})
   302  	xml.Marshal(&ToplevelPointerMarshalerText{})
   303  	xml.Marshal(ToplevelPointerMarshalerXML{})  //@ diag(`unsupported type`)
   304  	xml.Marshal(ToplevelPointerMarshalerText{}) //@ diag(`unsupported type`)
   305  }
   306  
   307  func cyclicPointer() {
   308  	type P *P
   309  	type S2 struct {
   310  		Bar P
   311  	}
   312  	type S1 struct {
   313  		Foo S2
   314  	}
   315  	var s S1
   316  	xml.Marshal(s) //@ diag(`cyclic type P, via x.Foo.Bar`)
   317  }