mirror of
https://github.com/golang/go
synced 2024-11-18 08:24:44 -07:00
6a8222ee25
gopls has many settings. We want to automatically generate documentation, and we want to allow clients to perform their own validation if they so desire. Using all three of AST, type information, and reflection, generate a JSON description of the settings and their default values. Add a gopls command that prints it. Add a documentation generator that uses it to write settings.md. I assumed that everything not explicitly documented was experimental, and moved it into that section. I also moved expandWorkspaceToModule to experimental; I hope it's not long for this world, personally. Along the way, rename many fields, make the enum matching case insensitive, and add a stringer call so that the defaults print nicely. Fixes golang/go#33544. Change-Id: Ibb652002933e355ed3c6038d6ca48345b39b3025 Reviewed-on: https://go-review.googlesource.com/c/tools/+/252322 Run-TryBot: Heschi Kreinick <heschi@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rebecca Stambler <rstambler@golang.org>
151 lines
4.5 KiB
Go
151 lines
4.5 KiB
Go
package lsp
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"golang.org/x/tools/internal/lsp/protocol"
|
|
"golang.org/x/tools/internal/lsp/source"
|
|
"golang.org/x/tools/internal/lsp/tests"
|
|
"golang.org/x/tools/internal/span"
|
|
)
|
|
|
|
func (r *runner) Completion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
opts.DeepCompletion = false
|
|
opts.Matcher = source.CaseInsensitive
|
|
opts.CompleteUnimported = false
|
|
opts.InsertTextFormat = protocol.SnippetTextFormat
|
|
if !strings.Contains(string(src.URI()), "literal") {
|
|
opts.LiteralCompletions = false
|
|
}
|
|
})
|
|
got = tests.FilterBuiltins(src, got)
|
|
want := expected(t, test, items)
|
|
if diff := tests.DiffCompletionItems(want, got); diff != "" {
|
|
t.Errorf("%s", diff)
|
|
}
|
|
}
|
|
|
|
func (r *runner) CompletionSnippet(t *testing.T, src span.Span, expected tests.CompletionSnippet, placeholders bool, items tests.CompletionItems) {
|
|
list := r.callCompletion(t, src, func(opts *source.Options) {
|
|
opts.UsePlaceholders = placeholders
|
|
opts.DeepCompletion = true
|
|
opts.Matcher = source.Fuzzy
|
|
opts.CompleteUnimported = false
|
|
})
|
|
got := tests.FindItem(list, *items[expected.CompletionItem])
|
|
want := expected.PlainSnippet
|
|
if placeholders {
|
|
want = expected.PlaceholderSnippet
|
|
}
|
|
if diff := tests.DiffSnippets(want, got); diff != "" {
|
|
t.Errorf("%s", diff)
|
|
}
|
|
}
|
|
|
|
func (r *runner) UnimportedCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {})
|
|
got = tests.FilterBuiltins(src, got)
|
|
want := expected(t, test, items)
|
|
if diff := tests.CheckCompletionOrder(want, got, false); diff != "" {
|
|
t.Errorf("%s", diff)
|
|
}
|
|
}
|
|
|
|
func (r *runner) DeepCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
opts.DeepCompletion = true
|
|
opts.Matcher = source.CaseInsensitive
|
|
opts.CompleteUnimported = false
|
|
})
|
|
got = tests.FilterBuiltins(src, got)
|
|
want := expected(t, test, items)
|
|
if msg := tests.DiffCompletionItems(want, got); msg != "" {
|
|
t.Errorf("%s", msg)
|
|
}
|
|
}
|
|
|
|
func (r *runner) FuzzyCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
opts.DeepCompletion = true
|
|
opts.Matcher = source.Fuzzy
|
|
opts.CompleteUnimported = false
|
|
})
|
|
got = tests.FilterBuiltins(src, got)
|
|
want := expected(t, test, items)
|
|
if msg := tests.DiffCompletionItems(want, got); msg != "" {
|
|
t.Errorf("%s", msg)
|
|
}
|
|
}
|
|
|
|
func (r *runner) CaseSensitiveCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
opts.Matcher = source.CaseSensitive
|
|
opts.CompleteUnimported = false
|
|
})
|
|
got = tests.FilterBuiltins(src, got)
|
|
want := expected(t, test, items)
|
|
if msg := tests.DiffCompletionItems(want, got); msg != "" {
|
|
t.Errorf("%s", msg)
|
|
}
|
|
}
|
|
|
|
func (r *runner) RankCompletion(t *testing.T, src span.Span, test tests.Completion, items tests.CompletionItems) {
|
|
got := r.callCompletion(t, src, func(opts *source.Options) {
|
|
opts.DeepCompletion = true
|
|
opts.Matcher = source.Fuzzy
|
|
opts.CompleteUnimported = false
|
|
opts.LiteralCompletions = true
|
|
})
|
|
want := expected(t, test, items)
|
|
if msg := tests.CheckCompletionOrder(want, got, true); msg != "" {
|
|
t.Errorf("%s", msg)
|
|
}
|
|
}
|
|
|
|
func expected(t *testing.T, test tests.Completion, items tests.CompletionItems) []protocol.CompletionItem {
|
|
t.Helper()
|
|
|
|
var want []protocol.CompletionItem
|
|
for _, pos := range test.CompletionItems {
|
|
item := items[pos]
|
|
want = append(want, tests.ToProtocolCompletionItem(*item))
|
|
}
|
|
return want
|
|
}
|
|
|
|
func (r *runner) callCompletion(t *testing.T, src span.Span, options func(*source.Options)) []protocol.CompletionItem {
|
|
t.Helper()
|
|
|
|
view, err := r.server.session.ViewOf(src.URI())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
original := view.Options()
|
|
modified := original
|
|
options(&modified)
|
|
view, err = view.SetOptions(r.ctx, modified)
|
|
if err != nil {
|
|
t.Error(err)
|
|
return nil
|
|
}
|
|
defer view.SetOptions(r.ctx, original)
|
|
|
|
list, err := r.server.Completion(r.ctx, &protocol.CompletionParams{
|
|
TextDocumentPositionParams: protocol.TextDocumentPositionParams{
|
|
TextDocument: protocol.TextDocumentIdentifier{
|
|
URI: protocol.URIFromSpanURI(src.URI()),
|
|
},
|
|
Position: protocol.Position{
|
|
Line: float64(src.Start().Line() - 1),
|
|
Character: float64(src.Start().Column() - 1),
|
|
},
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return list.Items
|
|
}
|