Skip to content

Commit 8e7a6f0

Browse files
Initial commit
1 parent 2e9c5a7 commit 8e7a6f0

File tree

7 files changed

+176
-1
lines changed

7 files changed

+176
-1
lines changed

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
1-
# interfacebloat
1+
# interfacebloat
2+
3+
A linter that checks length of interface.
4+
5+
## Install
6+
7+
```
8+
go install github.com/sashamelentyev/interfacebloat
9+
```
10+
11+
## Examples
12+
13+
```bash
14+
interfacebloat ./...
15+
```

go.mod

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module github.com/sashamelentyev/interfacebloat
2+
3+
go 1.18
4+
5+
require (
6+
github.com/sashamelentyev/usestdlibvars v1.7.0
7+
golang.org/x/tools v0.1.12
8+
)
9+
10+
require (
11+
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
12+
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect
13+
)

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
github.com/sashamelentyev/usestdlibvars v1.7.0 h1:jjDzfl4RjcUWer1EwhNyipT+f+LL0HmcuGF0jDhb7sM=
2+
github.com/sashamelentyev/usestdlibvars v1.7.0/go.mod h1:BFt7b5mSVHaaa26ZupiNRV2ODViQBxZZVhtAxAJRrjs=
3+
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
4+
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
5+
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s=
6+
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
7+
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
8+
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
import (
4+
"golang.org/x/tools/go/analysis/singlechecker"
5+
6+
"github.com/sashamelentyev/usestdlibvars/pkg/analyzer"
7+
)
8+
9+
func main() {
10+
singlechecker.Main(analyzer.New())
11+
}

pkg/analyzer/analyzer.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package analyzer
2+
3+
import (
4+
"flag"
5+
"go/ast"
6+
"go/token"
7+
8+
"golang.org/x/tools/go/analysis"
9+
"golang.org/x/tools/go/analysis/passes/inspect"
10+
"golang.org/x/tools/go/ast/inspector"
11+
)
12+
13+
const InterfaceLenFlag = "interface-len"
14+
15+
const defaultInterfaceLen = 10
16+
17+
// New returns new interfacebloat analyzer.
18+
func New() *analysis.Analyzer {
19+
return &analysis.Analyzer{
20+
Name: "interfacebloat",
21+
Doc: "A linter that checks length of interface.",
22+
Run: run,
23+
Flags: flags(),
24+
Requires: []*analysis.Analyzer{inspect.Analyzer},
25+
}
26+
}
27+
28+
func flags() flag.FlagSet {
29+
flags := flag.NewFlagSet("", flag.ExitOnError)
30+
flags.Int(InterfaceLenFlag, 10, "length of interface")
31+
return *flags
32+
}
33+
34+
func run(pass *analysis.Pass) (interface{}, error) {
35+
insp := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
36+
37+
filter := []ast.Node{
38+
(*ast.InterfaceType)(nil),
39+
}
40+
41+
insp.Preorder(filter, func(node ast.Node) {
42+
i, ok := node.(*ast.InterfaceType)
43+
if !ok {
44+
return
45+
}
46+
interfaceLen := interfaceLen(pass, InterfaceLenFlag)
47+
if len(i.Methods.List) > interfaceLen {
48+
report(pass, node.Pos(), interfaceLen)
49+
}
50+
})
51+
52+
return nil, nil
53+
}
54+
55+
func interfaceLen(pass *analysis.Pass, name string) (interfaceLen int) {
56+
interfaceLen, ok := pass.Analyzer.Flags.Lookup(name).Value.(flag.Getter).Get().(int)
57+
if !ok {
58+
interfaceLen = defaultInterfaceLen
59+
}
60+
return
61+
}
62+
63+
func report(pass *analysis.Pass, pos token.Pos, interfaceLen int) {
64+
pass.Reportf(pos, `length of interface greater than %d`, interfaceLen)
65+
}

pkg/analyzer/analyzer_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package analyzer
2+
3+
import (
4+
"testing"
5+
6+
"golang.org/x/tools/go/analysis/analysistest"
7+
)
8+
9+
func TestUseStdlibVars(t *testing.T) {
10+
pkgs := []string{
11+
"a",
12+
}
13+
14+
analyzer := New()
15+
16+
analysistest.Run(t, analysistest.TestData(), analyzer, pkgs...)
17+
}

pkg/analyzer/testdata/src/a/a.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package a
2+
3+
type _ interface { // want "length of interface greater than 10"
4+
a()
5+
b()
6+
c()
7+
d()
8+
f()
9+
g()
10+
h()
11+
i()
12+
j()
13+
k()
14+
l()
15+
}
16+
17+
func _() {
18+
var _ interface { // want "length of interface greater than 10"
19+
a()
20+
b()
21+
c()
22+
d()
23+
f()
24+
g()
25+
h()
26+
i()
27+
j()
28+
k()
29+
l()
30+
}
31+
}
32+
33+
func __() interface { // want "length of interface greater than 10"
34+
a()
35+
b()
36+
c()
37+
d()
38+
f()
39+
g()
40+
h()
41+
i()
42+
j()
43+
k()
44+
l()
45+
} {
46+
return nil
47+
}

0 commit comments

Comments
 (0)