Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pkg/linters/seenmapbool/seenmapbool.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@ func inspectBody(pass *analysis.Pass, body *ast.BlockStmt, noLintLinesByFile map
candidates := make(map[types.Object]ast.Node) // object -> declaration node for reporting

// First pass: collect declarations of map[string]bool locals.
// Stop at nested FuncLit boundaries so each closure is handled by its own
// Preorder visit — preventing duplicate diagnostics.
ast.Inspect(body, func(n ast.Node) bool {
if n == nil {
return false
}
if _, ok := n.(*ast.FuncLit); ok {
return false // do not descend into nested closures
}
Comment on lines 72 to +78
switch stmt := n.(type) {
case *ast.AssignStmt:
// seen := make(map[string]bool) or seen := map[string]bool{}
Expand Down
41 changes: 41 additions & 0 deletions pkg/linters/seenmapbool/testdata/src/seenmapbool/seenmapbool.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,44 @@ func GoodBoolMapWithFalse() {
flags["disabled"] = false
_ = flags
}

func BadSetBoolInClosure() []string {
// Set-map declared inside a closure must be reported exactly once.
unique := func(in []string) []string {
seen := make(map[string]bool) // want `map\[string\]bool "seen" used as a set`
var out []string
for _, x := range in {
if !seen[x] {
seen[x] = true
out = append(out, x)
}
}
return out
}
return unique([]string{"a", "b", "a"})
}

func BadSetBoolInNestedClosure() {
// Two levels of nesting: each set-map is reported exactly once.
Comment on lines +59 to +60
outer := func() {
inner := func() {
seen := make(map[string]bool) // want `map\[string\]bool "seen" used as a set`
seen["x"] = true
_ = seen
}
inner()
}
outer()
}

func GoodOuterMapWrittenFalseInClosure() {
// Map declared in outer function but written false inside a closure — not a
// pure set; must NOT be reported.
flags := make(map[string]bool)
modify := func() {
flags["disabled"] = false
}
flags["enabled"] = true
modify()
_ = flags
}