Skip to content

Commit cbc76ba

Browse files
Copilotpelikhan
andauthored
Add astutil.Root and migrate two linters to Cursor traversal
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
1 parent 823cbee commit cbc76ba

3 files changed

Lines changed: 30 additions & 27 deletions

File tree

pkg/linters/httpstatuscode/httpstatuscode.go

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -91,34 +91,29 @@ var httpStatusNames = map[int]string{
9191
}
9292

9393
func run(pass *analysis.Pass) (any, error) {
94-
insp, err := astutil.Inspector(pass)
94+
root, err := astutil.Root(pass)
9595
if err != nil {
9696
return nil, err
9797
}
9898
noLintLinesByFile := nolint.BuildLineIndex(pass, "httpstatuscode")
9999

100-
nodeFilter := []ast.Node{
101-
(*ast.BinaryExpr)(nil),
102-
(*ast.SwitchStmt)(nil),
103-
}
104-
105-
insp.Preorder(nodeFilter, func(n ast.Node) {
106-
switch node := n.(type) {
100+
for cur := range root.Preorder((*ast.BinaryExpr)(nil), (*ast.SwitchStmt)(nil)) {
101+
switch node := cur.Node().(type) {
107102
case *ast.BinaryExpr:
108103
if node.Op != token.EQL && node.Op != token.NEQ {
109-
return
104+
continue
110105
}
111106
lit, other := extractStatusLiteral(node)
112107
if lit == nil {
113-
return
108+
continue
114109
}
115110
if !isHTTPStatusContext(pass, other) {
116-
return
111+
continue
117112
}
118113
checkAndReport(pass, lit, noLintLinesByFile)
119114
case *ast.SwitchStmt:
120115
if node.Tag == nil || !isHTTPStatusContext(pass, node.Tag) {
121-
return
116+
continue
122117
}
123118
for _, s := range node.Body.List {
124119
cc, ok := s.(*ast.CaseClause)
@@ -134,7 +129,7 @@ func run(pass *analysis.Pass) (any, error) {
134129
}
135130
}
136131
}
137-
})
132+
}
138133

139134
return nil, nil
140135
}

pkg/linters/internal/astutil/astutil.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,16 @@ func Inspector(pass *analysis.Pass) (*inspector.Inspector, error) {
103103
return insp, nil
104104
}
105105

106+
// Root extracts the inspector root cursor from pass.ResultOf.
107+
// It returns an error if the inspect result has an unexpected type.
108+
func Root(pass *analysis.Pass) (inspector.Cursor, error) {
109+
insp, err := Inspector(pass)
110+
if err != nil {
111+
return inspector.Cursor{}, err
112+
}
113+
return insp.Root(), nil
114+
}
115+
106116
// NodeText formats node as Go source text using go/printer.
107117
func NodeText(fset *token.FileSet, node ast.Node) string {
108118
var buf bytes.Buffer

pkg/linters/sortslice/sortslice.go

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,47 +25,45 @@ var Analyzer = &analysis.Analyzer{
2525
}
2626

2727
func run(pass *analysis.Pass) (any, error) {
28-
insp, err := astutil.Inspector(pass)
28+
root, err := astutil.Root(pass)
2929
if err != nil {
3030
return nil, err
3131
}
3232
noLintLinesByFile := nolint.BuildLineIndex(pass, "sortslice")
3333

34-
nodeFilter := []ast.Node{(*ast.CallExpr)(nil)}
35-
36-
insp.Preorder(nodeFilter, func(n ast.Node) {
37-
call, ok := n.(*ast.CallExpr)
34+
for cur := range root.Preorder((*ast.CallExpr)(nil)) {
35+
call, ok := cur.Node().(*ast.CallExpr)
3836
if !ok {
39-
return
37+
continue
4038
}
4139

4240
pos := pass.Fset.PositionFor(call.Pos(), false)
4341
if filecheck.IsTestFile(pos.Filename) {
44-
return
42+
continue
4543
}
4644
if nolint.HasDirective(pos, noLintLinesByFile) {
47-
return
45+
continue
4846
}
4947

5048
sel, ok := call.Fun.(*ast.SelectorExpr)
5149
if !ok {
52-
return
50+
continue
5351
}
5452
pkgIdent, ok := sel.X.(*ast.Ident)
5553
if !ok {
56-
return
54+
continue
5755
}
5856
if pass.TypesInfo == nil {
59-
return
57+
continue
6058
}
6159
obj := pass.TypesInfo.ObjectOf(pkgIdent)
6260
// ObjectOf can be nil when type information is incomplete.
6361
if obj == nil {
64-
return
62+
continue
6563
}
6664
pkgName, ok := obj.(*types.PkgName)
6765
if !ok || pkgName.Imported().Path() != "sort" {
68-
return
66+
continue
6967
}
7068

7169
switch sel.Sel.Name {
@@ -75,7 +73,7 @@ func run(pass *analysis.Pass) (any, error) {
7573
case "SliceStable":
7674
pass.ReportRangef(call, "sort.SliceStable is not type-safe; use slices.SortStableFunc instead")
7775
}
78-
})
76+
}
7977

8078
return nil, nil
8179
}

0 commit comments

Comments
 (0)