diff --git a/called.go b/called.go index b329086..9ad5b3c 100644 --- a/called.go +++ b/called.go @@ -55,7 +55,10 @@ func run(pass *analysis.Pass) (interface{}, error) { } func restrictedFuncs(pass *analysis.Pass, names string) []*types.Func { - var fs []*types.Func + var ( + fs []*types.Func + seen = map[*types.Func]struct{}{} + ) for _, fn := range strings.Split(names, ",") { ss := strings.Split(strings.TrimSpace(fn), ".") @@ -65,7 +68,10 @@ func restrictedFuncs(pass *analysis.Pass, names string) []*types.Func { } f, _ := analysisutil.ObjectOf(pass, ss[0], ss[1]).(*types.Func) if f != nil { - fs = append(fs, f) + if _, ok := seen[f]; !ok { + fs = append(fs, f) + seen[f] = struct{}{} + } continue } @@ -87,7 +93,10 @@ func restrictedFuncs(pass *analysis.Pass, names string) []*types.Func { m := analysisutil.MethodOf(typ, ss[2]) if m != nil { - fs = append(fs, m) + if _, ok := seen[m]; !ok { + fs = append(fs, m) + seen[m] = struct{}{} + } } } diff --git a/restrictedfuncs_test.go b/restrictedfuncs_test.go new file mode 100644 index 0000000..c34945c --- /dev/null +++ b/restrictedfuncs_test.go @@ -0,0 +1,26 @@ +package called + +import ( + "testing" + + "go/types" + + "golang.org/x/tools/go/analysis" + "golang.org/x/tools/go/analysis/analysistest" +) + +func TestRestrictedFuncsDuplicate(t *testing.T) { + testdata := analysistest.TestData() + var funcs []*types.Func + a := &analysis.Analyzer{ + Name: "test", + Run: func(pass *analysis.Pass) (interface{}, error) { + funcs = restrictedFuncs(pass, "b.Func,b.Func,(*b.Type).Method,(*b.Type).Method,b/bsub.Type.Method,b/bsub.Type.Method") + return nil, nil + }, + } + analysistest.Run(t, testdata, a, "a") + if len(funcs) != 3 { + t.Fatalf("expected 3 funcs, got %d", len(funcs)) + } +}