1
0
mirror of https://github.com/golang/go synced 2024-11-18 18:44:42 -07:00

internal/lsp/source: fix unimported member completion ranking

When completing members on a type checked, unimported package, you get
fully typed members. That means you get deep completions. Because we
downrank the initial unimported package members so much, any deep
completions were dominating the rankings. For example

    context.Back<>

yielded "context.Background().Err" ranked above "context.Background".
Fix by scoring context.Background in this example as
stdScore+tinyRelevanceScore instead of just tinyRelevanceScore. I also
changed untyped candidate scores in the same way so they stay
competitive when you have both imported and unimported candidates.

The other option was to propagate the score penalty into deep
candidates, but that wasn't easy. In general I think you are better off
avoiding big score penalties because they complicate the interplay
between different kinds of candidates. Scoring needs an overhaul, but
at least we are building up our test suite in the meantime.

Change-Id: Ia5d32c057b04174229686cec6ac0542c30e186e2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/218378
Run-TryBot: Muir Manders <muir@mnd.rs>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
This commit is contained in:
Muir Manders 2020-02-06 21:22:05 -08:00 committed by Heschi Kreinick
parent 9fbd0ccf67
commit 2ef0387721
4 changed files with 12 additions and 6 deletions

View File

@ -721,7 +721,7 @@ func (c *completer) unimportedMembers(id *ast.Ident) error {
if imports.ImportPathToAssumedName(path) != pkg.GetTypes().Name() {
imp.name = pkg.GetTypes().Name()
}
c.packageMembers(pkg.GetTypes(), .01*float64(relevances[path]), imp)
c.packageMembers(pkg.GetTypes(), stdScore+.01*float64(relevances[path]), imp)
if len(c.items) >= unimportedTarget {
return nil
}
@ -740,7 +740,7 @@ func (c *completer) unimportedMembers(id *ast.Ident) error {
// Continue with untyped proposals.
pkg := types.NewPackage(pkgExport.Fix.StmtInfo.ImportPath, pkgExport.Fix.IdentName)
for _, export := range pkgExport.Exports {
score := 0.01 * float64(pkgExport.Fix.Relevance)
score := stdScore + 0.01*float64(pkgExport.Fix.Relevance)
c.found(candidate{
obj: types.NewVar(0, pkg, export, nil),
score: score,

View File

@ -6,6 +6,7 @@ func _() {
// container/ring is extremely unlikely to be imported by anything, so shouldn't have type information.
ring.Ring //@unimported("Ring", ringring)
signature.Foo //@unimported("Foo", signaturefoo)
context.Bac //@unimported("Bac", contextBackground, contextBackgroundErr)
}
// Create markers for unimported std lib packages. Only for use by this test.
@ -18,3 +19,6 @@ func _() {
/* ring.Ring */ //@item(ringring, "Ring", "(from \"container/ring\")", "var")
/* signature.Foo */ //@item(signaturefoo, "Foo", "func(a string, b int) (c bool) (from \"golang.org/x/tools/internal/lsp/signature\")", "func")
/* context.Background */ //@item(contextBackground, "Background", "func() context.Context (from \"context\")", "func")
/* context.Background().Err */ //@item(contextBackgroundErr, "Background().Err", "func() error (from \"context\")", "method")

View File

@ -1,8 +1,10 @@
package unimported
import (
_ "context"
"golang.org/x/tools/internal/lsp/baz"
"golang.org/x/tools/internal/lsp/signature" // provide type information for unimported completions in the other file
_ "golang.org/x/tools/internal/lsp/signature" // provide type information for unimported completions in the other file
)
func _() {

View File

@ -1,7 +1,7 @@
-- summary --
CompletionsCount = 227
CompletionSnippetCount = 66
UnimportedCompletionsCount = 9
UnimportedCompletionsCount = 11
DeepCompletionsCount = 5
FuzzyCompletionsCount = 8
RankedCompletionsCount = 84