mirror of
https://github.com/golang/go
synced 2024-11-18 15:34:53 -07:00
internal/lsp: offer basic type conversion candidates
When the expected type is a basic type, we will now offer a corresponding type conversion candidate. For example: var foo int64 foo = // offer "int64(<>)" as a candidate The type conversion candidate will be ranked below matching concrete candidates but above the sea of non-matching candidates. This change broke almost every completion test. I added a new completion option for literal candidates so tests can selectively ask for literal completions. Updates golang/go#36015. Change-Id: I63fbdb33436d662a666c1ffd3b2d918d840dccc7 Reviewed-on: https://go-review.googlesource.com/c/tools/+/210288 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:
parent
cfcbc7796e
commit
0f69de236b
@ -15,6 +15,7 @@ func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion,
|
|||||||
Deep: false,
|
Deep: false,
|
||||||
FuzzyMatching: false,
|
FuzzyMatching: false,
|
||||||
Documentation: true,
|
Documentation: true,
|
||||||
|
Literal: strings.Contains(string(src.URI()), "literal"),
|
||||||
})
|
})
|
||||||
if !strings.Contains(string(src.URI()), "builtins") {
|
if !strings.Contains(string(src.URI()), "builtins") {
|
||||||
got = tests.FilterBuiltins(got)
|
got = tests.FilterBuiltins(got)
|
||||||
@ -30,6 +31,7 @@ func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.C
|
|||||||
Placeholders: placeholders,
|
Placeholders: placeholders,
|
||||||
Deep: true,
|
Deep: true,
|
||||||
FuzzyMatching: true,
|
FuzzyMatching: true,
|
||||||
|
Literal: true,
|
||||||
})
|
})
|
||||||
got := tests.FindItem(list, *items[expected.CompletionItem])
|
got := tests.FindItem(list, *items[expected.CompletionItem])
|
||||||
want := expected.PlainSnippet
|
want := expected.PlainSnippet
|
||||||
@ -99,6 +101,7 @@ func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completi
|
|||||||
got := r.callCompletion(t, src, source.CompletionOptions{
|
got := r.callCompletion(t, src, source.CompletionOptions{
|
||||||
FuzzyMatching: true,
|
FuzzyMatching: true,
|
||||||
Deep: true,
|
Deep: true,
|
||||||
|
Literal: true,
|
||||||
})
|
})
|
||||||
want := expected(t, test, items)
|
want := expected(t, test, items)
|
||||||
if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
|
if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
|
||||||
|
@ -322,7 +322,11 @@ func (c *completer) found(obj types.Object, score float64, imp *importInfo) {
|
|||||||
} else if isTypeName(obj) {
|
} else if isTypeName(obj) {
|
||||||
// If obj is a *types.TypeName that didn't otherwise match, check
|
// If obj is a *types.TypeName that didn't otherwise match, check
|
||||||
// if a literal object of this type makes a good candidate.
|
// if a literal object of this type makes a good candidate.
|
||||||
c.literal(obj.Type(), imp)
|
|
||||||
|
// We only care about named types (i.e. don't want builtin types).
|
||||||
|
if _, isNamed := obj.Type().(*types.Named); isNamed {
|
||||||
|
c.literal(obj.Type(), imp)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Favor shallow matches by lowering weight according to depth.
|
// Favor shallow matches by lowering weight according to depth.
|
||||||
|
@ -20,6 +20,10 @@ import (
|
|||||||
// literal generates composite literal, function literal, and make()
|
// literal generates composite literal, function literal, and make()
|
||||||
// completion items.
|
// completion items.
|
||||||
func (c *completer) literal(literalType types.Type, imp *importInfo) {
|
func (c *completer) literal(literalType types.Type, imp *importInfo) {
|
||||||
|
if !c.opts.Literal {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
expType := c.expectedType.objType
|
expType := c.expectedType.objType
|
||||||
|
|
||||||
if c.expectedType.variadic {
|
if c.expectedType.variadic {
|
||||||
@ -124,8 +128,9 @@ func (c *completer) literal(literalType types.Type, imp *importInfo) {
|
|||||||
case *types.Basic, *types.Signature:
|
case *types.Basic, *types.Signature:
|
||||||
// Add a literal completion for basic types that implement our
|
// Add a literal completion for basic types that implement our
|
||||||
// expected interface (e.g. named string type http.Dir
|
// expected interface (e.g. named string type http.Dir
|
||||||
// implements http.FileSystem).
|
// implements http.FileSystem), or are identical to our expected
|
||||||
if isInterface(expType) {
|
// type (i.e. yielding a type conversion such as "float64()").
|
||||||
|
if isInterface(expType) || types.Identical(expType, literalType) {
|
||||||
c.basicLiteral(t, typeName, float64(score), addlEdits)
|
c.basicLiteral(t, typeName, float64(score), addlEdits)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ var (
|
|||||||
Documentation: true,
|
Documentation: true,
|
||||||
Deep: true,
|
Deep: true,
|
||||||
FuzzyMatching: true,
|
FuzzyMatching: true,
|
||||||
|
Literal: true,
|
||||||
Budget: 100 * time.Millisecond,
|
Budget: 100 * time.Millisecond,
|
||||||
},
|
},
|
||||||
ComputeEdits: myers.ComputeEdits,
|
ComputeEdits: myers.ComputeEdits,
|
||||||
@ -123,6 +124,7 @@ type CompletionOptions struct {
|
|||||||
Documentation bool
|
Documentation bool
|
||||||
FullDocumentation bool
|
FullDocumentation bool
|
||||||
Placeholders bool
|
Placeholders bool
|
||||||
|
Literal bool
|
||||||
|
|
||||||
// Budget is the soft latency goal for completion requests. Most
|
// Budget is the soft latency goal for completion requests. Most
|
||||||
// requests finish in a couple milliseconds, but in some cases deep
|
// requests finish in a couple milliseconds, but in some cases deep
|
||||||
|
@ -110,6 +110,7 @@ func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion,
|
|||||||
prefix, list := r.callCompletion(t, src, source.CompletionOptions{
|
prefix, list := r.callCompletion(t, src, source.CompletionOptions{
|
||||||
Documentation: true,
|
Documentation: true,
|
||||||
FuzzyMatching: true,
|
FuzzyMatching: true,
|
||||||
|
Literal: strings.Contains(string(src.URI()), "literal"),
|
||||||
})
|
})
|
||||||
if !strings.Contains(string(src.URI()), "builtins") {
|
if !strings.Contains(string(src.URI()), "builtins") {
|
||||||
list = tests.FilterBuiltins(list)
|
list = tests.FilterBuiltins(list)
|
||||||
@ -130,6 +131,7 @@ func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.C
|
|||||||
_, list := r.callCompletion(t, src, source.CompletionOptions{
|
_, list := r.callCompletion(t, src, source.CompletionOptions{
|
||||||
Placeholders: placeholders,
|
Placeholders: placeholders,
|
||||||
Deep: true,
|
Deep: true,
|
||||||
|
Literal: true,
|
||||||
})
|
})
|
||||||
got := tests.FindItem(list, *items[expected.CompletionItem])
|
got := tests.FindItem(list, *items[expected.CompletionItem])
|
||||||
want := expected.PlainSnippet
|
want := expected.PlainSnippet
|
||||||
@ -234,6 +236,7 @@ func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completi
|
|||||||
prefix, list := r.callCompletion(t, src, source.CompletionOptions{
|
prefix, list := r.callCompletion(t, src, source.CompletionOptions{
|
||||||
FuzzyMatching: true,
|
FuzzyMatching: true,
|
||||||
Deep: true,
|
Deep: true,
|
||||||
|
Literal: true,
|
||||||
})
|
})
|
||||||
fuzzyMatcher := fuzzy.NewMatcher(prefix)
|
fuzzyMatcher := fuzzy.NewMatcher(prefix)
|
||||||
var got []protocol.CompletionItem
|
var got []protocol.CompletionItem
|
||||||
|
@ -160,3 +160,16 @@ func _() {
|
|||||||
sf = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}")
|
sf = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}")
|
||||||
sf = foo. //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}")
|
sf = foo. //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _() {
|
||||||
|
float64() //@item(litFloat64, "float64()", "float64", "var")
|
||||||
|
|
||||||
|
var f float64
|
||||||
|
f = fl //@complete(" //", litFloat64),snippet(" //", litFloat64, "float64($0)", "float64($0)")
|
||||||
|
|
||||||
|
type myInt int
|
||||||
|
myInt() //@item(litMyInt, "myInt()", "", "var")
|
||||||
|
|
||||||
|
var mi myInt
|
||||||
|
mi = my //@snippet(" //", litMyInt, "myInt($0)", "myInt($0)")
|
||||||
|
}
|
||||||
|
4
internal/lsp/testdata/summary.txt.golden
vendored
4
internal/lsp/testdata/summary.txt.golden
vendored
@ -1,6 +1,6 @@
|
|||||||
-- summary --
|
-- summary --
|
||||||
CompletionsCount = 221
|
CompletionsCount = 222
|
||||||
CompletionSnippetCount = 51
|
CompletionSnippetCount = 53
|
||||||
UnimportedCompletionsCount = 4
|
UnimportedCompletionsCount = 4
|
||||||
DeepCompletionsCount = 5
|
DeepCompletionsCount = 5
|
||||||
FuzzyCompletionsCount = 7
|
FuzzyCompletionsCount = 7
|
||||||
|
Loading…
Reference in New Issue
Block a user