1 package st1001
2 3 import (
4 "honnef.co/go/tools/analysis/code"
5 "honnef.co/go/tools/analysis/facts/generated"
6 "honnef.co/go/tools/analysis/lint"
7 "honnef.co/go/tools/analysis/report"
8 "honnef.co/go/tools/config"
9 10 "golang.org/x/tools/go/analysis"
11 )
12 13 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
14 Analyzer: &analysis.Analyzer{
15 Name: "ST1001",
16 Run: run,
17 Requires: []*analysis.Analyzer{generated.Analyzer, config.Analyzer},
18 },
19 Doc: &lint.RawDocumentation{
20 Title: `Dot imports are discouraged`,
21 Text: `Dot imports that aren't in external test packages are discouraged.
22 23 The \'dot_import_whitelist\' option can be used to whitelist certain
24 imports.
25 26 Quoting Go Code Review Comments:
27 28 > The \'import .\' form can be useful in tests that, due to circular
29 > dependencies, cannot be made part of the package being tested:
30 >
31 > package foo_test
32 >
33 > import (
34 > "bar/testutil" // also imports "foo"
35 > . "foo"
36 > )
37 >
38 > In this case, the test file cannot be in package foo because it
39 > uses \'bar/testutil\', which imports \'foo\'. So we use the \'import .\'
40 > form to let the file pretend to be part of package foo even though
41 > it is not. Except for this one case, do not use \'import .\' in your
42 > programs. It makes the programs much harder to read because it is
43 > unclear whether a name like \'Quux\' is a top-level identifier in the
44 > current package or in an imported package.`,
45 Since: "2019.1",
46 Options: []string{"dot_import_whitelist"},
47 MergeIf: lint.MergeIfAny,
48 },
49 })
50 51 var Analyzer = SCAnalyzer.Analyzer
52 53 func run(pass *analysis.Pass) (interface{}, error) {
54 for _, f := range pass.Files {
55 imports:
56 for _, imp := range f.Imports {
57 path := imp.Path.Value
58 path = path[1 : len(path)-1]
59 for _, w := range config.For(pass).DotImportWhitelist {
60 if w == path {
61 continue imports
62 }
63 }
64 65 if imp.Name != nil && imp.Name.Name == "." && !code.IsInTest(pass, f) {
66 report.Report(pass, imp, "should not use dot imports", report.FilterGenerated())
67 }
68 }
69 }
70 return nil, nil
71 }
72