1
0
mirror of https://github.com/golang/go synced 2024-10-01 01:38:33 -06:00

internal/lsp: fix scope of FuncType completion candidates

Fix objects defined in the function signature to only be completable
inside the function body. For example:

func (dog Dog) bark(d<>) { // Don't complete <> to "dog".
  d<> // Do complete <> to "dog".
}

Change-Id: Ic9a2dc2ce6771212780f2d6af2221a67d203f35f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/196559
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Muir Manders 2019-09-17 15:10:05 -07:00 committed by Rebecca Stambler
parent ae58c0ff6b
commit 2e68ad74ea
3 changed files with 21 additions and 3 deletions

View File

@ -563,11 +563,16 @@ func (c *completer) methodsAndFields(typ types.Type, addressable bool) error {
func (c *completer) lexical() error { func (c *completer) lexical() error {
var scopes []*types.Scope // scopes[i], where i<len(path), is the possibly nil Scope of path[i]. var scopes []*types.Scope // scopes[i], where i<len(path), is the possibly nil Scope of path[i].
for _, n := range c.path { for _, n := range c.path {
// Include *FuncType scope if pos is inside the function body.
switch node := n.(type) { switch node := n.(type) {
case *ast.FuncDecl: case *ast.FuncDecl:
n = node.Type if node.Body != nil && nodeContains(node.Body, c.pos) {
n = node.Type
}
case *ast.FuncLit: case *ast.FuncLit:
n = node.Type if node.Body != nil && nodeContains(node.Body, c.pos) {
n = node.Type
}
} }
scopes = append(scopes, c.pkg.GetTypesInfo().Scopes[n]) scopes = append(scopes, c.pkg.GetTypesInfo().Scopes[n])
} }
@ -654,6 +659,10 @@ func (c *completer) lexical() error {
return nil return nil
} }
func nodeContains(n ast.Node, pos token.Pos) bool {
return n != nil && n.Pos() <= pos && pos < n.End()
}
func (c *completer) inConstDecl() bool { func (c *completer) inConstDecl() bool {
for _, n := range c.path { for _, n := range c.path {
if decl, ok := n.(*ast.GenDecl); ok && decl.Tok == token.CONST { if decl, ok := n.(*ast.GenDecl); ok && decl.Tok == token.CONST {

View File

@ -0,0 +1,9 @@
package funcsig
type someType int //@item(sigSomeType, "someType", "int", "type")
// Don't complete "foo" in signature.
func (foo someType) _() { //@item(sigFoo, "foo", "someType", "var"),complete(") {", sigSomeType)
//@complete("", sigFoo, sigSomeType)
}

View File

@ -29,7 +29,7 @@ import (
// We hardcode the expected number of test cases to ensure that all tests // We hardcode the expected number of test cases to ensure that all tests
// are being executed. If a test is added, this number must be changed. // are being executed. If a test is added, this number must be changed.
const ( const (
ExpectedCompletionsCount = 152 ExpectedCompletionsCount = 154
ExpectedCompletionSnippetCount = 36 ExpectedCompletionSnippetCount = 36
ExpectedUnimportedCompletionsCount = 1 ExpectedUnimportedCompletionsCount = 1
ExpectedDeepCompletionsCount = 5 ExpectedDeepCompletionsCount = 5