Skip to content

Commit

Permalink
Merge e4a5fb1 into a258616
Browse files Browse the repository at this point in the history
  • Loading branch information
k1LoW committed Sep 13, 2023
2 parents a258616 + e4a5fb1 commit cab207a
Show file tree
Hide file tree
Showing 15 changed files with 183 additions and 7 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ $ go vet -vettool=`which gostyle`
- [**Guide**](https://google.github.io/styleguide/go/guide)
- [mixedcaps](analyzer/guide/mixedcaps) ... based on https://google.github.io/styleguide/go/guide#mixed-caps
- [**Decisions**](https://google.github.io/styleguide/go/decisions)
- [nilslices](analyzer/decisions/nilslices) ... based on https://google.github.io/styleguide/go/decisions#nil-slices
- [pkgnames](analyzer/decisions/pkgnames) ... based on https://google.github.io/styleguide/go/decisions#package-names
- [recvnames](analyzer/decisions/recvnames) ... based on https://google.github.io/styleguide/go/decisions#receiver-names
- [repetition](analyzer/decisions/repetition) ... based on https://google.github.io/styleguide/go/decisions#repetition
Expand Down Expand Up @@ -93,6 +94,14 @@ analyzers-settings:
- EXPECT
```

#### nilslices

```yaml
analyzers-settings:
nilslices:
include-generated: false # include generated codes (default: false)
```

#### pkgnames

```yaml
Expand Down
115 changes: 115 additions & 0 deletions analyzer/decisions/nilslices/nilslices.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package nilslices

import (
"fmt"
"go/ast"
"go/token"

"github.com/gostaticanalysis/comment/passes/commentmap"
"github.com/k1LoW/gostyle/config"
"github.com/k1LoW/gostyle/reporter"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
)

const (
name = "nilslices"
doc = "Analyzer based on https://google.github.io/styleguide/go/decisions#nil-slices"
msg = "if you declare an empty slice as a local variable (especially if it can be the source of a return value), prefer the nil initialization to reduce the risk of bugs by callers. (ref: https://google.github.io/styleguide/go/decisions#nil-slices)"
)

var (
disable bool
includeGenerated bool
)

// Analyzer based on https://google.github.io/styleguide/go/guide#nil-slices
var Analyzer = &analysis.Analyzer{
Name: name,
Doc: doc,
Run: run,
Requires: []*analysis.Analyzer{
config.Loader,
inspect.Analyzer,
commentmap.Analyzer,
},
}

func run(pass *analysis.Pass) (any, error) {
c, err := config.Load(pass)
if err != nil {
return nil, err
}
if c != nil {
disable = c.IsDisabled(name)
includeGenerated = c.AnalyzersSettings.Nilslices.IncludeGenerated
}
if disable {
return nil, nil
}
i, ok := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
if !ok {
return nil, fmt.Errorf("unexpected result type from inspect: %T", pass.ResultOf[inspect.Analyzer])
}

nodeFilter := []ast.Node{
(*ast.ValueSpec)(nil),
(*ast.AssignStmt)(nil),
}

var opts []reporter.Option
if includeGenerated {
opts = append(opts, reporter.IncludeGenerated())
}
r, err := reporter.New(name, pass, opts...)
if err != nil {
return nil, err
}
i.Preorder(nodeFilter, func(n ast.Node) {
switch n := n.(type) {
case *ast.ValueSpec:
for i, v := range n.Values {
c, ok := v.(*ast.CompositeLit)
if !ok {
continue
}
if c.Elts != nil {
continue
}
if _, ok := c.Type.(*ast.ArrayType); !ok {
continue
}
r.Append(n.Pos(), fmt.Sprintf("%s: %s", msg, n.Names[i].Name))
}
case *ast.AssignStmt:
if n.Tok != token.DEFINE {
return
}
for i, e := range n.Rhs {
c, ok := e.(*ast.CompositeLit)
if !ok {
continue
}
if c.Elts != nil {
continue
}
if _, ok := c.Type.(*ast.ArrayType); !ok {
continue
}
id, ok := n.Lhs[i].(*ast.Ident)
if !ok {
continue
}
r.Append(n.Pos(), fmt.Sprintf("%s: %s", msg, id.Name))
}
}
})
r.Report()
return nil, nil
}

func init() {
Analyzer.Flags.BoolVar(&disable, "disable", false, "disable "+name+" analyzer")
Analyzer.Flags.BoolVar(&includeGenerated, "include-generated", false, "include generated codes")
}
14 changes: 14 additions & 0 deletions analyzer/decisions/nilslices/nilslices_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package nilslices

import (
"testing"

"github.com/gostaticanalysis/testutil"
"golang.org/x/tools/go/analysis/analysistest"
)

// TestAnalyzer is a test for Analyzer.
func TestAnalyzer(t *testing.T) {
td := testutil.WithModules(t, analysistest.TestData(), nil)
analysistest.Run(t, td, Analyzer, "a")
}
16 changes: 16 additions & 0 deletions analyzer/decisions/nilslices/testdata/src/a/a.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package a

var s = []string{} // want "gostyle.nilslices"

var s2 = []string{"a", "b", "c"}

func f() {
s := []string{} // want "gostyle.nilslices"
print(s)
var s2 []string
print(s2)
s3 := []string{"a", "b", "c"}
print(s3)
s4 := []string{} //nostyle:nilslices
print(s4)
}
11 changes: 11 additions & 0 deletions analyzer/decisions/nilslices/testdata/src/a/a_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package a_test

import "testing"

func TestA(t *testing.T) {
t.Error(1)
}

func Test_B(t *testing.T) {
t.Error(1)
}
4 changes: 4 additions & 0 deletions analyzer/decisions/nilslices/testdata/src/a/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module a

go 1.21

2 changes: 1 addition & 1 deletion analyzer/decisions/pkgnames/pkgnames.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func run(pass *analysis.Pass) (any, error) {
(*ast.ImportSpec)(nil),
}

opts := []reporter.Option{}
var opts []reporter.Option
if includeGenerated {
opts = append(opts, reporter.IncludeGenerated())
}
Expand Down
2 changes: 1 addition & 1 deletion analyzer/decisions/recvnames/recvnames.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func run(pass *analysis.Pass) (any, error) {
(*ast.FuncDecl)(nil),
}

opts := []reporter.Option{}
var opts []reporter.Option
if includeGenerated {
opts = append(opts, reporter.IncludeGenerated())
}
Expand Down
2 changes: 1 addition & 1 deletion analyzer/decisions/repetition/repetition.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func run(pass *analysis.Pass) (any, error) {
(*ast.FuncDecl)(nil),
}

opts := []reporter.Option{}
var opts []reporter.Option
if includeGenerated {
opts = append(opts, reporter.IncludeGenerated())
}
Expand Down
2 changes: 1 addition & 1 deletion analyzer/decisions/underscores/underscores.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func run(pass *analysis.Pass) (any, error) {
(*ast.RangeStmt)(nil),
}

opts := []reporter.Option{}
var opts []reporter.Option
if includeGenerated {
opts = append(opts, reporter.IncludeGenerated())
}
Expand Down
2 changes: 1 addition & 1 deletion analyzer/decisions/varnames/varnames.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func run(pass *analysis.Pass) (any, error) {
(*ast.RangeStmt)(nil),
}

opts := []reporter.Option{}
var opts []reporter.Option
if includeGenerated {
opts = append(opts, reporter.IncludeGenerated())
}
Expand Down
2 changes: 1 addition & 1 deletion analyzer/effective/ifacenames/ifacenames.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func run(pass *analysis.Pass) (any, error) {
}

var ii *ast.Ident
opts := []reporter.Option{}
var opts []reporter.Option
if includeGenerated {
opts = append(opts, reporter.IncludeGenerated())
}
Expand Down
2 changes: 1 addition & 1 deletion analyzer/guide/mixedcaps/mixedcaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func run(pass *analysis.Pass) (any, error) {
(*ast.RangeStmt)(nil),
}

opts := []reporter.Option{}
var opts []reporter.Option
if includeGenerated {
opts = append(opts, reporter.IncludeGenerated())
}
Expand Down
5 changes: 5 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type Analyzers struct {
type AnalyzersSettings struct {
Ifacenames Ifacenames `yaml:"ifacenames"`
Mixedcaps Mixedcaps `yaml:"mixedcaps"`
Nilslices Nilslices `yaml:"nilslices"`
Pkgnames Pkgnames `yaml:"pkgnames"`
Recvnames Recvnames `yaml:"recvnames"`
Repetition Repetition `yaml:"repetition"`
Expand All @@ -55,6 +56,10 @@ type Mixedcaps struct {
IncludeGenerated bool `yaml:"include-generated"`
}

type Nilslices struct {
IncludeGenerated bool `yaml:"include-generated"`
}

type Pkgnames struct {
IncludeGenerated bool `yaml:"include-generated"`
}
Expand Down
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"github.com/k1LoW/gostyle/analyzer/decisions/nilslices"
"github.com/k1LoW/gostyle/analyzer/decisions/pkgnames"
"github.com/k1LoW/gostyle/analyzer/decisions/recvnames"
"github.com/k1LoW/gostyle/analyzer/decisions/repetition"
Expand All @@ -18,6 +19,7 @@ func main() {
ifacenames.Analyzer,
pkgnames.Analyzer,
mixedcaps.Analyzer,
nilslices.Analyzer,
recvnames.Analyzer,
repetition.Analyzer,
underscores.Analyzer,
Expand Down

0 comments on commit cab207a

Please sign in to comment.