aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/ckaznocha
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2024-09-10 12:16:33 +0200
committerTaras Madan <tarasmadan@google.com>2024-09-10 14:05:26 +0000
commitc97c816133b42257d0bcf1ee4bd178bb2a7a2b9e (patch)
tree0bcbc2e540bbf8f62f6c17887cdd53b8c2cee637 /vendor/github.com/ckaznocha
parent54e657429ab892ad06c90cd7c1a4eb33ba93a3dc (diff)
vendor: update
Diffstat (limited to 'vendor/github.com/ckaznocha')
-rw-r--r--vendor/github.com/ckaznocha/intrange/go.work2
-rw-r--r--vendor/github.com/ckaznocha/intrange/intrange.go311
2 files changed, 203 insertions, 110 deletions
diff --git a/vendor/github.com/ckaznocha/intrange/go.work b/vendor/github.com/ckaznocha/intrange/go.work
index f41a04a2f..3814c99f9 100644
--- a/vendor/github.com/ckaznocha/intrange/go.work
+++ b/vendor/github.com/ckaznocha/intrange/go.work
@@ -1,4 +1,4 @@
-go 1.22.0
+go 1.22
use (
.
diff --git a/vendor/github.com/ckaznocha/intrange/intrange.go b/vendor/github.com/ckaznocha/intrange/intrange.go
index f8d037dc4..33cddf303 100644
--- a/vendor/github.com/ckaznocha/intrange/intrange.go
+++ b/vendor/github.com/ckaznocha/intrange/intrange.go
@@ -5,6 +5,7 @@ import (
"fmt"
"go/ast"
"go/token"
+ "go/types"
"strconv"
"golang.org/x/tools/go/analysis"
@@ -23,7 +24,10 @@ var (
errFailedAnalysis = errors.New("failed analysis")
)
-const msg = "for loop can be changed to use an integer range (Go 1.22+)"
+const (
+ msg = "for loop can be changed to use an integer range (Go 1.22+)"
+ msgLenRange = "for loop can be changed to `i := range %s`"
+)
func run(pass *analysis.Pass) (any, error) {
result, ok := pass.ResultOf[inspect.Analyzer]
@@ -44,90 +48,134 @@ func run(pass *analysis.Pass) (any, error) {
)
}
- resultInspector.Preorder([]ast.Node{(*ast.ForStmt)(nil)}, check(pass))
+ resultInspector.Preorder([]ast.Node{(*ast.ForStmt)(nil), (*ast.RangeStmt)(nil)}, check(pass))
return nil, nil
}
func check(pass *analysis.Pass) func(node ast.Node) {
return func(node ast.Node) {
- forStmt, ok := node.(*ast.ForStmt)
- if !ok {
+ switch stmt := node.(type) {
+ case *ast.ForStmt:
+ checkForStmt(pass, stmt)
+ case *ast.RangeStmt:
+ checkRangeStmt(pass, stmt)
+ default:
return
}
+ }
+}
+
+func checkForStmt(pass *analysis.Pass, forStmt *ast.ForStmt) {
+ // Existing checks for other patterns
+ if forStmt.Init == nil || forStmt.Cond == nil || forStmt.Post == nil {
+ return
+ }
+
+ // i := 0;;
+ init, ok := forStmt.Init.(*ast.AssignStmt)
+ if !ok {
+ return
+ }
+
+ if len(init.Lhs) != 1 || len(init.Rhs) != 1 {
+ return
+ }
+
+ initIdent, ok := init.Lhs[0].(*ast.Ident)
+ if !ok {
+ return
+ }
- if forStmt.Init == nil || forStmt.Cond == nil || forStmt.Post == nil {
+ if !compareNumberLit(init.Rhs[0], 0) {
+ return
+ }
+
+ cond, ok := forStmt.Cond.(*ast.BinaryExpr)
+ if !ok {
+ return
+ }
+
+ var nExpr ast.Expr
+
+ switch cond.Op {
+ case token.LSS: // ;i < n;
+ if isBenchmark(cond.Y) {
return
}
- // i := 0;;
- init, ok := forStmt.Init.(*ast.AssignStmt)
+ nExpr = findNExpr(cond.Y)
+
+ x, ok := cond.X.(*ast.Ident)
if !ok {
return
}
- if len(init.Lhs) != 1 || len(init.Rhs) != 1 {
+ if x.Name != initIdent.Name {
+ return
+ }
+ case token.GTR: // ;n > i;
+ if isBenchmark(cond.X) {
return
}
- initIdent, ok := init.Lhs[0].(*ast.Ident)
+ nExpr = findNExpr(cond.X)
+
+ y, ok := cond.Y.(*ast.Ident)
if !ok {
return
}
- if !compareNumberLit(init.Rhs[0], 0) {
+ if y.Name != initIdent.Name {
return
}
+ default:
+ return
+ }
- cond, ok := forStmt.Cond.(*ast.BinaryExpr)
- if !ok {
+ switch post := forStmt.Post.(type) {
+ case *ast.IncDecStmt: // ;;i++
+ if post.Tok != token.INC {
return
}
- var nExpr ast.Expr
+ ident, ok := post.X.(*ast.Ident)
+ if !ok {
+ return
+ }
- switch cond.Op {
- case token.LSS: // ;i < n;
- if isBenchmark(cond.Y) {
+ if ident.Name != initIdent.Name {
+ return
+ }
+ case *ast.AssignStmt:
+ switch post.Tok {
+ case token.ADD_ASSIGN: // ;;i += 1
+ if len(post.Lhs) != 1 {
return
}
- nExpr = findNExpr(cond.Y)
-
- x, ok := cond.X.(*ast.Ident)
+ ident, ok := post.Lhs[0].(*ast.Ident)
if !ok {
return
}
- if x.Name != initIdent.Name {
- return
- }
- case token.GTR: // ;n > i;
- if isBenchmark(cond.X) {
+ if ident.Name != initIdent.Name {
return
}
- nExpr = findNExpr(cond.X)
-
- y, ok := cond.Y.(*ast.Ident)
- if !ok {
+ if len(post.Rhs) != 1 {
return
}
- if y.Name != initIdent.Name {
+ if !compareNumberLit(post.Rhs[0], 1) {
return
}
- default:
- return
- }
-
- switch post := forStmt.Post.(type) {
- case *ast.IncDecStmt: // ;;i++
- if post.Tok != token.INC {
+ case token.ASSIGN: // ;;i = i + 1 && ;;i = 1 + i
+ if len(post.Lhs) != 1 || len(post.Rhs) != 1 {
return
}
- ident, ok := post.X.(*ast.Ident)
+ ident, ok := post.Lhs[0].(*ast.Ident)
if !ok {
return
}
@@ -135,35 +183,31 @@ func check(pass *analysis.Pass) func(node ast.Node) {
if ident.Name != initIdent.Name {
return
}
- case *ast.AssignStmt:
- switch post.Tok {
- case token.ADD_ASSIGN: // ;;i += 1
- if len(post.Lhs) != 1 {
- return
- }
- ident, ok := post.Lhs[0].(*ast.Ident)
- if !ok {
- return
- }
+ bin, ok := post.Rhs[0].(*ast.BinaryExpr)
+ if !ok {
+ return
+ }
- if ident.Name != initIdent.Name {
- return
- }
+ if bin.Op != token.ADD {
+ return
+ }
- if len(post.Rhs) != 1 {
+ switch x := bin.X.(type) {
+ case *ast.Ident: // ;;i = i + 1
+ if x.Name != initIdent.Name {
return
}
- if !compareNumberLit(post.Rhs[0], 1) {
+ if !compareNumberLit(bin.Y, 1) {
return
}
- case token.ASSIGN: // ;;i = i + 1 && ;;i = 1 + i
- if len(post.Lhs) != 1 || len(post.Rhs) != 1 {
+ case *ast.BasicLit: // ;;i = 1 + i
+ if !compareNumberLit(x, 1) {
return
}
- ident, ok := post.Lhs[0].(*ast.Ident)
+ ident, ok := bin.Y.(*ast.Ident)
if !ok {
return
}
@@ -171,84 +215,121 @@ func check(pass *analysis.Pass) func(node ast.Node) {
if ident.Name != initIdent.Name {
return
}
-
- bin, ok := post.Rhs[0].(*ast.BinaryExpr)
- if !ok {
- return
- }
-
- if bin.Op != token.ADD {
- return
- }
-
- switch x := bin.X.(type) {
- case *ast.Ident: // ;;i = i + 1
- if x.Name != initIdent.Name {
- return
- }
-
- if !compareNumberLit(bin.Y, 1) {
- return
- }
- case *ast.BasicLit: // ;;i = 1 + i
- if !compareNumberLit(x, 1) {
- return
- }
-
- ident, ok := bin.Y.(*ast.Ident)
- if !ok {
- return
- }
-
- if ident.Name != initIdent.Name {
- return
- }
- default:
- return
- }
default:
return
}
default:
return
}
+ default:
+ return
+ }
- bc := &bodyChecker{
- initIdent: initIdent,
- nExpr: nExpr,
- }
+ bc := &bodyChecker{
+ initIdent: initIdent,
+ nExpr: nExpr,
+ }
- ast.Inspect(forStmt.Body, bc.check)
+ ast.Inspect(forStmt.Body, bc.check)
- if bc.modified {
- return
- }
+ if bc.modified {
+ return
+ }
+
+ pass.Report(analysis.Diagnostic{
+ Pos: forStmt.Pos(),
+ Message: msg,
+ })
+}
+
+func checkRangeStmt(pass *analysis.Pass, rangeStmt *ast.RangeStmt) {
+ if rangeStmt.Key == nil {
+ return
+ }
+
+ ident, ok := rangeStmt.Key.(*ast.Ident)
+ if !ok {
+ return
+ }
+
+ if ident.Name == "_" {
+ return
+ }
- pass.Report(analysis.Diagnostic{
- Pos: forStmt.Pos(),
- Message: msg,
- })
+ if rangeStmt.Value != nil {
+ return
}
+
+ if rangeStmt.X == nil {
+ return
+ }
+
+ x, ok := rangeStmt.X.(*ast.CallExpr)
+ if !ok {
+ return
+ }
+
+ fn, ok := x.Fun.(*ast.Ident)
+ if !ok {
+ return
+ }
+
+ if fn.Name != "len" || len(x.Args) != 1 {
+ return
+ }
+
+ arg, ok := x.Args[0].(*ast.Ident)
+ if !ok {
+ return
+ }
+
+ // make sure arg is a slice or array
+ obj := pass.TypesInfo.ObjectOf(arg)
+ if obj == nil {
+ return
+ }
+
+ switch obj.Type().Underlying().(type) {
+ case *types.Slice, *types.Array:
+ default:
+ return
+ }
+
+ pass.Report(analysis.Diagnostic{
+ Pos: ident.Pos(),
+ End: x.End(),
+ Message: fmt.Sprintf(msgLenRange, arg.Name),
+ SuggestedFixes: []analysis.SuggestedFix{
+ {
+ Message: fmt.Sprintf("Replace `len(%s)` with `%s`", arg.Name, arg.Name),
+ TextEdits: []analysis.TextEdit{
+ {
+ Pos: x.Pos(),
+ End: x.End(),
+ NewText: []byte(arg.Name),
+ },
+ },
+ },
+ },
+ })
}
func findNExpr(expr ast.Expr) ast.Expr {
switch e := expr.(type) {
case *ast.CallExpr:
- if e.Fun.(*ast.Ident).Name != "len" {
- return nil
- }
-
- if len(e.Args) != 1 {
- return nil
+ if fun, ok := e.Fun.(*ast.Ident); ok && fun.Name == "len" && len(e.Args) == 1 {
+ return findNExpr(e.Args[0])
}
- return findNExpr(e.Args[0])
+ return nil
case *ast.BasicLit:
return nil
case *ast.Ident:
return e
case *ast.SelectorExpr:
return e
+ case *ast.IndexExpr:
+ return e
default:
return nil
}
@@ -297,7 +378,19 @@ func identEqual(a, b ast.Expr) bool {
return identEqual(aT.Sel, selectorB.Sel) && identEqual(aT.X, selectorB.X)
case *ast.IndexExpr:
+ indexB, ok := b.(*ast.IndexExpr)
+ if ok {
+ return identEqual(aT.X, indexB.X) && identEqual(aT.Index, indexB.Index)
+ }
+
return identEqual(aT.X, b)
+ case *ast.BasicLit:
+ litB, ok := b.(*ast.BasicLit)
+ if !ok {
+ return false
+ }
+
+ return aT.Value == litB.Value
default:
return false
}