internal/lsp/source: fix some invalid literal candidates

We were marking all literal candidates as addressable so we were
getting invalid candidates like "&int()". Fix it to only mark literal
struct, array, slice and map types as addressable.

I also fixed the unnamed literal candidate to pass the dereferenced
expected type. For example, if the expected type was "*[]int" we were
passing a literal type of "*[]int" which wasn't working anymore. Now
we pass "[]int" and take its address as "&[]int{}".

Change-Id: I5d0ee074d3cc91c39dd881630583e31be5a05579
Reviewed-on: https://go-review.googlesource.com/c/tools/+/212677
Run-TryBot: Muir Manders <muir@mnd.rs>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
This commit is contained in:
Muir Manders 2019-12-26 21:31:56 -08:00 committed by Rebecca Stambler
parent 316d2f2484
commit 89082a3841
4 changed files with 21 additions and 6 deletions

View File

@ -917,8 +917,9 @@ func (c *completer) lexical() error {
// if an object literal makes a good candidate. For example, if
// our expected type is "[]int", this will add a candidate of
// "[]int{}".
if _, named := deref(c.expectedType.objType).(*types.Named); !named {
c.literal(c.expectedType.objType, nil)
t := deref(c.expectedType.objType)
if _, named := t.(*types.Named); !named {
c.literal(t, nil)
}
}

View File

@ -65,9 +65,16 @@ func (c *completer) literal(literalType types.Type, imp *importInfo) {
// Check if an object of type literalType would match our expected type.
cand := candidate{
obj: c.fakeObj(literalType),
addressable: true,
obj: c.fakeObj(literalType),
}
switch literalType.Underlying().(type) {
// These literal types are addressable (e.g. "&[]int{}"), others are
// not (e.g. can't do "&(func(){})").
case *types.Struct, *types.Array, *types.Slice, *types.Map:
cand.addressable = true
}
if !c.matchingCandidate(&cand) {
return
}

View File

@ -10,8 +10,12 @@ import (
func _() {
[]int{} //@item(litIntSlice, "[]int{}", "", "var")
&[]int{} //@item(litIntSliceAddr, "&[]int{}", "", "var")
make([]int, 0) //@item(makeIntSlice, "make([]int, 0)", "", "func")
var _ *[]int = in //@snippet(" //", litIntSliceAddr, "&[]int{$0\\}", "&[]int{$0\\}")
var _ **[]int = in //@complete(" //")
var slice []int
slice = i //@snippet(" //", litIntSlice, "[]int{$0\\}", "[]int{$0\\}")
slice = m //@snippet(" //", makeIntSlice, "make([]int, ${1:})", "make([]int, ${1:0})")
@ -164,6 +168,9 @@ func _() {
func _() {
float64() //@item(litFloat64, "float64()", "float64", "var")
// don't complete to "&float64()"
var _ *float64 = float64 //@complete(" //")
var f float64
f = fl //@complete(" //", litFloat64),snippet(" //", litFloat64, "float64($0)", "float64($0)")

View File

@ -1,6 +1,6 @@
-- summary --
CompletionsCount = 223
CompletionSnippetCount = 61
CompletionsCount = 225
CompletionSnippetCount = 62
UnimportedCompletionsCount = 4
DeepCompletionsCount = 5
FuzzyCompletionsCount = 8