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: sometimes documentation on hover is not shown #46158

Closed
inliquid opened this issue May 13, 2021 · 16 comments
Closed

x/tools/gopls: sometimes documentation on hover is not shown #46158

inliquid opened this issue May 13, 2021 · 16 comments
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@inliquid
Copy link

  1. VS Code
  2. go1.16.4
  3. gopls@master

For example in case of (*url.URL).Query():

изображение

изображение

@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels May 13, 2021
@gopherbot gopherbot added this to the Unreleased milestone May 13, 2021
@findleyr
Copy link
Contributor

Thanks for the report. Which gopls commit did you build at? I thought this might be related to recent work on AST trimming, but can't reproduce at tip.

Are you able to repro? If so, can you please capture RPC logs, as described here?
https://github.com/golang/vscode-go/blob/master/docs/troubleshooting.md#collect-gopls-information

@findleyr findleyr added NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. labels May 14, 2021
@findleyr findleyr modified the milestones: Unreleased, gopls/unplanned May 14, 2021
@inliquid
Copy link
Author

It was built with go install run from the gopls repo.

Unfortunately I can't reproduce it now, it had been in that state for a while, but after restart of VS Code, I can see documentation for this particular function. I'll watch over it and let you know if this repeats.

@ShoshinNikita
Copy link

I faced a similar issue. But in my case fields of a struct have disappeared. The first commit with this issue is golang/tools@cd1d088. Note that this behavior is inconsistent (see screenshots)

Steps to reproduce

package main

import (
	"github.com/go-pg/pg/v10/orm"
)

func main() {
	orm.NewQuery(nil, nil)
	(&orm.Query{}).New()
}
  1. Go to Definition of orm.NewQuery
  2. Hover on the return value
  3. Query has ho fields

And

  1. Go to Definition of method (*orm.Query).New
  2. Hover on Query in the line clone := &Query{
  3. Query has fields, but they are poorly formatted

gopls@09ab05b (master)

1 2
image image

gopls@v0.6.11

1 2
image image

@findleyr findleyr self-assigned this May 14, 2021
@findleyr
Copy link
Contributor

FWIW, I think these are separate issues.

@ShoshinNikita you issue seems to clearly be a result of AST trimming. I am not so sure about the original issue. Keeping this as a single issue until I understand it better.

@gopherbot
Copy link

Change https://golang.org/cl/320550 mentions this issue: internal/lsp/source: re-parse if needed when collecting identifier info

gopherbot pushed a commit to golang/tools that referenced this issue May 18, 2021
With the new ParseExported logic, we can lose some unexported fields on
exported structs. This can lead to misleading or malformatted hover
information.

Fix this by ensuring we always extract the Spec from a full parse. Since
this path is only hit via user-initiated requests (and should only be
hit ~once per request), it is preferable to do the parse on-demand
rather than parse via the cache and risk pinning the full AST for the
remaining duration of the session.

For golang/go#46158

Change-Id: Ib3eb61c3f75e16199eb492e3e129ba875bd8553e
Reviewed-on: https://go-review.googlesource.com/c/tools/+/320550
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
@findleyr
Copy link
Contributor

The CL above should fix the issue reported by @ShoshinNikita, but I'm still not sure what's going on in the original issue: none of the AST trimming should have dropped comments.

So I think we should leave this issue open for a little while in case the problem reoccurs and we can capture logs. Unassigning in the meantime.

@findleyr findleyr removed their assignment May 18, 2021
@findleyr findleyr removed the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label May 18, 2021
@stamblerre
Copy link
Contributor

@inliquid: Have you encountered this again, after the CL above? If not, let's close this issue as I think it has been resolved.

@inliquid
Copy link
Author

@stamblerre no, haven't seen this so far.

@ShoshinNikita
Copy link

@findleyr At first, I decided the issue I reported is not completely fixed. But then I understood it is the intended result of AST trimming. Is that correct?

Exported function ast.FilterFile:

image

Unexported function ast.filterFile:

image

@findleyr
Copy link
Contributor

findleyr commented Jun 9, 2021

Thanks for catching that. This must be an edge case that doesn't trigger re-parsing, for some reason.

I'll look into it.

@suzmue suzmue modified the milestones: Unreleased, gopls/unplanned Jun 21, 2021
@hyangah hyangah modified the milestones: gopls/unplanned, gopls/v0.7.1 Jun 21, 2021
@hyangah hyangah removed the WaitingForInfo Issue is not actionable because of missing required information, which needs to be provided. label Jun 21, 2021
@findleyr
Copy link
Contributor

findleyr commented Jul 9, 2021

The issue is that in the case of filterFile, we're not finding the hovered declaration at all. The patch of CL 320550 was really too shallow: we need a mechanism for specifying exactly what information is needed to fulfill the hover request, and this mechanism should go through the gopls cache.

I'm experimenting with this now, but it will likely turn out not to be a small change.

@gopherbot
Copy link

Change https://golang.org/cl/333689 mentions this issue: internal/lsp: improve package search in a couple places

@gopherbot
Copy link

Change https://golang.org/cl/333690 mentions this issue: internal/lsp/source: improve logic for finding full syntax in hover

gopherbot pushed a commit to golang/tools that referenced this issue Jul 13, 2021
When we open a file in a package, independent of whether it is in the
workspace, we type check in ParseFull mode. However, several other
code paths don't find this better parse mode.

We need a better abstraction, but for now improve a couple code paths
specifically for the purpose of fixing Hover content.

Updates golang/go#46158
Updates golang/go#46902

Change-Id: I34c0432fdba406d569ea963ab4366336068767a2
Reviewed-on: https://go-review.googlesource.com/c/tools/+/333689
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
@stamblerre stamblerre modified the milestones: gopls/v0.7.1, gopls/v0.7.2 Jul 26, 2021
gopherbot pushed a commit to golang/tools that referenced this issue Jul 26, 2021
When enriching identifier info with full syntax, it's cleaner to find
the enclosing decl. Use the full decl in hover if we were unable to find
a node in the original type-checked package.

Update the regtest to exercise hovering in a non-workspace package.

Updates golang/go#46158

Change-Id: Ic1772a38fb1758fb57a09da9483a8853cc5498f1
Reviewed-on: https://go-review.googlesource.com/c/tools/+/333690
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
@ShoshinNikita
Copy link

@findleyr I think I found a regression introduced in the last CL (https://golang.org/cl/333690):

  1. Open the following code

    package main
    
    import "go/ast"
    
    func main() {
    	var l *ast.BasicLit
    	_ = l.Value
    }
  2. Hover on Value - there's no comment

  3. Press Ctrl + Space 2 times (trigger suggestions and toggle details) - there's a comment

  4. Go to Value definition and trigger hover - there's a comment

Note: it's happening only with packages from std lib and other modules


Updated TestHoverUnexported to reproduce this issue:

code
func TestHoverUnexported(t *testing.T) {
	const proxy = `
-- golang.org/x/structs@v1.0.0/go.mod --
module golang.org/x/structs

go 1.12

-- golang.org/x/structs@v1.0.0/types.go --
package structs

type Mixed struct {
	// Exported comment
	Exported   int
	unexported string
}

func printMixed(m Mixed) {
	println(m)
}
`
	const mod = `
-- go.mod --
module mod.com

go 1.12

require golang.org/x/structs v1.0.0
-- go.sum --
golang.org/x/structs v1.0.0 h1:Ito/a7hBYZaNKShFrZKjfBA/SIPvmBrcPCBWPx5QeKk=
golang.org/x/structs v1.0.0/go.mod h1:47gkSIdo5AaQaWJS0upVORsxfEr1LL1MWv9dmYF3iq4=
-- main.go --
package main

import "golang.org/x/structs"

func main() {
	var m structs.Mixed
	_ = m.Exported
}
`

	// TODO: use a nested workspace folder here.
	WithOptions(
		ProxyFiles(proxy),
	).Run(t, mod, func(t *testing.T, env *Env) {
		env.OpenFile("main.go")
		mixedPos := env.RegexpSearch("main.go", "Mixed")
		got, _ := env.Hover("main.go", mixedPos)
		if !strings.Contains(got.Value, "unexported") {
			t.Errorf("Workspace hover: missing expected field 'unexported'. Got:\n%q", got.Value)
		}

		cacheFile, _ := env.GoToDefinition("main.go", mixedPos)
		argPos := env.RegexpSearch(cacheFile, "printMixed.*(Mixed)")
		got, _ = env.Hover(cacheFile, argPos)
		if !strings.Contains(got.Value, "unexported") {
			t.Errorf("Non-workspace hover: missing expected field 'unexported'. Got:\n%q", got.Value)
		}

		exportedFieldPos := env.RegexpSearch("main.go", "Exported")
		got, _ = env.Hover("main.go", exportedFieldPos)
		if !strings.Contains(got.Value, "comment") {
			t.Errorf("Workspace hover: missing comment for field 'Exported'. Got:\n%q", got.Value)
		}
	})
}

The regression is caused by this code:

// Always use the full declaration here if we have it, because the
// dependent code doesn't rely on pointer identity. This is fragile.
if d, _ := fullDecl.(*ast.GenDecl); d != nil {
	node = d
}

We can't find a comment (see function findFieldComment) because fields of fullDecl have completely different token positions. For example:

  1. We try to find a comment for field with pos 2318327
  2. node before update: &ast.GenDecl{Doc:(*ast.CommentGroup)(0xc002ba5c50), TokPos:2317438, Tok:84, ...}
  3. node after update: &ast.GenDecl{Doc:(*ast.CommentGroup)(0xc00d5d7cf8), TokPos:36467060, Tok:84, ...}
  4. Fields of "new" node has the following positions: 36467816, 36467859, 36467949

@findleyr
Copy link
Contributor

findleyr commented Feb 9, 2022

@ShoshinNikita thank you for that investigation!

Moving this to v0.8.0.

@findleyr findleyr modified the milestones: gopls/on-deck, gopls/v0.8.0 Feb 9, 2022
@gopherbot
Copy link

Change https://go.dev/cl/384697 mentions this issue: internal/lsp/source: adjust object position when formatting full AST

@golang golang locked and limited conversation to collaborators Jun 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

7 participants