diff --git a/internal/lsp/source/completion_format.go b/internal/lsp/source/completion_format.go index abad1f9f..b9718f78 100644 --- a/internal/lsp/source/completion_format.go +++ b/internal/lsp/source/completion_format.go @@ -40,7 +40,7 @@ func (c *completer) item(cand candidate) CompletionItem { params := formatParams(sig.Params(), sig.Variadic(), c.qf) plainSnippet, placeholderSnippet = c.functionCallSnippets(label, params) results, writeParens := formatResults(sig.Results(), c.qf) - label, detail = formatFunction(label, params, results, writeParens) + detail = "func" + formatFunction(params, results, writeParens) } switch obj := obj.(type) { @@ -112,7 +112,6 @@ func (c *completer) isParameter(v *types.Var) bool { func (c *completer) formatBuiltin(cand candidate) CompletionItem { obj := cand.obj - item := CompletionItem{ Label: obj.Name(), InsertText: obj.Name(), @@ -129,7 +128,8 @@ func (c *completer) formatBuiltin(cand candidate) CompletionItem { } params, _ := formatFieldList(c.ctx, c.view, decl.Type.Params) results, writeResultParens := formatFieldList(c.ctx, c.view, decl.Type.Results) - item.Label, item.Detail = formatFunction(obj.Name(), params, results, writeResultParens) + item.Label = obj.Name() + item.Detail = "func" + formatFunction(params, results, writeResultParens) item.plainSnippet, item.placeholderSnippet = c.functionCallSnippets(obj.Name(), params) case *types.TypeName: if types.IsInterface(obj.Type()) { diff --git a/internal/lsp/source/signature_help.go b/internal/lsp/source/signature_help.go index 7a657b6b..c17b8f59 100644 --- a/internal/lsp/source/signature_help.go +++ b/internal/lsp/source/signature_help.go @@ -152,11 +152,7 @@ func signatureInformation(name string, comment *ast.CommentGroup, params, result for _, p := range params { paramInfo = append(paramInfo, ParameterInformation{Label: p}) } - label, detail := formatFunction(name, params, results, writeResultParens) - // Show return values of the function in the label. - if detail != "" { - label += " " + detail - } + label := name + formatFunction(params, results, writeResultParens) return &SignatureInformation{ Label: label, // TODO: Should we have the HoverKind apply to signature information as well? diff --git a/internal/lsp/source/util.go b/internal/lsp/source/util.go index 8fe0498a..cfacb46a 100644 --- a/internal/lsp/source/util.go +++ b/internal/lsp/source/util.go @@ -219,17 +219,22 @@ func formatType(typ types.Type, qf types.Qualifier) (detail string, kind Complet return detail, kind } -func formatFunction(name string, params []string, results []string, writeResultParens bool) (string, string) { - var label, detail strings.Builder - label.WriteString(name) - label.WriteByte('(') +func formatFunction(params []string, results []string, writeResultParens bool) string { + var detail strings.Builder + + detail.WriteByte('(') for i, p := range params { if i > 0 { - label.WriteString(", ") + detail.WriteString(", ") } - label.WriteString(p) + detail.WriteString(p) + } + detail.WriteByte(')') + + // Add space between parameters and results. + if len(results) > 0 { + detail.WriteByte(' ') } - label.WriteByte(')') if writeResultParens { detail.WriteByte('(') @@ -244,5 +249,5 @@ func formatFunction(name string, params []string, results []string, writeResultP detail.WriteByte(')') } - return label.String(), detail.String() + return detail.String() } diff --git a/internal/lsp/testdata/bad/bad0.go b/internal/lsp/testdata/bad/bad0.go index e6df4c1c..b1782529 100644 --- a/internal/lsp/testdata/bad/bad0.go +++ b/internal/lsp/testdata/bad/bad0.go @@ -2,7 +2,7 @@ package bad -func stuff() { //@item(stuff, "stuff()", "", "func") +func stuff() { //@item(stuff, "stuff", "func()", "func") x := "heeeeyyyy" random2(x) //@diag("x", "LSP", "cannot use x (variable of type string) as int value in argument to random2") random2(1) //@complete("dom", random, random2, random3) diff --git a/internal/lsp/testdata/bad/bad1.go b/internal/lsp/testdata/bad/bad1.go index b9664cb8..c71d5557 100644 --- a/internal/lsp/testdata/bad/bad1.go +++ b/internal/lsp/testdata/bad/bad1.go @@ -8,12 +8,12 @@ package bad var a unknown //@item(global_a, "a", "unknown", "var"),diag("unknown", "LSP", "undeclared name: unknown") -func random() int { //@item(random, "random()", "int", "func") +func random() int { //@item(random, "random", "func() int", "func") //@complete("", global_a, bob, random, random2, random3, stuff) return 0 } -func random2(y int) int { //@item(random2, "random2(y int)", "int", "func"),item(bad_y_param, "y", "int", "parameter") +func random2(y int) int { //@item(random2, "random2", "func(y int) int", "func"),item(bad_y_param, "y", "int", "parameter") x := 6 //@item(x, "x", "int", "var"),diag("x", "LSP", "x declared but not used") var q blah //@item(q, "q", "blah", "var"),diag("q", "LSP", "q declared but not used"),diag("blah", "LSP", "undeclared name: blah") var t blob //@item(t, "t", "blob", "var"),diag("t", "LSP", "t declared but not used"),diag("blob", "LSP", "undeclared name: blob") @@ -22,6 +22,6 @@ func random2(y int) int { //@item(random2, "random2(y int)", "int", "func"),item return y } -func random3(y ...int) { //@item(random3, "random3(y ...int)", "", "func"),item(y_variadic_param, "y", "[]int", "parameter") +func random3(y ...int) { //@item(random3, "random3", "func(y ...int)", "func"),item(y_variadic_param, "y", "[]int", "parameter") //@complete("", y_variadic_param, global_a, bob, random, random2, random3, stuff) } diff --git a/internal/lsp/testdata/bar/bar.go.in b/internal/lsp/testdata/bar/bar.go.in index 94d8254a..c53facf0 100644 --- a/internal/lsp/testdata/bar/bar.go.in +++ b/internal/lsp/testdata/bar/bar.go.in @@ -6,14 +6,14 @@ import ( "golang.org/x/tools/internal/lsp/foo" //@item(foo, "foo", "\"golang.org/x/tools/internal/lsp/foo\"", "package") ) -func helper(i foo.IntFoo) {} //@item(helper, "helper(i foo.IntFoo)", "", "func") +func helper(i foo.IntFoo) {} //@item(helper, "helper", "func(i foo.IntFoo)", "func") func _() { help //@complete("l", helper) _ = foo.StructFoo{} //@complete("S", Foo, IntFoo, StructFoo) } -func Bar() { //@item(Bar, "Bar()", "", "func") +func Bar() { //@item(Bar, "Bar", "func()", "func") foo.Foo() //@complete("F", Foo, IntFoo, StructFoo) var _ foo.IntFoo //@complete("I", Foo, IntFoo, StructFoo) foo.() //@complete("(", Foo, IntFoo, StructFoo) diff --git a/internal/lsp/testdata/builtins/builtins.go b/internal/lsp/testdata/builtins/builtins.go index ae7280e0..14fd1441 100644 --- a/internal/lsp/testdata/builtins/builtins.go +++ b/internal/lsp/testdata/builtins/builtins.go @@ -5,36 +5,36 @@ func _() { } /* Create markers for builtin types. Only for use by this test. -/* append(slice []Type, elems ...Type) []Type */ //@item(append, "append(slice []Type, elems ...Type)", "[]Type", "func") +/* append(slice []Type, elems ...Type) []Type */ //@item(append, "append", "func(slice []Type, elems ...Type) []Type", "func") /* bool */ //@item(bool, "bool", "", "type") /* byte */ //@item(byte, "byte", "", "type") -/* cap(v Type) int */ //@item(cap, "cap(v Type)", "int", "func") -/* close(c chan<- Type) */ //@item(close, "close(c chan<- Type)", "", "func") -/* complex(r float64, i float64) */ //@item(complex, "complex(r float64, i float64)", "complex128", "func") +/* cap(v Type) int */ //@item(cap, "cap", "func(v Type) int", "func") +/* close(c chan<- Type) */ //@item(close, "close", "func(c chan<- Type)", "func") +/* complex(r float64, i float64) */ //@item(complex, "complex", "func(r float64, i float64) complex128", "func") /* complex128 */ //@item(complex128, "complex128", "", "type") /* complex64 */ //@item(complex64, "complex64", "", "type") -/* copy(dst []Type, src []Type) int */ //@item(copy, "copy(dst []Type, src []Type)", "int", "func") -/* delete(m map[Type]Type1, key Type) */ //@item(delete, "delete(m map[Type]Type1, key Type)", "", "func") +/* copy(dst []Type, src []Type) int */ //@item(copy, "copy", "func(dst []Type, src []Type) int", "func") +/* delete(m map[Type]Type1, key Type) */ //@item(delete, "delete", "func(m map[Type]Type1, key Type)", "func") /* error */ //@item(error, "error", "", "interface") /* false */ //@item(_false, "false", "", "const") /* float32 */ //@item(float32, "float32", "", "type") /* float64 */ //@item(float64, "float64", "", "type") -/* imag(c complex128) float64 */ //@item(imag, "imag(c complex128)", "float64", "func") +/* imag(c complex128) float64 */ //@item(imag, "imag", "func(c complex128) float64", "func") /* int */ //@item(int, "int", "", "type") /* int16 */ //@item(int16, "int16", "", "type") /* int32 */ //@item(int32, "int32", "", "type") /* int64 */ //@item(int64, "int64", "", "type") /* int8 */ //@item(int8, "int8", "", "type") /* iota */ //@item(iota, "iota", "", "const") -/* len(v Type) int */ //@item(len, "len(v Type)", "int", "func") -/* make(t Type, size ...int) Type */ //@item(make, "make(t Type, size ...int)", "Type", "func") -/* new(Type) *Type */ //@item(new, "new(Type)", "*Type", "func") +/* len(v Type) int */ //@item(len, "len", "func(v Type) int", "func") +/* make(t Type, size ...int) Type */ //@item(make, "make", "func(t Type, size ...int) Type", "func") +/* new(Type) *Type */ //@item(new, "new", "func(Type) *Type", "func") /* nil */ //@item(_nil, "nil", "", "var") -/* panic(v interface{}) */ //@item(panic, "panic(v interface{})", "", "func") -/* print(args ...Type) */ //@item(print, "print(args ...Type)", "", "func") -/* println(args ...Type) */ //@item(println, "println(args ...Type)", "", "func") -/* real(c complex128) float64 */ //@item(real, "real(c complex128)", "float64", "func") -/* recover() interface{} */ //@item(recover, "recover()", "interface{}", "func") +/* panic(v interface{}) */ //@item(panic, "panic", "func(v interface{})", "func") +/* print(args ...Type) */ //@item(print, "print", "func(args ...Type)", "func") +/* println(args ...Type) */ //@item(println, "println", "func(args ...Type)", "func") +/* real(c complex128) float64 */ //@item(real, "real", "func(c complex128) float64", "func") +/* recover() interface{} */ //@item(recover, "recover", "func() interface{}", "func") /* rune */ //@item(rune, "rune", "", "type") /* string */ //@item(string, "string", "", "type") /* true */ //@item(_true, "true", "", "const") diff --git a/internal/lsp/testdata/deepcomplete/deep_complete.go b/internal/lsp/testdata/deepcomplete/deep_complete.go index 1a56fbaa..970ec657 100644 --- a/internal/lsp/testdata/deepcomplete/deep_complete.go +++ b/internal/lsp/testdata/deepcomplete/deep_complete.go @@ -26,9 +26,9 @@ func _() { func wantsContext(context.Context) {} func _() { - context.Background() //@item(ctxBackground, "context.Background()", "context.Context", "func") - context.TODO() //@item(ctxTODO, "context.TODO()", "context.Context", "func") - /* context.WithValue(parent context.Context, key interface{}, val interface{}) */ //@item(ctxWithValue, "context.WithValue(parent context.Context, key interface{}, val interface{})", "context.Context", "func") + context.Background() //@item(ctxBackground, "context.Background", "func() context.Context", "func") + context.TODO() //@item(ctxTODO, "context.TODO", "func() context.Context", "func") + /* context.WithValue(parent context.Context, key interface{}, val interface{}) */ //@item(ctxWithValue, "context.WithValue", "func(parent context.Context, key interface{}, val interface{}) context.Context", "func") wantsContext(c) //@complete(")", ctxBackground, ctxTODO, ctxWithValue, ctxPackage) } diff --git a/internal/lsp/testdata/foo/foo.go b/internal/lsp/testdata/foo/foo.go index 094623e1..444f07f8 100644 --- a/internal/lsp/testdata/foo/foo.go +++ b/internal/lsp/testdata/foo/foo.go @@ -5,9 +5,9 @@ type StructFoo struct { //@item(StructFoo, "StructFoo", "struct{...}", "struct") } // Pre-set this marker, as we don't have a "source" for it in this package. -/* Error() */ //@item(Error, "Error()", "string", "method") +/* Error() */ //@item(Error, "Error", "func() string", "method") -func Foo() { //@item(Foo, "Foo()", "", "func") +func Foo() { //@item(Foo, "Foo", "func()", "func") var err error err.Error() //@complete("E", Error) } diff --git a/internal/lsp/testdata/func_rank/func_rank.go.in b/internal/lsp/testdata/func_rank/func_rank.go.in index ca983241..0d0feeb1 100644 --- a/internal/lsp/testdata/func_rank/func_rank.go.in +++ b/internal/lsp/testdata/func_rank/func_rank.go.in @@ -1,7 +1,7 @@ package func_rank var stringAVar = "var" //@item(stringAVar, "stringAVar", "string", "var") -func stringBFunc() string { return "str" } //@item(stringBFunc, "stringBFunc()", "string", "func") +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) diff --git a/internal/lsp/testdata/funcvalue/func_value.go b/internal/lsp/testdata/funcvalue/func_value.go index a36a4a26..913fcbcf 100644 --- a/internal/lsp/testdata/funcvalue/func_value.go +++ b/internal/lsp/testdata/funcvalue/func_value.go @@ -4,19 +4,19 @@ func fooFunc() int { //@item(fvFooFunc, "fooFunc", "func() int", "func") return 0 } -var _ = fooFunc() //@item(fvFooFuncCall, "fooFunc()", "int", "func") +var _ = fooFunc() //@item(fvFooFuncCall, "fooFunc", "func() int", "func") var fooVar = func() int { //@item(fvFooVar, "fooVar", "func() int", "var") return 0 } -var _ = fooVar() //@item(fvFooVarCall, "fooVar()", "int", "var") +var _ = fooVar() //@item(fvFooVarCall, "fooVar", "func() int", "var") type myFunc func() int var fooType myFunc = fooVar //@item(fvFooType, "fooType", "myFunc", "var") -var _ = fooType() //@item(fvFooTypeCall, "fooType()", "int", "var") +var _ = fooType() //@item(fvFooTypeCall, "fooType", "func() int", "var") func _() { var f func() int diff --git a/internal/lsp/testdata/good/good0.go b/internal/lsp/testdata/good/good0.go index 4e204e3f..ceb26c5d 100644 --- a/internal/lsp/testdata/good/good0.go +++ b/internal/lsp/testdata/good/good0.go @@ -1,6 +1,6 @@ package good //@diag("package", "", "") -func stuff() { //@item(good_stuff, "stuff()", "", "func") +func stuff() { //@item(good_stuff, "stuff", "func()", "func") x := 5 random2(x) } diff --git a/internal/lsp/testdata/good/good1.go b/internal/lsp/testdata/good/good1.go index b595950d..95a9250f 100644 --- a/internal/lsp/testdata/good/good1.go +++ b/internal/lsp/testdata/good/good1.go @@ -4,12 +4,12 @@ import ( "golang.org/x/tools/internal/lsp/types" //@item(types_import, "types", "\"golang.org/x/tools/internal/lsp/types\"", "package") ) -func random() int { //@item(good_random, "random()", "int", "func") +func random() int { //@item(good_random, "random", "func() int", "func") y := 6 + 7 return y } -func random2(y int) int { //@item(good_random2, "random2(y int)", "int", "func"),item(good_y_param, "y", "int", "parameter") +func random2(y int) int { //@item(good_random2, "random2", "func(y int) int", "func"),item(good_y_param, "y", "int", "parameter") //@complete("", good_y_param, types_import, good_random, good_random2, good_stuff) var b types.Bob = &types.X{} if _, ok := b.(*types.X); ok { //@complete("X", X_struct, Y_struct, Bob_interface) diff --git a/internal/lsp/testdata/selector/selector.go.in b/internal/lsp/testdata/selector/selector.go.in index 10c39120..77df0034 100644 --- a/internal/lsp/testdata/selector/selector.go.in +++ b/internal/lsp/testdata/selector/selector.go.in @@ -19,9 +19,9 @@ type george struct { b int } type jack struct { c int } //@item(c, "c", "int", "field") type jill struct { d int } -func (b *bob) george() *george {} //@item(george, "george()", "*george", "method") +func (b *bob) george() *george {} //@item(george, "george", "func() *george", "method") func (g *george) jack() *jack {} -func (j *jack) jill() *jill {} //@item(jill, "jill()", "*jill", "method") +func (j *jack) jill() *jill {} //@item(jill, "jill", "func() *jill", "method") func _() { b := &bob{} diff --git a/internal/lsp/testdata/snippets/snippets.go b/internal/lsp/testdata/snippets/snippets.go index 0cf92328..ee56eb3c 100644 --- a/internal/lsp/testdata/snippets/snippets.go +++ b/internal/lsp/testdata/snippets/snippets.go @@ -1,14 +1,14 @@ package snippets -func foo(i int, b bool) {} //@item(snipFoo, "foo(i int, b bool)", "", "func") -func bar(fn func()) func() {} //@item(snipBar, "bar(fn func())", "", "func") +func foo(i int, b bool) {} //@item(snipFoo, "foo", "func(i int, b bool)", "func") +func bar(fn func()) func() {} //@item(snipBar, "bar", "func(fn func())", "func") type Foo struct { Bar int //@item(snipFieldBar, "Bar", "int", "field") } -func (Foo) Baz() func() {} //@item(snipMethodBaz, "Baz()", "func()", "method") -func (Foo) BazBar() func() {} //@item(snipMethodBazBar, "BazBar()", "func()", "method") +func (Foo) Baz() func() {} //@item(snipMethodBaz, "Baz", "func() func()", "method") +func (Foo) BazBar() func() {} //@item(snipMethodBazBar, "BazBar", "func() func()", "method") func _() { f //@snippet(" //", snipFoo, "foo(${1})", "foo(${1:i int}, ${2:b bool})") diff --git a/internal/lsp/testdata/testy/testy.go b/internal/lsp/testdata/testy/testy.go index ba1205e8..1a738d7d 100644 --- a/internal/lsp/testdata/testy/testy.go +++ b/internal/lsp/testdata/testy/testy.go @@ -1,5 +1,5 @@ package testy -func a() { //@mark(identA, "a"),item(funcA, "a()", "", "func"),refs("a", identA, testyA) +func a() { //@mark(identA, "a"),item(funcA, "a", "func()", "func"),refs("a", identA, testyA) //@complete("", funcA) }