@@ -83,44 +83,20 @@ func (p *RequestBodyPlugin) GetLoadMode() string {
8383 return register .LoadModeSyntax
8484}
8585
86- // usage records which body types triggered each rule within a package, so that allow-list entries that are no longer needed can be reported.
87- type usage struct {
88- pointerTypes map [string ]bool
89- optionsTypes map [string ]bool
90- }
91-
9286func (p * RequestBodyPlugin ) run (pass * analysis.Pass ) (any , error ) {
93- used := usage {
94- pointerTypes : map [string ]bool {},
95- optionsTypes : map [string ]bool {},
96- }
97- declared := map [string ]* ast.Ident {}
98-
9987 for _ , file := range pass .Files {
10088 for _ , decl := range file .Decls {
101- switch d := decl .(type ) {
102- case * ast.GenDecl :
103- if d .Tok != token .TYPE {
104- continue
105- }
106- for _ , spec := range d .Specs {
107- if ts , ok := spec .(* ast.TypeSpec ); ok {
108- declared [ts .Name .Name ] = ts .Name
109- }
110- }
111- case * ast.FuncDecl :
112- if d .Body != nil {
113- p .analyzeFunc (pass , d , & used )
114- }
89+ fn , ok := decl .(* ast.FuncDecl )
90+ if ! ok || fn .Body == nil {
91+ continue
11592 }
93+ p .analyzeFunc (pass , fn )
11694 }
11795 }
118-
119- p .reportUnusedSettings (pass , declared , & used )
12096 return nil , nil
12197}
12298
123- func (p * RequestBodyPlugin ) analyzeFunc (pass * analysis.Pass , fn * ast.FuncDecl , used * usage ) {
99+ func (p * RequestBodyPlugin ) analyzeFunc (pass * analysis.Pass , fn * ast.FuncDecl ) {
124100 ast .Inspect (fn .Body , func (n ast.Node ) bool {
125101 call , ok := n .(* ast.CallExpr )
126102 if ! ok || ! isClientNewRequest (call ) || ! isMutatingMethod (call ) {
@@ -138,42 +114,12 @@ func (p *RequestBodyPlugin) analyzeFunc(pass *analysis.Pass, fn *ast.FuncDecl, u
138114 }
139115
140116 reportRename (pass , fn , name )
141- p .reportByValue (pass , field , name , used )
142- p .reportTypeSuffix (pass , field , used )
117+ p .reportByValue (pass , field , name )
118+ p .reportTypeSuffix (pass , field )
143119 return true
144120 })
145121}
146122
147- // reportUnusedSettings reports allow-list entries whose type is declared in this package but never triggered the rule they exempt,
148- // meaning the exception can be removed.
149- // Both the type declarations and their NewRequest usages live in the same package,
150- // so a type declared here that is never recorded as used is genuinely no longer in violation.
151- func (p * RequestBodyPlugin ) reportUnusedSettings (pass * analysis.Pass , declared map [string ]* ast.Ident , used * usage ) {
152- for name := range p .allowedPointerTypes {
153- ident , ok := declared [name ]
154- if ! ok || used .pointerTypes [name ] {
155- continue
156- }
157- pass .Report (analysis.Diagnostic {
158- Pos : ident .Pos (),
159- End : ident .End (),
160- Message : fmt .Sprintf ("unused requestbody exception: type %q in allowed-pointer-types is never passed by pointer to client.NewRequest" , name ),
161- })
162- }
163-
164- for name := range p .allowedWrongNames {
165- ident , ok := declared [name ]
166- if ! ok || used .optionsTypes [name ] {
167- continue
168- }
169- pass .Report (analysis.Diagnostic {
170- Pos : ident .Pos (),
171- End : ident .End (),
172- Message : fmt .Sprintf ("unused requestbody exception: type %q in allowed-wrong-names is never passed as a request body to client.NewRequest" , name ),
173- })
174- }
175- }
176-
177123func reportRename (pass * analysis.Pass , fn * ast.FuncDecl , name * ast.Ident ) {
178124 if name .Name == "body" {
179125 return
@@ -195,15 +141,12 @@ func reportRename(pass *analysis.Pass, fn *ast.FuncDecl, name *ast.Ident) {
195141 pass .Report (diag )
196142}
197143
198- func (p * RequestBodyPlugin ) reportByValue (pass * analysis.Pass , field * ast.Field , name * ast.Ident , used * usage ) {
144+ func (p * RequestBodyPlugin ) reportByValue (pass * analysis.Pass , field * ast.Field , name * ast.Ident ) {
199145 if _ , ok := field .Type .(* ast.StarExpr ); ! ok {
200146 return
201147 }
202- if ident := typeNameIdent (field .Type ); ident != nil {
203- used .pointerTypes [ident .Name ] = true
204- if p .allowedPointerTypes [ident .Name ] {
205- return
206- }
148+ if ident := typeNameIdent (field .Type ); ident != nil && p .allowedPointerTypes [ident .Name ] {
149+ return
207150 }
208151 pass .Report (analysis.Diagnostic {
209152 Pos : name .Pos (),
@@ -215,12 +158,11 @@ func (p *RequestBodyPlugin) reportByValue(pass *analysis.Pass, field *ast.Field,
215158// reportTypeSuffix reports body parameter types whose name ends with "Options", which should use a "Request" suffix instead
216159// (e.g. UserSuspendOptions -> UserSuspendRequest).
217160// It is report-only because renaming a type affects its declaration and every use across the codebase.
218- func (p * RequestBodyPlugin ) reportTypeSuffix (pass * analysis.Pass , field * ast.Field , used * usage ) {
161+ func (p * RequestBodyPlugin ) reportTypeSuffix (pass * analysis.Pass , field * ast.Field ) {
219162 ident := typeNameIdent (field .Type )
220163 if ident == nil || ! strings .HasSuffix (ident .Name , "Options" ) {
221164 return
222165 }
223- used .optionsTypes [ident .Name ] = true
224166 if p .allowedWrongNames [ident .Name ] {
225167 return
226168 }
0 commit comments