mirror of
https://github.com/golang/go
synced 2024-11-18 23:44:43 -07:00
internal/lsp/source: filter candidates when type name required
Now when we expect a type name at the cursor, we omit non-type name completion candidates. For example: inch := 1 var foo in<> // don't offer "inch" I also added expected type name detection for value specs: // Expect a type name at <> var foo <> Fixes golang/go#32806. Change-Id: I32477cb286d2050bac5ccc767f8a608124fa5acd Reviewed-on: https://go-review.googlesource.com/c/tools/+/216400 Run-TryBot: Muir Manders <muir@mnd.rs> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Findley <rfindley@google.com>
This commit is contained in:
parent
11eff242d1
commit
ea181f53ac
@ -324,6 +324,15 @@ func (c *completer) found(cand candidate) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we know we want a type name, don't offer non-type name
|
||||||
|
// candidates. However, do offer package names since they can
|
||||||
|
// contain type names, and do offer any candidate without a type
|
||||||
|
// since we aren't sure if it is a type name or not (i.e. unimported
|
||||||
|
// candidate).
|
||||||
|
if c.wantTypeName() && obj.Type() != nil && !isTypeName(obj) && !isPkgName(obj) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if c.matchingCandidate(&cand, nil) {
|
if c.matchingCandidate(&cand, nil) {
|
||||||
cand.score *= highScore
|
cand.score *= highScore
|
||||||
} else if isTypeName(obj) {
|
} else if isTypeName(obj) {
|
||||||
@ -856,7 +865,7 @@ func (c *completer) lexical() error {
|
|||||||
|
|
||||||
// If obj's type is invalid, find the AST node that defines the lexical block
|
// If obj's type is invalid, find the AST node that defines the lexical block
|
||||||
// containing the declaration of obj. Don't resolve types for packages.
|
// containing the declaration of obj. Don't resolve types for packages.
|
||||||
if _, ok := obj.(*types.PkgName); !ok && !typeIsValid(obj.Type()) {
|
if !isPkgName(obj) && !typeIsValid(obj.Type()) {
|
||||||
// Match the scope to its ast.Node. If the scope is the package scope,
|
// Match the scope to its ast.Node. If the scope is the package scope,
|
||||||
// use the *ast.File as the starting node.
|
// use the *ast.File as the starting node.
|
||||||
var node ast.Node
|
var node ast.Node
|
||||||
@ -1720,6 +1729,11 @@ Nodes:
|
|||||||
wantComparable = c.pos == n.Pos()+token.Pos(len("map["))
|
wantComparable = c.pos == n.Pos()+token.Pos(len("map["))
|
||||||
}
|
}
|
||||||
break Nodes
|
break Nodes
|
||||||
|
case *ast.ValueSpec:
|
||||||
|
if n.Type != nil && n.Type.Pos() <= c.pos && c.pos <= n.Type.End() {
|
||||||
|
wantTypeName = true
|
||||||
|
}
|
||||||
|
break Nodes
|
||||||
default:
|
default:
|
||||||
if breaksExpectedTypeInference(p) {
|
if breaksExpectedTypeInference(p) {
|
||||||
return typeNameInference{}
|
return typeNameInference{}
|
||||||
|
@ -415,6 +415,11 @@ func isUntyped(T types.Type) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isPkgName(obj types.Object) bool {
|
||||||
|
_, ok := obj.(*types.PkgName)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
// isSelector returns the enclosing *ast.SelectorExpr when pos is in the
|
// isSelector returns the enclosing *ast.SelectorExpr when pos is in the
|
||||||
// selector.
|
// selector.
|
||||||
func enclosingSelector(path []ast.Node, pos token.Pos) *ast.SelectorExpr {
|
func enclosingSelector(path []ast.Node, pos token.Pos) *ast.SelectorExpr {
|
||||||
|
@ -9,9 +9,9 @@ func _() {
|
|||||||
val string //@item(atVal, "val", "string", "var")
|
val string //@item(atVal, "val", "string", "var")
|
||||||
)
|
)
|
||||||
|
|
||||||
[] //@complete(" //", atVal, PackageFoo)
|
[] //@complete(" //", PackageFoo)
|
||||||
|
|
||||||
[]val //@complete(" //", atVal)
|
[]val //@complete(" //")
|
||||||
|
|
||||||
[]foo.StructFoo //@complete(" //", StructFoo)
|
[]foo.StructFoo //@complete(" //", StructFoo)
|
||||||
|
|
||||||
@ -32,12 +32,12 @@ func _() {
|
|||||||
var mark []myInt //@item(atMark, "mark", "[]myInt", "var")
|
var mark []myInt //@item(atMark, "mark", "[]myInt", "var")
|
||||||
|
|
||||||
var s []myInt //@item(atS, "s", "[]myInt", "var")
|
var s []myInt //@item(atS, "s", "[]myInt", "var")
|
||||||
s = []m //@complete(" //", atMyInt, atMark)
|
s = []m //@complete(" //", atMyInt)
|
||||||
s = [] //@complete(" //", atMyInt, atMark, atS, PackageFoo)
|
s = [] //@complete(" //", atMyInt, PackageFoo)
|
||||||
|
|
||||||
var a [1]myInt
|
var a [1]myInt
|
||||||
a = [1]m //@complete(" //", atMyInt, atMark)
|
a = [1]m //@complete(" //", atMyInt)
|
||||||
|
|
||||||
var ds [][]myInt
|
var ds [][]myInt
|
||||||
ds = [][]m //@complete(" //", atMyInt, atMark)
|
ds = [][]m //@complete(" //", atMyInt)
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,13 @@ func helper(i foo.IntFoo) {} //@item(helper, "helper", "func(i foo.IntFoo)", "fu
|
|||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
help //@complete("l", helper)
|
help //@complete("l", helper)
|
||||||
_ = foo.StructFoo{} //@complete("S", IntFoo, StructFoo, Foo)
|
_ = foo.StructFoo{} //@complete("S", IntFoo, StructFoo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bar is a function.
|
// Bar is a function.
|
||||||
func Bar() { //@item(Bar, "Bar", "func()", "func", "Bar is a function.")
|
func Bar() { //@item(Bar, "Bar", "func()", "func", "Bar is a function.")
|
||||||
foo.Foo() //@complete("F", Foo, IntFoo, StructFoo)
|
foo.Foo() //@complete("F", Foo, IntFoo, StructFoo)
|
||||||
var _ foo.IntFoo //@complete("I", Foo, IntFoo, StructFoo)
|
var _ foo.IntFoo //@complete("I", IntFoo, StructFoo)
|
||||||
foo.() //@complete("(", Foo, IntFoo, StructFoo)
|
foo.() //@complete("(", Foo, IntFoo, StructFoo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,13 +33,12 @@ func _() {
|
|||||||
|
|
||||||
cap() //@rank(")", builtinSlice, builtinMap),rank(")", builtinArray, builtinString),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt)
|
cap() //@rank(")", builtinSlice, builtinMap),rank(")", builtinArray, builtinString),rank(")", builtinArrayPtr, builtinPtr),rank(")", builtinChan, builtinInt)
|
||||||
|
|
||||||
make() //@rank(")", builtinMapType, int),rank(")", builtinChanType, int),rank(")", builtinSliceType, int),rank(")", builtinMapType, builtinMap)
|
make() //@rank(")", builtinMapType, int),rank(")", builtinChanType, int),rank(")", builtinSliceType, int),rank(")", builtinMapType, int)
|
||||||
make(aSliceType, a) //@rank(")", builtinInt, builtinSlice)
|
make(aSliceType, a) //@rank(")", builtinInt, builtinSlice)
|
||||||
|
|
||||||
var _ []int = make() //@rank(")", builtinSliceType, builtinSlice)
|
var _ []int = make() //@rank(")", builtinSliceType, builtinMapType)
|
||||||
|
|
||||||
type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct")
|
type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct")
|
||||||
new() //@rank(")", builtinStructType, builtinInt)
|
|
||||||
var _ *myStruct = new() //@rank(")", builtinStructType, int)
|
var _ *myStruct = new() //@rank(")", builtinStructType, int)
|
||||||
|
|
||||||
for k := range a { //@rank(" {", builtinSlice, builtinInt),rank(" {", builtinString, builtinInt),rank(" {", builtinChan, builtinInt),rank(" {", builtinArray, builtinInt),rank(" {", builtinArrayPtr, builtinInt),rank(" {", builtinMap, builtinInt),
|
for k := range a { //@rank(" {", builtinSlice, builtinInt),rank(" {", builtinString, builtinInt),rank(" {", builtinChan, builtinInt),rank(" {", builtinArray, builtinInt),rank(" {", builtinArrayPtr, builtinInt),rank(" {", builtinMap, builtinInt),
|
||||||
|
@ -3,25 +3,25 @@ package fieldlist
|
|||||||
var myInt int //@item(flVar, "myInt", "int", "var")
|
var myInt int //@item(flVar, "myInt", "int", "var")
|
||||||
type myType int //@item(flType, "myType", "int", "type")
|
type myType int //@item(flType, "myType", "int", "type")
|
||||||
|
|
||||||
func (my) _() {} //@complete(") _", flType, flVar)
|
func (my) _() {} //@complete(") _", flType)
|
||||||
func (my my) _() {} //@complete(" my)"),complete(") _", flType, flVar)
|
func (my my) _() {} //@complete(" my)"),complete(") _", flType)
|
||||||
|
|
||||||
func (myType) _() {} //@complete(") {", flType, flVar)
|
func (myType) _() {} //@complete(") {", flType)
|
||||||
|
|
||||||
func (myType) _(my my) {} //@complete(" my)"),complete(") {", flType, flVar)
|
func (myType) _(my my) {} //@complete(" my)"),complete(") {", flType)
|
||||||
|
|
||||||
func (myType) _() my {} //@complete(" {", flType, flVar)
|
func (myType) _() my {} //@complete(" {", flType)
|
||||||
|
|
||||||
func (myType) _() (my my) {} //@complete(" my"),complete(") {", flType, flVar)
|
func (myType) _() (my my) {} //@complete(" my"),complete(") {", flType)
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
var _ struct {
|
var _ struct {
|
||||||
//@complete("", flType, flVar)
|
//@complete("", flType)
|
||||||
m my //@complete(" my"),complete(" //", flType, flVar)
|
m my //@complete(" my"),complete(" //", flType)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ interface {
|
var _ interface {
|
||||||
//@complete("", flType, flVar)
|
//@complete("", flType)
|
||||||
m() my //@complete("("),complete(" //", flType, flVar)
|
m() my //@complete("("),complete(" //", flType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@ var stringAVar = "var" //@item(stringAVar, "stringAVar", "string", "var")
|
|||||||
func stringBFunc() string { return "str" } //@item(stringBFunc, "stringBFunc", "func() string", "func")
|
func stringBFunc() string { return "str" } //@item(stringBFunc, "stringBFunc", "func() string", "func")
|
||||||
type stringer struct{} //@item(stringer, "stringer", "struct{...}", "struct")
|
type stringer struct{} //@item(stringer, "stringer", "struct{...}", "struct")
|
||||||
|
|
||||||
func _() stringer //@complete("tr", stringer, stringAVar, stringBFunc)
|
func _() stringer //@complete("tr", stringer)
|
||||||
|
|
||||||
func _(val stringer) {} //@complete("tr", stringer, stringAVar, stringBFunc)
|
func _(val stringer) {} //@complete("tr", stringer)
|
||||||
|
|
||||||
func (stringer) _() {} //@complete("tr", stringer, stringAVar, stringBFunc)
|
func (stringer) _() {} //@complete("tr", stringer)
|
||||||
|
|
||||||
func _() {
|
func _() {
|
||||||
var s struct {
|
var s struct {
|
||||||
|
@ -11,8 +11,8 @@ func _() {
|
|||||||
// comparable
|
// comparable
|
||||||
type aStruct struct{} //@item(mapStructType, "aStruct", "struct{...}", "struct")
|
type aStruct struct{} //@item(mapStructType, "aStruct", "struct{...}", "struct")
|
||||||
|
|
||||||
map[]a{} //@complete("]", mapSliceTypePtr, mapStructType, mapVar)
|
map[]a{} //@complete("]", mapSliceTypePtr, mapStructType)
|
||||||
|
|
||||||
map[a]a{} //@complete("]", mapSliceTypePtr, mapStructType, mapVar)
|
map[a]a{} //@complete("]", mapSliceTypePtr, mapStructType)
|
||||||
map[a]a{} //@complete("{", mapSliceType, mapStructType, mapVar)
|
map[a]a{} //@complete("{", mapSliceType, mapStructType)
|
||||||
}
|
}
|
||||||
|
@ -4,5 +4,5 @@ func _() {
|
|||||||
type flower int //@item(flower, "flower", "int", "type")
|
type flower int //@item(flower, "flower", "int", "type")
|
||||||
var fig string //@item(fig, "fig", "string", "var")
|
var fig string //@item(fig, "fig", "string", "var")
|
||||||
|
|
||||||
_ = interface{}(nil).(f) //@complete(") //", flower, fig)
|
_ = interface{}(nil).(f) //@complete(") //", flower)
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ func _() {
|
|||||||
var banana string //@item(banana, "banana", "string", "var")
|
var banana string //@item(banana, "banana", "string", "var")
|
||||||
|
|
||||||
switch interface{}(pear).(type) {
|
switch interface{}(pear).(type) {
|
||||||
case b: //@complete(":", basket, banana)
|
case b: //@complete(":", basket)
|
||||||
b //@complete(" //", banana, basket)
|
b //@complete(" //", banana, basket)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package unresolved
|
package unresolved
|
||||||
|
|
||||||
func foo(interface{}) { //@item(unresolvedFoo, "foo", "func(interface{})", "func")
|
func foo(interface{}) {
|
||||||
// don't crash on fake "resolved" type
|
// don't crash on fake "resolved" type
|
||||||
foo(func(i, j f //@complete(" //", unresolvedFoo)
|
foo(func(i, j f //@complete(" //")
|
||||||
}
|
}
|
||||||
|
2
internal/lsp/testdata/lsp/summary.txt.golden
vendored
2
internal/lsp/testdata/lsp/summary.txt.golden
vendored
@ -4,7 +4,7 @@ CompletionSnippetCount = 67
|
|||||||
UnimportedCompletionsCount = 11
|
UnimportedCompletionsCount = 11
|
||||||
DeepCompletionsCount = 5
|
DeepCompletionsCount = 5
|
||||||
FuzzyCompletionsCount = 8
|
FuzzyCompletionsCount = 8
|
||||||
RankedCompletionsCount = 86
|
RankedCompletionsCount = 85
|
||||||
CaseSensitiveCompletionsCount = 4
|
CaseSensitiveCompletionsCount = 4
|
||||||
DiagnosticsCount = 38
|
DiagnosticsCount = 38
|
||||||
FoldingRangesCount = 2
|
FoldingRangesCount = 2
|
||||||
|
Loading…
Reference in New Issue
Block a user