From 987de349f4bd5c62d77fde99c97cd4f1b83691a0 Mon Sep 17 00:00:00 2001 From: Robert Findley Date: Sat, 13 Aug 2022 15:02:08 -0400 Subject: [PATCH] internal/lsp/completion: don't use Type.String for checking identity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completion is very performance sensitive, and building a string to check for *testing.F has a significant cost. StructCompletion-8 20.7ms ±14% 16.8ms ± 1% -18.59% (p=0.000 n=10+10) ImportCompletion-8 1.36ms ± 5% 1.05ms ±18% -22.55% (p=0.000 n=9+10) SliceCompletion-8 23.5ms ± 2% 19.3ms ±18% -17.85% (p=0.000 n=7+10) FuncDeepCompletion-8 17.6ms ± 2% 15.5ms ± 2% -11.82% (p=0.000 n=8+8) CompletionFollowingEdit-8 81.2ms ± 8% 74.2ms ± 5% -8.60% (p=0.000 n=9+9) For golang/go#53992 For golang/go#53798 Change-Id: Ia138cbadce142a424caabe8259bda05bcc536055 Reviewed-on: https://go-review.googlesource.com/c/tools/+/422906 TryBot-Result: Gopher Robot Reviewed-by: Alan Donovan Run-TryBot: Robert Findley --- internal/lsp/source/completion/completion.go | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/internal/lsp/source/completion/completion.go b/internal/lsp/source/completion/completion.go index be613d3e3e..e230fc58e5 100644 --- a/internal/lsp/source/completion/completion.go +++ b/internal/lsp/source/completion/completion.go @@ -1245,7 +1245,7 @@ func (c *completer) methodsAndFields(typ types.Type, addressable bool, imp *impo c.methodSetCache[methodSetKey{typ, addressable}] = mset } - if typ.String() == "*testing.F" && addressable { + if isStarTestingDotF(typ) && addressable { // is that a sufficient test? (or is more care needed?) if c.fuzz(typ, mset, imp, cb, c.snapshot.FileSet()) { return @@ -1272,6 +1272,19 @@ func (c *completer) methodsAndFields(typ types.Type, addressable bool, imp *impo }) } +// isStarTestingDotF reports whether typ is *testing.F. +func isStarTestingDotF(typ types.Type) bool { + ptr, _ := typ.(*types.Pointer) + if ptr == nil { + return false + } + named, _ := ptr.Elem().(*types.Named) + if named == nil { + return false + } + return named.Obj() != nil && named.Obj().Pkg().Path() == "testing" && named.Obj().Name() == "F" +} + // lexical finds completions in the lexical environment. func (c *completer) lexical(ctx context.Context) error { var (