From f54bdb699a8cab72101391489f5bf61322ed21ab Mon Sep 17 00:00:00 2001 From: Alexey Piyanin <162457+7phs@users.noreply.github.com> Date: Sat, 19 Jan 2019 00:27:35 +0300 Subject: [PATCH] checkers: add stringXbytes checker Fixes #427 --- checkers/stringXbytes_checker.go | 47 +++++++++++++++++++ .../testdata/stringXbytes/negative_tests.go | 8 ++++ .../testdata/stringXbytes/positive_tests.go | 9 ++++ 3 files changed, 64 insertions(+) create mode 100644 checkers/stringXbytes_checker.go create mode 100644 checkers/testdata/stringXbytes/negative_tests.go create mode 100644 checkers/testdata/stringXbytes/positive_tests.go diff --git a/checkers/stringXbytes_checker.go b/checkers/stringXbytes_checker.go new file mode 100644 index 000000000..996c3fa5f --- /dev/null +++ b/checkers/stringXbytes_checker.go @@ -0,0 +1,47 @@ +package checkers + +import ( + "go/ast" + "strings" + + "github.com/go-lintpack/lintpack" + "github.com/go-lintpack/lintpack/astwalk" + "github.com/go-toolsmith/astfmt" + "github.com/go-toolsmith/typep" +) + +func init() { + var info lintpack.CheckerInfo + info.Name = "stringXbytes" + info.Tags = []string{"diagnostic", "experimental"} + info.Summary = "Detects redundant conversions between string and []byte" + info.Before = `copy(b, []byte(s))` + info.After = `copy(b, s)` + + collection.AddChecker(&info, func(ctx *lintpack.CheckerContext) lintpack.FileWalker { + return astwalk.WalkerForExpr(&stringXbytes{ctx: ctx}) + }) +} + +type stringXbytes struct { + astwalk.WalkHandler + ctx *lintpack.CheckerContext +} + +func (c *stringXbytes) VisitExpr(expr ast.Expr) { + if x, ok := expr.(*ast.CallExpr); ok && qualifiedName(x.Fun) == "copy" { + src := x.Args[1] + + if byteCast, ok := src.(*ast.CallExpr); ok && + typep.IsTypeExpr(c.ctx.TypesInfo, byteCast.Fun) && + typep.HasStringProp(c.ctx.TypesInfo.TypeOf(byteCast.Args[0])) { + + c.warn(byteCast, strings.TrimSuffix(strings.TrimPrefix(astfmt.Sprint(byteCast), "[]byte("), ")")) + } + } +} + +func (c *stringXbytes) warn(cause *ast.CallExpr, suggestion string) { + c.ctx.Warn(cause, "can simplify `%s` to `%s`", + cause, suggestion) +} diff --git a/checkers/testdata/stringXbytes/negative_tests.go b/checkers/testdata/stringXbytes/negative_tests.go new file mode 100644 index 000000000..6480760af --- /dev/null +++ b/checkers/testdata/stringXbytes/negative_tests.go @@ -0,0 +1,8 @@ +package checker_test + +func noWarnings() { + var b []byte + var s string + + copy(b, s) +} diff --git a/checkers/testdata/stringXbytes/positive_tests.go b/checkers/testdata/stringXbytes/positive_tests.go new file mode 100644 index 000000000..362652605 --- /dev/null +++ b/checkers/testdata/stringXbytes/positive_tests.go @@ -0,0 +1,9 @@ +package checker_test + +func warnings() { + var b []byte + var s string + + /*! can simplify `[]byte(s)` to `s` */ + copy(b, []byte(s)) +}