Skip to content

Commit 5a10814

Browse files
authored
dev: replace forEachKey with iterator (#84)
1 parent 8e10f6a commit 5a10814

File tree

1 file changed

+53
-33
lines changed

1 file changed

+53
-33
lines changed

sloglint.go

+53-33
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"go/token"
1010
"go/types"
1111
"go/version"
12+
"iter"
1213
"slices"
1314
"strconv"
1415
"strings"
@@ -302,32 +303,35 @@ func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node)
302303
}
303304

304305
if opts.NoRawKeys {
305-
forEachKey(pass.TypesInfo, keys, attrs, func(key ast.Expr) {
306+
for key := range AllKeys(pass.TypesInfo, keys, attrs) {
306307
if sel, ok := key.(*ast.SelectorExpr); ok {
307308
key = sel.Sel // the key is defined in another package, e.g. pkg.ConstKey.
308309
}
310+
309311
isConst := false
312+
310313
if ident, ok := key.(*ast.Ident); ok {
311314
if obj := pass.TypesInfo.ObjectOf(ident); obj != nil {
312315
if _, ok := obj.(*types.Const); ok {
313316
isConst = true
314317
}
315318
}
316319
}
320+
317321
if !isConst {
318322
pass.Reportf(key.Pos(), "raw keys should not be used")
319323
}
320-
})
324+
}
321325
}
322326

323327
checkKeysNaming(opts, pass, keys, attrs)
324328

325329
if len(opts.ForbiddenKeys) > 0 {
326-
forEachKey(pass.TypesInfo, keys, attrs, func(key ast.Expr) {
330+
for key := range AllKeys(pass.TypesInfo, keys, attrs) {
327331
if name, ok := getKeyName(key); ok && slices.Contains(opts.ForbiddenKeys, name) {
328332
pass.Reportf(key.Pos(), "%q key is forbidden and should not be used", name)
329333
}
330-
})
334+
}
331335
}
332336

333337
if opts.ArgsOnSepLines && areArgsOnSameLine(pass.Fset, call, keys, attrs) {
@@ -337,7 +341,7 @@ func visit(pass *analysis.Pass, opts *Options, node ast.Node, stack []ast.Node)
337341

338342
func checkKeysNaming(opts *Options, pass *analysis.Pass, keys, attrs []ast.Expr) {
339343
checkKeyNamingCase := func(caseFn func(string) string, caseName string) {
340-
forEachKey(pass.TypesInfo, keys, attrs, func(key ast.Expr) {
344+
for key := range AllKeys(pass.TypesInfo, keys, attrs) {
341345
name, ok := getKeyName(key)
342346
if !ok || name == caseFn(name) {
343347
return
@@ -354,7 +358,7 @@ func checkKeysNaming(opts *Options, pass *analysis.Pass, keys, attrs []ast.Expr)
354358
}},
355359
}},
356360
})
357-
})
361+
}
358362
}
359363

360364
switch opts.KeyNamingCase {
@@ -479,36 +483,52 @@ func isValidMsgStyle(msg, style string) bool {
479483
}
480484
}
481485

482-
func forEachKey(info *types.Info, keys, attrs []ast.Expr, fn func(key ast.Expr)) {
483-
for _, key := range keys {
484-
fn(key)
485-
}
486-
487-
for _, attr := range attrs {
488-
switch attr := attr.(type) {
489-
case *ast.CallExpr: // e.g. slog.Int()
490-
callee := typeutil.StaticCallee(info, attr)
491-
if callee == nil {
492-
continue
493-
}
494-
if _, ok := attrFuncs[callee.FullName()]; !ok {
495-
continue
486+
func AllKeys(info *types.Info, keys, attrs []ast.Expr) iter.Seq[ast.Expr] {
487+
return func(yield func(key ast.Expr) bool) {
488+
for _, key := range keys {
489+
if !yield(key) {
490+
return
496491
}
497-
fn(attr.Args[0])
492+
}
493+
494+
for _, attr := range attrs {
495+
switch attr := attr.(type) {
496+
case *ast.CallExpr: // e.g. slog.Int()
497+
callee := typeutil.StaticCallee(info, attr)
498+
if callee == nil {
499+
continue
500+
}
501+
if _, ok := attrFuncs[callee.FullName()]; !ok {
502+
continue
503+
}
498504

499-
case *ast.CompositeLit: // slog.Attr{}
500-
switch len(attr.Elts) {
501-
case 1: // slog.Attr{Key: ...} | slog.Attr{Value: ...}
502-
if kv := attr.Elts[0].(*ast.KeyValueExpr); kv.Key.(*ast.Ident).Name == "Key" {
503-
fn(kv.Value)
505+
if !yield(attr.Args[0]) {
506+
return
504507
}
505-
case 2: // slog.Attr{Key: ..., Value: ...} | slog.Attr{Value: ..., Key: ...} | slog.Attr{..., ...}
506-
if kv, ok := attr.Elts[0].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
507-
fn(kv.Value)
508-
} else if kv, ok := attr.Elts[1].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
509-
fn(kv.Value)
510-
} else {
511-
fn(attr.Elts[0])
508+
509+
case *ast.CompositeLit: // slog.Attr{}
510+
switch len(attr.Elts) {
511+
case 1: // slog.Attr{Key: ...} | slog.Attr{Value: ...}
512+
if kv := attr.Elts[0].(*ast.KeyValueExpr); kv.Key.(*ast.Ident).Name == "Key" {
513+
if !yield(kv.Value) {
514+
return
515+
}
516+
}
517+
518+
case 2: // slog.Attr{Key: ..., Value: ...} | slog.Attr{Value: ..., Key: ...} | slog.Attr{..., ...}
519+
if kv, ok := attr.Elts[0].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
520+
if !yield(kv.Value) {
521+
return
522+
}
523+
} else if kv, ok := attr.Elts[1].(*ast.KeyValueExpr); ok && kv.Key.(*ast.Ident).Name == "Key" {
524+
if !yield(kv.Value) {
525+
return
526+
}
527+
} else {
528+
if !yield(attr.Elts[0]) {
529+
return
530+
}
531+
}
512532
}
513533
}
514534
}

0 commit comments

Comments
 (0)