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 }