mirror of
https://github.com/docker/docker-agent.git
synced 2026-11-04 10:02:15 +00:00
perf(lint): collect interface method sets once
Dedup interface pointers so Complete().Methods() isn't walked twice per analysis pass. Assisted-By: docker-agent Signed-off-by: David Gageot <david.gageot@docker.com>
This commit is contained in:
2 files changed
+31
-7
No files matched your search
@@ -75,6 +75,16 @@ func analyzeChannelDirections(p *prog.Pass, pkgs []*packages.Package) {
|
||||
objects: make(map[types.Object]*channelSlot), functions: make(map[string]*channelFunction),
|
||||
direct: make(map[ast.Expr]bool), interfaces: make(map[string][]*types.Signature),
|
||||
}
|
||||
seenInterfaces := make(map[*types.Interface]bool)
|
||||
collectInterface := func(iface *types.Interface) {
|
||||
if seenInterfaces[iface] {
|
||||
return
|
||||
}
|
||||
seenInterfaces[iface] = true
|
||||
for method := range iface.Complete().Methods() {
|
||||
a.interfaces[method.Name()] = append(a.interfaces[method.Name()], method.Type().(*types.Signature))
|
||||
}
|
||||
}
|
||||
visited := make(map[*types.Package]bool)
|
||||
var interfaces func(*types.Package)
|
||||
interfaces = func(pkg *types.Package) {
|
||||
@@ -85,10 +95,7 @@ func analyzeChannelDirections(p *prog.Pass, pkgs []*packages.Package) {
|
||||
for _, name := range pkg.Scope().Names() {
|
||||
if obj, ok := pkg.Scope().Lookup(name).(*types.TypeName); ok {
|
||||
if iface, ok := obj.Type().Underlying().(*types.Interface); ok {
|
||||
for method := range iface.Complete().Methods() {
|
||||
sig := method.Type().(*types.Signature)
|
||||
a.interfaces[method.Name()] = append(a.interfaces[method.Name()], sig)
|
||||
}
|
||||
collectInterface(iface)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,9 +116,7 @@ func analyzeChannelDirections(p *prog.Pass, pkgs []*packages.Package) {
|
||||
if expr, ok := n.(ast.Expr); ok {
|
||||
if typ := a.info.TypeOf(expr); typ != nil {
|
||||
if iface, ok := typ.Underlying().(*types.Interface); ok {
|
||||
for method := range iface.Complete().Methods() {
|
||||
a.interfaces[method.Name()] = append(a.interfaces[method.Name()], method.Type().(*types.Signature))
|
||||
}
|
||||
collectInterface(iface)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,3 +199,22 @@ func TestChannelDirectionInvalidTests(t *testing.T) {
|
||||
"sample_test.go": "package p\nfunc broken() { close() }\nfunc bodyless(c chan int)",
|
||||
}))
|
||||
}
|
||||
|
||||
func TestChannelDirectionRepeatedInterfaceUses(t *testing.T) {
|
||||
t.Parallel()
|
||||
offenses := coptest.RunProgram(t, ChannelDirection, coptest.ProgramFiles{
|
||||
"sample.go": `package p
|
||||
type Sender interface { Send(chan int) }
|
||||
type Receiver interface { Send(<-chan int) }
|
||||
type Worker struct{}
|
||||
func (Worker) Send(c chan int) { c <- 1 }
|
||||
func use(a, b Sender) { _ = a; _ = b; _ = []Sender{a,b} }
|
||||
func anonymous(a, b interface{ Send(chan int) }) { _ = a; _ = b }
|
||||
func narrow(c chan int) { c <- 1 }
|
||||
`,
|
||||
})
|
||||
assert.Len(t, offenses, 1)
|
||||
if len(offenses) == 1 {
|
||||
assert.Equal(t, 8, offenses[0].Pos.Line)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user