Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/gopls: bad ranking for global variables in completion #39207

Closed
stamblerre opened this issue May 22, 2020 · 3 comments
Closed

x/tools/gopls: bad ranking for global variables in completion #39207

stamblerre opened this issue May 22, 2020 · 3 comments

Comments

@stamblerre
Copy link
Contributor

@stamblerre stamblerre commented May 22, 2020

In this case, the completion item I wanted was defined "near" the code I was writing, and it had a matching type. It seems to me that a global variable of a matching type defined in my file should be ranked about completions from other packages and variables that have to be dereferenced.

Screen Shot 2020-05-21 at 10 52 14 PM

/cc @heschik

@gopherbot gopherbot added this to the Unreleased milestone May 22, 2020
@stamblerre stamblerre removed this from the Unreleased milestone May 22, 2020
@stamblerre stamblerre added this to the gopls/v0.5.0 milestone May 22, 2020
@muirdm
Copy link

@muirdm muirdm commented May 22, 2020

I presume the string you want is an untyped constant string? I think there are two things causing this:

  1. We downrank untyped constant candidates so that typed constants rank higher. For example, you don't want an untyped int constant to be suggested as a candidate for a named int "myInt" when there is also a "myInt" value in scope (even though they are both assignable). Maybe the fix is to only downrank untyped constants if the expected type is a named basic type.

  2. We don't give a score penalty for dereferencing candidates.

The scoring logic needs a retrofit. Mainly I want to consolidate scoring to a single place since it is not maintainable to have random score tweaks happening all over the place. We could add a bitmask (or boolean flags) for each candidate attribute/fact (e.g. Dereferenced | Assignable | Untyped) and then have a single scoring method that considers all dimensions of the candidate at once.

@stamblerre stamblerre removed this from the gopls/v0.5.0 milestone Jun 24, 2020
@stamblerre stamblerre added this to the gopls/unplanned milestone Oct 21, 2020
@stamblerre
Copy link
Contributor Author

@stamblerre stamblerre commented Nov 13, 2020

Closing this in favor of #40599.

@gopherbot
Copy link

@gopherbot gopherbot commented Nov 22, 2020

Change https://golang.org/cl/272286 mentions this issue: internal/lsp: offer type converted completion candidates

gopherbot pushed a commit to golang/tools that referenced this issue Nov 30, 2020
For example:

    func wantsInt64(int64)            {}
    func wantsDuration(time.Duration) {}

    func _() {
      for i := range []string{} {
        // inserts "i" as "int64(i)"
        wantsInt64(i<>)

        // inserts "i" as "time.Duration(i)"
        wantsDuration(i<>)
      }
    }

Type converted candidates have a significant score penalty so they
should never outrank a directly assignable candidate, other factors
being equal.

To minimize false positive completions, we don't offer converted
candidates if either:
- The candidate is a deep completion into another package. This avoids
  random "float64(somepkg.SomeVar)" popping up when completing a
  float64.
- Don't offer to convert ints to strings since that's not normally
  what the user wants.

After going back and forth I decided not to include the type
conversion in the candidate label. This means you will just see the
candidate "i" in the completion popup instead of "float64(i)". Type
names add a lot of noise to the candidate list.

I also tweaked the untyped constant penalty to interplay better with
the new type conversion penalty. I wanted untyped constants to be
ranked above type conversion candidates since they are directly
assignable, so I reduced untyped constants' penalty. However, to
continue suppressing untyped constants from random other packages, I
applied a similar heuristic to above where we give a bigger penalty if
the untyped constant is a deep completion from another package.

Fixes golang/go#42764.

Updates golang/go#39207 (untyped constant penalty tweak may improve
this situation).

Change-Id: I565114b3a1c9628285d07200b9dfc45c61e5d898
Reviewed-on: https://go-review.googlesource.com/c/tools/+/272286
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
Trust: Robert Findley <rfindley@google.com>
Trust: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants