-
Notifications
You must be signed in to change notification settings - Fork 0
/
makeallocs.go
79 lines (63 loc) · 1.61 KB
/
makeallocs.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
package consistent
import (
"go/ast"
"go/types"
"github.com/go-toolsmith/astcast"
"golang.org/x/tools/go/analysis"
)
const (
makeAllocsLiteral = "literal"
makeAllocsMake = "make"
)
var makeAllocsFlagAllowedValues = []string{flagIgnore, makeAllocsLiteral, makeAllocsMake}
func checkMakeAllocLit(pass *analysis.Pass, expr *ast.CompositeLit, mode string) {
if mode != makeAllocsMake {
return
}
if len(expr.Elts) != 0 {
return
}
switch pass.TypesInfo.TypeOf(expr.Type).Underlying().(type) {
case *types.Slice:
reportf(pass, expr.Pos(), "call make instead of using slice literal")
case *types.Map:
reportf(pass, expr.Pos(), "call make instead of using map literal")
}
}
func checkMakeAllocMake(pass *analysis.Pass, call *ast.CallExpr, mode string) { //nolint:gocognit,cyclop // lots of constraints to check
if mode != makeAllocsLiteral {
return
}
if astcast.ToIdent(call.Fun).Name != "make" {
return
}
if len(call.Args) == 0 {
return
}
typ := pass.TypesInfo.TypeOf(call.Args[0]).Underlying()
_, arrayTyp := typ.(*types.Slice)
_, mapTyp := typ.(*types.Map)
switch {
case arrayTyp && (len(call.Args) < 2 || len(call.Args) > 3):
return
case mapTyp && len(call.Args) > 2:
return
case !arrayTyp && !mapTyp:
return
}
if len(call.Args) >= 2 {
if l, ok := litInt(call.Args[1]); !ok || l != 0 {
return
}
}
if arrayTyp && len(call.Args) == 3 {
if c, ok := litInt(call.Args[2]); !ok || c != 0 {
return
}
}
if mapTyp {
reportf(pass, call.Pos(), "use map literal instead of calling make")
return
}
reportf(pass, call.Pos(), "use slice literal instead of calling make")
}