Skip to content

Commit

Permalink
pkg/analyzers: add 'var' analyzer
Browse files Browse the repository at this point in the history
  • Loading branch information
leonklingele committed Jan 19, 2022
1 parent 43f93ee commit adcadef
Show file tree
Hide file tree
Showing 15 changed files with 449 additions and 1 deletion.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,9 @@ GOPATH/src/github.com/leonklingele/grouper/pkg/analyzer/flags.go:3:1: should onl
require the use of grouped global 'type' declarations
-type-require-single-type
require the use of a single global 'type' declaration only
-var-require-grouping
require the use of grouped global 'var' declarations
-var-require-single-var
require the use of a single global 'var' declaration only
```
12 changes: 11 additions & 1 deletion pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import (
"github.com/leonklingele/grouper/pkg/analyzer/consts"
"github.com/leonklingele/grouper/pkg/analyzer/imports"
"github.com/leonklingele/grouper/pkg/analyzer/types"
"github.com/leonklingele/grouper/pkg/analyzer/vars"

"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
)

const (
Name = "grouper"
Doc = `expression group analyzer: require 'import', 'const' and/or 'var' declaration groups`
Doc = `expression group analyzer: require 'import', 'const', 'var' and/or 'type' declaration groups`
)

func New() *analysis.Analyzer {
Expand Down Expand Up @@ -47,6 +48,11 @@ func run(p *analysis.Pass) (interface{}, error) {
RequireSingleType: flagLookupBool(FlagNameTypeRequireSingleType),
RequireGrouping: flagLookupBool(FlagNameTypeRequireGrouping),
},

VarsConfig: &vars.Config{
RequireSingleVar: flagLookupBool(FlagNameVarRequireSingleVar),
RequireGrouping: flagLookupBool(FlagNameVarRequireGrouping),
},
}

return nil, pass(c, p)
Expand Down Expand Up @@ -75,5 +81,9 @@ func filepass(c *Config, p *analysis.Pass, f *ast.File) error {
return fmt.Errorf("failed to types.Filepass: %w", err)
}

if err := vars.Filepass(c.VarsConfig, p, f); err != nil {
return fmt.Errorf("failed to vars.Filepass: %w", err)
}

return nil
}
95 changes: 95 additions & 0 deletions pkg/analyzer/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,85 @@ func TestType(t *testing.T) {
}
}

func TestVar(t *testing.T) {
t.Parallel()

fixtures := []struct {
name string
flags flag.FlagSet
}{
{
name: "single-grouped",
flags: flags().
withVarRequireGrouping().
build(),
},
{
name: "single-ungrouped",
flags: flags().
withVarRequireGrouping().
build(),
},

{
name: "multi-grouped",
flags: flags().
withVarRequireSingleVar().
withVarRequireGrouping().
build(),
},
{
name: "multi-ungrouped",
flags: flags().
withVarRequireSingleVar().
withVarRequireGrouping().
build(),
},

{
name: "mixed-require-single-var",
flags: flags().
withVarRequireSingleVar().
build(),
},
{
name: "mixed-require-grouping",
flags: flags().
withVarRequireGrouping().
build(),
},

{
name: "mixed-named-with-consts",
flags: flags().
withVarRequireSingleVar().
withVarRequireGrouping().
build(),
},
{
name: "mixed-named-with-var-shorthand",
flags: flags().
withVarRequireSingleVar().
withVarRequireGrouping().
build(),
},
}

for _, f := range fixtures {
f := f

t.Run(f.name, func(t *testing.T) {
t.Parallel()

a := analyzer.New()
a.Flags = f.flags

testdata := filepath.Join(analysistest.TestData(), "var")
_ = analysistest.Run(t, testdata, a, f.name)
})
}
}

type flagger struct {
fs *flag.FlagSet
}
Expand Down Expand Up @@ -277,6 +356,22 @@ func (f *flagger) withTypeRequireGrouping() *flagger {
return f
}

func (f *flagger) withVarRequireSingleVar() *flagger {
if err := f.fs.Lookup(analyzer.FlagNameVarRequireSingleVar).Value.Set("true"); err != nil {
panic(err)
}

return f
}

func (f *flagger) withVarRequireGrouping() *flagger {
if err := f.fs.Lookup(analyzer.FlagNameVarRequireGrouping).Value.Set("true"); err != nil {
panic(err)
}

return f
}

func (f *flagger) build() flag.FlagSet {
return *f.fs
}
Expand Down
2 changes: 2 additions & 0 deletions pkg/analyzer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"github.com/leonklingele/grouper/pkg/analyzer/consts"
"github.com/leonklingele/grouper/pkg/analyzer/imports"
"github.com/leonklingele/grouper/pkg/analyzer/types"
"github.com/leonklingele/grouper/pkg/analyzer/vars"
)

type Config struct {
ConstsConfig *consts.Config
ImportsConfig *imports.Config
TypesConfig *types.Config
VarsConfig *vars.Config
}
6 changes: 6 additions & 0 deletions pkg/analyzer/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const (

FlagNameTypeRequireSingleType = "type-require-single-type"
FlagNameTypeRequireGrouping = "type-require-grouping"

FlagNameVarRequireSingleVar = "var-require-single-var"
FlagNameVarRequireGrouping = "var-require-grouping"
)

func Flags() flag.FlagSet {
Expand All @@ -27,5 +30,8 @@ func Flags() flag.FlagSet {
fs.Bool(FlagNameTypeRequireSingleType, false, "require the use of a single global 'type' declaration only")
fs.Bool(FlagNameTypeRequireGrouping, false, "require the use of grouped global 'type' declarations")

fs.Bool(FlagNameVarRequireSingleVar, false, "require the use of a single global 'var' declaration only")
fs.Bool(FlagNameVarRequireGrouping, false, "require the use of grouped global 'var' declarations")

return *fs
}
52 changes: 52 additions & 0 deletions pkg/analyzer/testdata/var/src/mixed-named-with-consts/testcase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package testcase

var (
a = "a"
b = "b"

_ = "underscore1"
)

var ( // want "should only use a single global 'var' declaration, 5 found"
comment1 = "comment1" // some comment
)

const ignoreconst1 = "ignoreconst1"
const (
ignoreconst2 = "ignoreconst2"
ignoreconst3 = "ignoreconst3"
)

func dummy() {
var (
ignorea = "ignorea"
ignoreb = "ignoreb"

_ = "ignoreunderscore1"
)

var (
ignorecomment1 = "ignorecomment1" // some comment
)

var ignorec = "ignorec"
var _ = "ignoreunderscore2"

var ()

_ = a
_ = b
_ = c
_ = comment1
_ = comment2
_ = ignorecomment1
_ = ignorea
_ = ignoreb
_ = ignorec
}

var c = "c" // want "should only use grouped global 'var' declarations"

var comment2 = "comment2" // some comment

var ()
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package testcase

var (
a = "a"
b = "b"

_ = "underscore1"
)

var ( // want "should only use a single global 'var' declaration, 5 found"
comment1 = "comment1" // some comment
)

const ignoreconst1 = "ignoreconst1"
const (
ignoreconst2 = "ignoreconst2"
ignoreconst3 = "ignoreconst3"
)

func dummy() {
var (
ignorea = "ignorea"
ignoreb = "ignoreb"

_ = "ignoreunderscore1"
)

var (
ignorecomment1 = "ignorecomment1" // some comment
)

var ignorec = "ignorec"
var _ = "ignoreunderscore2"

var ()

_ = a
_ = b
_ = c
_ = comment1
_ = comment2
_ = ignorecomment1
_ = ignorea
_ = ignoreb
_ = ignorec

hello := "world"
println(hello)
}

var c = "c" // want "should only use grouped global 'var' declarations"

var comment2 = "comment2" // some comment

var ()
37 changes: 37 additions & 0 deletions pkg/analyzer/testdata/var/src/mixed-require-grouping/testcase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package testcase

var (
a = "a"
b = "b"

_ = "underscore1"
)

var (
comment1 = "comment1" // some comment
)

var c = "c" // want "should only use grouped global 'var' declarations"

var comment2 = "comment2" // some comment

var ()

func dummy() {
var (
_ = "ignore1"
_ = "ignore2"
)

var (
_ = "ignore3"
)

var d = "d"
var comment3 = "comment3" // some comment

println(d)
println(comment3)

var ()
}
37 changes: 37 additions & 0 deletions pkg/analyzer/testdata/var/src/mixed-require-single-var/testcase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package testcase

var (
a = "a"
b = "b"

_ = "underscore1"
)

var ( // want "should only use a single global 'var' declaration, 5 found"
comment1 = "comment1" // some comment
)

var c = "c"

var comment2 = "comment2" // some comment

var ()

func dummy() {
var (
_ = "ignore1"
_ = "ignore2"
)

var (
_ = "ignore3"
)

var d = "d"
var comment3 = "comment3" // some comment

println(d)
println(comment3)

var ()
}
15 changes: 15 additions & 0 deletions pkg/analyzer/testdata/var/src/multi-grouped/testcase.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package testcase

var (
a = "a"
b = "b"

_ = "underscore1"
)

func dummy() {
var (
_ = "ignore1"
_ = "ignore2"
)
}
Loading

0 comments on commit adcadef

Please sign in to comment.