diff --git a/pkg/linters/httpstatuscode/httpstatuscode.go b/pkg/linters/httpstatuscode/httpstatuscode.go index 702e3a1584b..dbca642295a 100644 --- a/pkg/linters/httpstatuscode/httpstatuscode.go +++ b/pkg/linters/httpstatuscode/httpstatuscode.go @@ -91,34 +91,29 @@ var httpStatusNames = map[int]string{ } func run(pass *analysis.Pass) (any, error) { - insp, err := astutil.Inspector(pass) + root, err := astutil.Root(pass) if err != nil { return nil, err } noLintLinesByFile := nolint.BuildLineIndex(pass, "httpstatuscode") - nodeFilter := []ast.Node{ - (*ast.BinaryExpr)(nil), - (*ast.SwitchStmt)(nil), - } - - insp.Preorder(nodeFilter, func(n ast.Node) { - switch node := n.(type) { + for cur := range root.Preorder((*ast.BinaryExpr)(nil), (*ast.SwitchStmt)(nil)) { + switch node := cur.Node().(type) { case *ast.BinaryExpr: if node.Op != token.EQL && node.Op != token.NEQ { - return + continue } lit, other := extractStatusLiteral(node) if lit == nil { - return + continue } if !isHTTPStatusContext(pass, other) { - return + continue } checkAndReport(pass, lit, noLintLinesByFile) case *ast.SwitchStmt: if node.Tag == nil || !isHTTPStatusContext(pass, node.Tag) { - return + continue } for _, s := range node.Body.List { cc, ok := s.(*ast.CaseClause) @@ -134,7 +129,7 @@ func run(pass *analysis.Pass) (any, error) { } } } - }) + } return nil, nil } diff --git a/pkg/linters/internal/astutil/astutil.go b/pkg/linters/internal/astutil/astutil.go index a5877ccf3b1..d2fe94ce111 100644 --- a/pkg/linters/internal/astutil/astutil.go +++ b/pkg/linters/internal/astutil/astutil.go @@ -103,6 +103,16 @@ func Inspector(pass *analysis.Pass) (*inspector.Inspector, error) { return insp, nil } +// Root extracts the inspector root cursor from pass.ResultOf. +// It returns an error if the inspect result has an unexpected type. +func Root(pass *analysis.Pass) (inspector.Cursor, error) { + insp, err := Inspector(pass) + if err != nil { + return inspector.Cursor{}, err + } + return insp.Root(), nil +} + // NodeText formats node as Go source text using go/printer. func NodeText(fset *token.FileSet, node ast.Node) string { var buf bytes.Buffer diff --git a/pkg/linters/sortslice/sortslice.go b/pkg/linters/sortslice/sortslice.go index 0ca6b90eef5..70c60e48ecf 100644 --- a/pkg/linters/sortslice/sortslice.go +++ b/pkg/linters/sortslice/sortslice.go @@ -25,47 +25,45 @@ var Analyzer = &analysis.Analyzer{ } func run(pass *analysis.Pass) (any, error) { - insp, err := astutil.Inspector(pass) + root, err := astutil.Root(pass) if err != nil { return nil, err } noLintLinesByFile := nolint.BuildLineIndex(pass, "sortslice") - nodeFilter := []ast.Node{(*ast.CallExpr)(nil)} - - insp.Preorder(nodeFilter, func(n ast.Node) { - call, ok := n.(*ast.CallExpr) + for cur := range root.Preorder((*ast.CallExpr)(nil)) { + call, ok := cur.Node().(*ast.CallExpr) if !ok { - return + continue } pos := pass.Fset.PositionFor(call.Pos(), false) if filecheck.IsTestFile(pos.Filename) { - return + continue } if nolint.HasDirective(pos, noLintLinesByFile) { - return + continue } sel, ok := call.Fun.(*ast.SelectorExpr) if !ok { - return + continue } pkgIdent, ok := sel.X.(*ast.Ident) if !ok { - return + continue } if pass.TypesInfo == nil { - return + continue } obj := pass.TypesInfo.ObjectOf(pkgIdent) // ObjectOf can be nil when type information is incomplete. if obj == nil { - return + continue } pkgName, ok := obj.(*types.PkgName) if !ok || pkgName.Imported().Path() != "sort" { - return + continue } switch sel.Sel.Name { @@ -75,7 +73,7 @@ func run(pass *analysis.Pass) (any, error) { case "SliceStable": pass.ReportRangef(call, "sort.SliceStable is not type-safe; use slices.SortStableFunc instead") } - }) + } return nil, nil }