Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sashamelentyev committed Jul 30, 2022
1 parent 2e9c5a7 commit 8e7a6f0
Show file tree
Hide file tree
Showing 7 changed files with 176 additions and 1 deletion.
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
# interfacebloat
# interfacebloat

A linter that checks length of interface.

## Install

```
go install github.com/sashamelentyev/interfacebloat
```

## Examples

```bash
interfacebloat ./...
```
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module github.com/sashamelentyev/interfacebloat

go 1.18

require (
github.com/sashamelentyev/usestdlibvars v1.7.0
golang.org/x/tools v0.1.12
)

require (
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
)
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
github.com/sashamelentyev/usestdlibvars v1.7.0 h1:jjDzfl4RjcUWer1EwhNyipT+f+LL0HmcuGF0jDhb7sM=
github.com/sashamelentyev/usestdlibvars v1.7.0/go.mod h1:BFt7b5mSVHaaa26ZupiNRV2ODViQBxZZVhtAxAJRrjs=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
11 changes: 11 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package main

import (
"golang.org/x/tools/go/analysis/singlechecker"

"github.com/sashamelentyev/usestdlibvars/pkg/analyzer"
)

func main() {
singlechecker.Main(analyzer.New())
}
65 changes: 65 additions & 0 deletions pkg/analyzer/analyzer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package analyzer

import (
"flag"
"go/ast"
"go/token"

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

const InterfaceLenFlag = "interface-len"

const defaultInterfaceLen = 10

// New returns new interfacebloat analyzer.
func New() *analysis.Analyzer {
return &analysis.Analyzer{
Name: "interfacebloat",
Doc: "A linter that checks length of interface.",
Run: run,
Flags: flags(),
Requires: []*analysis.Analyzer{inspect.Analyzer},
}
}

func flags() flag.FlagSet {
flags := flag.NewFlagSet("", flag.ExitOnError)
flags.Int(InterfaceLenFlag, 10, "length of interface")
return *flags
}

func run(pass *analysis.Pass) (interface{}, error) {
insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)

filter := []ast.Node{
(*ast.InterfaceType)(nil),
}

insp.Preorder(filter, func(node ast.Node) {
i, ok := node.(*ast.InterfaceType)
if !ok {
return
}
interfaceLen := interfaceLen(pass, InterfaceLenFlag)
if len(i.Methods.List) > interfaceLen {
report(pass, node.Pos(), interfaceLen)
}
})

return nil, nil
}

func interfaceLen(pass *analysis.Pass, name string) (interfaceLen int) {
interfaceLen, ok := pass.Analyzer.Flags.Lookup(name).Value.(flag.Getter).Get().(int)
if !ok {
interfaceLen = defaultInterfaceLen
}
return
}

func report(pass *analysis.Pass, pos token.Pos, interfaceLen int) {
pass.Reportf(pos, `length of interface greater than %d`, interfaceLen)
}
17 changes: 17 additions & 0 deletions pkg/analyzer/analyzer_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package analyzer

import (
"testing"

"golang.org/x/tools/go/analysis/analysistest"
)

func TestUseStdlibVars(t *testing.T) {
pkgs := []string{
"a",
}

analyzer := New()

analysistest.Run(t, analysistest.TestData(), analyzer, pkgs...)
}
47 changes: 47 additions & 0 deletions pkg/analyzer/testdata/src/a/a.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package a

type _ interface { // want "length of interface greater than 10"
a()
b()
c()
d()
f()
g()
h()
i()
j()
k()
l()
}

func _() {
var _ interface { // want "length of interface greater than 10"
a()
b()
c()
d()
f()
g()
h()
i()
j()
k()
l()
}
}

func __() interface { // want "length of interface greater than 10"
a()
b()
c()
d()
f()
g()
h()
i()
j()
k()
l()
} {
return nil
}

0 comments on commit 8e7a6f0

Please sign in to comment.