@@ -119,22 +119,14 @@ func run(pass *analysis.Pass, mainModule string, funcs map[string]Func) (_ any,
119
119
return // no type info found.
120
120
}
121
121
122
- // TODO: check nested structs too.
123
- if implementsInterface (typ , fn .ifaceWhitelist , pass .Pkg .Imports ()) {
124
- return // the type implements a Marshaler interface; see issue #64.
125
- }
126
-
127
122
checker := checker {
128
- mainModule : mainModule ,
129
- seenTypes : make (map [string ]struct {}),
130
- }
131
-
132
- styp , ok := checker .parseStruct (typ )
133
- if ! ok {
134
- return // not a struct.
123
+ mainModule : mainModule ,
124
+ seenTypes : make (map [string ]struct {}),
125
+ ifaceWhitelist : fn .ifaceWhitelist ,
126
+ imports : pass .Pkg .Imports (),
135
127
}
136
128
137
- if valid := checker .checkStruct ( styp , fn .Tag ); valid {
129
+ if valid := checker .checkType ( typ , fn .Tag ); valid {
138
130
return // nothing to report.
139
131
}
140
132
@@ -145,8 +137,28 @@ func run(pass *analysis.Pass, mainModule string, funcs map[string]Func) (_ any,
145
137
}
146
138
147
139
type checker struct {
148
- mainModule string
149
- seenTypes map [string ]struct {}
140
+ mainModule string
141
+ seenTypes map [string ]struct {}
142
+ ifaceWhitelist []string
143
+ imports []* types.Package
144
+ }
145
+
146
+ func (c * checker ) checkType (typ types.Type , tag string ) bool {
147
+ if _ , ok := c .seenTypes [typ .String ()]; ok {
148
+ return true // already checked.
149
+ }
150
+ c .seenTypes [typ .String ()] = struct {}{}
151
+
152
+ if implementsInterface (typ , c .ifaceWhitelist , c .imports ) {
153
+ return true // the type implements a Marshaler interface; see issue #64.
154
+ }
155
+
156
+ styp , ok := c .parseStruct (typ )
157
+ if ! ok {
158
+ return true // not a struct.
159
+ }
160
+
161
+ return c .checkStruct (styp , tag )
150
162
}
151
163
152
164
func (c * checker ) parseStruct (typ types.Type ) (* types.Struct , bool ) {
@@ -186,8 +198,6 @@ func (c *checker) parseStruct(typ types.Type) (*types.Struct, bool) {
186
198
}
187
199
188
200
func (c * checker ) checkStruct (styp * types.Struct , tag string ) (valid bool ) {
189
- c .seenTypes [styp .String ()] = struct {}{}
190
-
191
201
for i := 0 ; i < styp .NumFields (); i ++ {
192
202
field := styp .Field (i )
193
203
if ! field .Exported () {
@@ -201,14 +211,7 @@ func (c *checker) checkStruct(styp *types.Struct, tag string) (valid bool) {
201
211
}
202
212
}
203
213
204
- nested , ok := c .parseStruct (field .Type ())
205
- if ! ok {
206
- continue
207
- }
208
- if _ , ok := c .seenTypes [nested .String ()]; ok {
209
- continue
210
- }
211
- if valid := c .checkStruct (nested , tag ); ! valid {
214
+ if valid := c .checkType (field .Type (), tag ); ! valid {
212
215
return false
213
216
}
214
217
}
0 commit comments