-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathconstructorcheck.go
96 lines (80 loc) · 2.76 KB
/
constructorcheck.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
//golangcitest:args -Econstructorcheck
package testdata
import (
"bytes"
"fmt"
)
var buf = bytes.Buffer{} // standard library is excluded from analysis
// T is a type whose zero values are supposedly invalid
// so a constructor NewT was created.
type T struct {
x int
s string
m map[int]int
}
var (
tNil *T // want `nil value of type command-line-arguments.T may be unsafe, use constructor NewT instead`
tZero = T{} // want `zero value of type command-line-arguments.T may be unsafe, use constructor NewT instead`
tZeroPtr = &T{} // want `zero value of type command-line-arguments.T may be unsafe, use constructor NewT instead`
tNew = new(T) // want `zero value of type command-line-arguments.T may be unsafe, use constructor NewT instead`
tComposite = T{ // want `use constructor NewT for type command-line-arguments.T instead of a composite literal`
x: 1,
s: "abc",
}
tCompositePtr = &T{ // want `use constructor NewT for type command-line-arguments.T instead of a composite literal`
x: 1,
s: "abc",
}
tColl = []T{T{x: 1}} // want `use constructor NewT for type command-line-arguments.T instead of a composite literal`
tPtrColl = []*T{&T{x: 1}} // want `use constructor NewT for type command-line-arguments.T instead of a composite literal`
)
// NewT is a valid constructor for type T. Here we check if it's called
// instead of constructing values of type T manually
func NewT() *T {
return &T{
m: make(map[int]int),
}
}
type structWithTField struct {
i int
t T
}
var structWithT = structWithTField{
i: 1,
t: T{x: 1}, // want `use constructor NewT for type command-line-arguments.T instead of a composite literal`
}
type structWithTPtrField struct {
i int
t *T
}
var structWithTPtr = structWithTPtrField{
i: 1,
t: &T{x: 1}, // want `use constructor NewT for type command-line-arguments.T instead of a composite literal`
}
func fnWithT() {
x := T{} // want `zero value of type command-line-arguments.T may be unsafe, use constructor NewT instead`
x2 := &T{} // want `zero value of type command-line-arguments.T may be unsafe, use constructor NewT instead`
x3 := new(T) // want `zero value of type command-line-arguments.T may be unsafe, use constructor NewT instead`
fmt.Println(x, x2, x3)
}
func retT() T {
return T{ // want `use constructor NewT for type command-line-arguments.T instead of a composite literal`
x: 1,
}
}
func retTPtr() *T {
return &T{ // want `use constructor NewT for type command-line-arguments.T instead of a composite literal`
x: 1,
}
}
func retTNilPtr() *T {
var t *T // want `nil value of type command-line-arguments.T may be unsafe, use constructor NewT instead`
return t
}
type T2 struct {
x int
}
func NewT2() *T2 {
// new(T) inside T's constructor is permitted
return new(T2)
}