feat: detect potential nested contexts in function declarations

This commit is contained in:
Gabriel Augendre 2025-01-13 15:46:00 +01:00
parent 939d65bc16
commit 5b689092ef
2 changed files with 34 additions and 13 deletions
pkg/analyzer
testdata/src

View file

@ -30,6 +30,7 @@ func run(pass *analysis.Pass) (interface{}, error) {
(*ast.ForStmt)(nil),
(*ast.RangeStmt)(nil),
(*ast.FuncLit)(nil),
(*ast.FuncDecl)(nil),
}
inspctr.Preorder(nodeFilter, func(node ast.Node) {
@ -81,25 +82,23 @@ func getReportMessage(node ast.Node) string {
return "nested context in loop"
case *ast.FuncLit:
return "nested context in function literal"
case *ast.FuncDecl:
return "potential nested context in function declaration"
default:
return "unsupported nested context type"
}
}
func getBody(node ast.Node) (*ast.BlockStmt, error) {
forStmt, ok := node.(*ast.ForStmt)
if ok {
return forStmt.Body, nil
}
rangeStmt, ok := node.(*ast.RangeStmt)
if ok {
return rangeStmt.Body, nil
}
funcLit, ok := node.(*ast.FuncLit)
if ok {
return funcLit.Body, nil
switch typedNode := node.(type) {
case *ast.ForStmt:
return typedNode.Body, nil
case *ast.RangeStmt:
return typedNode.Body, nil
case *ast.FuncLit:
return typedNode.Body, nil
case *ast.FuncDecl:
return typedNode.Body, nil
}
return nil, errUnknown

View file

@ -249,3 +249,25 @@ func testCasesInit(t *testing.T) {
})
}
}
type Container struct {
Ctx context.Context
}
func something() func(*Container) {
return func(r *Container) {
ctx := r.Ctx
ctx = context.WithValue(ctx, "key", "val")
r.Ctx = ctx // want "nested context in function literal"
}
}
func other() func(*Container) {
return blah
}
func blah(r *Container) {
ctx := r.Ctx
ctx = context.WithValue(ctx, "key", "val")
r.Ctx = ctx // want "potential nested context in function declaration"
}