gopls/internal/lsp/tests: eliminate several old marker types
This CL is the unraveling of a single thread, which ended up spanning
many different tests and markers. The goal was to eliminate the three
remaining diagnostic markers in the old test framework, but due to the
tightly bound nature of the old marker tests, that led to the
elimination of Diagnostics, Definitions, TypeDefinitions, and
UnimportedCompletions, along with the definition of several new markers
in the new marker tests.
The new tests are perhaps cleaner in some areas, but still a tangle: my
goal is to delete the old marker tests ASAP, and it's easier to port
them more-or-less faithfully rather than read through and fix bugs /
broken assertions, verbose APIs, unexpected diagnostics, etc.
To this end, the -ignore_extra_diags flag is introduced as some of the
old tests had too many diagnostics for me to annotate. At least this
looseness is contained only to the tests in which the flag is set.
Also, the @rank and @snippet markers didn't make a ton of sense to me
(they refer to completion items but only care about labels), but I
didn't want to fix that. At a later time, I may go back through and
change the way completion items are represented: the current style is
rather verbose.
Some completion markers in the old framework were changing settings for
each mark, sometimes applying _multiple_ settings (see signatureHelp).
The new marker framework does not support this (rightly so, in my opinion),
and so where appropriate certain tests such as unimported completion
had to be moved into a different test file so that they can use
different settings.
As for the tests themselves: they are _mostly_ the same as before,
though I had to tweak them in various small ways to make them work. For
example annotating diagnostics, redefining an import, changing the
marker signature, etc. I don't think I meaningfully changed the test
assertions, but I don't expect this to be carefully verified during
review. I can only hope that the new state is slightly more maintainable
than the old; and provides us a platform to eventually make the tests
significantly more maintainable.
For golang/go#54845
Change-Id: I701bfcbfecf32cd780caba9e324a134e2d9bd048
Reviewed-on: https://go-review.googlesource.com/c/tools/+/528736
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
diff --git a/gopls/internal/lsp/completion_test.go b/gopls/internal/lsp/completion_test.go
index 48ec9ea..06a6a09 100644
--- a/gopls/internal/lsp/completion_test.go
+++ b/gopls/internal/lsp/completion_test.go
@@ -49,15 +49,6 @@
}
}
-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
diff --git a/gopls/internal/lsp/fake/editor.go b/gopls/internal/lsp/fake/editor.go
index 78db2cc..2cf77d1 100644
--- a/gopls/internal/lsp/fake/editor.go
+++ b/gopls/internal/lsp/fake/editor.go
@@ -794,10 +794,7 @@
// GoToDefinition jumps to the definition of the symbol at the given position
// in an open buffer. It returns the location of the resulting jump.
-//
-// TODO(rfindley): rename to "Definition", to be consistent with LSP
-// terminology.
-func (e *Editor) GoToDefinition(ctx context.Context, loc protocol.Location) (protocol.Location, error) {
+func (e *Editor) Definition(ctx context.Context, loc protocol.Location) (protocol.Location, error) {
if err := e.checkBufferLocation(loc); err != nil {
return protocol.Location{}, err
}
@@ -812,9 +809,9 @@
return e.extractFirstLocation(ctx, resp)
}
-// GoToTypeDefinition jumps to the type definition of the symbol at the given location
-// in an open buffer.
-func (e *Editor) GoToTypeDefinition(ctx context.Context, loc protocol.Location) (protocol.Location, error) {
+// TypeDefinition jumps to the type definition of the symbol at the given
+// location in an open buffer.
+func (e *Editor) TypeDefinition(ctx context.Context, loc protocol.Location) (protocol.Location, error) {
if err := e.checkBufferLocation(loc); err != nil {
return protocol.Location{}, err
}
diff --git a/gopls/internal/lsp/lsp_test.go b/gopls/internal/lsp/lsp_test.go
index 9934fee..0bda4e6 100644
--- a/gopls/internal/lsp/lsp_test.go
+++ b/gopls/internal/lsp/lsp_test.go
@@ -14,7 +14,6 @@
"strings"
"testing"
- "github.com/google/go-cmp/cmp"
"golang.org/x/tools/gopls/internal/bug"
"golang.org/x/tools/gopls/internal/lsp/cache"
"golang.org/x/tools/gopls/internal/lsp/command"
@@ -210,13 +209,6 @@
}
}
-func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []*source.Diagnostic) {
- // Get the diagnostics for this view if we have not done it before.
- v := r.server.session.ViewByName(r.data.Config.Dir)
- r.collectDiagnostics(v)
- tests.CompareDiagnostics(t, uri, want, r.diagnostics[uri])
-}
-
func (r *runner) SemanticTokens(t *testing.T, spn span.Span) {
uri := spn.URI()
filename := uri.Filename()
@@ -400,85 +392,6 @@
}
}
-// TODO(rfindley): This handler needs more work. The output is still a bit hard
-// to read (range diffs do not format nicely), and it is too entangled with hover.
-func (r *runner) Definition(t *testing.T, _ span.Span, d tests.Definition) {
- sm, err := r.data.Mapper(d.Src.URI())
- if err != nil {
- t.Fatal(err)
- }
- loc, err := sm.SpanLocation(d.Src)
- if err != nil {
- t.Fatalf("failed for %v: %v", d.Src, err)
- }
- tdpp := protocol.LocationTextDocumentPositionParams(loc)
- var got []protocol.Location
- var hover *protocol.Hover
- if d.IsType {
- params := &protocol.TypeDefinitionParams{
- TextDocumentPositionParams: tdpp,
- }
- got, err = r.server.TypeDefinition(r.ctx, params)
- } else {
- params := &protocol.DefinitionParams{
- TextDocumentPositionParams: tdpp,
- }
- got, err = r.server.Definition(r.ctx, params)
- if err != nil {
- t.Fatalf("failed for %v: %+v", d.Src, err)
- }
- v := &protocol.HoverParams{
- TextDocumentPositionParams: tdpp,
- }
- hover, err = r.server.Hover(r.ctx, v)
- }
- if err != nil {
- t.Fatalf("failed for %v: %v", d.Src, err)
- }
- dm, err := r.data.Mapper(d.Def.URI())
- if err != nil {
- t.Fatal(err)
- }
- def, err := dm.SpanLocation(d.Def)
- if err != nil {
- t.Fatal(err)
- }
- if !d.OnlyHover {
- want := []protocol.Location{def}
- if diff := cmp.Diff(want, got); diff != "" {
- t.Fatalf("Definition(%s) mismatch (-want +got):\n%s", d.Src, diff)
- }
- }
- didSomething := false
- if hover != nil {
- didSomething = true
- tag := fmt.Sprintf("%s-hoverdef", d.Name)
- want := string(r.data.Golden(t, tag, d.Src.URI().Filename(), func() ([]byte, error) {
- return []byte(hover.Contents.Value), nil
- }))
- got := hover.Contents.Value
- if diff := tests.DiffMarkdown(want, got); diff != "" {
- t.Errorf("%s: markdown mismatch:\n%s", d.Src, diff)
- }
- }
- if !d.OnlyHover {
- didSomething = true
- locURI := got[0].URI.SpanURI()
- lm, err := r.data.Mapper(locURI)
- if err != nil {
- t.Fatal(err)
- }
- if def, err := lm.LocationSpan(got[0]); err != nil {
- t.Fatalf("failed for %v: %v", got[0], err)
- } else if def != d.Def {
- t.Errorf("for %v got %v want %v", d.Src, def, d.Def)
- }
- }
- if !didSomething {
- t.Errorf("no tests ran for %s", d.Src.URI())
- }
-}
-
func (r *runner) InlayHints(t *testing.T, spn span.Span) {
uri := spn.URI()
filename := uri.Filename()
diff --git a/gopls/internal/lsp/regtest/marker.go b/gopls/internal/lsp/regtest/marker.go
index ca4c9a8..17d210c 100644
--- a/gopls/internal/lsp/regtest/marker.go
+++ b/gopls/internal/lsp/regtest/marker.go
@@ -111,6 +111,7 @@
// in these directories before running the test.
// -skip_goos=a,b,c instructs the test runner to skip the test for the
// listed GOOS values.
+// -ignore_extra_diags suppresses errors for unmatched diagnostics
// TODO(rfindley): using build constraint expressions for -skip_goos would
// be clearer.
// TODO(rfindley): support flag values containing whitespace.
@@ -199,7 +200,8 @@
//
// - item(label, details, kind): defines a completion item with the provided
// fields. This information is not positional, and therefore @item markers
-// may occur anywhere in the source. Used in conjunction with @complete.
+// may occur anywhere in the source. Used in conjunction with @complete,
+// snippet, or rank.
//
// TODO(rfindley): rethink whether floating @item annotations are the best
// way to specify completion results.
@@ -220,9 +222,23 @@
// This action is executed for its editing effects on the source files.
// Like rename, the golden directory contains the expected transformed files.
//
-// - refs(location, want ...location): executes a 'references' query at the
-// first location and asserts that the result is the set of 'want' locations.
-// The first want location must be the declaration (assumedly unique).
+// - rank(location, ...completionItem): executes a textDocument/completion
+// request at the given location, and verifies that each expected
+// completion item occurs in the results, in the expected order. Other
+// unexpected completion items may occur in the results.
+// TODO(rfindley): this should accept a slice of labels, rather than
+// completion items.
+//
+// - refs(location, want ...location): executes a textDocument/references
+// request at the first location and asserts that the result is the set of
+// 'want' locations. The first want location must be the declaration
+// (assumedly unique).
+//
+// - snippet(location, completionItem, snippet): executes a
+// textDocument/completion request at the location, and searches for a
+// result with label matching that of the provided completion item
+// (TODO(rfindley): accept a label rather than a completion item). Check
+// the the result snippet matches the provided snippet.
//
// - symbol(golden): makes a textDocument/documentSymbol request
// for the enclosing file, formats the response with one symbol
@@ -342,7 +358,6 @@
// - CompletionItems
// - Completions
// - CompletionSnippets
-// - UnimportedCompletions
// - DeepCompletions
// - FuzzyCompletions
// - CaseSensitiveCompletions
@@ -471,9 +486,11 @@
}
// Any remaining (un-eliminated) diagnostics are an error.
- for loc, diags := range run.diags {
- for _, diag := range diags {
- t.Errorf("%s: unexpected diagnostic: %q", run.fmtLoc(loc), diag.Message)
+ if !test.ignoreExtraDiags {
+ for loc, diags := range run.diags {
+ for _, diag := range diags {
+ t.Errorf("%s: unexpected diagnostic: %q", run.fmtLoc(loc), diag.Message)
+ }
}
}
@@ -691,11 +708,15 @@
"highlight": markerFunc(highlightMarker),
"hover": markerFunc(hoverMarker),
"implementation": markerFunc(implementationMarker),
+ "rank": markerFunc(rankMarker),
+ "refs": markerFunc(refsMarker),
"rename": markerFunc(renameMarker),
"renameerr": markerFunc(renameErrMarker),
+ "signature": markerFunc(signatureMarker),
+ "snippet": markerFunc(snippetMarker),
"suggestedfix": markerFunc(suggestedfixMarker),
"symbol": markerFunc(symbolMarker),
- "refs": markerFunc(refsMarker),
+ "typedef": markerFunc(typedefMarker),
"workspacesymbol": markerFunc(workspaceSymbolMarker),
}
@@ -720,10 +741,11 @@
flags []string // flags extracted from the special "flags" archive file.
// Parsed flags values.
- minGoVersion string
- cgo bool
- writeGoSum []string // comma separated dirs to write go sum for
- skipGOOS []string // comma separated GOOS values to skip
+ minGoVersion string
+ cgo bool
+ writeGoSum []string // comma separated dirs to write go sum for
+ skipGOOS []string // comma separated GOOS values to skip
+ ignoreExtraDiags bool
}
// flagSet returns the flagset used for parsing the special "flags" file in the
@@ -734,6 +756,7 @@
flags.BoolVar(&t.cgo, "cgo", false, "if set, requires cgo (both the cgo tool and CGO_ENABLED=1)")
flags.Var((*stringListValue)(&t.writeGoSum), "write_sumfile", "if set, write the sumfile for these directories")
flags.Var((*stringListValue)(&t.skipGOOS), "skip_goos", "if set, skip this test on these GOOS values")
+ flags.BoolVar(&t.ignoreExtraDiags, "ignore_extra_diags", false, "if set, suppress errors for unmatched diagnostics")
return flags
}
@@ -1188,11 +1211,13 @@
}
if id, ok := arg.(expect.Identifier); ok {
if arg, ok := mark.run.data[id]; ok {
+ if !reflect.TypeOf(arg).AssignableTo(paramType) {
+ return nil, fmt.Errorf("cannot convert %v to %s", arg, paramType)
+ }
return arg, nil
}
}
- argType := reflect.TypeOf(arg)
- if argType.AssignableTo(paramType) {
+ if reflect.TypeOf(arg).AssignableTo(paramType) {
return arg, nil // no conversion required
}
switch paramType {
@@ -1201,7 +1226,7 @@
case wantErrorType:
return convertWantError(mark, arg)
default:
- return nil, fmt.Errorf("cannot convert type %s to %s", argType, paramType)
+ return nil, fmt.Errorf("cannot convert %v to %s", arg, paramType)
}
}
@@ -1374,18 +1399,78 @@
// ---- marker functions ----
+// TODO(rfindley): consolidate documentation of these markers. They are already
+// documented above, so much of the documentation here is redundant.
+
// completionItem is a simplified summary of a completion item.
type completionItem struct {
- Label, Detail, Kind string
+ Label, Detail, Kind, Documentation string
}
-func completionItemMarker(mark marker, label, detail, kind string) completionItem {
- return completionItem{
- Label: label,
- Detail: detail,
- Kind: kind,
- // TODO(rfindley): add variadic documentation? It is supported by the old
- // marker tests but almost no test cases use it.
+func completionItemMarker(mark marker, label string, other ...string) completionItem {
+ if len(other) > 3 {
+ mark.errorf("too many arguments to @item: expect at most 4")
+ }
+ item := completionItem{
+ Label: label,
+ }
+ if len(other) > 0 {
+ item.Detail = other[0]
+ }
+ if len(other) > 1 {
+ item.Kind = other[1]
+ }
+ if len(other) > 2 {
+ item.Documentation = other[2]
+ }
+ return item
+}
+
+func rankMarker(mark marker, src protocol.Location, items ...completionItem) {
+ list := mark.run.env.Completion(src)
+ var got []string
+ // Collect results that are present in items, preserving their order.
+ for _, g := range list.Items {
+ for _, w := range items {
+ if g.Label == w.Label {
+ got = append(got, g.Label)
+ break
+ }
+ }
+ }
+ var want []string
+ for _, w := range items {
+ want = append(want, w.Label)
+ }
+ if diff := cmp.Diff(want, got); diff != "" {
+ mark.errorf("completion rankings do not match (-want +got):\n%s", diff)
+ }
+}
+
+func snippetMarker(mark marker, src protocol.Location, item completionItem, want string) {
+ list := mark.run.env.Completion(src)
+ var (
+ found bool
+ got string
+ all []string // for errors
+ )
+ items := filterBuiltinsAndKeywords(list.Items)
+ for _, i := range items {
+ all = append(all, i.Label)
+ if i.Label == item.Label {
+ found = true
+ if i.TextEdit != nil {
+ got = i.TextEdit.NewText
+ }
+ break
+ }
+ }
+ if !found {
+ mark.errorf("no completion item found matching %s (got: %v)", item.Label, all)
+ return
+ }
+ if got != want {
+ mark.errorf("snippets do not match: got %q, want %q", got, want)
}
}
@@ -1402,7 +1487,15 @@
Detail: item.Detail,
Kind: fmt.Sprint(item.Kind),
}
- // Support short-hand notation: if Detail or Kind are omitted from the
+ if item.Documentation != nil {
+ switch v := item.Documentation.Value.(type) {
+ case string:
+ simplified.Documentation = v
+ case protocol.MarkupContent:
+ simplified.Documentation = strings.TrimSpace(v.Value) // trim newlines
+ }
+ }
+ // Support short-hand notation: if Detail, Kind, or Documentation are omitted from the
// item, don't match them.
if i < len(want) {
if want[i].Detail == "" {
@@ -1411,13 +1504,15 @@
if want[i].Kind == "" {
simplified.Kind = ""
}
- }
- if i < len(want) && want[i].Detail == "" {
- simplified.Detail = ""
+ if want[i].Documentation == "" {
+ simplified.Documentation = ""
+ }
}
got = append(got, simplified)
}
-
+ if len(want) == 0 {
+ want = nil // got is nil if empty
+ }
if diff := cmp.Diff(want, got); diff != "" {
mark.errorf("Completion(...) returned unexpect results (-want +got):\n%s", diff)
}
@@ -1488,6 +1583,14 @@
}
}
+func typedefMarker(mark marker, src, dst protocol.Location) {
+ got := mark.run.env.TypeDefinition(src)
+ if got != dst {
+ mark.errorf("type definition location does not match:\n\tgot: %s\n\twant %s",
+ mark.run.fmtLoc(got), mark.run.fmtLoc(dst))
+ }
+}
+
func foldingRangeMarker(mark marker, g *Golden) {
env := mark.run.env
ranges, err := mark.server().FoldingRange(env.Ctx, &protocol.FoldingRangeParams{
@@ -1663,6 +1766,17 @@
wantErr.check(mark, err)
}
+func signatureMarker(mark marker, src protocol.Location, want string) {
+ got := mark.run.env.SignatureHelp(src)
+ if got == nil || len(got.Signatures) != 1 {
+ mark.errorf("signatureHelp = %v, want exactly 1 signature", got)
+ return
+ }
+ if got := got.Signatures[0].Label; got != want {
+ mark.errorf("signatureHelp: got %q, want %q", got, want)
+ }
+}
+
// rename returns the new contents of the files that would be modified
// by renaming the identifier at loc to newName.
func rename(env *Env, loc protocol.Location, newName string) (map[string][]byte, error) {
diff --git a/gopls/internal/lsp/regtest/wrappers.go b/gopls/internal/lsp/regtest/wrappers.go
index d0df086..d56d0c0 100644
--- a/gopls/internal/lsp/regtest/wrappers.go
+++ b/gopls/internal/lsp/regtest/wrappers.go
@@ -155,9 +155,20 @@
// GoToDefinition goes to definition in the editor, calling t.Fatal on any
// error. It returns the path and position of the resulting jump.
+//
+// TODO(rfindley): rename this to just 'Definition'.
func (e *Env) GoToDefinition(loc protocol.Location) protocol.Location {
e.T.Helper()
- loc, err := e.Editor.GoToDefinition(e.Ctx, loc)
+ loc, err := e.Editor.Definition(e.Ctx, loc)
+ if err != nil {
+ e.T.Fatal(err)
+ }
+ return loc
+}
+
+func (e *Env) TypeDefinition(loc protocol.Location) protocol.Location {
+ e.T.Helper()
+ loc, err := e.Editor.TypeDefinition(e.Ctx, loc)
if err != nil {
e.T.Fatal(err)
}
diff --git a/gopls/internal/lsp/testdata/arraytype/array_type.go.in b/gopls/internal/lsp/testdata/arraytype/array_type.go.in
deleted file mode 100644
index ac1a3e7..0000000
--- a/gopls/internal/lsp/testdata/arraytype/array_type.go.in
+++ /dev/null
@@ -1,50 +0,0 @@
-package arraytype
-
-import (
- "golang.org/lsptests/foo"
-)
-
-func _() {
- var (
- val string //@item(atVal, "val", "string", "var")
- )
-
- // disabled - see issue #54822
- [] // complete(" //", PackageFoo)
-
- []val //@complete(" //")
-
- []foo.StructFoo //@complete(" //", StructFoo)
-
- []foo.StructFoo(nil) //@complete("(", StructFoo)
-
- []*foo.StructFoo //@complete(" //", StructFoo)
-
- [...]foo.StructFoo //@complete(" //", StructFoo)
-
- [2][][4]foo.StructFoo //@complete(" //", StructFoo)
-
- []struct { f []foo.StructFoo } //@complete(" }", StructFoo)
-}
-
-func _() {
- type myInt int //@item(atMyInt, "myInt", "int", "type")
-
- var mark []myInt //@item(atMark, "mark", "[]myInt", "var")
-
- var s []myInt //@item(atS, "s", "[]myInt", "var")
- s = []m //@complete(" //", atMyInt)
- // disabled - see issue #54822
- s = [] // complete(" //", atMyInt, PackageFoo)
-
- var a [1]myInt
- a = [1]m //@complete(" //", atMyInt)
-
- var ds [][]myInt
- ds = [][]m //@complete(" //", atMyInt)
-}
-
-func _() {
- var b [0]byte //@item(atByte, "b", "[0]byte", "var")
- var _ []byte = b //@snippet(" //", atByte, "b[:]", "b[:]")
-}
diff --git a/gopls/internal/lsp/testdata/badstmt/badstmt.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt.go.in
deleted file mode 100644
index 3b8f9e0..0000000
--- a/gopls/internal/lsp/testdata/badstmt/badstmt.go.in
+++ /dev/null
@@ -1,28 +0,0 @@
-package badstmt
-
-import (
- "golang.org/lsptests/foo"
-)
-
-// (The syntax error causes suppression of diagnostics for type errors.
-// See issue #59888.)
-
-func _(x int) {
- defer foo.F //@complete(" //", Foo),diag(" //", "syntax", "function must be invoked in defer statement|expression in defer must be function call", "error")
- defer foo.F //@complete(" //", Foo)
-}
-
-func _() {
- switch true {
- case true:
- go foo.F //@complete(" //", Foo)
- }
-}
-
-func _() {
- defer func() {
- foo.F //@complete(" //", Foo),snippet(" //", Foo, "Foo()", "Foo()")
-
- foo. //@rank(" //", Foo)
- }
-}
diff --git a/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in
deleted file mode 100644
index 6af9c35..0000000
--- a/gopls/internal/lsp/testdata/badstmt/badstmt_2.go.in
+++ /dev/null
@@ -1,9 +0,0 @@
-package badstmt
-
-import (
- "golang.org/lsptests/foo"
-)
-
-func _() {
- defer func() { foo. } //@rank(" }", Foo)
-}
diff --git a/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in
deleted file mode 100644
index d135e20..0000000
--- a/gopls/internal/lsp/testdata/badstmt/badstmt_3.go.in
+++ /dev/null
@@ -1,9 +0,0 @@
-package badstmt
-
-import (
- "golang.org/lsptests/foo"
-)
-
-func _() {
- go foo. //@rank(" //", Foo, IntFoo),snippet(" //", Foo, "Foo()", "Foo()")
-}
diff --git a/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in b/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in
deleted file mode 100644
index 6afd635..0000000
--- a/gopls/internal/lsp/testdata/badstmt/badstmt_4.go.in
+++ /dev/null
@@ -1,11 +0,0 @@
-package badstmt
-
-import (
- "golang.org/lsptests/foo"
-)
-
-func _() {
- go func() {
- defer foo. //@rank(" //", Foo, IntFoo)
- }
-}
diff --git a/gopls/internal/lsp/testdata/bar/bar.go.in b/gopls/internal/lsp/testdata/bar/bar.go.in
deleted file mode 100644
index 502bdf7..0000000
--- a/gopls/internal/lsp/testdata/bar/bar.go.in
+++ /dev/null
@@ -1,47 +0,0 @@
-// +build go1.11
-
-package bar
-
-import (
- "golang.org/lsptests/foo" //@item(foo, "foo", "\"golang.org/lsptests/foo\"", "package")
-)
-
-func helper(i foo.IntFoo) {} //@item(helper, "helper", "func(i foo.IntFoo)", "func")
-
-func _() {
- help //@complete("l", helper)
- _ = 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", IntFoo, StructFoo)
- foo.() //@complete("(", Foo, IntFoo, StructFoo)
-}
-
-func _() {
- var Valentine int //@item(Valentine, "Valentine", "int", "var")
-
- _ = foo.StructFoo{
- Valu //@complete(" //", Value)
- }
- _ = foo.StructFoo{
- Va //@complete("a", Value, Valentine)
- }
- _ = foo.StructFoo{
- Value: 5, //@complete("a", Value)
- }
- _ = foo.StructFoo{
- //@complete("", Value, Valentine, foo, helper, Bar)
- }
- _ = foo.StructFoo{
- Value: Valen //@complete("le", Valentine)
- }
- _ = foo.StructFoo{
- Value: //@complete(" //", Valentine, foo, helper, Bar)
- }
- _ = foo.StructFoo{
- Value: //@complete(" ", Valentine, foo, helper, Bar)
- }
-}
diff --git a/gopls/internal/lsp/testdata/baz/baz.go.in b/gopls/internal/lsp/testdata/baz/baz.go.in
deleted file mode 100644
index 94952e1..0000000
--- a/gopls/internal/lsp/testdata/baz/baz.go.in
+++ /dev/null
@@ -1,33 +0,0 @@
-// +build go1.11
-
-package baz
-
-import (
- "golang.org/lsptests/bar"
-
- f "golang.org/lsptests/foo"
-)
-
-var FooStruct f.StructFoo
-
-func Baz() {
- defer bar.Bar() //@complete("B", Bar)
- // TODO(rstambler): Test completion here.
- defer bar.B
- var x f.IntFoo //@complete("n", IntFoo),typdef("x", IntFoo)
- bar.Bar() //@complete("B", Bar)
-}
-
-func _() {
- bob := f.StructFoo{Value: 5}
- if x := bob. //@complete(" //", Value)
- switch true == false {
- case true:
- if x := bob. //@complete(" //", Value)
- case false:
- }
- if x := bob.Va //@complete("a", Value)
- switch true == true {
- default:
- }
-}
diff --git a/gopls/internal/lsp/testdata/cgo/declarecgo.go b/gopls/internal/lsp/testdata/cgo/declarecgo.go
deleted file mode 100644
index c283cdf..0000000
--- a/gopls/internal/lsp/testdata/cgo/declarecgo.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package cgo
-
-/*
-#include <stdio.h>
-#include <stdlib.h>
-
-void myprint(char* s) {
- printf("%s\n", s);
-}
-*/
-import "C"
-
-import (
- "fmt"
- "unsafe"
-)
-
-func Example() { //@mark(funccgoexample, "Example"),item(funccgoexample, "Example", "func()", "func")
- fmt.Println()
- cs := C.CString("Hello from stdio\n")
- C.myprint(cs)
- C.free(unsafe.Pointer(cs))
-}
-
-func _() {
- Example() //@godef("ample", funccgoexample),complete("ample", funccgoexample)
-}
diff --git a/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden b/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden
deleted file mode 100644
index 0d6fbb0..0000000
--- a/gopls/internal/lsp/testdata/cgo/declarecgo.go.golden
+++ /dev/null
@@ -1,30 +0,0 @@
--- funccgoexample-definition --
-cgo/declarecgo.go:18:6-13: defined here as ```go
-func Example()
-```
-
-[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)
--- funccgoexample-definition-json --
-{
- "span": {
- "uri": "file://cgo/declarecgo.go",
- "start": {
- "line": 18,
- "column": 6,
- "offset": 151
- },
- "end": {
- "line": 18,
- "column": 13,
- "offset": 158
- }
- },
- "description": "```go\nfunc Example()\n```\n\n[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)"
-}
-
--- funccgoexample-hoverdef --
-```go
-func Example()
-```
-
-[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)
diff --git a/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go b/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go
deleted file mode 100644
index a05c012..0000000
--- a/gopls/internal/lsp/testdata/cgo/declarecgo_nocgo.go
+++ /dev/null
@@ -1,6 +0,0 @@
-//+build !cgo
-
-package cgo
-
-// Set a dummy marker to keep the test framework happy. The tests should be skipped.
-var _ = "Example" //@mark(funccgoexample, "Example"),godef("ample", funccgoexample),complete("ample", funccgoexample)
diff --git a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden
deleted file mode 100644
index 03fc224..0000000
--- a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.golden
+++ /dev/null
@@ -1,30 +0,0 @@
--- funccgoexample-definition --
-cgo/declarecgo.go:18:6-13: defined here as ```go
-func cgo.Example()
-```
-
-[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)
--- funccgoexample-definition-json --
-{
- "span": {
- "uri": "file://cgo/declarecgo.go",
- "start": {
- "line": 18,
- "column": 6,
- "offset": 151
- },
- "end": {
- "line": 18,
- "column": 13,
- "offset": 158
- }
- },
- "description": "```go\nfunc cgo.Example()\n```\n\n[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)"
-}
-
--- funccgoexample-hoverdef --
-```go
-func cgo.Example()
-```
-
-[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/cgo#Example)
diff --git a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in b/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in
deleted file mode 100644
index 414a739..0000000
--- a/gopls/internal/lsp/testdata/cgoimport/usecgo.go.in
+++ /dev/null
@@ -1,9 +0,0 @@
-package cgoimport
-
-import (
- "golang.org/lsptests/cgo"
-)
-
-func _() {
- cgo.Example() //@godef("ample", funccgoexample),complete("ample", funccgoexample)
-}
diff --git a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go
index 8d4b15b..e25b00c 100644
--- a/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go
+++ b/gopls/internal/lsp/testdata/danglingstmt/dangling_selector_2.go
@@ -1,8 +1,10 @@
package danglingstmt
-import "golang.org/lsptests/foo"
+// TODO: re-enable this test, which was broken when the foo package was removed.
+// (we can replicate the relevant definitions in the new marker test)
+// import "golang.org/lsptests/foo"
func _() {
- foo. //@rank(" //", Foo)
- var _ = []string{foo.} //@rank("}", Foo)
+ foo. // rank(" //", Foo)
+ var _ = []string{foo.} // rank("}", Foo)
}
diff --git a/gopls/internal/lsp/testdata/foo/foo.go b/gopls/internal/lsp/testdata/foo/foo.go
deleted file mode 100644
index 490ff2e..0000000
--- a/gopls/internal/lsp/testdata/foo/foo.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package foo //@mark(PackageFoo, "foo"),item(PackageFoo, "foo", "\"golang.org/lsptests/foo\"", "package")
-
-type StructFoo struct { //@item(StructFoo, "StructFoo", "struct{...}", "struct")
- Value int //@item(Value, "Value", "int", "field")
-}
-
-// Pre-set this marker, as we don't have a "source" for it in this package.
-/* Error() */ //@item(Error, "Error", "func() string", "method")
-
-func Foo() { //@item(Foo, "Foo", "func()", "func")
- var err error
- err.Error() //@complete("E", Error)
-}
-
-func _() {
- var sFoo StructFoo //@complete("t", StructFoo)
- if x := sFoo; x.Value == 1 { //@complete("V", Value),typdef("sFoo", StructFoo)
- return
- }
-}
-
-func _() {
- shadowed := 123
- {
- shadowed := "hi" //@item(shadowed, "shadowed", "string", "var")
- sha //@complete("a", shadowed)
- }
-}
-
-type IntFoo int //@item(IntFoo, "IntFoo", "int", "type")
diff --git a/gopls/internal/lsp/testdata/godef/a/a_x_test.go b/gopls/internal/lsp/testdata/godef/a/a_x_test.go
deleted file mode 100644
index f166f05..0000000
--- a/gopls/internal/lsp/testdata/godef/a/a_x_test.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package a_test
-
-import (
- "testing"
-)
-
-func TestA2(t *testing.T) { //@TestA2,godef(TestA2, TestA2)
- Nonexistant() //@diag("Nonexistant", "compiler", "(undeclared name|undefined): Nonexistant", "error")
-}
diff --git a/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden b/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden
deleted file mode 100644
index 2e30647..0000000
--- a/gopls/internal/lsp/testdata/godef/a/a_x_test.go.golden
+++ /dev/null
@@ -1,26 +0,0 @@
--- TestA2-definition --
-godef/a/a_x_test.go:7:6-12: defined here as ```go
-func TestA2(t *testing.T)
-```
--- TestA2-definition-json --
-{
- "span": {
- "uri": "file://godef/a/a_x_test.go",
- "start": {
- "line": 7,
- "column": 6,
- "offset": 44
- },
- "end": {
- "line": 7,
- "column": 12,
- "offset": 50
- }
- },
- "description": "```go\nfunc TestA2(t *testing.T)\n```"
-}
-
--- TestA2-hoverdef --
-```go
-func TestA2(t *testing.T)
-```
diff --git a/gopls/internal/lsp/testdata/godef/a/d.go b/gopls/internal/lsp/testdata/godef/a/d.go
deleted file mode 100644
index a1d17ad..0000000
--- a/gopls/internal/lsp/testdata/godef/a/d.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package a //@mark(a, "a "),hoverdef("a ", a)
-
-import "fmt"
-
-type Thing struct { //@Thing
- Member string //@Member
-}
-
-var Other Thing //@Other
-
-func Things(val []string) []Thing { //@Things
- return nil
-}
-
-func (t Thing) Method(i int) string { //@Method
- return t.Member
-}
-
-func (t Thing) Method3() {
-}
-
-func (t *Thing) Method2(i int, j int) (error, string) {
- return nil, t.Member
-}
-
-func (t *Thing) private() {
-}
-
-func useThings() {
- t := Thing{ //@mark(aStructType, "ing")
- Member: "string", //@mark(fMember, "ember")
- }
- fmt.Print(t.Member) //@mark(aMember, "ember")
- fmt.Print(Other) //@mark(aVar, "ther")
- Things() //@mark(aFunc, "ings")
- t.Method() //@mark(aMethod, "eth")
-}
-
-type NextThing struct { //@NextThing
- Thing
- Value int
-}
-
-func (n NextThing) another() string {
- return n.Member
-}
-
-// Shadows Thing.Method3
-func (n *NextThing) Method3() int {
- return n.Value
-}
-
-var nextThing NextThing //@hoverdef("NextThing", NextThing)
-
-/*@
-godef(aStructType, Thing)
-godef(aMember, Member)
-godef(aVar, Other)
-godef(aFunc, Things)
-godef(aMethod, Method)
-godef(fMember, Member)
-godef(Member, Member)
-
-//param
-//package name
-//const
-//anon field
-
-*/
diff --git a/gopls/internal/lsp/testdata/godef/a/d.go.golden b/gopls/internal/lsp/testdata/godef/a/d.go.golden
deleted file mode 100644
index ee68775..0000000
--- a/gopls/internal/lsp/testdata/godef/a/d.go.golden
+++ /dev/null
@@ -1,191 +0,0 @@
--- Member-definition --
-godef/a/d.go:6:2-8: defined here as ```go
-field Member string
-```
-
-@Member
-
-
-[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)
--- Member-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 6,
- "column": 2,
- "offset": 90
- },
- "end": {
- "line": 6,
- "column": 8,
- "offset": 96
- }
- },
- "description": "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)"
-}
-
--- Member-hoverdef --
-```go
-field Member string
-```
-
-@Member
-
-
-[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)
--- Method-definition --
-godef/a/d.go:15:16-22: defined here as ```go
-func (Thing).Method(i int) string
-```
-
-[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method)
--- Method-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 15,
- "column": 16,
- "offset": 219
- },
- "end": {
- "line": 15,
- "column": 22,
- "offset": 225
- }
- },
- "description": "```go\nfunc (Thing).Method(i int) string\n```\n\n[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method)"
-}
-
--- Method-hoverdef --
-```go
-func (Thing).Method(i int) string
-```
-
-[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Method)
--- NextThing-hoverdef --
-```go
-type NextThing struct {
- Thing
- Value int
-}
-
-func (*NextThing).Method3() int
-func (NextThing).another() string
-```
-
-[`a.NextThing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#NextThing)
--- Other-definition --
-godef/a/d.go:9:5-10: defined here as ```go
-var Other Thing
-```
-
-@Other
-
-
-[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)
--- Other-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 9,
- "column": 5,
- "offset": 121
- },
- "end": {
- "line": 9,
- "column": 10,
- "offset": 126
- }
- },
- "description": "```go\nvar Other Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)"
-}
-
--- Other-hoverdef --
-```go
-var Other Thing
-```
-
-@Other
-
-
-[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)
--- Thing-definition --
-godef/a/d.go:5:6-11: defined here as ```go
-type Thing struct {
- Member string //@Member
-}
-
-func (Thing).Method(i int) string
-func (*Thing).Method2(i int, j int) (error, string)
-func (Thing).Method3()
-func (*Thing).private()
-```
-
-[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)
--- Thing-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 5,
- "column": 6,
- "offset": 65
- },
- "end": {
- "line": 5,
- "column": 11,
- "offset": 70
- }
- },
- "description": "```go\ntype Thing struct {\n\tMember string //@Member\n}\n\nfunc (Thing).Method(i int) string\nfunc (*Thing).Method2(i int, j int) (error, string)\nfunc (Thing).Method3()\nfunc (*Thing).private()\n```\n\n[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)"
-}
-
--- Thing-hoverdef --
-```go
-type Thing struct {
- Member string //@Member
-}
-
-func (Thing).Method(i int) string
-func (*Thing).Method2(i int, j int) (error, string)
-func (Thing).Method3()
-func (*Thing).private()
-```
-
-[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)
--- Things-definition --
-godef/a/d.go:11:6-12: defined here as ```go
-func Things(val []string) []Thing
-```
-
-[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)
--- Things-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 11,
- "column": 6,
- "offset": 148
- },
- "end": {
- "line": 11,
- "column": 12,
- "offset": 154
- }
- },
- "description": "```go\nfunc Things(val []string) []Thing\n```\n\n[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)"
-}
-
--- Things-hoverdef --
-```go
-func Things(val []string) []Thing
-```
-
-[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)
--- a-hoverdef --
-Package a is a package for testing go to definition.
-
diff --git a/gopls/internal/lsp/testdata/godef/a/f.go b/gopls/internal/lsp/testdata/godef/a/f.go
deleted file mode 100644
index 10f8826..0000000
--- a/gopls/internal/lsp/testdata/godef/a/f.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Package a is a package for testing go to definition.
-package a
-
-import "fmt"
-
-func TypeStuff() { //@Stuff
- var x string
-
- switch y := interface{}(x).(type) { //@mark(switchY, "y"),godef("y", switchY)
- case int: //@mark(intY, "int")
- fmt.Printf("%v", y) //@hoverdef("y", intY)
- case string: //@mark(stringY, "string")
- fmt.Printf("%v", y) //@hoverdef("y", stringY)
- }
-
-}
diff --git a/gopls/internal/lsp/testdata/godef/a/f.go.golden b/gopls/internal/lsp/testdata/godef/a/f.go.golden
deleted file mode 100644
index a084356..0000000
--- a/gopls/internal/lsp/testdata/godef/a/f.go.golden
+++ /dev/null
@@ -1,34 +0,0 @@
--- intY-hoverdef --
-```go
-var y int
-```
--- stringY-hoverdef --
-```go
-var y string
-```
--- switchY-definition --
-godef/a/f.go:8:9-10: defined here as ```go
-var y interface{}
-```
--- switchY-definition-json --
-{
- "span": {
- "uri": "file://godef/a/f.go",
- "start": {
- "line": 8,
- "column": 9,
- "offset": 76
- },
- "end": {
- "line": 8,
- "column": 10,
- "offset": 77
- }
- },
- "description": "```go\nvar y interface{}\n```"
-}
-
--- switchY-hoverdef --
-```go
-var y interface{}
-```
diff --git a/gopls/internal/lsp/testdata/godef/a/h.go b/gopls/internal/lsp/testdata/godef/a/h.go
deleted file mode 100644
index 5a5dcc6..0000000
--- a/gopls/internal/lsp/testdata/godef/a/h.go
+++ /dev/null
@@ -1,147 +0,0 @@
-package a
-
-func _() {
- type s struct {
- nested struct {
- // nested number
- number int64 //@mark(nestedNumber, "number")
- }
- nested2 []struct {
- // nested string
- str string //@mark(nestedString, "str")
- }
- x struct {
- x struct {
- x struct {
- x struct {
- x struct {
- // nested map
- m map[string]float64 //@mark(nestedMap, "m")
- }
- }
- }
- }
- }
- }
-
- var t s
- _ = t.nested.number //@hoverdef("number", nestedNumber)
- _ = t.nested2[0].str //@hoverdef("str", nestedString)
- _ = t.x.x.x.x.x.m //@hoverdef("m", nestedMap)
-}
-
-func _() {
- var s struct {
- // a field
- a int //@mark(structA, "a")
- // b nested struct
- b struct { //@mark(structB, "b")
- // c field of nested struct
- c int //@mark(structC, "c")
- }
- }
- _ = s.a //@hoverdef("a", structA)
- _ = s.b //@hoverdef("b", structB)
- _ = s.b.c //@hoverdef("c", structC)
-
- var arr []struct {
- // d field
- d int //@mark(arrD, "d")
- // e nested struct
- e struct { //@mark(arrE, "e")
- // f field of nested struct
- f int //@mark(arrF, "f")
- }
- }
- _ = arr[0].d //@hoverdef("d", arrD)
- _ = arr[0].e //@hoverdef("e", arrE)
- _ = arr[0].e.f //@hoverdef("f", arrF)
-
- var complex []struct {
- c <-chan map[string][]struct {
- // h field
- h int //@mark(complexH, "h")
- // i nested struct
- i struct { //@mark(complexI, "i")
- // j field of nested struct
- j int //@mark(complexJ, "j")
- }
- }
- }
- _ = (<-complex[0].c)["0"][0].h //@hoverdef("h", complexH)
- _ = (<-complex[0].c)["0"][0].i //@hoverdef("i", complexI)
- _ = (<-complex[0].c)["0"][0].i.j //@hoverdef("j", complexJ)
-
- var mapWithStructKey map[struct {
- // X key field
- x []string //@mark(mapStructKeyX, "x")
- }]int
- for k := range mapWithStructKey {
- _ = k.x //@hoverdef("x", mapStructKeyX)
- }
-
- var mapWithStructKeyAndValue map[struct {
- // Y key field
- y string //@mark(mapStructKeyY, "y")
- }]struct {
- // X value field
- x string //@mark(mapStructValueX, "x")
- }
- for k, v := range mapWithStructKeyAndValue {
- // TODO: we don't show docs for y field because both map key and value
- // are structs. And in this case, we parse only map value
- _ = k.y //@hoverdef("y", mapStructKeyY)
- _ = v.x //@hoverdef("x", mapStructValueX)
- }
-
- var i []map[string]interface {
- // open method comment
- open() error //@mark(openMethod, "open")
- }
- i[0]["1"].open() //@hoverdef("open", openMethod)
-}
-
-func _() {
- test := struct {
- // test description
- desc string //@mark(testDescription, "desc")
- }{}
- _ = test.desc //@hoverdef("desc", testDescription)
-
- for _, tt := range []struct {
- // test input
- in map[string][]struct { //@mark(testInput, "in")
- // test key
- key string //@mark(testInputKey, "key")
- // test value
- value interface{} //@mark(testInputValue, "value")
- }
- result struct {
- v <-chan struct {
- // expected test value
- value int //@mark(testResultValue, "value")
- }
- }
- }{} {
- _ = tt.in //@hoverdef("in", testInput)
- _ = tt.in["0"][0].key //@hoverdef("key", testInputKey)
- _ = tt.in["0"][0].value //@hoverdef("value", testInputValue)
-
- _ = (<-tt.result.v).value //@hoverdef("value", testResultValue)
- }
-}
-
-func _() {
- getPoints := func() []struct {
- // X coord
- x int //@mark(returnX, "x")
- // Y coord
- y int //@mark(returnY, "y")
- } {
- return nil
- }
-
- r := getPoints()
- r[0].x //@hoverdef("x", returnX)
- r[0].y //@hoverdef("y", returnY)
-}
diff --git a/gopls/internal/lsp/testdata/godef/a/h.go.golden b/gopls/internal/lsp/testdata/godef/a/h.go.golden
deleted file mode 100644
index 7cef9ee..0000000
--- a/gopls/internal/lsp/testdata/godef/a/h.go.golden
+++ /dev/null
@@ -1,161 +0,0 @@
--- arrD-hoverdef --
-```go
-field d int
-```
-
-d field
-
--- arrE-hoverdef --
-```go
-field e struct{f int}
-```
-
-e nested struct
-
--- arrF-hoverdef --
-```go
-field f int
-```
-
-f field of nested struct
-
--- complexH-hoverdef --
-```go
-field h int
-```
-
-h field
-
--- complexI-hoverdef --
-```go
-field i struct{j int}
-```
-
-i nested struct
-
--- complexJ-hoverdef --
-```go
-field j int
-```
-
-j field of nested struct
-
--- mapStructKeyX-hoverdef --
-```go
-field x []string
-```
-
-X key field
-
--- mapStructKeyY-hoverdef --
-```go
-field y string
-```
-
-Y key field
-
--- mapStructValueX-hoverdef --
-```go
-field x string
-```
-
-X value field
-
--- nestedMap-hoverdef --
-```go
-field m map[string]float64
-```
-
-nested map
-
--- nestedNumber-hoverdef --
-```go
-field number int64
-```
-
-nested number
-
--- nestedString-hoverdef --
-```go
-field str string
-```
-
-nested string
-
--- openMethod-hoverdef --
-```go
-func (interface).open() error
-```
-
-open method comment
-
--- returnX-hoverdef --
-```go
-field x int
-```
-
-X coord
-
--- returnY-hoverdef --
-```go
-field y int
-```
-
-Y coord
-
--- structA-hoverdef --
-```go
-field a int
-```
-
-a field
-
--- structB-hoverdef --
-```go
-field b struct{c int}
-```
-
-b nested struct
-
--- structC-hoverdef --
-```go
-field c int
-```
-
-c field of nested struct
-
--- testDescription-hoverdef --
-```go
-field desc string
-```
-
-test description
-
--- testInput-hoverdef --
-```go
-field in map[string][]struct{key string; value interface{}}
-```
-
-test input
-
--- testInputKey-hoverdef --
-```go
-field key string
-```
-
-test key
-
--- testInputValue-hoverdef --
-```go
-field value interface{}
-```
-
-test value
-
--- testResultValue-hoverdef --
-```go
-field value int
-```
-
-expected test value
-
diff --git a/gopls/internal/lsp/testdata/godef/b/e.go b/gopls/internal/lsp/testdata/godef/b/e.go
deleted file mode 100644
index 9c81cad..0000000
--- a/gopls/internal/lsp/testdata/godef/b/e.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package b
-
-import (
- "fmt"
-
- "golang.org/lsptests/godef/a"
-)
-
-func useThings() {
- t := a.Thing{} //@mark(bStructType, "ing")
- fmt.Print(t.Member) //@mark(bMember, "ember")
- fmt.Print(a.Other) //@mark(bVar, "ther")
- a.Things() //@mark(bFunc, "ings")
-}
-
-/*@
-godef(bStructType, Thing)
-godef(bMember, Member)
-godef(bVar, Other)
-godef(bFunc, Things)
-*/
-
-func _() {
- var x interface{} //@mark(eInterface, "interface{}")
- switch x := x.(type) { //@hoverdef("x", eInterface)
- case string: //@mark(eString, "string")
- fmt.Println(x) //@hoverdef("x", eString)
- case int: //@mark(eInt, "int")
- fmt.Println(x) //@hoverdef("x", eInt)
- }
-}
diff --git a/gopls/internal/lsp/testdata/godef/b/e.go.golden b/gopls/internal/lsp/testdata/godef/b/e.go.golden
deleted file mode 100644
index 3d7d897..0000000
--- a/gopls/internal/lsp/testdata/godef/b/e.go.golden
+++ /dev/null
@@ -1,156 +0,0 @@
--- Member-definition --
-godef/a/d.go:6:2-8: defined here as ```go
-field Member string
-```
-
-@Member
-
-
-[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)
--- Member-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 6,
- "column": 2,
- "offset": 90
- },
- "end": {
- "line": 6,
- "column": 8,
- "offset": 96
- }
- },
- "description": "```go\nfield Member string\n```\n\n@Member\n\n\n[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)"
-}
-
--- Member-hoverdef --
-```go
-field Member string
-```
-
-@Member
-
-
-[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing.Member)
--- Other-definition --
-godef/a/d.go:9:5-10: defined here as ```go
-var a.Other a.Thing
-```
-
-@Other
-
-
-[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)
--- Other-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 9,
- "column": 5,
- "offset": 121
- },
- "end": {
- "line": 9,
- "column": 10,
- "offset": 126
- }
- },
- "description": "```go\nvar a.Other a.Thing\n```\n\n@Other\n\n\n[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)"
-}
-
--- Other-hoverdef --
-```go
-var a.Other a.Thing
-```
-
-@Other
-
-
-[`a.Other` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Other)
--- Thing-definition --
-godef/a/d.go:5:6-11: defined here as ```go
-type Thing struct {
- Member string //@Member
-}
-
-func (a.Thing).Method(i int) string
-func (*a.Thing).Method2(i int, j int) (error, string)
-func (a.Thing).Method3()
-```
-
-[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)
--- Thing-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 5,
- "column": 6,
- "offset": 65
- },
- "end": {
- "line": 5,
- "column": 11,
- "offset": 70
- }
- },
- "description": "```go\ntype Thing struct {\n\tMember string //@Member\n}\n\nfunc (a.Thing).Method(i int) string\nfunc (*a.Thing).Method2(i int, j int) (error, string)\nfunc (a.Thing).Method3()\n```\n\n[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)"
-}
-
--- Thing-hoverdef --
-```go
-type Thing struct {
- Member string //@Member
-}
-
-func (a.Thing).Method(i int) string
-func (*a.Thing).Method2(i int, j int) (error, string)
-func (a.Thing).Method3()
-```
-
-[`a.Thing` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Thing)
--- Things-definition --
-godef/a/d.go:11:6-12: defined here as ```go
-func a.Things(val []string) []a.Thing
-```
-
-[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)
--- Things-definition-json --
-{
- "span": {
- "uri": "file://godef/a/d.go",
- "start": {
- "line": 11,
- "column": 6,
- "offset": 148
- },
- "end": {
- "line": 11,
- "column": 12,
- "offset": 154
- }
- },
- "description": "```go\nfunc a.Things(val []string) []a.Thing\n```\n\n[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)"
-}
-
--- Things-hoverdef --
-```go
-func a.Things(val []string) []a.Thing
-```
-
-[`a.Things` on pkg.go.dev](https://pkg.go.dev/golang.org/lsptests/godef/a#Things)
--- eInt-hoverdef --
-```go
-var x int
-```
--- eInterface-hoverdef --
-```go
-var x interface{}
-```
--- eString-hoverdef --
-```go
-var x string
-```
diff --git a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden
deleted file mode 100644
index 9ce8698..0000000
--- a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.golden
+++ /dev/null
@@ -1,31 +0,0 @@
--- myUnclosedIf-definition --
-godef/broken/unclosedIf.go:7:7-19: defined here as ```go
-var myUnclosedIf string
-```
-
-@myUnclosedIf
--- myUnclosedIf-definition-json --
-{
- "span": {
- "uri": "file://godef/broken/unclosedIf.go",
- "start": {
- "line": 7,
- "column": 7,
- "offset": 68
- },
- "end": {
- "line": 7,
- "column": 19,
- "offset": 80
- }
- },
- "description": "```go\nvar myUnclosedIf string\n```\n\n@myUnclosedIf"
-}
-
--- myUnclosedIf-hoverdef --
-```go
-var myUnclosedIf string
-```
-
-@myUnclosedIf
-
diff --git a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in b/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in
deleted file mode 100644
index 0f2cf1b..0000000
--- a/gopls/internal/lsp/testdata/godef/broken/unclosedIf.go.in
+++ /dev/null
@@ -1,9 +0,0 @@
-package broken
-
-import "fmt"
-
-func unclosedIf() {
- if false {
- var myUnclosedIf string //@myUnclosedIf
- fmt.Printf("s = %v\n", myUnclosedIf) //@godef("my", myUnclosedIf)
-}
diff --git a/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in b/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in
index 2f4cbad..05ba540 100644
--- a/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in
+++ b/gopls/internal/lsp/testdata/importedcomplit/imported_complit.go.in
@@ -1,22 +1,32 @@
package importedcomplit
import (
- "golang.org/lsptests/foo"
+ // TODO(rfindley): re-enable after moving to new framework
+ // "golang.org/lsptests/foo"
- // import completions
- "fm" //@complete("\" //", fmtImport)
- "go/pars" //@complete("\" //", parserImport)
- "golang.org/lsptests/signa" //@complete("na\" //", signatureImport)
- "golang.org/lspte" //@complete("\" //", lsptestsImport)
+ // import completions (separate blocks to avoid comment alignment)
"crypto/elli" //@complete("\" //", cryptoImport)
- "golang.org/lsptests/sign" //@complete("\" //", signatureImport)
- "golang.org/lsptests/sign" //@complete("ests", lsptestsImport)
+
+ "fm" //@complete("\" //", fmtImport)
+
+ "go/pars" //@complete("\" //", parserImport)
+
namedParser "go/pars" //@complete("\" //", parserImport)
+
+ "golang.org/lspte" //@complete("\" //", lsptestsImport)
+
+ "golang.org/lsptests/sign" //@complete("\" //", signatureImport)
+
+ "golang.org/lsptests/sign" //@complete("ests", lsptestsImport)
+
+ "golang.org/lsptests/signa" //@complete("na\" //", signatureImport)
)
func _() {
var V int //@item(icVVar, "V", "int", "var")
- _ = foo.StructFoo{V} //@complete("}", Value, icVVar)
+
+ // TODO(rfindley): re-enable after moving to new framework
+ // _ = foo.StructFoo{V} // complete("}", Value, icVVar)
}
func _() {
@@ -25,14 +35,16 @@
ab int //@item(icABVar, "ab", "int", "var")
)
- _ = foo.StructFoo{a} //@complete("}", abVar, aaVar)
+ // TODO(rfindley): re-enable after moving to new framework
+ // _ = foo.StructFoo{a} // complete("}", abVar, aaVar)
var s struct {
AA string //@item(icFieldAA, "AA", "string", "field")
AB int //@item(icFieldAB, "AB", "int", "field")
}
- _ = foo.StructFoo{s.} //@complete("}", icFieldAB, icFieldAA)
+ // TODO(rfindley): re-enable after moving to new framework
+ //_ = foo.StructFoo{s.} // complete("}", icFieldAB, icFieldAA)
}
/* "fmt" */ //@item(fmtImport, "fmt", "\"fmt\"", "package")
diff --git a/gopls/internal/lsp/testdata/nodisk/empty b/gopls/internal/lsp/testdata/nodisk/empty
deleted file mode 100644
index 0c10a42..0000000
--- a/gopls/internal/lsp/testdata/nodisk/empty
+++ /dev/null
@@ -1 +0,0 @@
-an empty file so that this directory exists
\ No newline at end of file
diff --git a/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go b/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go
deleted file mode 100644
index 08aebd1..0000000
--- a/gopls/internal/lsp/testdata/nodisk/nodisk.overlay.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package nodisk
-
-import (
- "golang.org/lsptests/foo"
-)
-
-func _() {
- foo.Foo() //@complete("F", Foo, IntFoo, StructFoo)
-}
diff --git a/gopls/internal/lsp/testdata/selector/selector.go.in b/gopls/internal/lsp/testdata/selector/selector.go.in
deleted file mode 100644
index b1498a0..0000000
--- a/gopls/internal/lsp/testdata/selector/selector.go.in
+++ /dev/null
@@ -1,66 +0,0 @@
-// +build go1.11
-
-package selector
-
-import (
- "golang.org/lsptests/bar"
-)
-
-type S struct {
- B, A, C int //@item(Bf, "B", "int", "field"),item(Af, "A", "int", "field"),item(Cf, "C", "int", "field")
-}
-
-func _() {
- _ = S{}.; //@complete(";", Af, Bf, Cf)
-}
-
-type bob struct { a int } //@item(a, "a", "int", "field")
-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", "func() *george", "method")
-func (g *george) jack() *jack {}
-func (j *jack) jill() *jill {} //@item(jill, "jill", "func() *jill", "method")
-
-func _() {
- b := &bob{}
- y := b.george().
- jack();
- y.; //@complete(";", c, jill)
-}
-
-func _() {
- bar. //@complete(" /", Bar)
- x := 5
-
- var b *bob
- b. //@complete(" /", a, george)
- y, z := 5, 6
-
- b. //@complete(" /", a, george)
- y, z, a, b, c := 5, 6
-}
-
-func _() {
- bar. //@complete(" /", Bar)
- bar.Bar()
-
- bar. //@complete(" /", Bar)
- go f()
-}
-
-func _() {
- var b *bob
- if y != b. //@complete(" /", a, george)
- z := 5
-
- if z + y + 1 + b. //@complete(" /", a, george)
- r, s, t := 4, 5
-
- if y != b. //@complete(" /", a, george)
- z = 5
-
- if z + y + 1 + b. //@complete(" /", a, george)
- r = 4
-}
diff --git a/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in b/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in
deleted file mode 100644
index c6e6c0f..0000000
--- a/gopls/internal/lsp/testdata/snippets/literal_snippets.go.in
+++ /dev/null
@@ -1,233 +0,0 @@
-package snippets
-
-import (
- "bytes"
- "context"
- "go/ast"
- "net/http"
- "sort"
-
- "golang.org/lsptests/foo"
-)
-
-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})")
-}
-
-func _() {
- type namedInt []int
-
- namedInt{} //@item(litNamedSlice, "namedInt{}", "", "var")
- make(namedInt, 0) //@item(makeNamedSlice, "make(namedInt, 0)", "", "func")
-
- var namedSlice namedInt
- namedSlice = n //@snippet(" //", litNamedSlice, "namedInt{$0\\}", "namedInt{$0\\}")
- namedSlice = m //@snippet(" //", makeNamedSlice, "make(namedInt, ${1:})", "make(namedInt, ${1:0})")
-}
-
-func _() {
- make(chan int) //@item(makeChan, "make(chan int)", "", "func")
-
- var ch chan int
- ch = m //@snippet(" //", makeChan, "make(chan int)", "make(chan int)")
-}
-
-func _() {
- map[string]struct{}{} //@item(litMap, "map[string]struct{}{}", "", "var")
- make(map[string]struct{}) //@item(makeMap, "make(map[string]struct{})", "", "func")
-
- var m map[string]struct{}
- m = m //@snippet(" //", litMap, "map[string]struct{\\}{$0\\}", "map[string]struct{\\}{$0\\}")
- m = m //@snippet(" //", makeMap, "make(map[string]struct{\\})", "make(map[string]struct{\\})")
-
- struct{}{} //@item(litEmptyStruct, "struct{}{}", "", "var")
-
- m["hi"] = s //@snippet(" //", litEmptyStruct, "struct{\\}{\\}", "struct{\\}{\\}")
-}
-
-func _() {
- type myStruct struct{ i int } //@item(myStructType, "myStruct", "struct{...}", "struct")
-
- myStruct{} //@item(litStruct, "myStruct{}", "", "var")
- &myStruct{} //@item(litStructPtr, "&myStruct{}", "", "var")
-
- var ms myStruct
- ms = m //@snippet(" //", litStruct, "myStruct{$0\\}", "myStruct{$0\\}")
-
- var msPtr *myStruct
- msPtr = m //@snippet(" //", litStructPtr, "&myStruct{$0\\}", "&myStruct{$0\\}")
-
- msPtr = &m //@snippet(" //", litStruct, "myStruct{$0\\}", "myStruct{$0\\}")
-
- type myStructCopy struct { i int } //@item(myStructCopyType, "myStructCopy", "struct{...}", "struct")
-
- // Don't offer literal completion for convertible structs.
- ms = myStruct //@complete(" //", litStruct, myStructType, myStructCopyType)
-}
-
-type myImpl struct{}
-
-func (myImpl) foo() {}
-
-func (*myImpl) bar() {}
-
-type myBasicImpl string
-
-func (myBasicImpl) foo() {}
-
-func _() {
- type myIntf interface {
- foo()
- }
-
- myImpl{} //@item(litImpl, "myImpl{}", "", "var")
-
- var mi myIntf
- mi = m //@snippet(" //", litImpl, "myImpl{\\}", "myImpl{\\}")
-
- myBasicImpl() //@item(litBasicImpl, "myBasicImpl()", "string", "var")
-
- mi = m //@snippet(" //", litBasicImpl, "myBasicImpl($0)", "myBasicImpl($0)")
-
- // only satisfied by pointer to myImpl
- type myPtrIntf interface {
- bar()
- }
-
- &myImpl{} //@item(litImplPtr, "&myImpl{}", "", "var")
-
- var mpi myPtrIntf
- mpi = m //@snippet(" //", litImplPtr, "&myImpl{\\}", "&myImpl{\\}")
-}
-
-func _() {
- var s struct{ i []int } //@item(litSliceField, "i", "[]int", "field")
- var foo []int
- // no literal completions after selector
- foo = s.i //@complete(" //", litSliceField)
-}
-
-func _() {
- type myStruct struct{ i int } //@item(litMyStructType, "myStruct", "struct{...}", "struct")
- myStruct{} //@item(litMyStruct, "myStruct{}", "", "var")
-
- foo := func(s string, args ...myStruct) {}
- // Don't give literal slice candidate for variadic arg.
- // Do give literal candidates for variadic element.
- foo("", myStruct) //@complete(")", litMyStruct, litMyStructType)
-}
-
-func _() {
- Buffer{} //@item(litBuffer, "Buffer{}", "", "var")
-
- var b *bytes.Buffer
- b = bytes.Bu //@snippet(" //", litBuffer, "Buffer{\\}", "Buffer{\\}")
-}
-
-func _() {
- _ = "func(...) {}" //@item(litFunc, "func(...) {}", "", "var")
-
- sort.Slice(nil, fun) //@complete(")", litFunc),snippet(")", litFunc, "func(i, j int) bool {$0\\}", "func(i, j int) bool {$0\\}")
-
- http.HandleFunc("", f) //@snippet(")", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}", "func(${1:w} http.ResponseWriter, ${2:r} *http.Request) {$0\\}")
-
- // no literal "func" completions
- http.Handle("", fun) //@complete(")")
-
- http.HandlerFunc() //@item(handlerFunc, "http.HandlerFunc()", "", "var")
- http.Handle("", h) //@snippet(")", handlerFunc, "http.HandlerFunc($0)", "http.HandlerFunc($0)")
- http.Handle("", http.HandlerFunc()) //@snippet("))", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}", "func(${1:w} http.ResponseWriter, ${2:r} *http.Request) {$0\\}")
-
- var namedReturn func(s string) (b bool)
- namedReturn = f //@snippet(" //", litFunc, "func(s string) (b bool) {$0\\}", "func(s string) (b bool) {$0\\}")
-
- var multiReturn func() (bool, int)
- multiReturn = f //@snippet(" //", litFunc, "func() (bool, int) {$0\\}", "func() (bool, int) {$0\\}")
-
- var multiNamedReturn func() (b bool, i int)
- multiNamedReturn = f //@snippet(" //", litFunc, "func() (b bool, i int) {$0\\}", "func() (b bool, i int) {$0\\}")
-
- var duplicateParams func(myImpl, int, myImpl)
- duplicateParams = f //@snippet(" //", litFunc, "func(mi1 myImpl, i int, mi2 myImpl) {$0\\}", "func(${1:mi1} myImpl, ${2:i} int, ${3:mi2} myImpl) {$0\\}")
-
- type aliasImpl = myImpl
- var aliasParams func(aliasImpl) aliasImpl
- aliasParams = f //@snippet(" //", litFunc, "func(ai aliasImpl) aliasImpl {$0\\}", "func(${1:ai} aliasImpl) aliasImpl {$0\\}")
-
- const two = 2
- var builtinTypes func([]int, [two]bool, map[string]string, struct{ i int }, interface{ foo() }, <-chan int)
- builtinTypes = f //@snippet(" //", litFunc, "func(i1 []int, b [two]bool, m map[string]string, s struct{ i int \\}, i2 interface{ foo() \\}, c <-chan int) {$0\\}", "func(${1:i1} []int, ${2:b} [two]bool, ${3:m} map[string]string, ${4:s} struct{ i int \\}, ${5:i2} interface{ foo() \\}, ${6:c} <-chan int) {$0\\}")
-
- var _ func(ast.Node) = f //@snippet(" //", litFunc, "func(n ast.Node) {$0\\}", "func(${1:n} ast.Node) {$0\\}")
- var _ func(error) = f //@snippet(" //", litFunc, "func(err error) {$0\\}", "func(${1:err} error) {$0\\}")
- var _ func(context.Context) = f //@snippet(" //", litFunc, "func(ctx context.Context) {$0\\}", "func(${1:ctx} context.Context) {$0\\}")
-
- type context struct {}
- var _ func(context) = f //@snippet(" //", litFunc, "func(ctx context) {$0\\}", "func(${1:ctx} context) {$0\\}")
-}
-
-func _() {
- StructFoo{} //@item(litStructFoo, "StructFoo{}", "struct{...}", "struct")
-
- var sfp *foo.StructFoo
- // Don't insert the "&" before "StructFoo{}".
- sfp = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}")
-
- var sf foo.StructFoo
- sf = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}")
- sf = foo. //@snippet(" //", litStructFoo, "StructFoo{$0\\}", "StructFoo{$0\\}")
-}
-
-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)")
-
- type myInt int
- myInt() //@item(litMyInt, "myInt()", "", "var")
-
- var mi myInt
- mi = my //@snippet(" //", litMyInt, "myInt($0)", "myInt($0)")
-}
-
-func _() {
- type ptrStruct struct {
- p *ptrStruct
- }
-
- ptrStruct{} //@item(litPtrStruct, "ptrStruct{}", "", "var")
-
- ptrStruct{
- p: &ptrSt, //@rank(",", litPtrStruct)
- }
-
- &ptrStruct{} //@item(litPtrStructPtr, "&ptrStruct{}", "", "var")
-
- &ptrStruct{
- p: ptrSt, //@rank(",", litPtrStructPtr)
- }
-}
-
-func _() {
- f := func(...[]int) {}
- f() //@snippet(")", litIntSlice, "[]int{$0\\}", "[]int{$0\\}")
-}
-
-
-func _() {
- // don't complete to "untyped int()"
- []int{}[untyped] //@complete("] //")
-}
diff --git a/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in b/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in
deleted file mode 100644
index 8251a63..0000000
--- a/gopls/internal/lsp/testdata/snippets/literal_snippets118.go.in
+++ /dev/null
@@ -1,14 +0,0 @@
-// +build go1.18
-//go:build go1.18
-
-package snippets
-
-type Tree[T any] struct{}
-
-func (tree Tree[T]) Do(f func(s T)) {}
-
-func _() {
- _ = "func(...) {}" //@item(litFunc, "func(...) {}", "", "var")
- var t Tree[string]
- t.Do(fun) //@complete(")", litFunc),snippet(")", litFunc, "func(s string) {$0\\}", "func(s string) {$0\\}")
-}
diff --git a/gopls/internal/lsp/testdata/snippets/snippets.go.in b/gopls/internal/lsp/testdata/snippets/snippets.go.in
index 58150c6..79bff33 100644
--- a/gopls/internal/lsp/testdata/snippets/snippets.go.in
+++ b/gopls/internal/lsp/testdata/snippets/snippets.go.in
@@ -1,5 +1,8 @@
package snippets
+// Pre-set this marker, as we don't have a "source" for it in this package.
+/* Error() */ //@item(Error, "Error", "func() string", "method")
+
type AliasType = int //@item(sigAliasType, "AliasType", "AliasType", "type")
func foo(i int, b bool) {} //@item(snipFoo, "foo", "func(i int, b bool)", "func")
diff --git a/gopls/internal/lsp/testdata/summary.txt.golden b/gopls/internal/lsp/testdata/summary.txt.golden
index 4da0693..7059a38 100644
--- a/gopls/internal/lsp/testdata/summary.txt.golden
+++ b/gopls/internal/lsp/testdata/summary.txt.golden
@@ -1,22 +1,18 @@
-- summary --
CallHierarchyCount = 2
-CompletionsCount = 258
-CompletionSnippetCount = 115
-UnimportedCompletionsCount = 5
+CompletionsCount = 194
+CompletionSnippetCount = 74
DeepCompletionsCount = 5
FuzzyCompletionsCount = 8
-RankedCompletionsCount = 174
+RankedCompletionsCount = 166
CaseSensitiveCompletionsCount = 4
-DiagnosticsCount = 3
SemanticTokenCount = 3
SuggestedFixCount = 80
MethodExtractionCount = 8
-DefinitionsCount = 46
-TypeDefinitionsCount = 18
InlayHintsCount = 5
RenamesCount = 48
PrepareRenamesCount = 7
-SignaturesCount = 33
+SignaturesCount = 32
LinksCount = 7
SelectionRangesCount = 3
diff --git a/gopls/internal/lsp/testdata/testy/testy.go b/gopls/internal/lsp/testdata/testy/testy.go
deleted file mode 100644
index 9f74091..0000000
--- a/gopls/internal/lsp/testdata/testy/testy.go
+++ /dev/null
@@ -1,5 +0,0 @@
-package testy
-
-func a() { //@item(funcA, "a", "func()", "func")
- //@complete("", funcA)
-}
diff --git a/gopls/internal/lsp/testdata/testy/testy_test.go b/gopls/internal/lsp/testdata/testy/testy_test.go
deleted file mode 100644
index 793aacf..0000000
--- a/gopls/internal/lsp/testdata/testy/testy_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package testy
-
-import (
- "testing"
-
- sig "golang.org/lsptests/signature"
- "golang.org/lsptests/snippets"
-)
-
-func TestSomething(t *testing.T) { //@item(TestSomething, "TestSomething(t *testing.T)", "", "func")
- var x int //@mark(testyX, "x"),diag("x", "compiler", "x declared (and|but) not used", "error")
- a() //@mark(testyA, "a")
-}
-
-func _() {
- _ = snippets.X(nil) //@signature("nil", "X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias", 0)
- var _ sig.Alias
-}
diff --git a/gopls/internal/lsp/testdata/testy/testy_test.go.golden b/gopls/internal/lsp/testdata/testy/testy_test.go.golden
deleted file mode 100644
index cafc380..0000000
--- a/gopls/internal/lsp/testdata/testy/testy_test.go.golden
+++ /dev/null
@@ -1,3 +0,0 @@
--- X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias-signature --
-X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias
-
diff --git a/gopls/internal/lsp/testdata/typdef/typdef.go b/gopls/internal/lsp/testdata/typdef/typdef.go
deleted file mode 100644
index bd2ea4b..0000000
--- a/gopls/internal/lsp/testdata/typdef/typdef.go
+++ /dev/null
@@ -1,65 +0,0 @@
-package typdef
-
-type Struct struct { //@item(Struct, "Struct", "struct{...}", "struct")
- Field string
-}
-
-type Int int //@item(Int, "Int", "int", "type")
-
-func _() {
- var (
- value Struct
- point *Struct
- )
- _ = value //@typdef("value", Struct)
- _ = point //@typdef("point", Struct)
-
- var (
- array [3]Struct
- slice []Struct
- ch chan Struct
- complex [3]chan *[5][]Int
- )
- _ = array //@typdef("array", Struct)
- _ = slice //@typdef("slice", Struct)
- _ = ch //@typdef("ch", Struct)
- _ = complex //@typdef("complex", Int)
-
- var s struct {
- x struct {
- xx struct {
- field1 []Struct
- field2 []Int
- }
- }
- }
- s.x.xx.field1 //@typdef("field1", Struct)
- s.x.xx.field2 //@typdef("field2", Int)
-}
-
-func F1() Int { return 0 }
-func F2() (Int, float64) { return 0, 0 }
-func F3() (Struct, int, bool, error) { return Struct{}, 0, false, nil }
-func F4() (**int, Int, bool, *error) { return nil, Struct{}, false, nil }
-func F5() (int, float64, error, Struct) { return 0, 0, nil, Struct{} }
-func F6() (int, float64, ***Struct, error) { return 0, 0, nil, nil }
-
-func _() {
- F1() //@typdef("F1", Int)
- F2() //@typdef("F2", Int)
- F3() //@typdef("F3", Struct)
- F4() //@typdef("F4", Int)
- F5() //@typdef("F5", Struct)
- F6() //@typdef("F6", Struct)
-
- f := func() Int { return 0 }
- f() //@typdef("f", Int)
-}
-
-// https://github.com/golang/go/issues/38589#issuecomment-620350922
-func _() {
- type myFunc func(int) Int //@item(myFunc, "myFunc", "func", "type")
-
- var foo myFunc
- bar := foo() //@typdef("foo", myFunc)
-}
diff --git a/gopls/internal/lsp/testdata/unimported/export_test.go b/gopls/internal/lsp/testdata/unimported/export_test.go
deleted file mode 100644
index 707768e..0000000
--- a/gopls/internal/lsp/testdata/unimported/export_test.go
+++ /dev/null
@@ -1,3 +0,0 @@
-package unimported
-
-var TestExport int //@item(testexport, "TestExport", "var (from \"golang.org/lsptests/unimported\")", "var")
diff --git a/gopls/internal/lsp/testdata/unimported/unimported.go.in b/gopls/internal/lsp/testdata/unimported/unimported.go.in
deleted file mode 100644
index 74d51ff..0000000
--- a/gopls/internal/lsp/testdata/unimported/unimported.go.in
+++ /dev/null
@@ -1,23 +0,0 @@
-package unimported
-
-func _() {
- http //@unimported("p", nethttp)
- // container/ring is extremely unlikely to be imported by anything, so shouldn't have type information.
- ring.Ring //@unimported("Ring", ringring)
- signature.Foo //@unimported("Foo", signaturefoo)
-
- context.Bac //@unimported(" //", contextBackground)
-}
-
-// Create markers for unimported std lib packages. Only for use by this test.
-/* http */ //@item(nethttp, "http", "\"net/http\"", "package")
-
-/* ring.Ring */ //@item(ringring, "Ring", "(from \"container/ring\")", "var")
-
-/* signature.Foo */ //@item(signaturefoo, "Foo", "func (from \"golang.org/lsptests/signature\")", "func")
-
-/* context.Background */ //@item(contextBackground, "Background", "func (from \"context\")", "func")
-
-// Now that we no longer type-check imported completions,
-// we don't expect the context.Background().Err method (see golang/go#58663).
-/* context.Background().Err */ //@item(contextBackgroundErr, "Background().Err", "func (from \"context\")", "method")
diff --git a/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go b/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go
deleted file mode 100644
index 554c426..0000000
--- a/gopls/internal/lsp/testdata/unimported/unimported_cand_type.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package unimported
-
-import (
- _ "context"
-
- "golang.org/lsptests/baz"
- _ "golang.org/lsptests/signature" // provide type information for unimported completions in the other file
-)
-
-func _() {
- foo.StructFoo{} //@item(litFooStructFoo, "foo.StructFoo{}", "struct{...}", "struct")
-
- // We get the literal completion for "foo.StructFoo{}" even though we haven't
- // imported "foo" yet.
- baz.FooStruct = f //@snippet(" //", litFooStructFoo, "foo.StructFoo{$0\\}", "foo.StructFoo{$0\\}")
-}
diff --git a/gopls/internal/lsp/testdata/unimported/x_test.go b/gopls/internal/lsp/testdata/unimported/x_test.go
deleted file mode 100644
index 681dcb2..0000000
--- a/gopls/internal/lsp/testdata/unimported/x_test.go
+++ /dev/null
@@ -1,9 +0,0 @@
-package unimported_test
-
-import (
- "testing"
-)
-
-func TestSomething(t *testing.T) {
- _ = unimported.TestExport //@unimported("TestExport", testexport)
-}
diff --git a/gopls/internal/lsp/tests/tests.go b/gopls/internal/lsp/tests/tests.go
index 2a0bda3..5b7074f 100644
--- a/gopls/internal/lsp/tests/tests.go
+++ b/gopls/internal/lsp/tests/tests.go
@@ -55,11 +55,9 @@
// These type names apparently avoid the need to repeat the
// type in the field name and the make() expression.
type CallHierarchy = map[span.Span]*CallHierarchyResult
-type Diagnostics = map[span.URI][]*source.Diagnostic
type CompletionItems = map[token.Pos]*completion.CompletionItem
type Completions = map[span.Span][]Completion
type CompletionSnippets = map[span.Span][]CompletionSnippet
-type UnimportedCompletions = map[span.Span][]Completion
type DeepCompletions = map[span.Span][]Completion
type FuzzyCompletions = map[span.Span][]Completion
type CaseSensitiveCompletions = map[span.Span][]Completion
@@ -67,7 +65,6 @@
type SemanticTokens = []span.Span
type SuggestedFixes = map[span.Span][]SuggestedFix
type MethodExtractions = map[span.Span]span.Span
-type Definitions = map[span.Span]Definition
type Renames = map[span.Span]string
type PrepareRenames = map[span.Span]*source.PrepareItem
type InlayHints = []span.Span
@@ -80,11 +77,9 @@
Config packages.Config
Exported *packagestest.Exported
CallHierarchy CallHierarchy
- Diagnostics Diagnostics
CompletionItems CompletionItems
Completions Completions
CompletionSnippets CompletionSnippets
- UnimportedCompletions UnimportedCompletions
DeepCompletions DeepCompletions
FuzzyCompletions FuzzyCompletions
CaseSensitiveCompletions CaseSensitiveCompletions
@@ -92,7 +87,6 @@
SemanticTokens SemanticTokens
SuggestedFixes SuggestedFixes
MethodExtractions MethodExtractions
- Definitions Definitions
Renames Renames
InlayHints InlayHints
PrepareRenames PrepareRenames
@@ -120,10 +114,8 @@
// we can abolish the interface now.
type Tests interface {
CallHierarchy(*testing.T, span.Span, *CallHierarchyResult)
- Diagnostics(*testing.T, span.URI, []*source.Diagnostic)
Completion(*testing.T, span.Span, Completion, CompletionItems)
CompletionSnippet(*testing.T, span.Span, CompletionSnippet, bool, CompletionItems)
- UnimportedCompletion(*testing.T, span.Span, Completion, CompletionItems)
DeepCompletion(*testing.T, span.Span, Completion, CompletionItems)
FuzzyCompletion(*testing.T, span.Span, Completion, CompletionItems)
CaseSensitiveCompletion(*testing.T, span.Span, Completion, CompletionItems)
@@ -131,7 +123,6 @@
SemanticTokens(*testing.T, span.Span)
SuggestedFix(*testing.T, span.Span, []SuggestedFix, int)
MethodExtraction(*testing.T, span.Span, span.Span)
- Definition(*testing.T, span.Span, Definition)
InlayHints(*testing.T, span.Span)
Rename(*testing.T, span.Span, string)
PrepareRename(*testing.T, span.Span, *source.PrepareItem)
@@ -141,22 +132,12 @@
SelectionRanges(*testing.T, span.Span)
}
-type Definition struct {
- Name string
- IsType bool
- OnlyHover bool
- Src, Def span.Span
-}
-
type CompletionTestType int
const (
// Default runs the standard completion tests.
CompletionDefault = CompletionTestType(iota)
- // Unimported tests the autocompletion of unimported packages.
- CompletionUnimported
-
// Deep tests deep completion.
CompletionDeep
@@ -221,7 +202,6 @@
source.Work: {},
source.Tmpl: {},
}
- o.HoverKind = source.SynopsisDocumentation
o.InsertTextFormat = protocol.SnippetTextFormat
o.CompletionBudget = time.Minute
o.HierarchicalDocumentSymbolSupport = true
@@ -255,16 +235,13 @@
func load(t testing.TB, mode string, dir string) *Data {
datum := &Data{
CallHierarchy: make(CallHierarchy),
- Diagnostics: make(Diagnostics),
CompletionItems: make(CompletionItems),
Completions: make(Completions),
CompletionSnippets: make(CompletionSnippets),
- UnimportedCompletions: make(UnimportedCompletions),
DeepCompletions: make(DeepCompletions),
FuzzyCompletions: make(FuzzyCompletions),
RankCompletions: make(RankCompletions),
CaseSensitiveCompletions: make(CaseSensitiveCompletions),
- Definitions: make(Definitions),
Renames: make(Renames),
PrepareRenames: make(PrepareRenames),
SuggestedFixes: make(SuggestedFixes),
@@ -404,19 +381,14 @@
// Collect any data that needs to be used by subsequent tests.
if err := datum.Exported.Expect(map[string]interface{}{
- "diag": datum.collectDiagnostics,
"item": datum.collectCompletionItems,
"complete": datum.collectCompletions(CompletionDefault),
- "unimported": datum.collectCompletions(CompletionUnimported),
"deep": datum.collectCompletions(CompletionDeep),
"fuzzy": datum.collectCompletions(CompletionFuzzy),
"casesensitive": datum.collectCompletions(CompletionCaseSensitive),
"rank": datum.collectCompletions(CompletionRank),
"snippet": datum.collectCompletionSnippets,
"semantic": datum.collectSemanticTokens,
- "godef": datum.collectDefinitions,
- "typdef": datum.collectTypeDefinitions,
- "hoverdef": datum.collectHoverDefinitions,
"inlayHint": datum.collectInlayHints,
"rename": datum.collectRenames,
"prepare": datum.collectPrepareRenames,
@@ -432,13 +404,6 @@
t.Fatal(err)
}
- // Collect names for the entries that require golden files.
- if err := datum.Exported.Expect(map[string]interface{}{
- "godef": datum.collectDefinitionNames,
- "hoverdef": datum.collectDefinitionNames,
- }); err != nil {
- t.Fatal(err)
- }
if mode == "MultiModule" {
if err := moveFile(filepath.Join(datum.Config.Dir, "go.mod"), filepath.Join(datum.Config.Dir, "testmodule/go.mod")); err != nil {
t.Fatal(err)
@@ -540,11 +505,6 @@
}
})
- t.Run("UnimportedCompletion", func(t *testing.T) {
- t.Helper()
- eachCompletion(t, data.UnimportedCompletions, tests.UnimportedCompletion)
- })
-
t.Run("DeepCompletion", func(t *testing.T) {
t.Helper()
eachCompletion(t, data.DeepCompletions, tests.DeepCompletion)
@@ -565,20 +525,6 @@
eachCompletion(t, data.RankCompletions, tests.RankCompletion)
})
- t.Run("Diagnostics", func(t *testing.T) {
- t.Helper()
- for uri, want := range data.Diagnostics {
- // Check if we should skip this URI if the -modfile flag is not available.
- if shouldSkip(data, uri) {
- continue
- }
- t.Run(uriName(uri), func(t *testing.T) {
- t.Helper()
- tests.Diagnostics(t, uri, want)
- })
- }
- })
-
t.Run("SemanticTokens", func(t *testing.T) {
t.Helper()
for _, spn := range data.SemanticTokens {
@@ -617,19 +563,6 @@
}
})
- t.Run("Definition", func(t *testing.T) {
- t.Helper()
- for spn, d := range data.Definitions {
- t.Run(SpanName(spn), func(t *testing.T) {
- t.Helper()
- if strings.Contains(t.Name(), "cgo") {
- testenv.NeedsTool(t, "cgo")
- }
- tests.Definition(t, spn, d)
- })
- }
- })
-
t.Run("InlayHints", func(t *testing.T) {
t.Helper()
for _, src := range data.InlayHints {
@@ -727,23 +660,10 @@
func checkData(t *testing.T, data *Data) {
buf := &bytes.Buffer{}
- diagnosticsCount := 0
- for _, want := range data.Diagnostics {
- diagnosticsCount += len(want)
- }
linksCount := 0
for _, want := range data.Links {
linksCount += len(want)
}
- definitionCount := 0
- typeDefinitionCount := 0
- for _, d := range data.Definitions {
- if d.IsType {
- typeDefinitionCount++
- } else {
- definitionCount++
- }
- }
snippetCount := 0
for _, want := range data.CompletionSnippets {
@@ -760,17 +680,13 @@
fmt.Fprintf(buf, "CallHierarchyCount = %v\n", len(data.CallHierarchy))
fmt.Fprintf(buf, "CompletionsCount = %v\n", countCompletions(data.Completions))
fmt.Fprintf(buf, "CompletionSnippetCount = %v\n", snippetCount)
- fmt.Fprintf(buf, "UnimportedCompletionsCount = %v\n", countCompletions(data.UnimportedCompletions))
fmt.Fprintf(buf, "DeepCompletionsCount = %v\n", countCompletions(data.DeepCompletions))
fmt.Fprintf(buf, "FuzzyCompletionsCount = %v\n", countCompletions(data.FuzzyCompletions))
fmt.Fprintf(buf, "RankedCompletionsCount = %v\n", countCompletions(data.RankCompletions))
fmt.Fprintf(buf, "CaseSensitiveCompletionsCount = %v\n", countCompletions(data.CaseSensitiveCompletions))
- fmt.Fprintf(buf, "DiagnosticsCount = %v\n", diagnosticsCount)
fmt.Fprintf(buf, "SemanticTokenCount = %v\n", len(data.SemanticTokens))
fmt.Fprintf(buf, "SuggestedFixCount = %v\n", len(data.SuggestedFixes))
fmt.Fprintf(buf, "MethodExtractionCount = %v\n", len(data.MethodExtractions))
- fmt.Fprintf(buf, "DefinitionsCount = %v\n", definitionCount)
- fmt.Fprintf(buf, "TypeDefinitionsCount = %v\n", typeDefinitionCount)
fmt.Fprintf(buf, "InlayHintsCount = %v\n", len(data.InlayHints))
fmt.Fprintf(buf, "RenamesCount = %v\n", len(data.Renames))
fmt.Fprintf(buf, "PrepareRenamesCount = %v\n", len(data.PrepareRenames))
@@ -857,27 +773,6 @@
return file.Data[:len(file.Data)-1] // drop the trailing \n
}
-func (data *Data) collectDiagnostics(spn span.Span, msgSource, msgPattern, msgSeverity string) {
- severity := protocol.SeverityError
- switch msgSeverity {
- case "error":
- severity = protocol.SeverityError
- case "warning":
- severity = protocol.SeverityWarning
- case "hint":
- severity = protocol.SeverityHint
- case "information":
- severity = protocol.SeverityInformation
- }
-
- data.Diagnostics[spn.URI()] = append(data.Diagnostics[spn.URI()], &source.Diagnostic{
- Range: data.mustRange(spn),
- Severity: severity,
- Source: source.DiagnosticSource(msgSource),
- Message: msgPattern,
- })
-}
-
func (data *Data) collectCompletions(typ CompletionTestType) func(span.Span, []token.Pos) {
result := func(m map[span.Span][]Completion, src span.Span, expected []token.Pos) {
m[src] = append(m[src], Completion{
@@ -889,10 +784,6 @@
return func(src span.Span, expected []token.Pos) {
result(data.DeepCompletions, src, expected)
}
- case CompletionUnimported:
- return func(src span.Span, expected []token.Pos) {
- result(data.UnimportedCompletions, src, expected)
- }
case CompletionFuzzy:
return func(src span.Span, expected []token.Pos) {
result(data.FuzzyCompletions, src, expected)
@@ -943,13 +834,6 @@
}
}
-func (data *Data) collectDefinitions(src, target span.Span) {
- data.Definitions[src] = Definition{
- Src: src,
- Def: target,
- }
-}
-
func (data *Data) collectSelectionRanges(spn span.Span) {
data.SelectionRanges = append(data.SelectionRanges, spn)
}
@@ -988,28 +872,6 @@
}
}
-func (data *Data) collectHoverDefinitions(src, target span.Span) {
- data.Definitions[src] = Definition{
- Src: src,
- Def: target,
- OnlyHover: true,
- }
-}
-
-func (data *Data) collectTypeDefinitions(src, target span.Span) {
- data.Definitions[src] = Definition{
- Src: src,
- Def: target,
- IsType: true,
- }
-}
-
-func (data *Data) collectDefinitionNames(src span.Span, name string) {
- d := data.Definitions[src]
- d.Name = name
- data.Definitions[src] = d
-}
-
func (data *Data) collectInlayHints(src span.Span) {
data.InlayHints = append(data.InlayHints, src)
}
diff --git a/gopls/internal/lsp/tests/util.go b/gopls/internal/lsp/tests/util.go
index 67b9390..b9a21fe 100644
--- a/gopls/internal/lsp/tests/util.go
+++ b/gopls/internal/lsp/tests/util.go
@@ -8,17 +8,13 @@
"bytes"
"fmt"
"go/token"
- "path"
- "regexp"
"sort"
"strconv"
"strings"
- "testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"golang.org/x/tools/gopls/internal/lsp/protocol"
- "golang.org/x/tools/gopls/internal/lsp/source"
"golang.org/x/tools/gopls/internal/lsp/source/completion"
"golang.org/x/tools/gopls/internal/lsp/tests/compare"
"golang.org/x/tools/gopls/internal/span"
@@ -92,73 +88,6 @@
return msg.String()
}
-// CompareDiagnostics reports testing errors to t when the diagnostic set got
-// does not match want.
-func CompareDiagnostics(t *testing.T, uri span.URI, want, got []*source.Diagnostic) {
- t.Helper()
- fileName := path.Base(string(uri))
-
- // Build a helper function to match an actual diagnostic to an overlapping
- // expected diagnostic (if any).
- unmatched := make([]*source.Diagnostic, len(want))
- copy(unmatched, want)
- source.SortDiagnostics(unmatched)
- match := func(g *source.Diagnostic) *source.Diagnostic {
- // Find the last expected diagnostic d for which start(d) < end(g), and
- // check to see if it overlaps.
- i := sort.Search(len(unmatched), func(i int) bool {
- d := unmatched[i]
- // See rangeOverlaps: if a range is a single point, we consider End to be
- // included in the range...
- if g.Range.Start == g.Range.End {
- return protocol.ComparePosition(d.Range.Start, g.Range.End) > 0
- }
- // ...otherwise the end position of a range is not included.
- return protocol.ComparePosition(d.Range.Start, g.Range.End) >= 0
- })
- if i == 0 {
- return nil
- }
- w := unmatched[i-1]
- if rangeOverlaps(w.Range, g.Range) {
- unmatched = append(unmatched[:i-1], unmatched[i:]...)
- return w
- }
- return nil
- }
-
- for _, g := range got {
- w := match(g)
- if w == nil {
- t.Errorf("%s:%s: unexpected diagnostic %q", fileName, g.Range, g.Message)
- continue
- }
- if match, err := regexp.MatchString(w.Message, g.Message); err != nil {
- t.Errorf("%s:%s: invalid regular expression %q: %v", fileName, w.Range.Start, w.Message, err)
- } else if !match {
- t.Errorf("%s:%s: got Message %q, want match for pattern %q", fileName, g.Range.Start, g.Message, w.Message)
- }
- if w.Severity != g.Severity {
- t.Errorf("%s:%s: got Severity %v, want %v", fileName, g.Range.Start, g.Severity, w.Severity)
- }
- if w.Source != g.Source {
- t.Errorf("%s:%s: got Source %v, want %v", fileName, g.Range.Start, g.Source, w.Source)
- }
- }
-
- for _, w := range unmatched {
- t.Errorf("%s:%s: unmatched diagnostic pattern %q", fileName, w.Range, w.Message)
- }
-}
-
-// rangeOverlaps reports whether r1 and r2 overlap.
-func rangeOverlaps(r1, r2 protocol.Range) bool {
- if inRange(r2.Start, r1) || inRange(r1.Start, r2) {
- return true
- }
- return false
-}
-
// inRange reports whether p is contained within [r.Start, r.End), or if p ==
// r.Start == r.End (special handling for the case where the range is a single
// point).
diff --git a/gopls/internal/regtest/completion/completion_test.go b/gopls/internal/regtest/completion/completion_test.go
index 4294b92..3949578 100644
--- a/gopls/internal/regtest/completion/completion_test.go
+++ b/gopls/internal/regtest/completion/completion_test.go
@@ -911,7 +911,44 @@
sort.Strings(got)
if diff := cmp.Diff(builtins, got); diff != "" {
- t.Errorf("Completion: unexpected mismatch:\n%s", diff)
+ t.Errorf("Completion: unexpected mismatch (-want +got):\n%s", diff)
+ }
+ })
+}
+
+func TestOverlayCompletion(t *testing.T) {
+ const files = `
+-- go.mod --
+module foo.test
+
+go 1.18
+
+-- foo/foo.go --
+package foo
+
+type Foo struct{}
+`
+
+ Run(t, files, func(t *testing.T, env *Env) {
+ env.CreateBuffer("nodisk/nodisk.go", `
+package nodisk
+
+import (
+ "foo.test/foo"
+)
+
+func _() {
+ foo.Foo()
+}
+`)
+ list := env.Completion(env.RegexpSearch("nodisk/nodisk.go", "foo.(Foo)"))
+ want := []string{"Foo"}
+ var got []string
+ for _, item := range list.Items {
+ got = append(got, item.Label)
+ }
+ if diff := cmp.Diff(want, got); diff != "" {
+ t.Errorf("Completion: unexpected mismatch (-want +got):\n%s", diff)
}
})
}
diff --git a/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt b/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt
new file mode 100644
index 0000000..24ac717
--- /dev/null
+++ b/gopls/internal/regtest/marker/testdata/completion/foobarbaz.txt
@@ -0,0 +1,541 @@
+This test ports some arbitrary tests from the old marker framework, that were
+*mostly* about completion.
+
+-- flags --
+-ignore_extra_diags
+-min_go=go1.20
+
+-- settings.json --
+{
+ "completeUnimported": false,
+ "deepCompletion": false,
+ "experimentalPostfixCompletions": false
+}
+
+-- go.mod --
+module foobar.test
+
+go 1.18
+
+-- foo/foo.go --
+package foo //@loc(PackageFoo, "foo"),item(PackageFooItem, "foo", "\"foobar.test/foo\"", "package")
+
+type StructFoo struct { //@loc(StructFooLoc, "StructFoo"), item(StructFoo, "StructFoo", "struct{...}", "struct")
+ Value int //@item(Value, "Value", "int", "field")
+}
+
+// Pre-set this marker, as we don't have a "source" for it in this package.
+/* Error() */ //@item(Error, "Error", "func() string", "method")
+
+func Foo() { //@item(Foo, "Foo", "func()", "func")
+ var err error
+ err.Error() //@complete("E", Error)
+}
+
+func _() {
+ var sFoo StructFoo //@complete("t", StructFoo)
+ if x := sFoo; x.Value == 1 { //@complete("V", Value), typedef("sFoo", StructFooLoc)
+ return
+ }
+}
+
+func _() {
+ shadowed := 123
+ {
+ shadowed := "hi" //@item(shadowed, "shadowed", "string", "var")
+ sha //@complete("a", shadowed), diag("sha", re"(undefined|undeclared)")
+ _ = shadowed
+ }
+}
+
+type IntFoo int //@loc(IntFooLoc, "IntFoo"), item(IntFoo, "IntFoo", "int", "type")
+
+-- bar/bar.go --
+package bar
+
+import (
+ "foobar.test/foo" //@item(foo, "foo", "\"foobar.test/foo\"", "package")
+)
+
+func helper(i foo.IntFoo) {} //@item(helper, "helper", "func(i foo.IntFoo)", "func")
+
+func _() {
+ help //@complete("l", helper)
+ _ = 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", IntFoo, StructFoo)
+ foo.() //@complete("(", Foo, IntFoo, StructFoo), diag(")", re"expected type")
+}
+
+// These items weren't present in the old marker tests (due to settings), but
+// we may as well include them.
+//@item(intConversion, "int()"), item(fooFoo, "foo.Foo")
+//@item(fooIntFoo, "foo.IntFoo"), item(fooStructFoo, "foo.StructFoo")
+
+func _() {
+ var Valentine int //@item(Valentine, "Valentine", "int", "var")
+
+ _ = foo.StructFoo{ //@diag("foo", re"unkeyed fields")
+ Valu //@complete(" //", Value)
+ }
+ _ = foo.StructFoo{ //@diag("foo", re"unkeyed fields")
+ Va //@complete("a", Value, Valentine)
+
+ }
+ _ = foo.StructFoo{
+ Value: 5, //@complete("a", Value)
+ }
+ _ = foo.StructFoo{
+ //@complete("//", Value, Valentine, intConversion, foo, helper, Bar)
+ }
+ _ = foo.StructFoo{
+ Value: Valen //@complete("le", Valentine)
+ }
+ _ = foo.StructFoo{
+ Value: //@complete(" //", Valentine, intConversion, foo, helper, Bar)
+ }
+ _ = foo.StructFoo{
+ Value: //@complete(" ", Valentine, intConversion, foo, helper, Bar)
+ }
+}
+
+-- baz/baz.go --
+package baz
+
+import (
+ "foobar.test/bar"
+
+ f "foobar.test/foo"
+)
+
+var FooStruct f.StructFoo
+
+func Baz() {
+ defer bar.Bar() //@complete("B", Bar)
+ // TODO: Test completion here.
+ defer bar.B //@diag(re"bar.B()", re"must be function call")
+ var x f.IntFoo //@complete("n", IntFoo), typedef("x", IntFooLoc)
+ bar.Bar() //@complete("B", Bar)
+}
+
+func _() {
+ bob := f.StructFoo{Value: 5}
+ if x := bob. //@complete(" //", Value)
+ switch true == false {
+ case true:
+ if x := bob. //@complete(" //", Value)
+ case false:
+ }
+ if x := bob.Va //@complete("a", Value)
+ switch true == true {
+ default:
+ }
+}
+
+-- arraytype/arraytype.go --
+package arraytype
+
+import (
+ "foobar.test/foo"
+)
+
+func _() {
+ var (
+ val string //@item(atVal, "val", "string", "var")
+ )
+
+ [] //@complete(" //", atVal, PackageFooItem)
+
+ []val //@complete(" //")
+
+ []foo.StructFoo //@complete(" //", StructFoo)
+
+ []foo.StructFoo(nil) //@complete("(", StructFoo)
+
+ []*foo.StructFoo //@complete(" //", StructFoo)
+
+ [...]foo.StructFoo //@complete(" //", StructFoo)
+
+ [2][][4]foo.StructFoo //@complete(" //", StructFoo)
+
+ []struct { f []foo.StructFoo } //@complete(" }", StructFoo)
+}
+
+func _() {
+ type myInt int //@item(atMyInt, "myInt", "int", "type")
+
+ var mark []myInt //@item(atMark, "mark", "[]myInt", "var")
+
+ var s []myInt //@item(atS, "s", "[]myInt", "var")
+ s = []m //@complete(" //", atMyInt)
+
+ var a [1]myInt
+ a = [1]m //@complete(" //", atMyInt)
+
+ var ds [][]myInt
+ ds = [][]m //@complete(" //", atMyInt)
+}
+
+func _() {
+ var b [0]byte //@item(atByte, "b", "[0]byte", "var")
+ var _ []byte = b //@snippet(" //", atByte, "b[:]")
+}
+
+-- badstmt/badstmt.go --
+package badstmt
+
+import (
+ "foobar.test/foo"
+)
+
+// (The syntax error causes suppression of diagnostics for type errors.
+// See issue #59888.)
+
+func _(x int) {
+ defer foo.F //@complete(" //", Foo, IntFoo, StructFoo)
+ defer foo.F //@complete(" //", Foo, IntFoo, StructFoo)
+}
+
+func _() {
+ switch true {
+ case true:
+ go foo.F //@complete(" //", Foo, IntFoo, StructFoo)
+ }
+}
+
+func _() {
+ defer func() {
+ foo.F //@complete(" //", Foo, IntFoo, StructFoo), snippet(" //", Foo, "Foo()")
+
+ foo. //@rank(" //", Foo)
+ }
+}
+
+-- badstmt/badstmt_2.go --
+package badstmt
+
+import (
+ "foobar.test/foo"
+)
+
+func _() {
+ defer func() { foo. } //@rank(" }", Foo)
+}
+
+-- badstmt/badstmt_3.go --
+package badstmt
+
+import (
+ "foobar.test/foo"
+)
+
+func _() {
+ go foo. //@rank(" //", Foo, IntFoo), snippet(" //", Foo, "Foo()")
+}
+
+-- badstmt/badstmt_4.go --
+package badstmt
+
+import (
+ "foobar.test/foo"
+)
+
+func _() {
+ go func() {
+ defer foo. //@rank(" //", Foo, IntFoo)
+ }
+}
+
+-- selector/selector.go --
+package selector
+
+import (
+ "foobar.test/bar"
+)
+
+type S struct {
+ B, A, C int //@item(Bf, "B", "int", "field"),item(Af, "A", "int", "field"),item(Cf, "C", "int", "field")
+}
+
+func _() {
+ _ = S{}.; //@complete(";", Af, Bf, Cf)
+}
+
+type bob struct { a int } //@item(a, "a", "int", "field")
+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", "func() *george", "method")
+func (g *george) jack() *jack {}
+func (j *jack) jill() *jill {} //@item(jill, "jill", "func() *jill", "method")
+
+func _() {
+ b := &bob{}
+ y := b.george().
+ jack();
+ y.; //@complete(";", c, jill)
+}
+
+func _() {
+ bar. //@complete(" /", Bar)
+ x := 5
+
+ var b *bob
+ b. //@complete(" /", a, george)
+ y, z := 5, 6
+
+ b. //@complete(" /", a, george)
+ y, z, a, b, c := 5, 6
+}
+
+func _() {
+ bar. //@complete(" /", Bar)
+ bar.Bar()
+
+ bar. //@complete(" /", Bar)
+ go f()
+}
+
+func _() {
+ var b *bob
+ if y != b. //@complete(" /", a, george)
+ z := 5
+
+ if z + y + 1 + b. //@complete(" /", a, george)
+ r, s, t := 4, 5
+
+ if y != b. //@complete(" /", a, george)
+ z = 5
+
+ if z + y + 1 + b. //@complete(" /", a, george)
+ r = 4
+}
+
+-- literal_snippets/literal_snippets.go --
+package literal_snippets
+
+import (
+ "bytes"
+ "context"
+ "go/ast"
+ "net/http"
+ "sort"
+
+ "golang.org/lsptests/foo"
+)
+
+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\\}")
+ var _ **[]int = in //@complete(" //")
+
+ var slice []int
+ slice = i //@snippet(" //", litIntSlice, "[]int{$0\\}")
+ slice = m //@snippet(" //", makeIntSlice, "make([]int, ${1:})")
+}
+
+func _() {
+ type namedInt []int
+
+ namedInt{} //@item(litNamedSlice, "namedInt{}", "", "var")
+ make(namedInt, 0) //@item(makeNamedSlice, "make(namedInt, 0)", "", "func")
+
+ var namedSlice namedInt
+ namedSlice = n //@snippet(" //", litNamedSlice, "namedInt{$0\\}")
+ namedSlice = m //@snippet(" //", makeNamedSlice, "make(namedInt, ${1:})")
+}
+
+func _() {
+ make(chan int) //@item(makeChan, "make(chan int)", "", "func")
+
+ var ch chan int
+ ch = m //@snippet(" //", makeChan, "make(chan int)")
+}
+
+func _() {
+ map[string]struct{}{} //@item(litMap, "map[string]struct{}{}", "", "var")
+ make(map[string]struct{}) //@item(makeMap, "make(map[string]struct{})", "", "func")
+
+ var m map[string]struct{}
+ m = m //@snippet(" //", litMap, "map[string]struct{\\}{$0\\}")
+ m = m //@snippet(" //", makeMap, "make(map[string]struct{\\})")
+
+ struct{}{} //@item(litEmptyStruct, "struct{}{}", "", "var")
+
+ m["hi"] = s //@snippet(" //", litEmptyStruct, "struct{\\}{\\}")
+}
+
+func _() {
+ type myStruct struct{ i int } //@item(myStructType, "myStruct", "struct{...}", "struct")
+
+ myStruct{} //@item(litStruct, "myStruct{}", "", "var")
+ &myStruct{} //@item(litStructPtr, "&myStruct{}", "", "var")
+
+ var ms myStruct
+ ms = m //@snippet(" //", litStruct, "myStruct{$0\\}")
+
+ var msPtr *myStruct
+ msPtr = m //@snippet(" //", litStructPtr, "&myStruct{$0\\}")
+
+ msPtr = &m //@snippet(" //", litStruct, "myStruct{$0\\}")
+
+ type myStructCopy struct { i int } //@item(myStructCopyType, "myStructCopy", "struct{...}", "struct")
+
+ // Don't offer literal completion for convertible structs.
+ ms = myStruct //@complete(" //", litStruct, myStructType, myStructCopyType)
+}
+
+type myImpl struct{}
+
+func (myImpl) foo() {}
+
+func (*myImpl) bar() {}
+
+type myBasicImpl string
+
+func (myBasicImpl) foo() {}
+
+func _() {
+ type myIntf interface {
+ foo()
+ }
+
+ myImpl{} //@item(litImpl, "myImpl{}", "", "var")
+
+ var mi myIntf
+ mi = m //@snippet(" //", litImpl, "myImpl{\\}")
+
+ myBasicImpl() //@item(litBasicImpl, "myBasicImpl()", "string", "var")
+
+ mi = m //@snippet(" //", litBasicImpl, "myBasicImpl($0)")
+
+ // only satisfied by pointer to myImpl
+ type myPtrIntf interface {
+ bar()
+ }
+
+ &myImpl{} //@item(litImplPtr, "&myImpl{}", "", "var")
+
+ var mpi myPtrIntf
+ mpi = m //@snippet(" //", litImplPtr, "&myImpl{\\}")
+}
+
+func _() {
+ var s struct{ i []int } //@item(litSliceField, "i", "[]int", "field")
+ var foo []int
+ // no literal completions after selector
+ foo = s.i //@complete(" //", litSliceField)
+}
+
+func _() {
+ type myStruct struct{ i int } //@item(litMyStructType, "myStruct", "struct{...}", "struct")
+ myStruct{} //@item(litMyStruct, "myStruct{}", "", "var")
+
+ foo := func(s string, args ...myStruct) {}
+ // Don't give literal slice candidate for variadic arg.
+ // Do give literal candidates for variadic element.
+ foo("", myStruct) //@complete(")", litMyStruct, litMyStructType)
+}
+
+func _() {
+ Buffer{} //@item(litBuffer, "Buffer{}", "", "var")
+
+ var b *bytes.Buffer
+ b = bytes.Bu //@snippet(" //", litBuffer, "Buffer{\\}")
+}
+
+func _() {
+ _ = "func(...) {}" //@item(litFunc, "func(...) {}", "", "var")
+
+ // no literal "func" completions
+ http.Handle("", fun) //@complete(")")
+
+ var namedReturn func(s string) (b bool)
+ namedReturn = f //@snippet(" //", litFunc, "func(s string) (b bool) {$0\\}")
+
+ var multiReturn func() (bool, int)
+ multiReturn = f //@snippet(" //", litFunc, "func() (bool, int) {$0\\}")
+
+ var multiNamedReturn func() (b bool, i int)
+ multiNamedReturn = f //@snippet(" //", litFunc, "func() (b bool, i int) {$0\\}")
+
+ var duplicateParams func(myImpl, int, myImpl)
+ duplicateParams = f //@snippet(" //", litFunc, "func(mi1 myImpl, i int, mi2 myImpl) {$0\\}")
+
+ type aliasImpl = myImpl
+ var aliasParams func(aliasImpl) aliasImpl
+ aliasParams = f //@snippet(" //", litFunc, "func(ai aliasImpl) aliasImpl {$0\\}")
+
+ const two = 2
+ var builtinTypes func([]int, [two]bool, map[string]string, struct{ i int }, interface{ foo() }, <-chan int)
+ builtinTypes = f //@snippet(" //", litFunc, "func(i1 []int, b [two]bool, m map[string]string, s struct{ i int \\}, i2 interface{ foo() \\}, c <-chan int) {$0\\}")
+
+ var _ func(ast.Node) = f //@snippet(" //", litFunc, "func(n ast.Node) {$0\\}")
+ var _ func(error) = f //@snippet(" //", litFunc, "func(err error) {$0\\}")
+ var _ func(context.Context) = f //@snippet(" //", litFunc, "func(ctx context.Context) {$0\\}")
+
+ type context struct {}
+ var _ func(context) = f //@snippet(" //", litFunc, "func(ctx context) {$0\\}")
+}
+
+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)")
+
+ type myInt int
+ myInt() //@item(litMyInt, "myInt()", "", "var")
+
+ var mi myInt
+ mi = my //@snippet(" //", litMyInt, "myInt($0)")
+}
+
+func _() {
+ type ptrStruct struct {
+ p *ptrStruct
+ }
+
+ ptrStruct{} //@item(litPtrStruct, "ptrStruct{}", "", "var")
+
+ ptrStruct{
+ p: &ptrSt, //@rank(",", litPtrStruct)
+ }
+
+ &ptrStruct{} //@item(litPtrStructPtr, "&ptrStruct{}", "", "var")
+
+ &ptrStruct{
+ p: ptrSt, //@rank(",", litPtrStructPtr)
+ }
+}
+
+func _() {
+ f := func(...[]int) {}
+ f() //@snippet(")", litIntSlice, "[]int{$0\\}")
+}
+
+
+func _() {
+ // don't complete to "untyped int()"
+ []int{}[untyped] //@complete("] //")
+}
+
+type Tree[T any] struct{}
+
+func (tree Tree[T]) Do(f func(s T)) {}
+
+func _() {
+ var t Tree[string]
+ t.Do(fun) //@complete(")", litFunc), snippet(")", litFunc, "func(s string) {$0\\}")
+}
diff --git a/gopls/internal/regtest/marker/testdata/completion/lit.txt b/gopls/internal/regtest/marker/testdata/completion/lit.txt
new file mode 100644
index 0000000..7224f42
--- /dev/null
+++ b/gopls/internal/regtest/marker/testdata/completion/lit.txt
@@ -0,0 +1,49 @@
+
+-- flags --
+-ignore_extra_diags
+
+-- go.mod --
+module mod.test
+
+go 1.18
+
+-- foo/foo.go --
+package foo
+
+type StructFoo struct{ F int }
+
+-- a.go --
+package a
+
+import "mod.test/foo"
+
+func _() {
+ StructFoo{} //@item(litStructFoo, "StructFoo{}", "struct{...}", "struct")
+
+ var sfp *foo.StructFoo
+ // Don't insert the "&" before "StructFoo{}".
+ sfp = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}")
+
+ var sf foo.StructFoo
+ sf = foo.Str //@snippet(" //", litStructFoo, "StructFoo{$0\\}")
+ sf = foo. //@snippet(" //", litStructFoo, "StructFoo{$0\\}")
+}
+
+-- http.go --
+package a
+
+import (
+ "net/http"
+ "sort"
+)
+
+func _() {
+ sort.Slice(nil, fun) //@snippet(")", litFunc, "func(i, j int) bool {$0\\}")
+
+ http.HandleFunc("", f) //@snippet(")", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}")
+
+ //@item(litFunc, "func(...) {}", "", "var")
+ http.HandlerFunc() //@item(handlerFunc, "http.HandlerFunc()", "", "var")
+ http.Handle("", http.HandlerFunc()) //@snippet("))", litFunc, "func(w http.ResponseWriter, r *http.Request) {$0\\}")
+ http.Handle("", h) //@snippet(")", handlerFunc, "http.HandlerFunc($0)")
+}
diff --git a/gopls/internal/regtest/marker/testdata/completion/testy.txt b/gopls/internal/regtest/marker/testdata/completion/testy.txt
new file mode 100644
index 0000000..f26b3ae
--- /dev/null
+++ b/gopls/internal/regtest/marker/testdata/completion/testy.txt
@@ -0,0 +1,57 @@
+
+-- flags --
+-ignore_extra_diags
+
+-- go.mod --
+module testy.test
+
+go 1.18
+
+-- types/types.go --
+package types
+
+
+-- signature/signature.go --
+package signature
+
+type Alias = int
+
+-- snippets/snippets.go --
+package snippets
+
+import (
+ "testy.test/signature"
+ t "testy.test/types"
+)
+
+func X(_ map[signature.Alias]t.CoolAlias) (map[signature.Alias]t.CoolAlias) {
+ return nil
+}
+
+-- testy/testy.go --
+package testy
+
+func a() { //@item(funcA, "a", "func()", "func")
+ //@complete("", funcA)
+}
+
+
+-- testy/testy_test.go --
+package testy
+
+import (
+ "testing"
+
+ sig "testy.test/signature"
+ "testy.test/snippets"
+)
+
+func TestSomething(t *testing.T) { //@item(TestSomething, "TestSomething(t *testing.T)", "", "func")
+ var x int //@loc(testyX, "x"), diag("x", re"x declared (and|but) not used")
+ a() //@loc(testyA, "a")
+}
+
+func _() {
+ _ = snippets.X(nil) //@signature("nil", "X(_ map[sig.Alias]types.CoolAlias) map[sig.Alias]types.CoolAlias")
+ var _ sig.Alias
+}
diff --git a/gopls/internal/regtest/marker/testdata/completion/unimported.txt b/gopls/internal/regtest/marker/testdata/completion/unimported.txt
new file mode 100644
index 0000000..7d12269
--- /dev/null
+++ b/gopls/internal/regtest/marker/testdata/completion/unimported.txt
@@ -0,0 +1,88 @@
+
+-- flags --
+-ignore_extra_diags
+
+-- go.mod --
+module unimported.test
+
+go 1.18
+
+-- unimported/export_test.go --
+package unimported
+
+var TestExport int //@item(testexport, "TestExport", "var (from \"unimported.test/unimported\")", "var")
+
+-- signature/signature.go --
+package signature
+
+func Foo() {}
+
+-- foo/foo.go --
+package foo
+
+type StructFoo struct{ F int }
+
+-- baz/baz.go --
+package baz
+
+import (
+ f "unimported.test/foo"
+)
+
+var FooStruct f.StructFoo
+
+-- unimported/unimported.go --
+package unimported
+
+func _() {
+ http //@complete("p", http, httptest, httptrace, httputil)
+ // container/ring is extremely unlikely to be imported by anything, so shouldn't have type information.
+ ring.Ring //@complete(re"R()ing", ringring)
+ signature.Foo //@complete("Foo", signaturefoo)
+
+ context.Bac //@complete(" //", contextBackground)
+}
+
+// Create markers for unimported std lib packages. Only for use by this test.
+/* http */ //@item(http, "http", "\"net/http\"", "package")
+/* httptest */ //@item(httptest, "httptest", "\"net/http/httptest\"", "package")
+/* httptrace */ //@item(httptrace, "httptrace", "\"net/http/httptrace\"", "package")
+/* httputil */ //@item(httputil, "httputil", "\"net/http/httputil\"", "package")
+
+/* ring.Ring */ //@item(ringring, "Ring", "(from \"container/ring\")", "var")
+
+/* signature.Foo */ //@item(signaturefoo, "Foo", "func (from \"unimported.test/signature\")", "func")
+
+/* context.Background */ //@item(contextBackground, "Background", "func (from \"context\")", "func")
+
+// Now that we no longer type-check imported completions,
+// we don't expect the context.Background().Err method (see golang/go#58663).
+/* context.Background().Err */ //@item(contextBackgroundErr, "Background().Err", "func (from \"context\")", "method")
+
+-- unimported/unimported_cand_type.go --
+package unimported
+
+import (
+ _ "context"
+
+ "unimported.test/baz"
+)
+
+func _() {
+ foo.StructFoo{} //@item(litFooStructFoo, "foo.StructFoo{}", "struct{...}", "struct")
+
+ // We get the literal completion for "foo.StructFoo{}" even though we haven't
+ // imported "foo" yet.
+ baz.FooStruct = f //@snippet(" //", litFooStructFoo, "foo.StructFoo{$0\\}")
+}
+
+-- unimported/x_test.go --
+package unimported_test
+
+import (
+ "testing"
+)
+
+func TestSomething(t *testing.T) {
+ _ = unimported.TestExport //@complete("TestExport", testexport)
+}
diff --git a/gopls/internal/regtest/marker/testdata/definition/cgo.txt b/gopls/internal/regtest/marker/testdata/definition/cgo.txt
new file mode 100644
index 0000000..6d108a4
--- /dev/null
+++ b/gopls/internal/regtest/marker/testdata/definition/cgo.txt
@@ -0,0 +1,62 @@
+This test is ported from the old marker tests.
+It tests hover and definition for cgo declarations.
+
+-- flags --
+-cgo
+
+-- go.mod --
+module cgo.test
+
+go 1.18
+
+-- cgo/cgo.go --
+package cgo
+
+/*
+#include <stdio.h>
+#include <stdlib.h>
+
+void myprint(char* s) {
+ printf("%s\n", s);
+}
+*/
+import "C"
+
+import (
+ "fmt"
+ "unsafe"
+)
+
+func Example() { //@loc(cgoexample, "Example"), item(cgoexampleItem, "Example", "func()", "func")
+ fmt.Println()
+ cs := C.CString("Hello from stdio\n")
+ C.myprint(cs)
+ C.free(unsafe.Pointer(cs))
+}
+
+func _() {
+ Example() //@hover("ample", "Example", hoverExample), def("ample", cgoexample), complete("ample", cgoexampleItem)
+}
+
+-- @hoverExample/hover.md --
+```go
+func Example()
+```
+
+[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/cgo.test/cgo#Example)
+-- usecgo/usecgo.go --
+package cgoimport
+
+import (
+ "cgo.test/cgo"
+)
+
+func _() {
+ cgo.Example() //@hover("ample", "Example", hoverImportedExample), def("ample", cgoexample), complete("ample", cgoexampleItem)
+}
+-- @hoverImportedExample/hover.md --
+```go
+func cgo.Example()
+```
+
+[`cgo.Example` on pkg.go.dev](https://pkg.go.dev/cgo.test/cgo#Example)
diff --git a/gopls/internal/regtest/marker/testdata/hover/godef.txt b/gopls/internal/regtest/marker/testdata/hover/godef.txt
new file mode 100644
index 0000000..e6a6761
--- /dev/null
+++ b/gopls/internal/regtest/marker/testdata/hover/godef.txt
@@ -0,0 +1,406 @@
+This test was ported from 'godef' in the old marker tests.
+It tests various hover and definition requests.
+
+-- flags --
+-min_go=go1.20
+
+-- go.mod --
+module godef.test
+
+go 1.18
+
+-- a/a_x_test.go --
+package a_test
+
+import (
+ "testing"
+)
+
+func TestA2(t *testing.T) { //@hover("TestA2", "TestA2", TestA2)
+ Nonexistant() //@diag("Nonexistant", re"(undeclared name|undefined): Nonexistant")
+}
+
+-- @TestA2/hover.md --
+```go
+func TestA2(t *testing.T)
+```
+-- @ember/hover.md --
+```go
+field Member string
+```
+
+@loc(Member, "Member")
+
+
+[`(a.Thing).Member` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Thing.Member)
+-- a/d.go --
+package a //@hover("a", _, a)
+
+import "fmt"
+
+type Thing struct { //@loc(Thing, "Thing")
+ Member string //@loc(Member, "Member")
+}
+
+var Other Thing //@loc(Other, "Other")
+
+func Things(val []string) []Thing { //@loc(Things, "Things")
+ return nil
+}
+
+func (t Thing) Method(i int) string { //@loc(Method, "Method")
+ return t.Member
+}
+
+func (t Thing) Method3() {
+}
+
+func (t *Thing) Method2(i int, j int) (error, string) {
+ return nil, t.Member
+}
+
+func (t *Thing) private() {
+}
+
+func useThings() {
+ t := Thing{ //@hover("ing", "Thing", ing)
+ Member: "string", //@hover("ember", "Member", ember), def("ember", Member)
+ }
+ fmt.Print(t.Member) //@hover("ember", "Member", ember), def("ember", Member)
+ fmt.Print(Other) //@hover("ther", "Other", ther), def("ther", Other)
+ Things(nil) //@hover("ings", "Things", ings), def("ings", Things)
+ t.Method(0) //@hover("eth", "Method", eth), def("eth", Method)
+}
+
+type NextThing struct { //@loc(NextThing, "NextThing")
+ Thing
+ Value int
+}
+
+func (n NextThing) another() string {
+ return n.Member
+}
+
+// Shadows Thing.Method3
+func (n *NextThing) Method3() int {
+ return n.Value
+}
+
+var nextThing NextThing //@hover("NextThing", "NextThing", NextThing), def("NextThing", NextThing)
+
+-- @ings/hover.md --
+```go
+func Things(val []string) []Thing
+```
+
+[`a.Things` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Things)
+-- @ther/hover.md --
+```go
+var Other Thing
+```
+
+@loc(Other, "Other")
+
+
+[`a.Other` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Other)
+-- @a/hover.md --
+-- @ing/hover.md --
+```go
+type Thing struct {
+ Member string //@loc(Member, "Member")
+}
+
+func (Thing).Method(i int) string
+func (*Thing).Method2(i int, j int) (error, string)
+func (Thing).Method3()
+func (*Thing).private()
+```
+
+[`a.Thing` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Thing)
+-- @NextThing/hover.md --
+```go
+type NextThing struct {
+ Thing
+ Value int
+}
+
+func (*NextThing).Method3() int
+func (NextThing).another() string
+```
+
+[`a.NextThing` on pkg.go.dev](https://pkg.go.dev/godef.test/a#NextThing)
+-- @eth/hover.md --
+```go
+func (Thing).Method(i int) string
+```
+
+[`(a.Thing).Method` on pkg.go.dev](https://pkg.go.dev/godef.test/a#Thing.Method)
+-- a/f.go --
+// Package a is a package for testing go to definition.
+package a
+
+import "fmt"
+
+func TypeStuff() {
+ var x string
+
+ switch y := interface{}(x).(type) { //@loc(y, "y"), hover("y", "y", y) , def("y", y)
+ case int: //@loc(intY, "int")
+ fmt.Printf("%v", y) //@hover("y", "y", inty), def("y", y)
+ case string: //@loc(stringY, "string")
+ fmt.Printf("%v", y) //@hover("y", "y", stringy), def("y", y)
+ }
+
+}
+-- @inty/hover.md --
+```go
+var y int
+```
+-- @stringy/hover.md --
+```go
+var y string
+```
+-- @y/hover.md --
+```go
+var y interface{}
+```
+-- a/h.go --
+package a
+
+func _() {
+ type s struct {
+ nested struct {
+ // nested number
+ number int64 //@loc(nestedNumber, "number")
+ }
+ nested2 []struct {
+ // nested string
+ str string //@loc(nestedString, "str")
+ }
+ x struct {
+ x struct {
+ x struct {
+ x struct {
+ x struct {
+ // nested map
+ m map[string]float64 //@loc(nestedMap, "m")
+ }
+ }
+ }
+ }
+ }
+ }
+
+ var t s
+ _ = t.nested.number //@hover("number", "number", nestedNumber), def("number", nestedNumber)
+ _ = t.nested2[0].str //@hover("str", "str", nestedString), def("str", nestedString)
+ _ = t.x.x.x.x.x.m //@hover("m", "m", nestedMap), def("m", nestedMap)
+}
+
+func _() {
+ var s struct {
+ // a field
+ a int //@loc(structA, "a")
+ // b nested struct
+ b struct { //@loc(structB, "b")
+ // c field of nested struct
+ c int //@loc(structC, "c")
+ }
+ }
+ _ = s.a //@def("a", structA)
+ _ = s.b //@def("b", structB)
+ _ = s.b.c //@def("c", structC)
+
+ var arr []struct {
+ // d field
+ d int //@loc(arrD, "d")
+ // e nested struct
+ e struct { //@loc(arrE, "e")
+ // f field of nested struct
+ f int //@loc(arrF, "f")
+ }
+ }
+ _ = arr[0].d //@def("d", arrD)
+ _ = arr[0].e //@def("e", arrE)
+ _ = arr[0].e.f //@def("f", arrF)
+
+ var complex []struct {
+ c <-chan map[string][]struct {
+ // h field
+ h int //@loc(complexH, "h")
+ // i nested struct
+ i struct { //@loc(complexI, "i")
+ // j field of nested struct
+ j int //@loc(complexJ, "j")
+ }
+ }
+ }
+ _ = (<-complex[0].c)["0"][0].h //@def("h", complexH)
+ _ = (<-complex[0].c)["0"][0].i //@def("i", complexI)
+ _ = (<-complex[0].c)["0"][0].i.j //@def("j", complexJ)
+
+ var mapWithStructKey map[struct { //@diag("struct", re"invalid map key")
+ // X key field
+ x []string //@loc(mapStructKeyX, "x")
+ }]int
+ for k := range mapWithStructKey {
+ _ = k.x //@def("x", mapStructKeyX)
+ }
+
+ var mapWithStructKeyAndValue map[struct {
+ // Y key field
+ y string //@loc(mapStructKeyY, "y")
+ }]struct {
+ // X value field
+ x string //@loc(mapStructValueX, "x")
+ }
+ for k, v := range mapWithStructKeyAndValue {
+ // TODO: we don't show docs for y field because both map key and value
+ // are structs. And in this case, we parse only map value
+ _ = k.y //@hover("y", "y", hoverStructKeyY), def("y", mapStructKeyY)
+ _ = v.x //@hover("x", "x", hoverStructKeyX), def("x", mapStructValueX)
+ }
+
+ var i []map[string]interface {
+ // open method comment
+ open() error //@loc(openMethod, "open")
+ }
+ i[0]["1"].open() //@hover("pen","open", openMethod), def("open", openMethod)
+}
+
+func _() {
+ test := struct {
+ // test description
+ desc string //@loc(testDescription, "desc")
+ }{}
+ _ = test.desc //@def("desc", testDescription)
+
+ for _, tt := range []struct {
+ // test input
+ in map[string][]struct { //@loc(testInput, "in")
+ // test key
+ key string //@loc(testInputKey, "key")
+ // test value
+ value interface{} //@loc(testInputValue, "value")
+ }
+ result struct {
+ v <-chan struct {
+ // expected test value
+ value int //@loc(testResultValue, "value")
+ }
+ }
+ }{} {
+ _ = tt.in //@def("in", testInput)
+ _ = tt.in["0"][0].key //@def("key", testInputKey)
+ _ = tt.in["0"][0].value //@def("value", testInputValue)
+
+ _ = (<-tt.result.v).value //@def("value", testResultValue)
+ }
+}
+
+func _() {
+ getPoints := func() []struct {
+ // X coord
+ x int //@loc(returnX, "x")
+ // Y coord
+ y int //@loc(returnY, "y")
+ } {
+ return nil
+ }
+
+ r := getPoints()
+ _ = r[0].x //@def("x", returnX)
+ _ = r[0].y //@def("y", returnY)
+}
+-- @hoverStructKeyX/hover.md --
+```go
+field x string
+```
+
+X value field
+-- @hoverStructKeyY/hover.md --
+```go
+field y string
+```
+
+Y key field
+-- @nestedNumber/hover.md --
+```go
+field number int64
+```
+
+nested number
+-- @nestedString/hover.md --
+```go
+field str string
+```
+
+nested string
+-- @openMethod/hover.md --
+```go
+func (interface).open() error
+```
+
+open method comment
+-- @nestedMap/hover.md --
+```go
+field m map[string]float64
+```
+
+nested map
+-- b/e.go --
+package b
+
+import (
+ "fmt"
+
+ "godef.test/a"
+)
+
+func useThings() {
+ t := a.Thing{} //@loc(bStructType, "ing")
+ fmt.Print(t.Member) //@loc(bMember, "ember")
+ fmt.Print(a.Other) //@loc(bVar, "ther")
+ a.Things(nil) //@loc(bFunc, "ings")
+}
+
+/*@
+def(bStructType, Thing)
+def(bMember, Member)
+def(bVar, Other)
+def(bFunc, Things)
+*/
+
+func _() {
+ var x interface{}
+ switch x := x.(type) { //@hover("x", "x", xInterface)
+ case string: //@loc(eString, "string")
+ fmt.Println(x) //@hover("x", "x", xString)
+ case int: //@loc(eInt, "int")
+ fmt.Println(x) //@hover("x", "x", xInt)
+ }
+}
+-- @xInt/hover.md --
+```go
+var x int
+```
+-- @xInterface/hover.md --
+```go
+var x interface{}
+```
+-- @xString/hover.md --
+```go
+var x string
+```
+-- broken/unclosedIf.go --
+package broken
+
+import "fmt"
+
+func unclosedIf() {
+ if false {
+ var myUnclosedIf string //@loc(myUnclosedIf, "myUnclosedIf")
+ fmt.Printf("s = %v\n", myUnclosedIf) //@def("my", myUnclosedIf)
+}
+
+func _() {} //@diag("_", re"expected")
diff --git a/gopls/internal/regtest/marker/testdata/typedef/typedef.txt b/gopls/internal/regtest/marker/testdata/typedef/typedef.txt
new file mode 100644
index 0000000..3bc9dab
--- /dev/null
+++ b/gopls/internal/regtest/marker/testdata/typedef/typedef.txt
@@ -0,0 +1,68 @@
+This test exercises the textDocument/typeDefinition action.
+
+-- typedef.go --
+package typedef
+
+type Struct struct { //@loc(Struct, "Struct"),
+ Field string
+}
+
+type Int int //@loc(Int, "Int")
+
+func _() {
+ var (
+ value Struct
+ point *Struct
+ )
+ _ = value //@typedef("value", Struct)
+ _ = point //@typedef("point", Struct)
+
+ var (
+ array [3]Struct
+ slice []Struct
+ ch chan Struct
+ complex [3]chan *[5][]Int
+ )
+ _ = array //@typedef("array", Struct)
+ _ = slice //@typedef("slice", Struct)
+ _ = ch //@typedef("ch", Struct)
+ _ = complex //@typedef("complex", Int)
+
+ var s struct {
+ x struct {
+ xx struct {
+ field1 []Struct
+ field2 []Int
+ }
+ }
+ }
+ _ = s.x.xx.field1 //@typedef("field1", Struct)
+ _ = s.x.xx.field2 //@typedef("field2", Int)
+}
+
+func F1() Int { return 0 }
+func F2() (Int, float64) { return 0, 0 }
+func F3() (Struct, int, bool, error) { return Struct{}, 0, false, nil }
+func F4() (**int, Int, bool, *error) { return nil, 0, false, nil }
+func F5() (int, float64, error, Struct) { return 0, 0, nil, Struct{} }
+func F6() (int, float64, ***Struct, error) { return 0, 0, nil, nil }
+
+func _() {
+ F1() //@typedef("F1", Int)
+ F2() //@typedef("F2", Int)
+ F3() //@typedef("F3", Struct)
+ F4() //@typedef("F4", Int)
+ F5() //@typedef("F5", Struct)
+ F6() //@typedef("F6", Struct)
+
+ f := func() Int { return 0 }
+ f() //@typedef("f", Int)
+}
+
+// https://github.com/golang/go/issues/38589#issuecomment-620350922
+func _() {
+ type myFunc func(int) Int //@loc(myFunc, "myFunc")
+
+ var foo myFunc
+ _ = foo() //@typedef("foo", myFunc), diag(")", re"not enough arguments")
+}
diff --git a/gopls/internal/regtest/misc/definition_test.go b/gopls/internal/regtest/misc/definition_test.go
index 0a36336..f11b207 100644
--- a/gopls/internal/regtest/misc/definition_test.go
+++ b/gopls/internal/regtest/misc/definition_test.go
@@ -351,7 +351,7 @@
Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- loc, err := env.Editor.GoToTypeDefinition(env.Ctx, env.RegexpSearch("main.go", tt.re))
+ loc, err := env.Editor.TypeDefinition(env.Ctx, env.RegexpSearch("main.go", tt.re))
if tt.wantError {
if err == nil {
t.Fatal("expected error, got nil")
@@ -386,10 +386,7 @@
Run(t, mod, func(t *testing.T, env *Env) {
env.OpenFile("main.go")
- _, err := env.Editor.GoToTypeDefinition(env.Ctx, env.RegexpSearch("main.go", "comparable")) // must not panic
- if err != nil {
- t.Fatal(err)
- }
+ _ = env.TypeDefinition(env.RegexpSearch("main.go", "comparable")) // must not panic
})
}
diff --git a/gopls/internal/regtest/misc/references_test.go b/gopls/internal/regtest/misc/references_test.go
index a85bcc2..262284a 100644
--- a/gopls/internal/regtest/misc/references_test.go
+++ b/gopls/internal/regtest/misc/references_test.go
@@ -133,10 +133,8 @@
loc := env.RegexpSearch("a.go", `\b`+name+`\b`)
// definition -> {builtin,unsafe}.go
- def, err := env.Editor.GoToDefinition(env.Ctx, loc)
- if err != nil {
- t.Errorf("definition(%q) failed: %v", name, err)
- } else if (!strings.HasSuffix(string(def.URI), "builtin.go") &&
+ def := env.GoToDefinition(loc)
+ if (!strings.HasSuffix(string(def.URI), "builtin.go") &&
!strings.HasSuffix(string(def.URI), "unsafe.go")) ||
def.Range.Start.Line == 0 {
t.Errorf("definition(%q) = %v, want {builtin,unsafe}.go",
@@ -144,7 +142,7 @@
}
// "references to (builtin "Foo"|unsafe.Foo) are not supported"
- _, err = env.Editor.References(env.Ctx, loc)
+ _, err := env.Editor.References(env.Ctx, loc)
gotErr := fmt.Sprint(err)
if !strings.Contains(gotErr, "references to") ||
!strings.Contains(gotErr, "not supported") ||
diff --git a/gopls/internal/regtest/modfile/modfile_test.go b/gopls/internal/regtest/modfile/modfile_test.go
index 855141a..0763669 100644
--- a/gopls/internal/regtest/modfile/modfile_test.go
+++ b/gopls/internal/regtest/modfile/modfile_test.go
@@ -878,7 +878,7 @@
}
// Confirm that we no longer have metadata when the file is saved.
env.SaveBufferWithoutActions("go.mod")
- _, err := env.Editor.GoToDefinition(env.Ctx, env.RegexpSearch("main.go", "hello"))
+ _, err := env.Editor.Definition(env.Ctx, env.RegexpSearch("main.go", "hello"))
if err == nil {
t.Fatalf("expected error, got none")
}