diff --git a/internal/lsp/source/completion.go b/internal/lsp/source/completion.go index a9c599bbcb..712b595ebe 100644 --- a/internal/lsp/source/completion.go +++ b/internal/lsp/source/completion.go @@ -324,6 +324,15 @@ func (c *completer) found(cand candidate) { 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) { cand.score *= highScore } 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 // 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, // use the *ast.File as the starting node. var node ast.Node @@ -1720,6 +1729,11 @@ Nodes: wantComparable = c.pos == n.Pos()+token.Pos(len("map[")) } break Nodes + case *ast.ValueSpec: + if n.Type != nil && n.Type.Pos() <= c.pos && c.pos <= n.Type.End() { + wantTypeName = true + } + break Nodes default: if breaksExpectedTypeInference(p) { return typeNameInference{} diff --git a/internal/lsp/source/util.go b/internal/lsp/source/util.go index ff0d2be112..6a17839883 100644 --- a/internal/lsp/source/util.go +++ b/internal/lsp/source/util.go @@ -415,6 +415,11 @@ func isUntyped(T types.Type) bool { 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 // selector. func enclosingSelector(path []ast.Node, pos token.Pos) *ast.SelectorExpr { diff --git a/internal/lsp/testdata/lsp/primarymod/arraytype/array_type.go.in b/internal/lsp/testdata/lsp/primarymod/arraytype/array_type.go.in index fc052689db..a53ee74a66 100644 --- a/internal/lsp/testdata/lsp/primarymod/arraytype/array_type.go.in +++ b/internal/lsp/testdata/lsp/primarymod/arraytype/array_type.go.in @@ -9,14 +9,14 @@ func _() { val string //@item(atVal, "val", "string", "var") ) - [] //@complete(" //", atVal, PackageFoo) + [] //@complete(" //", PackageFoo) - []val //@complete(" //", atVal) + []val //@complete(" //") []foo.StructFoo //@complete(" //", StructFoo) []foo.StructFoo(nil) //@complete("(", StructFoo) - + []*foo.StructFoo //@complete(" //", StructFoo) [...]foo.StructFoo //@complete(" //", StructFoo) @@ -32,12 +32,12 @@ func _() { var mark []myInt //@item(atMark, "mark", "[]myInt", "var") var s []myInt //@item(atS, "s", "[]myInt", "var") - s = []m //@complete(" //", atMyInt, atMark) - s = [] //@complete(" //", atMyInt, atMark, atS, PackageFoo) + s = []m //@complete(" //", atMyInt) + s = [] //@complete(" //", atMyInt, PackageFoo) var a [1]myInt - a = [1]m //@complete(" //", atMyInt, atMark) + a = [1]m //@complete(" //", atMyInt) var ds [][]myInt - ds = [][]m //@complete(" //", atMyInt, atMark) + ds = [][]m //@complete(" //", atMyInt) } diff --git a/internal/lsp/testdata/lsp/primarymod/bar/bar.go.in b/internal/lsp/testdata/lsp/primarymod/bar/bar.go.in index dd80911be6..70b69b8f47 100644 --- a/internal/lsp/testdata/lsp/primarymod/bar/bar.go.in +++ b/internal/lsp/testdata/lsp/primarymod/bar/bar.go.in @@ -10,13 +10,13 @@ func helper(i foo.IntFoo) {} //@item(helper, "helper", "func(i foo.IntFoo)", "fu func _() { help //@complete("l", helper) - _ = foo.StructFoo{} //@complete("S", IntFoo, StructFoo, Foo) + _ = foo.StructFoo{} //@complete("S", IntFoo, StructFoo) } // Bar is a function. func Bar() { //@item(Bar, "Bar", "func()", "func", "Bar is a function.") 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) } diff --git a/internal/lsp/testdata/lsp/primarymod/builtins/builtin_args.go b/internal/lsp/testdata/lsp/primarymod/builtins/builtin_args.go index 8b3d10a46a..0ce5aa4802 100644 --- a/internal/lsp/testdata/lsp/primarymod/builtins/builtin_args.go +++ b/internal/lsp/testdata/lsp/primarymod/builtins/builtin_args.go @@ -33,13 +33,12 @@ func _() { 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) - var _ []int = make() //@rank(")", builtinSliceType, builtinSlice) + var _ []int = make() //@rank(")", builtinSliceType, builtinMapType) type myStruct struct{} //@item(builtinStructType, "myStruct", "struct{...}", "struct") - new() //@rank(")", builtinStructType, builtinInt) 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), diff --git a/internal/lsp/testdata/lsp/primarymod/fieldlist/field_list.go b/internal/lsp/testdata/lsp/primarymod/fieldlist/field_list.go index c70530a3cf..e687defb1d 100644 --- a/internal/lsp/testdata/lsp/primarymod/fieldlist/field_list.go +++ b/internal/lsp/testdata/lsp/primarymod/fieldlist/field_list.go @@ -3,25 +3,25 @@ package fieldlist var myInt int //@item(flVar, "myInt", "int", "var") type myType int //@item(flType, "myType", "int", "type") -func (my) _() {} //@complete(") _", flType, flVar) -func (my my) _() {} //@complete(" my)"),complete(") _", flType, flVar) +func (my) _() {} //@complete(") _", flType) +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 _() { var _ struct { - //@complete("", flType, flVar) - m my //@complete(" my"),complete(" //", flType, flVar) + //@complete("", flType) + m my //@complete(" my"),complete(" //", flType) } var _ interface { - //@complete("", flType, flVar) - m() my //@complete("("),complete(" //", flType, flVar) + //@complete("", flType) + m() my //@complete("("),complete(" //", flType) } } diff --git a/internal/lsp/testdata/lsp/primarymod/func_rank/func_rank.go.in b/internal/lsp/testdata/lsp/primarymod/func_rank/func_rank.go.in index 61ad6e9a0e..f9cc6a1d34 100644 --- a/internal/lsp/testdata/lsp/primarymod/func_rank/func_rank.go.in +++ b/internal/lsp/testdata/lsp/primarymod/func_rank/func_rank.go.in @@ -4,11 +4,11 @@ var stringAVar = "var" //@item(stringAVar, "stringAVar", "string", "var") func stringBFunc() string { return "str" } //@item(stringBFunc, "stringBFunc", "func() string", "func") 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 _() { var s struct { diff --git a/internal/lsp/testdata/lsp/primarymod/maps/maps.go.in b/internal/lsp/testdata/lsp/primarymod/maps/maps.go.in index 5c9dedd2ca..b4a4cdd770 100644 --- a/internal/lsp/testdata/lsp/primarymod/maps/maps.go.in +++ b/internal/lsp/testdata/lsp/primarymod/maps/maps.go.in @@ -11,8 +11,8 @@ func _() { // comparable 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("{", mapSliceType, mapStructType, mapVar) + map[a]a{} //@complete("]", mapSliceTypePtr, mapStructType) + map[a]a{} //@complete("{", mapSliceType, mapStructType) } diff --git a/internal/lsp/testdata/lsp/primarymod/rank/type_assert_rank.go.in b/internal/lsp/testdata/lsp/primarymod/rank/type_assert_rank.go.in index 3490c85b07..416541cdde 100644 --- a/internal/lsp/testdata/lsp/primarymod/rank/type_assert_rank.go.in +++ b/internal/lsp/testdata/lsp/primarymod/rank/type_assert_rank.go.in @@ -4,5 +4,5 @@ func _() { type flower int //@item(flower, "flower", "int", "type") var fig string //@item(fig, "fig", "string", "var") - _ = interface{}(nil).(f) //@complete(") //", flower, fig) + _ = interface{}(nil).(f) //@complete(") //", flower) } diff --git a/internal/lsp/testdata/lsp/primarymod/rank/type_switch_rank.go.in b/internal/lsp/testdata/lsp/primarymod/rank/type_switch_rank.go.in index 457c64b82e..293025ff8e 100644 --- a/internal/lsp/testdata/lsp/primarymod/rank/type_switch_rank.go.in +++ b/internal/lsp/testdata/lsp/primarymod/rank/type_switch_rank.go.in @@ -5,7 +5,7 @@ func _() { var banana string //@item(banana, "banana", "string", "var") switch interface{}(pear).(type) { - case b: //@complete(":", basket, banana) + case b: //@complete(":", basket) b //@complete(" //", banana, basket) } } diff --git a/internal/lsp/testdata/lsp/primarymod/unresolved/unresolved.go.in b/internal/lsp/testdata/lsp/primarymod/unresolved/unresolved.go.in index ceb7fe2b65..e1daecc2e5 100644 --- a/internal/lsp/testdata/lsp/primarymod/unresolved/unresolved.go.in +++ b/internal/lsp/testdata/lsp/primarymod/unresolved/unresolved.go.in @@ -1,6 +1,6 @@ package unresolved -func foo(interface{}) { //@item(unresolvedFoo, "foo", "func(interface{})", "func") +func foo(interface{}) { // don't crash on fake "resolved" type - foo(func(i, j f //@complete(" //", unresolvedFoo) + foo(func(i, j f //@complete(" //") } diff --git a/internal/lsp/testdata/lsp/summary.txt.golden b/internal/lsp/testdata/lsp/summary.txt.golden index c5efd04365..739316e565 100644 --- a/internal/lsp/testdata/lsp/summary.txt.golden +++ b/internal/lsp/testdata/lsp/summary.txt.golden @@ -4,7 +4,7 @@ CompletionSnippetCount = 67 UnimportedCompletionsCount = 11 DeepCompletionsCount = 5 FuzzyCompletionsCount = 8 -RankedCompletionsCount = 86 +RankedCompletionsCount = 85 CaseSensitiveCompletionsCount = 4 DiagnosticsCount = 38 FoldingRangesCount = 2