aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/charithe/durationcheck/durationcheck.go
diff options
context:
space:
mode:
authorTaras Madan <tarasmadan@google.com>2025-01-22 16:07:17 +0100
committerTaras Madan <tarasmadan@google.com>2025-01-23 10:42:36 +0000
commit7b4377ad9d8a7205416df8d6217ef2b010f89481 (patch)
treee6fec4fd12ff807a16d847923f501075bf71d16c /vendor/github.com/charithe/durationcheck/durationcheck.go
parent475a4c203afb8b7d3af51c4fd32bb170ff32a45e (diff)
vendor: delete
Diffstat (limited to 'vendor/github.com/charithe/durationcheck/durationcheck.go')
-rw-r--r--vendor/github.com/charithe/durationcheck/durationcheck.go191
1 files changed, 0 insertions, 191 deletions
diff --git a/vendor/github.com/charithe/durationcheck/durationcheck.go b/vendor/github.com/charithe/durationcheck/durationcheck.go
deleted file mode 100644
index c47b3a761..000000000
--- a/vendor/github.com/charithe/durationcheck/durationcheck.go
+++ /dev/null
@@ -1,191 +0,0 @@
-package durationcheck
-
-import (
- "bytes"
- "fmt"
- "go/ast"
- "go/format"
- "go/token"
- "go/types"
- "log"
- "os"
-
- "golang.org/x/tools/go/analysis"
- "golang.org/x/tools/go/analysis/passes/inspect"
- "golang.org/x/tools/go/ast/inspector"
-)
-
-var Analyzer = &analysis.Analyzer{
- Name: "durationcheck",
- Doc: "check for two durations multiplied together",
- Run: run,
- Requires: []*analysis.Analyzer{inspect.Analyzer},
-}
-
-func run(pass *analysis.Pass) (interface{}, error) {
- // if the package does not import time, it can be skipped from analysis
- if !hasImport(pass.Pkg, "time") {
- return nil, nil
- }
-
- inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
-
- nodeTypes := []ast.Node{
- (*ast.BinaryExpr)(nil),
- }
-
- inspect.Preorder(nodeTypes, check(pass))
-
- return nil, nil
-}
-
-func hasImport(pkg *types.Package, importPath string) bool {
- for _, imp := range pkg.Imports() {
- if imp.Path() == importPath {
- return true
- }
- }
-
- return false
-}
-
-// check contains the logic for checking that time.Duration is used correctly in the code being analysed
-func check(pass *analysis.Pass) func(ast.Node) {
- return func(node ast.Node) {
- expr := node.(*ast.BinaryExpr)
- // we are only interested in multiplication
- if expr.Op != token.MUL {
- return
- }
-
- // get the types of the two operands
- x, xOK := pass.TypesInfo.Types[expr.X]
- y, yOK := pass.TypesInfo.Types[expr.Y]
-
- if !xOK || !yOK {
- return
- }
-
- if isDuration(x.Type) && isDuration(y.Type) {
- // check that both sides are acceptable expressions
- if isUnacceptableExpr(pass, expr.X) && isUnacceptableExpr(pass, expr.Y) {
- pass.Reportf(expr.Pos(), "Multiplication of durations: `%s`", formatNode(expr))
- }
- }
- }
-}
-
-func isDuration(x types.Type) bool {
- return x.String() == "time.Duration" || x.String() == "*time.Duration"
-}
-
-// isUnacceptableExpr returns true if the argument is not an acceptable time.Duration expression
-func isUnacceptableExpr(pass *analysis.Pass, expr ast.Expr) bool {
- switch e := expr.(type) {
- case *ast.BasicLit:
- return false
- case *ast.Ident:
- return !isAcceptableNestedExpr(pass, e)
- case *ast.CallExpr:
- return !isAcceptableCast(pass, e)
- case *ast.BinaryExpr:
- return !isAcceptableNestedExpr(pass, e)
- case *ast.UnaryExpr:
- return !isAcceptableNestedExpr(pass, e)
- case *ast.SelectorExpr:
- return !isAcceptableNestedExpr(pass, e)
- case *ast.StarExpr:
- return !isAcceptableNestedExpr(pass, e)
- case *ast.ParenExpr:
- return !isAcceptableNestedExpr(pass, e)
- case *ast.IndexExpr:
- return !isAcceptableNestedExpr(pass, e)
- default:
- return true
- }
-}
-
-// isAcceptableCast returns true if the argument is an acceptable expression cast to time.Duration
-func isAcceptableCast(pass *analysis.Pass, e *ast.CallExpr) bool {
- // check that there's a single argument
- if len(e.Args) != 1 {
- return false
- }
-
- // check that the argument is acceptable
- if !isAcceptableNestedExpr(pass, e.Args[0]) {
- return false
- }
-
- // check for time.Duration cast
- selector, ok := e.Fun.(*ast.SelectorExpr)
- if !ok {
- return false
- }
-
- return isDurationCast(selector)
-}
-
-func isDurationCast(selector *ast.SelectorExpr) bool {
- pkg, ok := selector.X.(*ast.Ident)
- if !ok {
- return false
- }
-
- if pkg.Name != "time" {
- return false
- }
-
- return selector.Sel.Name == "Duration"
-}
-
-func isAcceptableNestedExpr(pass *analysis.Pass, n ast.Expr) bool {
- switch e := n.(type) {
- case *ast.BasicLit:
- return true
- case *ast.BinaryExpr:
- return isAcceptableNestedExpr(pass, e.X) && isAcceptableNestedExpr(pass, e.Y)
- case *ast.UnaryExpr:
- return isAcceptableNestedExpr(pass, e.X)
- case *ast.Ident:
- return isAcceptableIdent(pass, e)
- case *ast.CallExpr:
- if isAcceptableCast(pass, e) {
- return true
- }
- t := pass.TypesInfo.TypeOf(e)
- return !isDuration(t)
- case *ast.SelectorExpr:
- return isAcceptableNestedExpr(pass, e.X) && isAcceptableIdent(pass, e.Sel)
- case *ast.StarExpr:
- return isAcceptableNestedExpr(pass, e.X)
- case *ast.ParenExpr:
- return isAcceptableNestedExpr(pass, e.X)
- case *ast.IndexExpr:
- t := pass.TypesInfo.TypeOf(e)
- return !isDuration(t)
- default:
- return false
- }
-}
-
-func isAcceptableIdent(pass *analysis.Pass, ident *ast.Ident) bool {
- obj := pass.TypesInfo.ObjectOf(ident)
- return !isDuration(obj.Type())
-}
-
-func formatNode(node ast.Node) string {
- buf := new(bytes.Buffer)
- if err := format.Node(buf, token.NewFileSet(), node); err != nil {
- log.Printf("Error formatting expression: %v", err)
- return ""
- }
-
- return buf.String()
-}
-
-func printAST(msg string, node ast.Node) {
- fmt.Printf(">>> %s:\n%s\n\n\n", msg, formatNode(node))
- ast.Fprint(os.Stdout, nil, node, nil)
- fmt.Println("--------------")
-}