@@ -27,7 +27,7 @@ func NewAnalyzer(s Setting) *analysis.Analyzer {
27
27
return & analysis.Analyzer {
28
28
Name : "recvcheck" ,
29
29
Doc : "checks for receiver type consistency" ,
30
- Run : run ( newFilter ( excludeMethods )) ,
30
+ Run : analyzer { excludeMethods : excludeMethods }. run ,
31
31
Requires : []* analysis.Analyzer {inspect .Analyzer },
32
32
}
33
33
}
@@ -45,70 +45,70 @@ type Setting struct {
45
45
DisableBuiltin bool
46
46
}
47
47
48
- func run ( filter func ( * ast. FuncDecl ) bool ) func ( * analysis. Pass ) ( any , error ) {
49
- return func ( pass * analysis. Pass ) ( any , error ) {
50
- inspector := pass . ResultOf [ inspect . Analyzer ].( * inspector. Inspector )
48
+ type analyzer struct {
49
+ excludeMethods map [ string ] struct {}
50
+ }
51
51
52
- structs := map [string ]* structType {}
53
- inspector .Preorder ([]ast.Node {(* ast .FuncDecl )(nil )}, func (n ast.Node ) {
54
- funcDecl , ok := n .(* ast.FuncDecl )
55
- if ! ok || funcDecl .Recv == nil || len (funcDecl .Recv .List ) != 1 {
56
- return
57
- }
52
+ func (r * analyzer ) run (pass * analysis.Pass ) (interface {}, error ) {
53
+ inspector := pass .ResultOf [inspect .Analyzer ].(* inspector.Inspector )
58
54
59
- if filter (funcDecl ) {
60
- return
61
- }
55
+ structs := map [string ]* structType {}
56
+ inspector .Preorder ([]ast.Node {(* ast .FuncDecl )(nil )}, func (n ast.Node ) {
57
+ funcDecl , ok := n .(* ast.FuncDecl )
58
+ if ! ok || funcDecl .Recv == nil || len (funcDecl .Recv .List ) != 1 {
59
+ return
60
+ }
62
61
63
- var recv * ast.Ident
64
- var isStar bool
65
- switch recvType := funcDecl .Recv .List [0 ].Type .(type ) {
66
- case * ast.StarExpr :
67
- isStar = true
68
- if recv , ok = recvType .X .(* ast.Ident ); ! ok {
69
- return
70
- }
71
- case * ast.Ident :
72
- recv = recvType
73
- default :
62
+ if r .isExcluded (funcDecl ) {
63
+ return
64
+ }
65
+
66
+ var recv * ast.Ident
67
+ var isStar bool
68
+ switch recvType := funcDecl .Recv .List [0 ].Type .(type ) {
69
+ case * ast.StarExpr :
70
+ isStar = true
71
+ if recv , ok = recvType .X .(* ast.Ident ); ! ok {
74
72
return
75
73
}
74
+ case * ast.Ident :
75
+ recv = recvType
76
+ default :
77
+ return
78
+ }
76
79
77
- st , ok := structs [recv .Name ]
78
- if ! ok {
79
- structs [recv .Name ] = & structType {}
80
- st = structs [recv .Name ]
81
- }
80
+ st , ok := structs [recv .Name ]
81
+ if ! ok {
82
+ structs [recv .Name ] = & structType {}
83
+ st = structs [recv .Name ]
84
+ }
82
85
83
- if isStar {
84
- st .starUsed = true
85
- } else {
86
- st .typeUsed = true
87
- }
88
- })
86
+ if isStar {
87
+ st .starUsed = true
88
+ } else {
89
+ st .typeUsed = true
90
+ }
91
+ })
89
92
90
- for recv , st := range structs {
91
- if st .starUsed && st .typeUsed {
92
- pass .Reportf (pass .Pkg .Scope ().Lookup (recv ).Pos (), "the methods of %q use pointer receiver and non-pointer receiver." , recv )
93
- }
93
+ for recv , st := range structs {
94
+ if st .starUsed && st .typeUsed {
95
+ pass .Reportf (pass .Pkg .Scope ().Lookup (recv ).Pos (), "the methods of %q use pointer receiver and non-pointer receiver." , recv )
94
96
}
97
+ }
95
98
96
- return nil , nil
99
+ return nil , nil
100
+ }
101
+
102
+ func (r * analyzer ) isExcluded (f * ast.FuncDecl ) bool {
103
+ if f .Name == nil || f .Name .Name == "" {
104
+ return true
97
105
}
106
+
107
+ _ , found := r .excludeMethods [f .Name .Name ]
108
+ return found
98
109
}
99
110
100
111
type structType struct {
101
112
starUsed bool
102
113
typeUsed bool
103
114
}
104
-
105
- func newFilter (excludes map [string ]struct {}) func (* ast.FuncDecl ) bool {
106
- return func (f * ast.FuncDecl ) bool {
107
- if f .Name == nil || f .Name .Name == "" {
108
- return true
109
- }
110
-
111
- _ , found := excludes [f .Name .Name ]
112
- return found
113
- }
114
- }
0 commit comments