From 27097e8b3fa562e55cfa853089bda5a3abf6851b Mon Sep 17 00:00:00 2001 From: visualfc Date: Fri, 2 Feb 2024 11:13:38 +0800 Subject: [PATCH] gopls/internal/lsp/source/completion: skip index overload func by funcId --- .../lsp/source/completion/completion_gox.go | 4 +++ .../source/completion/deep_completion_gox.go | 5 +++ .../lsp/source/completion/format_gox.go | 34 ++++++++++++++++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/gopls/internal/lsp/source/completion/completion_gox.go b/gopls/internal/lsp/source/completion/completion_gox.go index 6b0f739a455..47967bf9ddb 100644 --- a/gopls/internal/lsp/source/completion/completion_gox.go +++ b/gopls/internal/lsp/source/completion/completion_gox.go @@ -71,6 +71,9 @@ type gopCompleter struct { // seen is the map that ensures we do not return duplicate results. seen map[types.Object]bool + // skipFunc is the map skip index overload func id + skipFunc map[string]bool + // items is the list of completion items returned. items []CompletionItem @@ -383,6 +386,7 @@ func GopCompletion(ctx context.Context, snapshot source.Snapshot, fh source.File path: path, pos: pos, seen: make(map[types.Object]bool), + skipFunc: make(map[string]bool), enclosingFunc: gopEnclosingFunction(path, pkg.GopTypesInfo()), enclosingCompositeLiteral: gopEnclosingCompositeLiteral(path, pos, pkg.GopTypesInfo()), deepState: deepCompletionState{ diff --git a/gopls/internal/lsp/source/completion/deep_completion_gox.go b/gopls/internal/lsp/source/completion/deep_completion_gox.go index f05de35d2e7..dd8de5bfbd0 100644 --- a/gopls/internal/lsp/source/completion/deep_completion_gox.go +++ b/gopls/internal/lsp/source/completion/deep_completion_gox.go @@ -80,6 +80,11 @@ func (c *gopCompleter) deepSearch(ctx context.Context, start time.Time, deadline } } + // skip index overload func + if fn, ok := obj.(*types.Func); ok && c.skipFunc[funcId(fn)] { + continue + } + c.addCandidate(ctx, &cand) c.deepState.candidateCount++ diff --git a/gopls/internal/lsp/source/completion/format_gox.go b/gopls/internal/lsp/source/completion/format_gox.go index b7fde89b993..7ee228f82f8 100644 --- a/gopls/internal/lsp/source/completion/format_gox.go +++ b/gopls/internal/lsp/source/completion/format_gox.go @@ -24,6 +24,38 @@ import ( "golang.org/x/tools/internal/typeparams" ) +func writeFuncName(buf *bytes.Buffer, f *types.Func) { + if f.Type() != nil { + sig := f.Type().(*types.Signature) + if recv := sig.Recv(); recv != nil { + buf.WriteByte('(') + switch t := recv.Type().(type) { + case *types.Interface: + buf.WriteString("interface") + case *types.Named: + obj := t.Origin().Obj() + if obj.Pkg() != nil { + buf.WriteString(obj.Pkg().Path()) + buf.WriteByte('.') + } + buf.WriteString(obj.Name()) + } + buf.WriteByte(')') + buf.WriteByte('.') + } else if f.Pkg() != nil { + buf.WriteString(f.Pkg().Path()) + buf.WriteByte('.') + } + } + buf.WriteString(f.Name()) +} + +func funcId(fn *types.Func) string { + var buf bytes.Buffer + writeFuncName(&buf, fn) + return buf.String() +} + // item formats a candidate to a CompletionItem. func (c *gopCompleter) item(ctx context.Context, cand candidate) (CompletionItem, error) { obj := cand.obj @@ -144,7 +176,7 @@ Suffixes: buf.WriteString("Go+ overload funcs\n") for _, o := range objs { if isIndexOverload(o.Name(), obj.Name()) { - c.seen[o] = true + c.skipFunc[funcId(o.(*types.Func))] = true } s, err := source.NewSignature(ctx, c.snapshot, c.pkg, o.Type().(*types.Signature), nil, c.qf, c.mq) if err != nil {