From f5dab9fca4a79dceb72d10394408af5cb6ad5898 Mon Sep 17 00:00:00 2001 From: Duco van Amstel Date: Thu, 28 Feb 2019 18:10:58 +0000 Subject: [PATCH] checkers: add dupImports checker (#814) --- checkers/dupImports_checker.go | 76 +++++++++++++++++++ .../testdata/dupImports/negative_tests.go | 9 +++ .../testdata/dupImports/positive_tests.go | 17 +++++ 3 files changed, 102 insertions(+) create mode 100644 checkers/dupImports_checker.go create mode 100644 checkers/testdata/dupImports/negative_tests.go create mode 100644 checkers/testdata/dupImports/positive_tests.go diff --git a/checkers/dupImports_checker.go b/checkers/dupImports_checker.go new file mode 100644 index 000000000..7a6c837c6 --- /dev/null +++ b/checkers/dupImports_checker.go @@ -0,0 +1,76 @@ +package checkers + +import ( + "fmt" + "go/ast" + + "github.com/go-lintpack/lintpack" +) + +func init() { + var info lintpack.CheckerInfo + info.Name = "dupImports" + info.Tags = []string{"style", "experimental"} + info.Summary = "Detects multiple imports of the same package under different aliases." + info.Before = ` +import ( + "fmt" + priting "fmt" +) + +func helloWorld() { + fmt.Println("Hello") + printing.Println("World") +}` + info.After = ` +import( + "fmt" +) + +func helloWorld() { + fmt.Println("Hello") + fmt.Println("World") +}` + + collection.AddChecker(&info, func(ctx *lintpack.CheckerContext) lintpack.FileWalker { + return &dupImportChecker{ctx: ctx} + }) +} + +type dupImportChecker struct { + ctx *lintpack.CheckerContext +} + +func (c *dupImportChecker) WalkFile(f *ast.File) { + imports := make(map[string][]*ast.ImportSpec) + for _, importDcl := range f.Imports { + pkg := importDcl.Path.Value + imports[pkg] = append(imports[pkg], importDcl) + } + + fPos := c.ctx.FileSet.File(f.Pos()) + if fPos == nil { + // Bail out if we can't, for any reason, determine + // the source file we are dealing with. + return + } + for _, importList := range imports { + if len(importList) == 1 { + continue + } + + msg := fmt.Sprintf("package is imported %d times under different aliases on lines", len(importList)) + for idx, importDcl := range importList { + switch { + case idx == len(importList)-1: + msg += " and" + case idx > 0: + msg += "," + } + msg += fmt.Sprintf(" %d", fPos.Line(importDcl.Pos())) + } + for _, importDcl := range importList { + c.ctx.Warn(importDcl, msg) + } + } +} diff --git a/checkers/testdata/dupImports/negative_tests.go b/checkers/testdata/dupImports/negative_tests.go new file mode 100644 index 000000000..833b862ef --- /dev/null +++ b/checkers/testdata/dupImports/negative_tests.go @@ -0,0 +1,9 @@ +package checker_test + +import "fmt" + +func negativeHelloworld() { + fmt.Println("Hello") + fmt.Println("Shiny") + fmt.Println("World") +} diff --git a/checkers/testdata/dupImports/positive_tests.go b/checkers/testdata/dupImports/positive_tests.go new file mode 100644 index 000000000..b1740446b --- /dev/null +++ b/checkers/testdata/dupImports/positive_tests.go @@ -0,0 +1,17 @@ +package checker_test + +/*! package is imported 3 times under different aliases on lines 4, 8 and 10 */ +import printing "fmt" + +import ( + /*! package is imported 3 times under different aliases on lines 4, 8 and 10 */ + "fmt" + /*! package is imported 3 times under different aliases on lines 4, 8 and 10 */ + print "fmt" +) + +func positiveHelloworld() { + fmt.Println("Hello") + print.Println("Shiny") + printing.Println("World") +}