Skip to content

Commit 369bcc2

Browse files
committed
Add suggested fix
1 parent 016239e commit 369bcc2

File tree

6 files changed

+186
-11
lines changed

6 files changed

+186
-11
lines changed

unused/testdata/src/a/a.go.golden

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package user
2+
3+
import "database/sql"
4+
5+
type User struct {
6+
ID string
7+
Name string
8+
}
9+
10+
type UserRepositorySQL struct {
11+
DB *sql.DB
12+
}
13+
14+
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
15+
var u User
16+
err := r.DB.QueryRow("SELECT id, name FROM users WHERE id = ?", id).Scan(u.ID, u.Name)
17+
if err != nil {
18+
return nil, err
19+
}
20+
21+
return &u, nil
22+
}
23+
24+
type Granter interface {
25+
Grant(permission string) error
26+
}
27+
28+
func AllowAll(g Granter) error {
29+
return g.Grant("all")
30+
}
31+
32+
type Allower interface {
33+
Allow(permission string) error
34+
}
35+
36+
func Allow(x interface{}) {
37+
_ = x.(Allower)
38+
}

unused/testdata/src/agroup/agroup.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package user
2+
3+
import "database/sql"
4+
5+
type (
6+
User struct {
7+
ID string
8+
Name string
9+
}
10+
11+
UserRepository interface { // want "interface UserRepository is declared but not used within the package"
12+
UserOf(id string) (*User, error)
13+
}
14+
15+
UserRepositorySQL struct {
16+
DB *sql.DB
17+
}
18+
)
19+
20+
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
21+
var u User
22+
err := r.DB.QueryRow("SELECT id, name FROM users WHERE id = ?", id).Scan(u.ID, u.Name)
23+
if err != nil {
24+
return nil, err
25+
}
26+
27+
return &u, nil
28+
}
29+
30+
type Granter interface {
31+
Grant(permission string) error
32+
}
33+
34+
func AllowAll(g Granter) error {
35+
return g.Grant("all")
36+
}
37+
38+
type Allower interface {
39+
Allow(permission string) error
40+
}
41+
42+
func Allow(x interface{}) {
43+
_ = x.(Allower)
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package user
2+
3+
import "database/sql"
4+
5+
type (
6+
User struct {
7+
ID string
8+
Name string
9+
}
10+
11+
UserRepositorySQL struct {
12+
DB *sql.DB
13+
}
14+
)
15+
16+
func (r *UserRepositorySQL) UserOf(id string) (*User, error) {
17+
var u User
18+
err := r.DB.QueryRow("SELECT id, name FROM users WHERE id = ?", id).Scan(u.ID, u.Name)
19+
if err != nil {
20+
return nil, err
21+
}
22+
23+
return &u, nil
24+
}
25+
26+
type Granter interface {
27+
Grant(permission string) error
28+
}
29+
30+
func AllowAll(g Granter) error {
31+
return g.Grant("all")
32+
}
33+
34+
type Allower interface {
35+
Allow(permission string) error
36+
}
37+
38+
func Allow(x interface{}) {
39+
_ = x.(Allower)
40+
}

unused/testdata/src/d/d.go.golden

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package actor
2+
3+
// Doer performs some work.
4+
//
5+
//iface:ignore
6+
type Doer interface {
7+
Do() error
8+
}
9+
10+
//iface:ignore=unused
11+
type Runner interface {
12+
Run() error
13+
}
14+
15+
//iface:ignore=other
16+
17+
//iface:ignore=other,unused
18+
type Server interface {
19+
Serve() error
20+
}

unused/unused.go

+39-7
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
4848
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
4949

5050
// Collect all interface type declarations
51-
ifaceDecls := make(map[string]token.Pos)
51+
ifaceDecls := make(map[string]*ast.TypeSpec)
52+
genDecls := make(map[string]*ast.GenDecl) // ifaceName -> GenDecl
5253

5354
nodeFilter := []ast.Node{
5455
(*ast.GenDecl)(nil),
@@ -80,7 +81,7 @@ func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
8081

8182
_, ok = ts.Type.(*ast.InterfaceType)
8283
if !ok {
83-
return
84+
continue
8485
}
8586

8687
if r.debug {
@@ -93,7 +94,8 @@ func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
9394
continue
9495
}
9596

96-
ifaceDecls[ts.Name.Name] = ts.Pos()
97+
ifaceDecls[ts.Name.Name] = ts
98+
genDecls[ts.Name.Name] = decl
9799
}
98100
})
99101

@@ -117,21 +119,51 @@ func (r *runner) run(pass *analysis.Pass) (interface{}, error) {
117119
return
118120
}
119121

120-
pos := ifaceDecls[ident.Name]
121-
if pos == ident.Pos() {
122+
ts, ok := ifaceDecls[ident.Name]
123+
if !ok {
124+
return
125+
}
126+
127+
if ts.Pos() == ident.Pos() {
122128
// The identifier is the interface type declaration
123129
return
124130
}
125131

126132
delete(ifaceDecls, ident.Name)
133+
delete(genDecls, ident.Name)
127134
})
128135

129136
if r.debug {
130137
fmt.Printf("Package %s %s\n", pass.Pkg.Path(), pass.Pkg.Name())
131138
}
132139

133-
for name, pos := range ifaceDecls {
134-
pass.Reportf(pos, "interface %s is declared but not used within the package", name)
140+
for name, ts := range ifaceDecls {
141+
decl := genDecls[name]
142+
143+
var node ast.Node
144+
if len(decl.Specs) == 1 {
145+
node = decl
146+
} else {
147+
node = ts
148+
}
149+
150+
msg := fmt.Sprintf("interface %s is declared but not used within the package", name)
151+
pass.Report(analysis.Diagnostic{
152+
Pos: ts.Pos(),
153+
Message: msg,
154+
SuggestedFixes: []analysis.SuggestedFix{
155+
{
156+
Message: "Remove the unused interface declaration",
157+
TextEdits: []analysis.TextEdit{
158+
{
159+
Pos: node.Pos(),
160+
End: node.End(),
161+
NewText: []byte{},
162+
},
163+
},
164+
},
165+
},
166+
})
135167
}
136168

137169
return nil, nil

unused/unused_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ func TestAnalyzer(t *testing.T) {
1414
}
1515

1616
testdata := analysistest.TestData()
17-
analysistest.Run(t, testdata, unused.Analyzer, "a")
18-
analysistest.Run(t, testdata, unused.Analyzer, "b")
19-
analysistest.Run(t, testdata, unused.Analyzer, "c")
20-
analysistest.Run(t, testdata, unused.Analyzer, "d")
17+
analysistest.RunWithSuggestedFixes(t, testdata, unused.Analyzer, "a")
18+
analysistest.RunWithSuggestedFixes(t, testdata, unused.Analyzer, "agroup")
19+
analysistest.RunWithSuggestedFixes(t, testdata, unused.Analyzer, "b")
20+
analysistest.RunWithSuggestedFixes(t, testdata, unused.Analyzer, "c")
21+
analysistest.RunWithSuggestedFixes(t, testdata, unused.Analyzer, "d")
2122
}

0 commit comments

Comments
 (0)