mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
internal/lsp: search for deep completions across function calls
We now continue deep completion search across function calls. The function must take no arguments and return a single argument. For example, when completing "fo<>" you might get candidates such as "foo.bar().baz()". Previously we would stop searching for deep completions when we hit a function call. For example, we would stop at "foo.bar()", never finding "foo.bar().baz()". At the time I was worried about the search scope growing too large, but now that we dynamically limit the search scope there isn't much left to worry about. Change-Id: I48772c154400662876682503c1f58ef6e3dca688 Reviewed-on: https://go-review.googlesource.com/c/tools/+/201222 Reviewed-by: Rebecca Stambler <rstambler@golang.org> Run-TryBot: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
parent
02335f11d5
commit
0abb09c987
@ -39,10 +39,16 @@ type deepCompletionState struct {
|
|||||||
candidateCount int
|
candidateCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
// push pushes obj onto our search stack.
|
// push pushes obj onto our search stack. If invoke is true then
|
||||||
func (s *deepCompletionState) push(obj types.Object) {
|
// invocation parens "()" will be appended to the object name.
|
||||||
|
func (s *deepCompletionState) push(obj types.Object, invoke bool) {
|
||||||
s.chain = append(s.chain, obj)
|
s.chain = append(s.chain, obj)
|
||||||
s.chainNames = append(s.chainNames, obj.Name())
|
|
||||||
|
name := obj.Name()
|
||||||
|
if invoke {
|
||||||
|
name += "()"
|
||||||
|
}
|
||||||
|
s.chainNames = append(s.chainNames, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pop pops the last object off our search stack.
|
// pop pops the last object off our search stack.
|
||||||
@ -156,8 +162,21 @@ func (c *completer) deepSearch(obj types.Object) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sig, ok := obj.Type().Underlying().(*types.Signature); ok {
|
||||||
|
// If obj is a function that takes no arguments and returns one
|
||||||
|
// value, keep searching across the function call.
|
||||||
|
if sig.Params().Len() == 0 && sig.Results().Len() == 1 {
|
||||||
|
// Pass invoke=true since the function needs to be invoked in
|
||||||
|
// the deep chain.
|
||||||
|
c.deepState.push(obj, true)
|
||||||
|
// The result of a function call is not addressable.
|
||||||
|
c.methodsAndFields(sig.Results().At(0).Type(), false)
|
||||||
|
c.deepState.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Push this object onto our search stack.
|
// Push this object onto our search stack.
|
||||||
c.deepState.push(obj)
|
c.deepState.push(obj, false)
|
||||||
|
|
||||||
switch obj := obj.(type) {
|
switch obj := obj.(type) {
|
||||||
case *types.PkgName:
|
case *types.PkgName:
|
||||||
|
35
internal/lsp/testdata/deep/deep.go
vendored
35
internal/lsp/testdata/deep/deep.go
vendored
@ -88,3 +88,38 @@ func _() {
|
|||||||
var i int
|
var i int
|
||||||
i = a //@deep(" //", deepAD, deepABC, deepA, deepAB)
|
i = a //@deep(" //", deepAD, deepABC, deepA, deepAB)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type foo struct {
|
||||||
|
b bar
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f foo) bar() bar {
|
||||||
|
return f.b
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f foo) barPtr() *bar {
|
||||||
|
return &f.b
|
||||||
|
}
|
||||||
|
|
||||||
|
type bar struct{}
|
||||||
|
|
||||||
|
func (b bar) valueReceiver() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *bar) ptrReceiver() int {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
var (
|
||||||
|
i int
|
||||||
|
f foo
|
||||||
|
)
|
||||||
|
|
||||||
|
f.bar().valueReceiver //@item(deepBarValue, "f.bar().valueReceiver", "func() int", "method")
|
||||||
|
f.barPtr().valueReceiver //@item(deepBarPtrValue, "f.barPtr().valueReceiver", "func() int", "method")
|
||||||
|
f.barPtr().ptrReceiver //@item(deepBarPtrPtr, "f.barPtr().ptrReceiver", "func() int", "method")
|
||||||
|
|
||||||
|
i = fb //@fuzzy(" //", deepBarValue, deepBarPtrPtr, deepBarPtrValue)
|
||||||
|
}
|
||||||
|
2
internal/lsp/testdata/summary.txt.golden
vendored
2
internal/lsp/testdata/summary.txt.golden
vendored
@ -3,7 +3,7 @@ CompletionsCount = 178
|
|||||||
CompletionSnippetCount = 39
|
CompletionSnippetCount = 39
|
||||||
UnimportedCompletionsCount = 1
|
UnimportedCompletionsCount = 1
|
||||||
DeepCompletionsCount = 5
|
DeepCompletionsCount = 5
|
||||||
FuzzyCompletionsCount = 6
|
FuzzyCompletionsCount = 7
|
||||||
RankedCompletionsCount = 1
|
RankedCompletionsCount = 1
|
||||||
CaseSensitiveCompletionsCount = 4
|
CaseSensitiveCompletionsCount = 4
|
||||||
DiagnosticsCount = 21
|
DiagnosticsCount = 21
|
||||||
|
Loading…
x
Reference in New Issue
Block a user