diff --git a/go/packages/packagestest/export.go b/go/packages/packagestest/export.go index 989e409938..0b9913b4ad 100644 --- a/go/packages/packagestest/export.go +++ b/go/packages/packagestest/export.go @@ -303,6 +303,110 @@ func Copy(source string) Writer { } } +// GroupFilesByModules attempts to map directories to the modules within each directory. +// This function assumes that the folder is structured in the following way: +// - dir +// - primarymod +// - .go files +// - packages +// - go.mod (optional) +// - modules +// - repoa +// - mod1 +// - .go files +// - packages +// - go.mod (optional) +// It scans the directory tree anchored at root and adds a Copy writer to the +// map for every file found. +// This is to enable the common case in tests where you have a full copy of the +// package in your testdata. +func GroupFilesByModules(root string) ([]Module, error) { + root = filepath.FromSlash(root) + primarymodPath := filepath.Join(root, "primarymod") + + _, err := os.Stat(primarymodPath) + if os.IsNotExist(err) { + return nil, fmt.Errorf("could not find primarymod folder within %s", root) + } + + primarymod := &Module{ + Name: root, + Files: make(map[string]interface{}), + Overlay: make(map[string][]byte), + } + mods := map[string]*Module{ + root: primarymod, + } + modules := []Module{*primarymod} + + if err := filepath.Walk(primarymodPath, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() { + return nil + } + fragment, err := filepath.Rel(primarymodPath, path) + if err != nil { + return err + } + primarymod.Files[filepath.ToSlash(fragment)] = Copy(path) + return nil + }); err != nil { + return nil, err + } + + modulesPath := filepath.Join(root, "modules") + if _, err := os.Stat(modulesPath); os.IsNotExist(err) { + return modules, nil + } + + var currentRepo, currentModule string + if err := filepath.Walk(modulesPath, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + // If the path is not a directory, then we want to add the path to + // the files map of the currentModule. + if !info.IsDir() { + fragment, err := filepath.Rel(currentModule, path) + if err != nil { + return err + } + mods[currentModule].Files[filepath.ToSlash(fragment)] = Copy(path) + return nil + } + // If the path is a directory and it's enclosing folder is equal to + // the modules folder, then the path is a new repo. + if filepath.Dir(path) == modulesPath { + currentRepo = path + return nil + } + // If the path is a directory and it's enclosing folder is not the same + // as the current repo, then the path is a folder/package of the current module. + if filepath.Dir(path) != currentRepo { + return nil + } + // If the path is a directory and it's enclosing folder is the current repo + // then the path is a new module. + module, err := filepath.Rel(modulesPath, path) + if err != nil { + return err + } + mods[path] = &Module{ + Name: filepath.ToSlash(module), + Files: make(map[string]interface{}), + Overlay: make(map[string][]byte), + } + currentModule = path + modules = append(modules, *mods[path]) + return nil + }); err != nil { + return nil, err + } + return modules, nil +} + // MustCopyFileTree returns a file set for a module based on a real directory tree. // It scans the directory tree anchored at root and adds a Copy writer to the // map for every file found. diff --git a/go/packages/packagestest/gopath_test.go b/go/packages/packagestest/gopath_test.go index a251dbce2c..d75d4ce04b 100644 --- a/go/packages/packagestest/gopath_test.go +++ b/go/packages/packagestest/gopath_test.go @@ -26,3 +26,79 @@ func TestGOPATHExport(t *testing.T) { {"golang.org/fake2/v2", "other/a.go", "fake2_v2/src/golang.org/fake2/v2/other/a.go", checkContent("package fake2")}, }) } + +func TestGroupFilesByModules(t *testing.T) { + for _, tt := range []struct { + testdir string + want []packagestest.Module + }{ + { + testdir: "testdata/groups/one", + want: []packagestest.Module{ + { + Name: "testdata/groups/one", + Files: map[string]interface{}{ + "main.go": true, + }, + }, + { + Name: "example.com/extra", + Files: map[string]interface{}{ + "help.go": true, + }, + }, + }, + }, + { + testdir: "testdata/groups/two", + want: []packagestest.Module{ + { + Name: "testdata/groups/two", + Files: map[string]interface{}{ + "main.go": true, + "expect/yo.go": true, + }, + }, + { + Name: "example.com/extra", + Files: map[string]interface{}{ + "me.go": true, + "geez/help.go": true, + }, + }, + { + Name: "example.com/tempmod", + Files: map[string]interface{}{ + "main.go": true, + }, + }, + }, + }, + } { + t.Run(tt.testdir, func(t *testing.T) { + got, err := packagestest.GroupFilesByModules(tt.testdir) + if err != nil { + t.Fatalf("could not group files %v", err) + } + if len(got) != len(tt.want) { + t.Fatalf("%s: wanted %d modules but got %d", tt.testdir, len(tt.want), len(got)) + } + for i, w := range tt.want { + g := got[i] + if filepath.FromSlash(g.Name) != filepath.FromSlash(w.Name) { + t.Fatalf("%s: wanted module[%d].Name to be %s but got %s", tt.testdir, i, filepath.FromSlash(w.Name), filepath.FromSlash(g.Name)) + } + for fh := range w.Files { + if _, ok := g.Files[fh]; !ok { + t.Fatalf("%s, module[%d]: wanted %s but could not find", tt.testdir, i, fh) + } + } + for fh := range g.Files { + if _, ok := w.Files[fh]; !ok { + t.Fatalf("%s, module[%d]: found unexpected file %s", tt.testdir, i, fh) + } + } + } + }) + } +} diff --git a/go/packages/packagestest/modules.go b/go/packages/packagestest/modules.go index 6d46d9ba7f..1704f9d2f5 100644 --- a/go/packages/packagestest/modules.go +++ b/go/packages/packagestest/modules.go @@ -125,7 +125,6 @@ func (modules) Finalize(exported *Exported) error { if err := invokeGo(exported.Config, "mod", "download"); err != nil { return err } - return nil } @@ -204,7 +203,7 @@ func modCache(exported *Exported) string { } func primaryDir(exported *Exported) string { - return filepath.Join(exported.temp, "primarymod", path.Base(exported.primary)) + return filepath.Join(exported.temp, path.Base(exported.primary)) } func moduleDir(exported *Exported, module string) string { diff --git a/go/packages/packagestest/modules_test.go b/go/packages/packagestest/modules_test.go index 8a85ae162d..0e88c45398 100644 --- a/go/packages/packagestest/modules_test.go +++ b/go/packages/packagestest/modules_test.go @@ -17,14 +17,14 @@ func TestModulesExport(t *testing.T) { exported := packagestest.Export(t, packagestest.Modules, testdata) defer exported.Cleanup() // Check that the cfg contains all the right bits - var expectDir = filepath.Join(exported.Temp(), "primarymod/fake1") + var expectDir = filepath.Join(exported.Temp(), "fake1") if exported.Config.Dir != expectDir { t.Errorf("Got working directory %v expected %v", exported.Config.Dir, expectDir) } checkFiles(t, exported, []fileTest{ - {"golang.org/fake1", "go.mod", "primarymod/fake1/go.mod", nil}, - {"golang.org/fake1", "a.go", "primarymod/fake1/a.go", checkLink("testdata/a.go")}, - {"golang.org/fake1", "b.go", "primarymod/fake1/b.go", checkContent("package fake1")}, + {"golang.org/fake1", "go.mod", "fake1/go.mod", nil}, + {"golang.org/fake1", "a.go", "fake1/a.go", checkLink("testdata/a.go")}, + {"golang.org/fake1", "b.go", "fake1/b.go", checkContent("package fake1")}, {"golang.org/fake2", "go.mod", "modcache/pkg/mod/golang.org/fake2@v1.0.0/go.mod", nil}, {"golang.org/fake2", "other/a.go", "modcache/pkg/mod/golang.org/fake2@v1.0.0/other/a.go", checkContent("package fake2")}, {"golang.org/fake2/v2", "other/a.go", "modcache/pkg/mod/golang.org/fake2/v2@v2.0.0/other/a.go", checkContent("package fake2")}, diff --git a/go/packages/packagestest/testdata/groups/one/modules/example.com/extra/help.go b/go/packages/packagestest/testdata/groups/one/modules/example.com/extra/help.go new file mode 100644 index 0000000000..ee03293755 --- /dev/null +++ b/go/packages/packagestest/testdata/groups/one/modules/example.com/extra/help.go @@ -0,0 +1 @@ +package extra \ No newline at end of file diff --git a/go/packages/packagestest/testdata/groups/one/primarymod/main.go b/go/packages/packagestest/testdata/groups/one/primarymod/main.go new file mode 100644 index 0000000000..54fe6e8b32 --- /dev/null +++ b/go/packages/packagestest/testdata/groups/one/primarymod/main.go @@ -0,0 +1 @@ +package one \ No newline at end of file diff --git a/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/geez/help.go b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/geez/help.go new file mode 100644 index 0000000000..930ffdc81f --- /dev/null +++ b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/geez/help.go @@ -0,0 +1 @@ +package example.com/extra/geez \ No newline at end of file diff --git a/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/me.go b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/me.go new file mode 100644 index 0000000000..6a8c7d31f2 --- /dev/null +++ b/go/packages/packagestest/testdata/groups/two/modules/example.com/extra/me.go @@ -0,0 +1 @@ +package example.com/extra \ No newline at end of file diff --git a/go/packages/packagestest/testdata/groups/two/modules/example.com/tempmod/main.go b/go/packages/packagestest/testdata/groups/two/modules/example.com/tempmod/main.go new file mode 100644 index 0000000000..85dbfa7cf3 --- /dev/null +++ b/go/packages/packagestest/testdata/groups/two/modules/example.com/tempmod/main.go @@ -0,0 +1 @@ +package example.com/tempmod \ No newline at end of file diff --git a/go/packages/packagestest/testdata/groups/two/primarymod/expect/yo.go b/go/packages/packagestest/testdata/groups/two/primarymod/expect/yo.go new file mode 100644 index 0000000000..a7067786ed --- /dev/null +++ b/go/packages/packagestest/testdata/groups/two/primarymod/expect/yo.go @@ -0,0 +1 @@ +package expect \ No newline at end of file diff --git a/go/packages/packagestest/testdata/groups/two/primarymod/main.go b/go/packages/packagestest/testdata/groups/two/primarymod/main.go new file mode 100644 index 0000000000..0b26334865 --- /dev/null +++ b/go/packages/packagestest/testdata/groups/two/primarymod/main.go @@ -0,0 +1 @@ +package two \ No newline at end of file diff --git a/gopls/test/gopls_test.go b/gopls/test/gopls_test.go index d57a9a6abb..07cc4d72ea 100644 --- a/gopls/test/gopls_test.go +++ b/gopls/test/gopls_test.go @@ -37,6 +37,11 @@ func testCommandLine(t *testing.T, exporter packagestest.Exporter) { t.Skip("testdata directory not present") } data := tests.Load(t, exporter, testdata) - defer data.Exported.Cleanup() - tests.Run(t, cmdtest.NewRunner(exporter, data, tests.Context(t), commandLineOptions), data) + for _, data := range data { + defer data.Exported.Cleanup() + t.Run(data.Folder, func(t *testing.T) { + t.Helper() + tests.Run(t, cmdtest.NewRunner(exporter, data, tests.Context(t), commandLineOptions), data) + }) + } } diff --git a/internal/lsp/cmd/cmd_test.go b/internal/lsp/cmd/cmd_test.go index 0e417c68a9..a602f7cfbe 100644 --- a/internal/lsp/cmd/cmd_test.go +++ b/internal/lsp/cmd/cmd_test.go @@ -30,8 +30,13 @@ func TestCommandLine(t *testing.T) { func testCommandLine(t *testing.T, exporter packagestest.Exporter) { data := tests.Load(t, exporter, "../testdata") - defer data.Exported.Cleanup() - tests.Run(t, cmdtest.NewRunner(exporter, data, tests.Context(t), nil), data) + for _, datum := range data { + defer datum.Exported.Cleanup() + t.Run(datum.Folder, func(t *testing.T) { + t.Helper() + tests.Run(t, cmdtest.NewRunner(exporter, datum, tests.Context(t), nil), datum) + }) + } } func TestDefinitionHelpExample(t *testing.T) { diff --git a/internal/lsp/lsp_test.go b/internal/lsp/lsp_test.go index f34febcdbf..d29a12fec6 100644 --- a/internal/lsp/lsp_test.go +++ b/internal/lsp/lsp_test.go @@ -45,54 +45,58 @@ type runner struct { ctx context.Context } -const viewName = "lsp_test" - func testLSP(t *testing.T, exporter packagestest.Exporter) { ctx := tests.Context(t) data := tests.Load(t, exporter, "testdata") - defer data.Exported.Cleanup() - cache := cache.New(nil) - session := cache.NewSession() - options := tests.DefaultOptions() - session.SetOptions(options) - options.Env = data.Config.Env - if _, _, err := session.NewView(ctx, viewName, span.FileURI(data.Config.Dir), options); err != nil { - t.Fatal(err) - } - var modifications []source.FileModification - for filename, content := range data.Config.Overlay { - kind := source.DetectLanguage("", filename) - if kind != source.Go { - continue + for _, datum := range data { + defer datum.Exported.Cleanup() + + cache := cache.New(nil) + session := cache.NewSession() + options := tests.DefaultOptions() + session.SetOptions(options) + options.Env = datum.Config.Env + if _, _, err := session.NewView(ctx, datum.Config.Dir, span.FileURI(datum.Config.Dir), options); err != nil { + t.Fatal(err) } - modifications = append(modifications, source.FileModification{ - URI: span.FileURI(filename), - Action: source.Open, - Version: -1, - Text: content, - LanguageID: "go", + var modifications []source.FileModification + for filename, content := range datum.Config.Overlay { + kind := source.DetectLanguage("", filename) + if kind != source.Go { + continue + } + modifications = append(modifications, source.FileModification{ + URI: span.FileURI(filename), + Action: source.Open, + Version: -1, + Text: content, + LanguageID: "go", + }) + } + if _, err := session.DidModifyFiles(ctx, modifications); err != nil { + t.Fatal(err) + } + r := &runner{ + server: &Server{ + session: session, + delivered: map[span.URI]sentDiagnostics{}, + }, + data: datum, + ctx: ctx, + } + t.Run(datum.Folder, func(t *testing.T) { + t.Helper() + tests.Run(t, r, datum) }) } - if _, err := session.DidModifyFiles(ctx, modifications); err != nil { - t.Fatal(err) - } - r := &runner{ - server: &Server{ - session: session, - delivered: map[span.URI]sentDiagnostics{}, - }, - data: data, - ctx: ctx, - } - tests.Run(t, r, data) } 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. if r.diagnostics == nil { r.diagnostics = make(map[span.URI][]source.Diagnostic) - v := r.server.session.View(viewName) + v := r.server.session.View(r.data.Config.Dir) // Always run diagnostics with analysis. reports := r.server.diagnose(r.ctx, v.Snapshot(), true) for key, diags := range reports { @@ -980,9 +984,9 @@ func TestModfileSuggestedFixes(t *testing.T) { delivered: map[span.URI]sentDiagnostics{}, } - for _, tt := range []string{"indirect", "unused"} { + for _, tt := range []string{"indirect/primarymod", "unused/primarymod"} { t.Run(tt, func(t *testing.T) { - folder, err := tests.CopyFolderToTempDir(filepath.Join("mod", "testdata", tt)) + folder, err := tests.CopyFolderToTempDir(filepath.Join("testdata", tt)) if err != nil { t.Fatal(err) } diff --git a/internal/lsp/mod/mod_test.go b/internal/lsp/mod/mod_test.go index c9c7d24e52..d8b4761d40 100644 --- a/internal/lsp/mod/mod_test.go +++ b/internal/lsp/mod/mod_test.go @@ -5,15 +5,12 @@ package mod import ( - "context" "io/ioutil" "os" "path/filepath" "testing" "golang.org/x/tools/internal/lsp/cache" - "golang.org/x/tools/internal/lsp/protocol" - "golang.org/x/tools/internal/lsp/source" "golang.org/x/tools/internal/lsp/tests" "golang.org/x/tools/internal/span" "golang.org/x/tools/internal/testenv" @@ -50,7 +47,7 @@ func TestModfileRemainsUnchanged(t *testing.T) { if err != nil { t.Fatal(err) } - if !hasTempModfile(ctx, snapshot) { + if _, t := snapshot.View().ModFiles(); t == "" { return } after, err := ioutil.ReadFile(filepath.Join(folder, "go.mod")) @@ -61,119 +58,3 @@ func TestModfileRemainsUnchanged(t *testing.T) { t.Errorf("the real go.mod file was changed even when tempModfile=true") } } - -// TODO(golang/go#36091): This file can be refactored to look like lsp_test.go -// when marker support gets added for go.mod files. -func TestDiagnostics(t *testing.T) { - ctx := tests.Context(t) - cache := cache.New(nil) - session := cache.NewSession() - options := tests.DefaultOptions() - options.TempModfile = true - options.Env = append(os.Environ(), "GOPACKAGESDRIVER=off", "GOROOT=") - - for _, tt := range []struct { - testdir string - want []source.Diagnostic - }{ - { - testdir: "indirect", - want: []source.Diagnostic{ - { - Message: "golang.org/x/tools should be a direct dependency.", - Source: "go mod tidy", - // TODO(golang/go#36091): When marker support gets added for go.mod files, we - // can remove these hard coded positions. - Range: protocol.Range{Start: getRawPos(4, 62), End: getRawPos(4, 73)}, - Severity: protocol.SeverityWarning, - }, - }, - }, - { - testdir: "unused", - want: []source.Diagnostic{ - { - Message: "golang.org/x/tools is not used in this module.", - Source: "go mod tidy", - Range: protocol.Range{Start: getRawPos(4, 0), End: getRawPos(4, 61)}, - Severity: protocol.SeverityWarning, - }, - }, - }, - { - testdir: "invalidrequire", - want: []source.Diagnostic{ - { - Message: "usage: require module/path v1.2.3", - Source: "syntax", - Range: protocol.Range{Start: getRawPos(4, 0), End: getRawPos(4, 16)}, - Severity: protocol.SeverityError, - }, - }, - }, - { - testdir: "invalidgo", - want: []source.Diagnostic{ - { - Message: "usage: go 1.23", - Source: "syntax", - Range: protocol.Range{Start: getRawPos(2, 0), End: getRawPos(2, 3)}, - Severity: protocol.SeverityError, - }, - }, - }, - { - testdir: "unknowndirective", - want: []source.Diagnostic{ - { - Message: "unknown directive: yo", - Source: "syntax", - Range: protocol.Range{Start: getRawPos(6, 0), End: getRawPos(6, 1)}, - Severity: protocol.SeverityError, - }, - }, - }, - } { - t.Run(tt.testdir, func(t *testing.T) { - // TODO: Once we refactor this to work with go/packages/packagestest. We do not - // need to copy to a temporary directory. - folder, err := tests.CopyFolderToTempDir(filepath.Join("testdata", tt.testdir)) - if err != nil { - t.Fatal(err) - } - defer os.RemoveAll(folder) - _, snapshot, err := session.NewView(ctx, "diagnostics_test", span.FileURI(folder), options) - if err != nil { - t.Fatal(err) - } - // TODO: Add testing for when the -modfile flag is turned off and we still get diagnostics. - if !hasTempModfile(ctx, snapshot) { - return - } - reports, _, err := Diagnostics(ctx, snapshot) - if err != nil { - t.Fatal(err) - } - if len(reports) != 1 { - t.Errorf("expected 1 diagnostic, got %d", len(reports)) - } - for fh, got := range reports { - if diff := tests.DiffDiagnostics(fh.URI, tt.want, got); diff != "" { - t.Error(diff) - } - } - }) - } -} - -func hasTempModfile(ctx context.Context, snapshot source.Snapshot) bool { - _, t := snapshot.View().ModFiles() - return t != "" -} - -func getRawPos(line, character int) protocol.Position { - return protocol.Position{ - Line: float64(line), - Character: float64(character), - } -} diff --git a/internal/lsp/mod/testdata/invalidgo/go.mod b/internal/lsp/mod/testdata/invalidgo/go.mod deleted file mode 100644 index ca06b60146..0000000000 --- a/internal/lsp/mod/testdata/invalidgo/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module invalidgo - -go 1 - -require golang.org/x/tools v0.0.0-20191219192050-56b0b28a00f7 // indirect diff --git a/internal/lsp/mod/testdata/invalidgo/main.go b/internal/lsp/mod/testdata/invalidgo/main.go deleted file mode 100644 index 5577a36e55..0000000000 --- a/internal/lsp/mod/testdata/invalidgo/main.go +++ /dev/null @@ -1,10 +0,0 @@ -// Package invalidgo does something -package invalidgo - -import ( - "golang.org/x/tools/go/packages" -) - -func Yo() { - var _ packages.Config -} diff --git a/internal/lsp/mod/testdata/invalidrequire/go.mod b/internal/lsp/mod/testdata/invalidrequire/go.mod deleted file mode 100644 index 98c5b052da..0000000000 --- a/internal/lsp/mod/testdata/invalidrequire/go.mod +++ /dev/null @@ -1,5 +0,0 @@ -module invalidrequire - -go 1.12 - -require golang.or diff --git a/internal/lsp/mod/testdata/invalidrequire/main.go b/internal/lsp/mod/testdata/invalidrequire/main.go deleted file mode 100644 index dd24341ae8..0000000000 --- a/internal/lsp/mod/testdata/invalidrequire/main.go +++ /dev/null @@ -1,10 +0,0 @@ -// Package invalidrequire does something -package invalidrequire - -import ( - "golang.org/x/tools/go/packages" -) - -func Yo() { - var _ packages.Config -} diff --git a/internal/lsp/mod/testdata/unchanged/summary.txt.golden b/internal/lsp/mod/testdata/unchanged/summary.txt.golden new file mode 100644 index 0000000000..7945998a09 --- /dev/null +++ b/internal/lsp/mod/testdata/unchanged/summary.txt.golden @@ -0,0 +1,24 @@ +-- summary -- +CompletionsCount = 0 +CompletionSnippetCount = 0 +UnimportedCompletionsCount = 0 +DeepCompletionsCount = 0 +FuzzyCompletionsCount = 0 +RankedCompletionsCount = 0 +CaseSensitiveCompletionsCount = 0 +DiagnosticsCount = 0 +FoldingRangesCount = 0 +FormatCount = 0 +ImportCount = 0 +SuggestedFixCount = 0 +DefinitionsCount = 0 +TypeDefinitionsCount = 0 +HighlightsCount = 0 +ReferencesCount = 0 +RenamesCount = 0 +PrepareRenamesCount = 0 +SymbolsCount = 0 +SignaturesCount = 0 +LinksCount = 0 +ImplementationsCount = 0 + diff --git a/internal/lsp/mod/testdata/unknowndirective/go.mod b/internal/lsp/mod/testdata/unknowndirective/go.mod deleted file mode 100644 index 4f07729db3..0000000000 --- a/internal/lsp/mod/testdata/unknowndirective/go.mod +++ /dev/null @@ -1,7 +0,0 @@ -module unknowndirective - -go 1.12 - -require golang.org/x/tools v0.0.0-20191219192050-56b0b28a00f7 - -yo diff --git a/internal/lsp/mod/testdata/unknowndirective/main.go b/internal/lsp/mod/testdata/unknowndirective/main.go deleted file mode 100644 index 5ee984e8e4..0000000000 --- a/internal/lsp/mod/testdata/unknowndirective/main.go +++ /dev/null @@ -1,10 +0,0 @@ -// Package unknowndirective does something -package unknowndirective - -import ( - "golang.org/x/tools/go/packages" -) - -func Yo() { - var _ packages.Config -} diff --git a/internal/lsp/source/source_test.go b/internal/lsp/source/source_test.go index b97c191cd9..d1c5ee48c2 100644 --- a/internal/lsp/source/source_test.go +++ b/internal/lsp/source/source_test.go @@ -45,39 +45,44 @@ type runner struct { func testSource(t *testing.T, exporter packagestest.Exporter) { ctx := tests.Context(t) data := tests.Load(t, exporter, "../testdata") - defer data.Exported.Cleanup() + for _, datum := range data { + defer datum.Exported.Cleanup() - cache := cache.New(nil) - session := cache.NewSession() - options := tests.DefaultOptions() - options.Env = data.Config.Env - view, _, err := session.NewView(ctx, "source_test", span.FileURI(data.Config.Dir), options) - if err != nil { - t.Fatal(err) - } - r := &runner{ - view: view, - data: data, - ctx: ctx, - } - var modifications []source.FileModification - for filename, content := range data.Config.Overlay { - kind := source.DetectLanguage("", filename) - if kind != source.Go { - continue + cache := cache.New(nil) + session := cache.NewSession() + options := tests.DefaultOptions() + options.Env = datum.Config.Env + view, _, err := session.NewView(ctx, "source_test", span.FileURI(datum.Config.Dir), options) + if err != nil { + t.Fatal(err) } - modifications = append(modifications, source.FileModification{ - URI: span.FileURI(filename), - Action: source.Open, - Version: -1, - Text: content, - LanguageID: "go", + r := &runner{ + view: view, + data: datum, + ctx: ctx, + } + var modifications []source.FileModification + for filename, content := range datum.Config.Overlay { + kind := source.DetectLanguage("", filename) + if kind != source.Go { + continue + } + modifications = append(modifications, source.FileModification{ + URI: span.FileURI(filename), + Action: source.Open, + Version: -1, + Text: content, + LanguageID: "go", + }) + } + if _, err := session.DidModifyFiles(ctx, modifications); err != nil { + t.Fatal(err) + } + t.Run(datum.Folder, func(t *testing.T) { + t.Helper() + tests.Run(t, r, datum) }) } - if _, err := session.DidModifyFiles(ctx, modifications); err != nil { - t.Fatal(err) - } - tests.Run(t, r, data) } func (r *runner) Diagnostics(t *testing.T, uri span.URI, want []source.Diagnostic) { diff --git a/internal/lsp/mod/testdata/indirect/go.mod b/internal/lsp/testdata/indirect/primarymod/go.mod similarity index 100% rename from internal/lsp/mod/testdata/indirect/go.mod rename to internal/lsp/testdata/indirect/primarymod/go.mod diff --git a/internal/lsp/mod/testdata/indirect/go.mod.golden b/internal/lsp/testdata/indirect/primarymod/go.mod.golden similarity index 100% rename from internal/lsp/mod/testdata/indirect/go.mod.golden rename to internal/lsp/testdata/indirect/primarymod/go.mod.golden diff --git a/internal/lsp/mod/testdata/indirect/go.sum b/internal/lsp/testdata/indirect/primarymod/go.sum similarity index 100% rename from internal/lsp/mod/testdata/indirect/go.sum rename to internal/lsp/testdata/indirect/primarymod/go.sum diff --git a/internal/lsp/mod/testdata/indirect/main.go b/internal/lsp/testdata/indirect/primarymod/main.go similarity index 100% rename from internal/lsp/mod/testdata/indirect/main.go rename to internal/lsp/testdata/indirect/primarymod/main.go diff --git a/internal/lsp/testdata/indirect/summary.txt.golden b/internal/lsp/testdata/indirect/summary.txt.golden new file mode 100644 index 0000000000..eec6c1e9c8 --- /dev/null +++ b/internal/lsp/testdata/indirect/summary.txt.golden @@ -0,0 +1,25 @@ +-- summary -- +CompletionsCount = 0 +CompletionSnippetCount = 0 +UnimportedCompletionsCount = 0 +DeepCompletionsCount = 0 +FuzzyCompletionsCount = 0 +RankedCompletionsCount = 0 +CaseSensitiveCompletionsCount = 0 +DiagnosticsCount = 0 +FoldingRangesCount = 0 +FormatCount = 0 +ImportCount = 0 +SuggestedFixCount = 0 +DefinitionsCount = 0 +TypeDefinitionsCount = 0 +HighlightsCount = 0 +ReferencesCount = 0 +RenamesCount = 0 +PrepareRenamesCount = 0 +SymbolsCount = 0 +WorkspaceSymbolsCount = 0 +SignaturesCount = 0 +LinksCount = 0 +ImplementationsCount = 0 + diff --git a/internal/lsp/testdata/lsp/modules/example.com/extramodule/pkg/x.go b/internal/lsp/testdata/lsp/modules/example.com/extramodule/pkg/x.go new file mode 100644 index 0000000000..cf7fc673d6 --- /dev/null +++ b/internal/lsp/testdata/lsp/modules/example.com/extramodule/pkg/x.go @@ -0,0 +1,3 @@ +package pkg + +const Test = 1 \ No newline at end of file diff --git a/internal/lsp/testdata/%percent/perc%ent.go b/internal/lsp/testdata/lsp/primarymod/%percent/perc%ent.go similarity index 100% rename from internal/lsp/testdata/%percent/perc%ent.go rename to internal/lsp/testdata/lsp/primarymod/%percent/perc%ent.go diff --git a/internal/lsp/testdata/address/address.go b/internal/lsp/testdata/lsp/primarymod/address/address.go similarity index 100% rename from internal/lsp/testdata/address/address.go rename to internal/lsp/testdata/lsp/primarymod/address/address.go diff --git a/internal/lsp/testdata/analyzer/bad_test.go b/internal/lsp/testdata/lsp/primarymod/analyzer/bad_test.go similarity index 100% rename from internal/lsp/testdata/analyzer/bad_test.go rename to internal/lsp/testdata/lsp/primarymod/analyzer/bad_test.go diff --git a/internal/lsp/testdata/anon/anon.go.in b/internal/lsp/testdata/lsp/primarymod/anon/anon.go.in similarity index 100% rename from internal/lsp/testdata/anon/anon.go.in rename to internal/lsp/testdata/lsp/primarymod/anon/anon.go.in diff --git a/internal/lsp/testdata/append/append.go b/internal/lsp/testdata/lsp/primarymod/append/append.go similarity index 100% rename from internal/lsp/testdata/append/append.go rename to internal/lsp/testdata/lsp/primarymod/append/append.go diff --git a/internal/lsp/testdata/arraytype/array_type.go.in b/internal/lsp/testdata/lsp/primarymod/arraytype/array_type.go.in similarity index 100% rename from internal/lsp/testdata/arraytype/array_type.go.in rename to internal/lsp/testdata/lsp/primarymod/arraytype/array_type.go.in diff --git a/internal/lsp/testdata/assign/assign.go.in b/internal/lsp/testdata/lsp/primarymod/assign/assign.go.in similarity index 100% rename from internal/lsp/testdata/assign/assign.go.in rename to internal/lsp/testdata/lsp/primarymod/assign/assign.go.in diff --git a/internal/lsp/testdata/bad/bad0.go b/internal/lsp/testdata/lsp/primarymod/bad/bad0.go similarity index 100% rename from internal/lsp/testdata/bad/bad0.go rename to internal/lsp/testdata/lsp/primarymod/bad/bad0.go diff --git a/internal/lsp/testdata/bad/bad1.go b/internal/lsp/testdata/lsp/primarymod/bad/bad1.go similarity index 100% rename from internal/lsp/testdata/bad/bad1.go rename to internal/lsp/testdata/lsp/primarymod/bad/bad1.go diff --git a/internal/lsp/testdata/bad/badimport.go b/internal/lsp/testdata/lsp/primarymod/bad/badimport.go similarity index 100% rename from internal/lsp/testdata/bad/badimport.go rename to internal/lsp/testdata/lsp/primarymod/bad/badimport.go diff --git a/internal/lsp/testdata/badstmt/badstmt.go.in b/internal/lsp/testdata/lsp/primarymod/badstmt/badstmt.go.in similarity index 100% rename from internal/lsp/testdata/badstmt/badstmt.go.in rename to internal/lsp/testdata/lsp/primarymod/badstmt/badstmt.go.in diff --git a/internal/lsp/testdata/badstmt/badstmt_2.go.in b/internal/lsp/testdata/lsp/primarymod/badstmt/badstmt_2.go.in similarity index 100% rename from internal/lsp/testdata/badstmt/badstmt_2.go.in rename to internal/lsp/testdata/lsp/primarymod/badstmt/badstmt_2.go.in diff --git a/internal/lsp/testdata/badstmt/badstmt_3.go.in b/internal/lsp/testdata/lsp/primarymod/badstmt/badstmt_3.go.in similarity index 100% rename from internal/lsp/testdata/badstmt/badstmt_3.go.in rename to internal/lsp/testdata/lsp/primarymod/badstmt/badstmt_3.go.in diff --git a/internal/lsp/testdata/badstmt/badstmt_4.go.in b/internal/lsp/testdata/lsp/primarymod/badstmt/badstmt_4.go.in similarity index 100% rename from internal/lsp/testdata/badstmt/badstmt_4.go.in rename to internal/lsp/testdata/lsp/primarymod/badstmt/badstmt_4.go.in diff --git a/internal/lsp/testdata/bar/bar.go.in b/internal/lsp/testdata/lsp/primarymod/bar/bar.go.in similarity index 100% rename from internal/lsp/testdata/bar/bar.go.in rename to internal/lsp/testdata/lsp/primarymod/bar/bar.go.in diff --git a/internal/lsp/testdata/basiclit/basiclit.go b/internal/lsp/testdata/lsp/primarymod/basiclit/basiclit.go similarity index 100% rename from internal/lsp/testdata/basiclit/basiclit.go rename to internal/lsp/testdata/lsp/primarymod/basiclit/basiclit.go diff --git a/internal/lsp/testdata/baz/baz.go.in b/internal/lsp/testdata/lsp/primarymod/baz/baz.go.in similarity index 100% rename from internal/lsp/testdata/baz/baz.go.in rename to internal/lsp/testdata/lsp/primarymod/baz/baz.go.in diff --git a/internal/lsp/testdata/builtins/builtin_args.go b/internal/lsp/testdata/lsp/primarymod/builtins/builtin_args.go similarity index 100% rename from internal/lsp/testdata/builtins/builtin_args.go rename to internal/lsp/testdata/lsp/primarymod/builtins/builtin_args.go diff --git a/internal/lsp/testdata/builtins/builtins.go b/internal/lsp/testdata/lsp/primarymod/builtins/builtins.go similarity index 100% rename from internal/lsp/testdata/builtins/builtins.go rename to internal/lsp/testdata/lsp/primarymod/builtins/builtins.go diff --git a/internal/lsp/testdata/builtins/constants.go b/internal/lsp/testdata/lsp/primarymod/builtins/constants.go similarity index 100% rename from internal/lsp/testdata/builtins/constants.go rename to internal/lsp/testdata/lsp/primarymod/builtins/constants.go diff --git a/internal/lsp/testdata/casesensitive/casesensitive.go b/internal/lsp/testdata/lsp/primarymod/casesensitive/casesensitive.go similarity index 100% rename from internal/lsp/testdata/casesensitive/casesensitive.go rename to internal/lsp/testdata/lsp/primarymod/casesensitive/casesensitive.go diff --git a/internal/lsp/testdata/cast/cast.go.in b/internal/lsp/testdata/lsp/primarymod/cast/cast.go.in similarity index 100% rename from internal/lsp/testdata/cast/cast.go.in rename to internal/lsp/testdata/lsp/primarymod/cast/cast.go.in diff --git a/internal/lsp/testdata/cgo/declarecgo.go b/internal/lsp/testdata/lsp/primarymod/cgo/declarecgo.go similarity index 100% rename from internal/lsp/testdata/cgo/declarecgo.go rename to internal/lsp/testdata/lsp/primarymod/cgo/declarecgo.go diff --git a/internal/lsp/testdata/cgo/declarecgo_nocgo.go b/internal/lsp/testdata/lsp/primarymod/cgo/declarecgo_nocgo.go similarity index 100% rename from internal/lsp/testdata/cgo/declarecgo_nocgo.go rename to internal/lsp/testdata/lsp/primarymod/cgo/declarecgo_nocgo.go diff --git a/internal/lsp/testdata/cgoimport/usecgo.go.golden b/internal/lsp/testdata/lsp/primarymod/cgoimport/usecgo.go.golden similarity index 100% rename from internal/lsp/testdata/cgoimport/usecgo.go.golden rename to internal/lsp/testdata/lsp/primarymod/cgoimport/usecgo.go.golden diff --git a/internal/lsp/testdata/cgoimport/usecgo.go.in b/internal/lsp/testdata/lsp/primarymod/cgoimport/usecgo.go.in similarity index 100% rename from internal/lsp/testdata/cgoimport/usecgo.go.in rename to internal/lsp/testdata/lsp/primarymod/cgoimport/usecgo.go.in diff --git a/internal/lsp/testdata/cgoimport/usegco.go.golden b/internal/lsp/testdata/lsp/primarymod/cgoimport/usegco.go.golden similarity index 100% rename from internal/lsp/testdata/cgoimport/usegco.go.golden rename to internal/lsp/testdata/lsp/primarymod/cgoimport/usegco.go.golden diff --git a/internal/lsp/testdata/channel/channel.go b/internal/lsp/testdata/lsp/primarymod/channel/channel.go similarity index 100% rename from internal/lsp/testdata/channel/channel.go rename to internal/lsp/testdata/lsp/primarymod/channel/channel.go diff --git a/internal/lsp/testdata/circular/double/b/b.go b/internal/lsp/testdata/lsp/primarymod/circular/double/b/b.go similarity index 100% rename from internal/lsp/testdata/circular/double/b/b.go rename to internal/lsp/testdata/lsp/primarymod/circular/double/b/b.go diff --git a/internal/lsp/testdata/circular/double/one/one.go b/internal/lsp/testdata/lsp/primarymod/circular/double/one/one.go similarity index 100% rename from internal/lsp/testdata/circular/double/one/one.go rename to internal/lsp/testdata/lsp/primarymod/circular/double/one/one.go diff --git a/internal/lsp/testdata/circular/self.go b/internal/lsp/testdata/lsp/primarymod/circular/self.go similarity index 100% rename from internal/lsp/testdata/circular/self.go rename to internal/lsp/testdata/lsp/primarymod/circular/self.go diff --git a/internal/lsp/testdata/circular/triple/a/a.go b/internal/lsp/testdata/lsp/primarymod/circular/triple/a/a.go similarity index 100% rename from internal/lsp/testdata/circular/triple/a/a.go rename to internal/lsp/testdata/lsp/primarymod/circular/triple/a/a.go diff --git a/internal/lsp/testdata/circular/triple/b/b.go b/internal/lsp/testdata/lsp/primarymod/circular/triple/b/b.go similarity index 100% rename from internal/lsp/testdata/circular/triple/b/b.go rename to internal/lsp/testdata/lsp/primarymod/circular/triple/b/b.go diff --git a/internal/lsp/testdata/circular/triple/c/c.go b/internal/lsp/testdata/lsp/primarymod/circular/triple/c/c.go similarity index 100% rename from internal/lsp/testdata/circular/triple/c/c.go rename to internal/lsp/testdata/lsp/primarymod/circular/triple/c/c.go diff --git a/internal/lsp/testdata/comments/comments.go b/internal/lsp/testdata/lsp/primarymod/comments/comments.go similarity index 100% rename from internal/lsp/testdata/comments/comments.go rename to internal/lsp/testdata/lsp/primarymod/comments/comments.go diff --git a/internal/lsp/testdata/complit/complit.go.in b/internal/lsp/testdata/lsp/primarymod/complit/complit.go.in similarity index 100% rename from internal/lsp/testdata/complit/complit.go.in rename to internal/lsp/testdata/lsp/primarymod/complit/complit.go.in diff --git a/internal/lsp/testdata/constant/constant.go b/internal/lsp/testdata/lsp/primarymod/constant/constant.go similarity index 100% rename from internal/lsp/testdata/constant/constant.go rename to internal/lsp/testdata/lsp/primarymod/constant/constant.go diff --git a/internal/lsp/testdata/deep/deep.go b/internal/lsp/testdata/lsp/primarymod/deep/deep.go similarity index 100% rename from internal/lsp/testdata/deep/deep.go rename to internal/lsp/testdata/lsp/primarymod/deep/deep.go diff --git a/internal/lsp/testdata/errors/errors.go b/internal/lsp/testdata/lsp/primarymod/errors/errors.go similarity index 100% rename from internal/lsp/testdata/errors/errors.go rename to internal/lsp/testdata/lsp/primarymod/errors/errors.go diff --git a/internal/lsp/testdata/fieldlist/field_list.go b/internal/lsp/testdata/lsp/primarymod/fieldlist/field_list.go similarity index 100% rename from internal/lsp/testdata/fieldlist/field_list.go rename to internal/lsp/testdata/lsp/primarymod/fieldlist/field_list.go diff --git a/internal/lsp/testdata/folding/a.go b/internal/lsp/testdata/lsp/primarymod/folding/a.go similarity index 100% rename from internal/lsp/testdata/folding/a.go rename to internal/lsp/testdata/lsp/primarymod/folding/a.go diff --git a/internal/lsp/testdata/folding/a.go.golden b/internal/lsp/testdata/lsp/primarymod/folding/a.go.golden similarity index 100% rename from internal/lsp/testdata/folding/a.go.golden rename to internal/lsp/testdata/lsp/primarymod/folding/a.go.golden diff --git a/internal/lsp/testdata/folding/bad.go.golden b/internal/lsp/testdata/lsp/primarymod/folding/bad.go.golden similarity index 100% rename from internal/lsp/testdata/folding/bad.go.golden rename to internal/lsp/testdata/lsp/primarymod/folding/bad.go.golden diff --git a/internal/lsp/testdata/folding/bad.go.in b/internal/lsp/testdata/lsp/primarymod/folding/bad.go.in similarity index 100% rename from internal/lsp/testdata/folding/bad.go.in rename to internal/lsp/testdata/lsp/primarymod/folding/bad.go.in diff --git a/internal/lsp/testdata/foo/foo.go b/internal/lsp/testdata/lsp/primarymod/foo/foo.go similarity index 100% rename from internal/lsp/testdata/foo/foo.go rename to internal/lsp/testdata/lsp/primarymod/foo/foo.go diff --git a/internal/lsp/testdata/format/bad_format.go.golden b/internal/lsp/testdata/lsp/primarymod/format/bad_format.go.golden similarity index 100% rename from internal/lsp/testdata/format/bad_format.go.golden rename to internal/lsp/testdata/lsp/primarymod/format/bad_format.go.golden diff --git a/internal/lsp/testdata/format/bad_format.go.in b/internal/lsp/testdata/lsp/primarymod/format/bad_format.go.in similarity index 100% rename from internal/lsp/testdata/format/bad_format.go.in rename to internal/lsp/testdata/lsp/primarymod/format/bad_format.go.in diff --git a/internal/lsp/testdata/format/good_format.go b/internal/lsp/testdata/lsp/primarymod/format/good_format.go similarity index 100% rename from internal/lsp/testdata/format/good_format.go rename to internal/lsp/testdata/lsp/primarymod/format/good_format.go diff --git a/internal/lsp/testdata/format/good_format.go.golden b/internal/lsp/testdata/lsp/primarymod/format/good_format.go.golden similarity index 100% rename from internal/lsp/testdata/format/good_format.go.golden rename to internal/lsp/testdata/lsp/primarymod/format/good_format.go.golden diff --git a/internal/lsp/testdata/format/newline_format.go.golden b/internal/lsp/testdata/lsp/primarymod/format/newline_format.go.golden similarity index 100% rename from internal/lsp/testdata/format/newline_format.go.golden rename to internal/lsp/testdata/lsp/primarymod/format/newline_format.go.golden diff --git a/internal/lsp/testdata/format/newline_format.go.in b/internal/lsp/testdata/lsp/primarymod/format/newline_format.go.in similarity index 100% rename from internal/lsp/testdata/format/newline_format.go.in rename to internal/lsp/testdata/lsp/primarymod/format/newline_format.go.in diff --git a/internal/lsp/testdata/format/one_line.go.golden b/internal/lsp/testdata/lsp/primarymod/format/one_line.go.golden similarity index 100% rename from internal/lsp/testdata/format/one_line.go.golden rename to internal/lsp/testdata/lsp/primarymod/format/one_line.go.golden diff --git a/internal/lsp/testdata/format/one_line.go.in b/internal/lsp/testdata/lsp/primarymod/format/one_line.go.in similarity index 100% rename from internal/lsp/testdata/format/one_line.go.in rename to internal/lsp/testdata/lsp/primarymod/format/one_line.go.in diff --git a/internal/lsp/testdata/func_rank/func_rank.go.in b/internal/lsp/testdata/lsp/primarymod/func_rank/func_rank.go.in similarity index 100% rename from internal/lsp/testdata/func_rank/func_rank.go.in rename to internal/lsp/testdata/lsp/primarymod/func_rank/func_rank.go.in diff --git a/internal/lsp/testdata/funcsig/func_sig.go b/internal/lsp/testdata/lsp/primarymod/funcsig/func_sig.go similarity index 100% rename from internal/lsp/testdata/funcsig/func_sig.go rename to internal/lsp/testdata/lsp/primarymod/funcsig/func_sig.go diff --git a/internal/lsp/testdata/funcvalue/func_value.go b/internal/lsp/testdata/lsp/primarymod/funcvalue/func_value.go similarity index 100% rename from internal/lsp/testdata/funcvalue/func_value.go rename to internal/lsp/testdata/lsp/primarymod/funcvalue/func_value.go diff --git a/internal/lsp/testdata/fuzzymatch/fuzzymatch.go b/internal/lsp/testdata/lsp/primarymod/fuzzymatch/fuzzymatch.go similarity index 100% rename from internal/lsp/testdata/fuzzymatch/fuzzymatch.go rename to internal/lsp/testdata/lsp/primarymod/fuzzymatch/fuzzymatch.go diff --git a/internal/lsp/testdata/generated/generated.go b/internal/lsp/testdata/lsp/primarymod/generated/generated.go similarity index 100% rename from internal/lsp/testdata/generated/generated.go rename to internal/lsp/testdata/lsp/primarymod/generated/generated.go diff --git a/internal/lsp/testdata/generated/generator.go b/internal/lsp/testdata/lsp/primarymod/generated/generator.go similarity index 100% rename from internal/lsp/testdata/generated/generator.go rename to internal/lsp/testdata/lsp/primarymod/generated/generator.go diff --git a/internal/lsp/testdata/godef/a/a.go b/internal/lsp/testdata/lsp/primarymod/godef/a/a.go similarity index 100% rename from internal/lsp/testdata/godef/a/a.go rename to internal/lsp/testdata/lsp/primarymod/godef/a/a.go diff --git a/internal/lsp/testdata/godef/a/a.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/a/a.go.golden similarity index 100% rename from internal/lsp/testdata/godef/a/a.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/a/a.go.golden diff --git a/internal/lsp/testdata/godef/a/a_test.go b/internal/lsp/testdata/lsp/primarymod/godef/a/a_test.go similarity index 100% rename from internal/lsp/testdata/godef/a/a_test.go rename to internal/lsp/testdata/lsp/primarymod/godef/a/a_test.go diff --git a/internal/lsp/testdata/godef/a/a_test.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/a/a_test.go.golden similarity index 100% rename from internal/lsp/testdata/godef/a/a_test.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/a/a_test.go.golden diff --git a/internal/lsp/testdata/godef/a/a_x_test.go b/internal/lsp/testdata/lsp/primarymod/godef/a/a_x_test.go similarity index 100% rename from internal/lsp/testdata/godef/a/a_x_test.go rename to internal/lsp/testdata/lsp/primarymod/godef/a/a_x_test.go diff --git a/internal/lsp/testdata/godef/a/a_x_test.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/a/a_x_test.go.golden similarity index 100% rename from internal/lsp/testdata/godef/a/a_x_test.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/a/a_x_test.go.golden diff --git a/internal/lsp/testdata/godef/a/d.go b/internal/lsp/testdata/lsp/primarymod/godef/a/d.go similarity index 100% rename from internal/lsp/testdata/godef/a/d.go rename to internal/lsp/testdata/lsp/primarymod/godef/a/d.go diff --git a/internal/lsp/testdata/godef/a/d.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/a/d.go.golden similarity index 100% rename from internal/lsp/testdata/godef/a/d.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/a/d.go.golden diff --git a/internal/lsp/testdata/godef/a/f.go b/internal/lsp/testdata/lsp/primarymod/godef/a/f.go similarity index 100% rename from internal/lsp/testdata/godef/a/f.go rename to internal/lsp/testdata/lsp/primarymod/godef/a/f.go diff --git a/internal/lsp/testdata/godef/a/f.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/a/f.go.golden similarity index 100% rename from internal/lsp/testdata/godef/a/f.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/a/f.go.golden diff --git a/internal/lsp/testdata/godef/a/random.go b/internal/lsp/testdata/lsp/primarymod/godef/a/random.go similarity index 100% rename from internal/lsp/testdata/godef/a/random.go rename to internal/lsp/testdata/lsp/primarymod/godef/a/random.go diff --git a/internal/lsp/testdata/godef/a/random.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/a/random.go.golden similarity index 100% rename from internal/lsp/testdata/godef/a/random.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/a/random.go.golden diff --git a/internal/lsp/testdata/godef/b/b.go b/internal/lsp/testdata/lsp/primarymod/godef/b/b.go similarity index 100% rename from internal/lsp/testdata/godef/b/b.go rename to internal/lsp/testdata/lsp/primarymod/godef/b/b.go diff --git a/internal/lsp/testdata/godef/b/b.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/b/b.go.golden similarity index 100% rename from internal/lsp/testdata/godef/b/b.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/b/b.go.golden diff --git a/internal/lsp/testdata/godef/b/c.go b/internal/lsp/testdata/lsp/primarymod/godef/b/c.go similarity index 100% rename from internal/lsp/testdata/godef/b/c.go rename to internal/lsp/testdata/lsp/primarymod/godef/b/c.go diff --git a/internal/lsp/testdata/godef/b/c.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/b/c.go.golden similarity index 100% rename from internal/lsp/testdata/godef/b/c.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/b/c.go.golden diff --git a/internal/lsp/testdata/godef/b/c.go.saved b/internal/lsp/testdata/lsp/primarymod/godef/b/c.go.saved similarity index 100% rename from internal/lsp/testdata/godef/b/c.go.saved rename to internal/lsp/testdata/lsp/primarymod/godef/b/c.go.saved diff --git a/internal/lsp/testdata/godef/b/e.go b/internal/lsp/testdata/lsp/primarymod/godef/b/e.go similarity index 100% rename from internal/lsp/testdata/godef/b/e.go rename to internal/lsp/testdata/lsp/primarymod/godef/b/e.go diff --git a/internal/lsp/testdata/godef/b/e.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/b/e.go.golden similarity index 100% rename from internal/lsp/testdata/godef/b/e.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/b/e.go.golden diff --git a/internal/lsp/testdata/godef/broken/unclosedIf.go.golden b/internal/lsp/testdata/lsp/primarymod/godef/broken/unclosedIf.go.golden similarity index 100% rename from internal/lsp/testdata/godef/broken/unclosedIf.go.golden rename to internal/lsp/testdata/lsp/primarymod/godef/broken/unclosedIf.go.golden diff --git a/internal/lsp/testdata/godef/broken/unclosedIf.go.in b/internal/lsp/testdata/lsp/primarymod/godef/broken/unclosedIf.go.in similarity index 100% rename from internal/lsp/testdata/godef/broken/unclosedIf.go.in rename to internal/lsp/testdata/lsp/primarymod/godef/broken/unclosedIf.go.in diff --git a/internal/lsp/testdata/good/good0.go b/internal/lsp/testdata/lsp/primarymod/good/good0.go similarity index 100% rename from internal/lsp/testdata/good/good0.go rename to internal/lsp/testdata/lsp/primarymod/good/good0.go diff --git a/internal/lsp/testdata/good/good1.go b/internal/lsp/testdata/lsp/primarymod/good/good1.go similarity index 100% rename from internal/lsp/testdata/good/good1.go rename to internal/lsp/testdata/lsp/primarymod/good/good1.go diff --git a/internal/lsp/testdata/highlights/highlights.go b/internal/lsp/testdata/lsp/primarymod/highlights/highlights.go similarity index 100% rename from internal/lsp/testdata/highlights/highlights.go rename to internal/lsp/testdata/lsp/primarymod/highlights/highlights.go diff --git a/internal/lsp/testdata/implementation/implementation.go b/internal/lsp/testdata/lsp/primarymod/implementation/implementation.go similarity index 100% rename from internal/lsp/testdata/implementation/implementation.go rename to internal/lsp/testdata/lsp/primarymod/implementation/implementation.go diff --git a/internal/lsp/testdata/implementation/other/other.go b/internal/lsp/testdata/lsp/primarymod/implementation/other/other.go similarity index 100% rename from internal/lsp/testdata/implementation/other/other.go rename to internal/lsp/testdata/lsp/primarymod/implementation/other/other.go diff --git a/internal/lsp/testdata/implementation/other/other_test.go b/internal/lsp/testdata/lsp/primarymod/implementation/other/other_test.go similarity index 100% rename from internal/lsp/testdata/implementation/other/other_test.go rename to internal/lsp/testdata/lsp/primarymod/implementation/other/other_test.go diff --git a/internal/lsp/testdata/importedcomplit/imported_complit.go b/internal/lsp/testdata/lsp/primarymod/importedcomplit/imported_complit.go similarity index 100% rename from internal/lsp/testdata/importedcomplit/imported_complit.go rename to internal/lsp/testdata/lsp/primarymod/importedcomplit/imported_complit.go diff --git a/internal/lsp/testdata/imports/add_import.go.golden b/internal/lsp/testdata/lsp/primarymod/imports/add_import.go.golden similarity index 100% rename from internal/lsp/testdata/imports/add_import.go.golden rename to internal/lsp/testdata/lsp/primarymod/imports/add_import.go.golden diff --git a/internal/lsp/testdata/imports/add_import.go.in b/internal/lsp/testdata/lsp/primarymod/imports/add_import.go.in similarity index 100% rename from internal/lsp/testdata/imports/add_import.go.in rename to internal/lsp/testdata/lsp/primarymod/imports/add_import.go.in diff --git a/internal/lsp/testdata/imports/good_imports.go.golden b/internal/lsp/testdata/lsp/primarymod/imports/good_imports.go.golden similarity index 100% rename from internal/lsp/testdata/imports/good_imports.go.golden rename to internal/lsp/testdata/lsp/primarymod/imports/good_imports.go.golden diff --git a/internal/lsp/testdata/imports/good_imports.go.in b/internal/lsp/testdata/lsp/primarymod/imports/good_imports.go.in similarity index 100% rename from internal/lsp/testdata/imports/good_imports.go.in rename to internal/lsp/testdata/lsp/primarymod/imports/good_imports.go.in diff --git a/internal/lsp/testdata/imports/issue35458.go.golden b/internal/lsp/testdata/lsp/primarymod/imports/issue35458.go.golden similarity index 100% rename from internal/lsp/testdata/imports/issue35458.go.golden rename to internal/lsp/testdata/lsp/primarymod/imports/issue35458.go.golden diff --git a/internal/lsp/testdata/imports/issue35458.go.in b/internal/lsp/testdata/lsp/primarymod/imports/issue35458.go.in similarity index 100% rename from internal/lsp/testdata/imports/issue35458.go.in rename to internal/lsp/testdata/lsp/primarymod/imports/issue35458.go.in diff --git a/internal/lsp/testdata/imports/multiple_blocks.go.golden b/internal/lsp/testdata/lsp/primarymod/imports/multiple_blocks.go.golden similarity index 100% rename from internal/lsp/testdata/imports/multiple_blocks.go.golden rename to internal/lsp/testdata/lsp/primarymod/imports/multiple_blocks.go.golden diff --git a/internal/lsp/testdata/imports/multiple_blocks.go.in b/internal/lsp/testdata/lsp/primarymod/imports/multiple_blocks.go.in similarity index 100% rename from internal/lsp/testdata/imports/multiple_blocks.go.in rename to internal/lsp/testdata/lsp/primarymod/imports/multiple_blocks.go.in diff --git a/internal/lsp/testdata/imports/needs_imports.go.golden b/internal/lsp/testdata/lsp/primarymod/imports/needs_imports.go.golden similarity index 100% rename from internal/lsp/testdata/imports/needs_imports.go.golden rename to internal/lsp/testdata/lsp/primarymod/imports/needs_imports.go.golden diff --git a/internal/lsp/testdata/imports/needs_imports.go.in b/internal/lsp/testdata/lsp/primarymod/imports/needs_imports.go.in similarity index 100% rename from internal/lsp/testdata/imports/needs_imports.go.in rename to internal/lsp/testdata/lsp/primarymod/imports/needs_imports.go.in diff --git a/internal/lsp/testdata/imports/remove_import.go.golden b/internal/lsp/testdata/lsp/primarymod/imports/remove_import.go.golden similarity index 100% rename from internal/lsp/testdata/imports/remove_import.go.golden rename to internal/lsp/testdata/lsp/primarymod/imports/remove_import.go.golden diff --git a/internal/lsp/testdata/imports/remove_import.go.in b/internal/lsp/testdata/lsp/primarymod/imports/remove_import.go.in similarity index 100% rename from internal/lsp/testdata/imports/remove_import.go.in rename to internal/lsp/testdata/lsp/primarymod/imports/remove_import.go.in diff --git a/internal/lsp/testdata/imports/remove_imports.go.golden b/internal/lsp/testdata/lsp/primarymod/imports/remove_imports.go.golden similarity index 100% rename from internal/lsp/testdata/imports/remove_imports.go.golden rename to internal/lsp/testdata/lsp/primarymod/imports/remove_imports.go.golden diff --git a/internal/lsp/testdata/imports/remove_imports.go.in b/internal/lsp/testdata/lsp/primarymod/imports/remove_imports.go.in similarity index 100% rename from internal/lsp/testdata/imports/remove_imports.go.in rename to internal/lsp/testdata/lsp/primarymod/imports/remove_imports.go.in diff --git a/internal/lsp/testdata/index/index.go b/internal/lsp/testdata/lsp/primarymod/index/index.go similarity index 100% rename from internal/lsp/testdata/index/index.go rename to internal/lsp/testdata/lsp/primarymod/index/index.go diff --git a/internal/lsp/testdata/interfacerank/interface_rank.go b/internal/lsp/testdata/lsp/primarymod/interfacerank/interface_rank.go similarity index 100% rename from internal/lsp/testdata/interfacerank/interface_rank.go rename to internal/lsp/testdata/lsp/primarymod/interfacerank/interface_rank.go diff --git a/internal/lsp/testdata/keywords/accidental_keywords.go.in b/internal/lsp/testdata/lsp/primarymod/keywords/accidental_keywords.go.in similarity index 100% rename from internal/lsp/testdata/keywords/accidental_keywords.go.in rename to internal/lsp/testdata/lsp/primarymod/keywords/accidental_keywords.go.in diff --git a/internal/lsp/testdata/keywords/keywords.go b/internal/lsp/testdata/lsp/primarymod/keywords/keywords.go similarity index 100% rename from internal/lsp/testdata/keywords/keywords.go rename to internal/lsp/testdata/lsp/primarymod/keywords/keywords.go diff --git a/internal/lsp/testdata/labels/labels.go b/internal/lsp/testdata/lsp/primarymod/labels/labels.go similarity index 100% rename from internal/lsp/testdata/labels/labels.go rename to internal/lsp/testdata/lsp/primarymod/labels/labels.go diff --git a/internal/lsp/testdata/links/links.go b/internal/lsp/testdata/lsp/primarymod/links/links.go similarity index 100% rename from internal/lsp/testdata/links/links.go rename to internal/lsp/testdata/lsp/primarymod/links/links.go diff --git a/internal/lsp/testdata/maps/maps.go.in b/internal/lsp/testdata/lsp/primarymod/maps/maps.go.in similarity index 100% rename from internal/lsp/testdata/maps/maps.go.in rename to internal/lsp/testdata/lsp/primarymod/maps/maps.go.in diff --git a/internal/lsp/testdata/multireturn/multi_return.go b/internal/lsp/testdata/lsp/primarymod/multireturn/multi_return.go similarity index 100% rename from internal/lsp/testdata/multireturn/multi_return.go rename to internal/lsp/testdata/lsp/primarymod/multireturn/multi_return.go diff --git a/internal/lsp/testdata/nested_complit/nested_complit.go.in b/internal/lsp/testdata/lsp/primarymod/nested_complit/nested_complit.go.in similarity index 100% rename from internal/lsp/testdata/nested_complit/nested_complit.go.in rename to internal/lsp/testdata/lsp/primarymod/nested_complit/nested_complit.go.in diff --git a/internal/lsp/testdata/nodisk/empty b/internal/lsp/testdata/lsp/primarymod/nodisk/empty similarity index 100% rename from internal/lsp/testdata/nodisk/empty rename to internal/lsp/testdata/lsp/primarymod/nodisk/empty diff --git a/internal/lsp/testdata/nodisk/nodisk.overlay.go b/internal/lsp/testdata/lsp/primarymod/nodisk/nodisk.overlay.go similarity index 100% rename from internal/lsp/testdata/nodisk/nodisk.overlay.go rename to internal/lsp/testdata/lsp/primarymod/nodisk/nodisk.overlay.go diff --git a/internal/lsp/testdata/noparse/noparse.go.in b/internal/lsp/testdata/lsp/primarymod/noparse/noparse.go.in similarity index 100% rename from internal/lsp/testdata/noparse/noparse.go.in rename to internal/lsp/testdata/lsp/primarymod/noparse/noparse.go.in diff --git a/internal/lsp/testdata/noparse_format/noparse_format.go.golden b/internal/lsp/testdata/lsp/primarymod/noparse_format/noparse_format.go.golden similarity index 100% rename from internal/lsp/testdata/noparse_format/noparse_format.go.golden rename to internal/lsp/testdata/lsp/primarymod/noparse_format/noparse_format.go.golden diff --git a/internal/lsp/testdata/noparse_format/noparse_format.go.in b/internal/lsp/testdata/lsp/primarymod/noparse_format/noparse_format.go.in similarity index 100% rename from internal/lsp/testdata/noparse_format/noparse_format.go.in rename to internal/lsp/testdata/lsp/primarymod/noparse_format/noparse_format.go.in diff --git a/internal/lsp/testdata/noparse_format/parse_format.go.golden b/internal/lsp/testdata/lsp/primarymod/noparse_format/parse_format.go.golden similarity index 100% rename from internal/lsp/testdata/noparse_format/parse_format.go.golden rename to internal/lsp/testdata/lsp/primarymod/noparse_format/parse_format.go.golden diff --git a/internal/lsp/testdata/noparse_format/parse_format.go.in b/internal/lsp/testdata/lsp/primarymod/noparse_format/parse_format.go.in similarity index 100% rename from internal/lsp/testdata/noparse_format/parse_format.go.in rename to internal/lsp/testdata/lsp/primarymod/noparse_format/parse_format.go.in diff --git a/internal/lsp/testdata/rank/assign_rank.go.in b/internal/lsp/testdata/lsp/primarymod/rank/assign_rank.go.in similarity index 100% rename from internal/lsp/testdata/rank/assign_rank.go.in rename to internal/lsp/testdata/lsp/primarymod/rank/assign_rank.go.in diff --git a/internal/lsp/testdata/rank/binexpr_rank.go.in b/internal/lsp/testdata/lsp/primarymod/rank/binexpr_rank.go.in similarity index 100% rename from internal/lsp/testdata/rank/binexpr_rank.go.in rename to internal/lsp/testdata/lsp/primarymod/rank/binexpr_rank.go.in diff --git a/internal/lsp/testdata/rank/convert_rank.go.in b/internal/lsp/testdata/lsp/primarymod/rank/convert_rank.go.in similarity index 100% rename from internal/lsp/testdata/rank/convert_rank.go.in rename to internal/lsp/testdata/lsp/primarymod/rank/convert_rank.go.in diff --git a/internal/lsp/testdata/rank/switch_rank.go.in b/internal/lsp/testdata/lsp/primarymod/rank/switch_rank.go.in similarity index 100% rename from internal/lsp/testdata/rank/switch_rank.go.in rename to internal/lsp/testdata/lsp/primarymod/rank/switch_rank.go.in diff --git a/internal/lsp/testdata/rank/type_assert_rank.go.in b/internal/lsp/testdata/lsp/primarymod/rank/type_assert_rank.go.in similarity index 100% rename from internal/lsp/testdata/rank/type_assert_rank.go.in rename to internal/lsp/testdata/lsp/primarymod/rank/type_assert_rank.go.in diff --git a/internal/lsp/testdata/rank/type_switch_rank.go.in b/internal/lsp/testdata/lsp/primarymod/rank/type_switch_rank.go.in similarity index 100% rename from internal/lsp/testdata/rank/type_switch_rank.go.in rename to internal/lsp/testdata/lsp/primarymod/rank/type_switch_rank.go.in diff --git a/internal/lsp/testdata/references/other/other.go b/internal/lsp/testdata/lsp/primarymod/references/other/other.go similarity index 100% rename from internal/lsp/testdata/references/other/other.go rename to internal/lsp/testdata/lsp/primarymod/references/other/other.go diff --git a/internal/lsp/testdata/references/refs.go b/internal/lsp/testdata/lsp/primarymod/references/refs.go similarity index 100% rename from internal/lsp/testdata/references/refs.go rename to internal/lsp/testdata/lsp/primarymod/references/refs.go diff --git a/internal/lsp/testdata/references/refs_test.go b/internal/lsp/testdata/lsp/primarymod/references/refs_test.go similarity index 100% rename from internal/lsp/testdata/references/refs_test.go rename to internal/lsp/testdata/lsp/primarymod/references/refs_test.go diff --git a/internal/lsp/testdata/rename/a/random.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/a/random.go.golden similarity index 100% rename from internal/lsp/testdata/rename/a/random.go.golden rename to internal/lsp/testdata/lsp/primarymod/rename/a/random.go.golden diff --git a/internal/lsp/testdata/rename/a/random.go.in b/internal/lsp/testdata/lsp/primarymod/rename/a/random.go.in similarity index 100% rename from internal/lsp/testdata/rename/a/random.go.in rename to internal/lsp/testdata/lsp/primarymod/rename/a/random.go.in diff --git a/internal/lsp/testdata/rename/b/b.go b/internal/lsp/testdata/lsp/primarymod/rename/b/b.go similarity index 100% rename from internal/lsp/testdata/rename/b/b.go rename to internal/lsp/testdata/lsp/primarymod/rename/b/b.go diff --git a/internal/lsp/testdata/rename/b/b.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden similarity index 100% rename from internal/lsp/testdata/rename/b/b.go.golden rename to internal/lsp/testdata/lsp/primarymod/rename/b/b.go.golden diff --git a/internal/lsp/testdata/rename/bad/bad.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/bad/bad.go.golden similarity index 100% rename from internal/lsp/testdata/rename/bad/bad.go.golden rename to internal/lsp/testdata/lsp/primarymod/rename/bad/bad.go.golden diff --git a/internal/lsp/testdata/rename/bad/bad.go.in b/internal/lsp/testdata/lsp/primarymod/rename/bad/bad.go.in similarity index 100% rename from internal/lsp/testdata/rename/bad/bad.go.in rename to internal/lsp/testdata/lsp/primarymod/rename/bad/bad.go.in diff --git a/internal/lsp/testdata/rename/bad/bad_test.go.in b/internal/lsp/testdata/lsp/primarymod/rename/bad/bad_test.go.in similarity index 100% rename from internal/lsp/testdata/rename/bad/bad_test.go.in rename to internal/lsp/testdata/lsp/primarymod/rename/bad/bad_test.go.in diff --git a/internal/lsp/testdata/rename/crosspkg/crosspkg.go b/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/crosspkg.go similarity index 100% rename from internal/lsp/testdata/rename/crosspkg/crosspkg.go rename to internal/lsp/testdata/lsp/primarymod/rename/crosspkg/crosspkg.go diff --git a/internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/crosspkg.go.golden similarity index 100% rename from internal/lsp/testdata/rename/crosspkg/crosspkg.go.golden rename to internal/lsp/testdata/lsp/primarymod/rename/crosspkg/crosspkg.go.golden diff --git a/internal/lsp/testdata/rename/crosspkg/other/other.go b/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/other/other.go similarity index 100% rename from internal/lsp/testdata/rename/crosspkg/other/other.go rename to internal/lsp/testdata/lsp/primarymod/rename/crosspkg/other/other.go diff --git a/internal/lsp/testdata/rename/crosspkg/other/other.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/crosspkg/other/other.go.golden similarity index 100% rename from internal/lsp/testdata/rename/crosspkg/other/other.go.golden rename to internal/lsp/testdata/lsp/primarymod/rename/crosspkg/other/other.go.golden diff --git a/internal/lsp/testdata/rename/testy/testy.go b/internal/lsp/testdata/lsp/primarymod/rename/testy/testy.go similarity index 100% rename from internal/lsp/testdata/rename/testy/testy.go rename to internal/lsp/testdata/lsp/primarymod/rename/testy/testy.go diff --git a/internal/lsp/testdata/rename/testy/testy.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/testy/testy.go.golden similarity index 100% rename from internal/lsp/testdata/rename/testy/testy.go.golden rename to internal/lsp/testdata/lsp/primarymod/rename/testy/testy.go.golden diff --git a/internal/lsp/testdata/rename/testy/testy_test.go b/internal/lsp/testdata/lsp/primarymod/rename/testy/testy_test.go similarity index 100% rename from internal/lsp/testdata/rename/testy/testy_test.go rename to internal/lsp/testdata/lsp/primarymod/rename/testy/testy_test.go diff --git a/internal/lsp/testdata/rename/testy/testy_test.go.golden b/internal/lsp/testdata/lsp/primarymod/rename/testy/testy_test.go.golden similarity index 100% rename from internal/lsp/testdata/rename/testy/testy_test.go.golden rename to internal/lsp/testdata/lsp/primarymod/rename/testy/testy_test.go.golden diff --git a/internal/lsp/testdata/selector/selector.go.in b/internal/lsp/testdata/lsp/primarymod/selector/selector.go.in similarity index 100% rename from internal/lsp/testdata/selector/selector.go.in rename to internal/lsp/testdata/lsp/primarymod/selector/selector.go.in diff --git a/internal/lsp/testdata/signature/signature.go b/internal/lsp/testdata/lsp/primarymod/signature/signature.go similarity index 100% rename from internal/lsp/testdata/signature/signature.go rename to internal/lsp/testdata/lsp/primarymod/signature/signature.go diff --git a/internal/lsp/testdata/signature/signature.go.golden b/internal/lsp/testdata/lsp/primarymod/signature/signature.go.golden similarity index 100% rename from internal/lsp/testdata/signature/signature.go.golden rename to internal/lsp/testdata/lsp/primarymod/signature/signature.go.golden diff --git a/internal/lsp/testdata/signature/signature2.go.golden b/internal/lsp/testdata/lsp/primarymod/signature/signature2.go.golden similarity index 100% rename from internal/lsp/testdata/signature/signature2.go.golden rename to internal/lsp/testdata/lsp/primarymod/signature/signature2.go.golden diff --git a/internal/lsp/testdata/signature/signature2.go.in b/internal/lsp/testdata/lsp/primarymod/signature/signature2.go.in similarity index 100% rename from internal/lsp/testdata/signature/signature2.go.in rename to internal/lsp/testdata/lsp/primarymod/signature/signature2.go.in diff --git a/internal/lsp/testdata/snippets/literal_snippets.go.in b/internal/lsp/testdata/lsp/primarymod/snippets/literal_snippets.go.in similarity index 100% rename from internal/lsp/testdata/snippets/literal_snippets.go.in rename to internal/lsp/testdata/lsp/primarymod/snippets/literal_snippets.go.in diff --git a/internal/lsp/testdata/snippets/snippets.go.golden b/internal/lsp/testdata/lsp/primarymod/snippets/snippets.go.golden similarity index 100% rename from internal/lsp/testdata/snippets/snippets.go.golden rename to internal/lsp/testdata/lsp/primarymod/snippets/snippets.go.golden diff --git a/internal/lsp/testdata/snippets/snippets.go.in b/internal/lsp/testdata/lsp/primarymod/snippets/snippets.go.in similarity index 100% rename from internal/lsp/testdata/snippets/snippets.go.in rename to internal/lsp/testdata/lsp/primarymod/snippets/snippets.go.in diff --git a/internal/lsp/testdata/suggestedfix/has_suggested_fix.go b/internal/lsp/testdata/lsp/primarymod/suggestedfix/has_suggested_fix.go similarity index 100% rename from internal/lsp/testdata/suggestedfix/has_suggested_fix.go rename to internal/lsp/testdata/lsp/primarymod/suggestedfix/has_suggested_fix.go diff --git a/internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden b/internal/lsp/testdata/lsp/primarymod/suggestedfix/has_suggested_fix.go.golden similarity index 100% rename from internal/lsp/testdata/suggestedfix/has_suggested_fix.go.golden rename to internal/lsp/testdata/lsp/primarymod/suggestedfix/has_suggested_fix.go.golden diff --git a/internal/lsp/testdata/symbols/main.go b/internal/lsp/testdata/lsp/primarymod/symbols/main.go similarity index 100% rename from internal/lsp/testdata/symbols/main.go rename to internal/lsp/testdata/lsp/primarymod/symbols/main.go diff --git a/internal/lsp/testdata/symbols/main.go.golden b/internal/lsp/testdata/lsp/primarymod/symbols/main.go.golden similarity index 100% rename from internal/lsp/testdata/symbols/main.go.golden rename to internal/lsp/testdata/lsp/primarymod/symbols/main.go.golden diff --git a/internal/lsp/testdata/testy/testy.go b/internal/lsp/testdata/lsp/primarymod/testy/testy.go similarity index 100% rename from internal/lsp/testdata/testy/testy.go rename to internal/lsp/testdata/lsp/primarymod/testy/testy.go diff --git a/internal/lsp/testdata/testy/testy_test.go b/internal/lsp/testdata/lsp/primarymod/testy/testy_test.go similarity index 100% rename from internal/lsp/testdata/testy/testy_test.go rename to internal/lsp/testdata/lsp/primarymod/testy/testy_test.go diff --git a/internal/lsp/testdata/typeassert/type_assert.go b/internal/lsp/testdata/lsp/primarymod/typeassert/type_assert.go similarity index 100% rename from internal/lsp/testdata/typeassert/type_assert.go rename to internal/lsp/testdata/lsp/primarymod/typeassert/type_assert.go diff --git a/internal/lsp/testdata/types/types.go b/internal/lsp/testdata/lsp/primarymod/types/types.go similarity index 100% rename from internal/lsp/testdata/types/types.go rename to internal/lsp/testdata/lsp/primarymod/types/types.go diff --git a/internal/lsp/testdata/unimported/export_test.go b/internal/lsp/testdata/lsp/primarymod/unimported/export_test.go similarity index 100% rename from internal/lsp/testdata/unimported/export_test.go rename to internal/lsp/testdata/lsp/primarymod/unimported/export_test.go diff --git a/internal/lsp/testdata/unimported/unimported.go.in b/internal/lsp/testdata/lsp/primarymod/unimported/unimported.go.in similarity index 100% rename from internal/lsp/testdata/unimported/unimported.go.in rename to internal/lsp/testdata/lsp/primarymod/unimported/unimported.go.in diff --git a/internal/lsp/testdata/unimported/unimported_cand_type.go b/internal/lsp/testdata/lsp/primarymod/unimported/unimported_cand_type.go similarity index 100% rename from internal/lsp/testdata/unimported/unimported_cand_type.go rename to internal/lsp/testdata/lsp/primarymod/unimported/unimported_cand_type.go diff --git a/internal/lsp/testdata/unimported/x_test.go b/internal/lsp/testdata/lsp/primarymod/unimported/x_test.go similarity index 100% rename from internal/lsp/testdata/unimported/x_test.go rename to internal/lsp/testdata/lsp/primarymod/unimported/x_test.go diff --git a/internal/lsp/testdata/unresolved/unresolved.go.in b/internal/lsp/testdata/lsp/primarymod/unresolved/unresolved.go.in similarity index 100% rename from internal/lsp/testdata/unresolved/unresolved.go.in rename to internal/lsp/testdata/lsp/primarymod/unresolved/unresolved.go.in diff --git a/internal/lsp/testdata/unsafe/unsafe.go b/internal/lsp/testdata/lsp/primarymod/unsafe/unsafe.go similarity index 100% rename from internal/lsp/testdata/unsafe/unsafe.go rename to internal/lsp/testdata/lsp/primarymod/unsafe/unsafe.go diff --git a/internal/lsp/testdata/variadic/variadic.go.in b/internal/lsp/testdata/lsp/primarymod/variadic/variadic.go.in similarity index 100% rename from internal/lsp/testdata/variadic/variadic.go.in rename to internal/lsp/testdata/lsp/primarymod/variadic/variadic.go.in diff --git a/internal/lsp/testdata/variadic/variadic_intf.go b/internal/lsp/testdata/lsp/primarymod/variadic/variadic_intf.go similarity index 100% rename from internal/lsp/testdata/variadic/variadic_intf.go rename to internal/lsp/testdata/lsp/primarymod/variadic/variadic_intf.go diff --git a/internal/lsp/testdata/workspacesymbol/a/a.go b/internal/lsp/testdata/lsp/primarymod/workspacesymbol/a/a.go similarity index 100% rename from internal/lsp/testdata/workspacesymbol/a/a.go rename to internal/lsp/testdata/lsp/primarymod/workspacesymbol/a/a.go diff --git a/internal/lsp/testdata/workspacesymbol/a/a.go.golden b/internal/lsp/testdata/lsp/primarymod/workspacesymbol/a/a.go.golden similarity index 100% rename from internal/lsp/testdata/workspacesymbol/a/a.go.golden rename to internal/lsp/testdata/lsp/primarymod/workspacesymbol/a/a.go.golden diff --git a/internal/lsp/testdata/workspacesymbol/b/b.go b/internal/lsp/testdata/lsp/primarymod/workspacesymbol/b/b.go similarity index 100% rename from internal/lsp/testdata/workspacesymbol/b/b.go rename to internal/lsp/testdata/lsp/primarymod/workspacesymbol/b/b.go diff --git a/internal/lsp/testdata/workspacesymbol/b/b.go.golden b/internal/lsp/testdata/lsp/primarymod/workspacesymbol/b/b.go.golden similarity index 100% rename from internal/lsp/testdata/workspacesymbol/b/b.go.golden rename to internal/lsp/testdata/lsp/primarymod/workspacesymbol/b/b.go.golden diff --git a/internal/lsp/testdata/workspacesymbol/workspacesymbol.go b/internal/lsp/testdata/lsp/primarymod/workspacesymbol/workspacesymbol.go similarity index 100% rename from internal/lsp/testdata/workspacesymbol/workspacesymbol.go rename to internal/lsp/testdata/lsp/primarymod/workspacesymbol/workspacesymbol.go diff --git a/internal/lsp/testdata/summary.txt.golden b/internal/lsp/testdata/lsp/summary.txt.golden similarity index 100% rename from internal/lsp/testdata/summary.txt.golden rename to internal/lsp/testdata/lsp/summary.txt.golden diff --git a/internal/lsp/mod/testdata/unused/go.mod b/internal/lsp/testdata/unused/primarymod/go.mod similarity index 100% rename from internal/lsp/mod/testdata/unused/go.mod rename to internal/lsp/testdata/unused/primarymod/go.mod diff --git a/internal/lsp/mod/testdata/unused/go.mod.golden b/internal/lsp/testdata/unused/primarymod/go.mod.golden similarity index 100% rename from internal/lsp/mod/testdata/unused/go.mod.golden rename to internal/lsp/testdata/unused/primarymod/go.mod.golden diff --git a/internal/lsp/mod/testdata/unused/go.sum b/internal/lsp/testdata/unused/primarymod/go.sum similarity index 100% rename from internal/lsp/mod/testdata/unused/go.sum rename to internal/lsp/testdata/unused/primarymod/go.sum diff --git a/internal/lsp/mod/testdata/unused/main.go b/internal/lsp/testdata/unused/primarymod/main.go similarity index 100% rename from internal/lsp/mod/testdata/unused/main.go rename to internal/lsp/testdata/unused/primarymod/main.go diff --git a/internal/lsp/testdata/unused/summary.txt.golden b/internal/lsp/testdata/unused/summary.txt.golden new file mode 100644 index 0000000000..eec6c1e9c8 --- /dev/null +++ b/internal/lsp/testdata/unused/summary.txt.golden @@ -0,0 +1,25 @@ +-- summary -- +CompletionsCount = 0 +CompletionSnippetCount = 0 +UnimportedCompletionsCount = 0 +DeepCompletionsCount = 0 +FuzzyCompletionsCount = 0 +RankedCompletionsCount = 0 +CaseSensitiveCompletionsCount = 0 +DiagnosticsCount = 0 +FoldingRangesCount = 0 +FormatCount = 0 +ImportCount = 0 +SuggestedFixCount = 0 +DefinitionsCount = 0 +TypeDefinitionsCount = 0 +HighlightsCount = 0 +ReferencesCount = 0 +RenamesCount = 0 +PrepareRenamesCount = 0 +SymbolsCount = 0 +WorkspaceSymbolsCount = 0 +SignaturesCount = 0 +LinksCount = 0 +ImplementationsCount = 0 + diff --git a/internal/lsp/tests/tests.go b/internal/lsp/tests/tests.go index 26ac4a4b92..405cd4cd6e 100644 --- a/internal/lsp/tests/tests.go +++ b/internal/lsp/tests/tests.go @@ -36,6 +36,7 @@ const ( overlayFileSuffix = ".overlay" goldenFileSuffix = ".golden" inFileSuffix = ".in" + summaryFile = "summary.txt.golden" testModule = "golang.org/x/tools/internal/lsp" ) @@ -99,6 +100,7 @@ type Data struct { t testing.TB fragments map[string]string dir string + Folder string golden map[string]*Golden mappersMu sync.Mutex @@ -205,151 +207,201 @@ func DefaultOptions() source.Options { var haveCgo = false -func Load(t testing.TB, exporter packagestest.Exporter, dir string) *Data { +// For Load() to properly create the folder structure required when testing with modules. +// The directory structure of a test needs to look like the example below: +// +// - dir +// - primarymod +// - .go files +// - packages +// - go.mod (optional) +// - modules +// - repoa +// - mod1 +// - .go files +// - packages +// - go.mod (optional) +// - mod2 +// - repob +// - mod1 +// +// All the files that are primarily being tested should be in the primarymod folder, +// any auxillary packages should be declared in the modules folder. +// The modules folder requires each module to have the following format: repo/module +// Then inside each repo/module, there can be any number of packages and files that are +// needed to test the primarymod. +func Load(t testing.TB, exporter packagestest.Exporter, dir string) []*Data { t.Helper() - data := &Data{ - 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), - Implementations: make(Implementations), - Highlights: make(Highlights), - References: make(References), - Renames: make(Renames), - PrepareRenames: make(PrepareRenames), - Symbols: make(Symbols), - symbolsChildren: make(SymbolsChildren), - symbolInformation: make(SymbolInformation), - WorkspaceSymbols: make(WorkspaceSymbols), - Signatures: make(Signatures), - Links: make(Links), - - t: t, - dir: dir, - fragments: map[string]string{}, - golden: map[string]*Golden{}, - mappers: map[span.URI]*protocol.ColumnMapper{}, + folders, err := testFolders(dir) + if err != nil { + t.Fatalf("could not get test folders for %v, %v", dir, err) } - files := packagestest.MustCopyFileTree(dir) - overlays := map[string][]byte{} - for fragment, operation := range files { - if trimmed := strings.TrimSuffix(fragment, goldenFileSuffix); trimmed != fragment { - delete(files, fragment) - goldFile := filepath.Join(dir, fragment) - archive, err := txtar.ParseFile(goldFile) - if err != nil { - t.Fatalf("could not read golden file %v: %v", fragment, err) - } - data.golden[trimmed] = &Golden{ - Filename: goldFile, - Archive: archive, - } - } else if trimmed := strings.TrimSuffix(fragment, inFileSuffix); trimmed != fragment { - delete(files, fragment) - files[trimmed] = operation - } else if index := strings.Index(fragment, overlayFileSuffix); index >= 0 { - delete(files, fragment) - partial := fragment[:index] + fragment[index+len(overlayFileSuffix):] - contents, err := ioutil.ReadFile(filepath.Join(dir, fragment)) - if err != nil { - t.Fatal(err) - } - overlays[partial] = contents + var data []*Data + for _, folder := range folders { + datum := &Data{ + 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), + Implementations: make(Implementations), + Highlights: make(Highlights), + References: make(References), + Renames: make(Renames), + PrepareRenames: make(PrepareRenames), + Symbols: make(Symbols), + symbolsChildren: make(SymbolsChildren), + symbolInformation: make(SymbolInformation), + WorkspaceSymbols: make(WorkspaceSymbols), + Signatures: make(Signatures), + Links: make(Links), + + t: t, + dir: folder, + Folder: folder, + fragments: map[string]string{}, + golden: map[string]*Golden{}, + mappers: map[span.URI]*protocol.ColumnMapper{}, } - } - modules := []packagestest.Module{ - { - Name: testModule, - Files: files, - Overlay: overlays, - }, - { - Name: "example.com/extramodule", - Files: map[string]interface{}{ - "pkg/x.go": "package pkg\n", + + summary := filepath.Join(filepath.FromSlash(folder), summaryFile) + if _, err := os.Stat(summary); os.IsNotExist(err) { + t.Fatalf("could not find golden file summary.txt in %#v", folder) + } + archive, err := txtar.ParseFile(summary) + if err != nil { + t.Fatalf("could not read golden file %v/%v: %v", folder, summary, err) + } + datum.golden["summary.txt"] = &Golden{ + Filename: summary, + Archive: archive, + } + + modules, _ := packagestest.GroupFilesByModules(folder) + for i, m := range modules { + for fragment, operation := range m.Files { + if trimmed := strings.TrimSuffix(fragment, goldenFileSuffix); trimmed != fragment { + delete(m.Files, fragment) + goldFile := filepath.Join(m.Name, fragment) + if i == 0 { + goldFile = filepath.Join(m.Name, "primarymod", fragment) + } + archive, err := txtar.ParseFile(goldFile) + if err != nil { + t.Fatalf("could not read golden file %v: %v", fragment, err) + } + datum.golden[trimmed] = &Golden{ + Filename: goldFile, + Archive: archive, + } + } else if trimmed := strings.TrimSuffix(fragment, inFileSuffix); trimmed != fragment { + delete(m.Files, fragment) + m.Files[trimmed] = operation + } else if index := strings.Index(fragment, overlayFileSuffix); index >= 0 { + delete(m.Files, fragment) + partial := fragment[:index] + fragment[index+len(overlayFileSuffix):] + overlayFile := filepath.Join(m.Name, fragment) + if i == 0 { + overlayFile = filepath.Join(m.Name, "primarymod", fragment) + } + contents, err := ioutil.ReadFile(overlayFile) + if err != nil { + t.Fatal(err) + } + m.Overlay[partial] = contents + } + } + } + if len(modules) > 0 { + // For certain LSP related tests to run, make sure that the primary + // module for the passed in directory is testModule. + modules[0].Name = testModule + } + // Add exampleModule to provide tests with another pkg. + datum.Exported = packagestest.Export(t, exporter, modules) + for _, m := range modules { + for fragment := range m.Files { + filename := datum.Exported.File(m.Name, fragment) + datum.fragments[filename] = fragment + } + } + + // Turn off go/packages debug logging. + datum.Exported.Config.Logf = nil + datum.Config.Logf = nil + + // Merge the exported.Config with the view.Config. + datum.Config = *datum.Exported.Config + datum.Config.Fset = token.NewFileSet() + datum.Config.Context = Context(nil) + datum.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { + panic("ParseFile should not be called") + } + + // Do a first pass to collect special markers for completion and workspace symbols. + if err := datum.Exported.Expect(map[string]interface{}{ + "item": func(name string, r packagestest.Range, _ []string) { + datum.Exported.Mark(name, r) }, - }, - } - data.Exported = packagestest.Export(t, exporter, modules) - for fragment := range files { - filename := data.Exported.File(testModule, fragment) - data.fragments[filename] = fragment - } - - // Turn off go/packages debug logging. - data.Exported.Config.Logf = nil - data.Config.Logf = nil - - // Merge the exported.Config with the view.Config. - data.Config = *data.Exported.Config - data.Config.Fset = token.NewFileSet() - data.Config.Context = Context(nil) - data.Config.ParseFile = func(fset *token.FileSet, filename string, src []byte) (*ast.File, error) { - panic("ParseFile should not be called") - } - - // Do a first pass to collect special markers for completion and workspace symbols. - if err := data.Exported.Expect(map[string]interface{}{ - "item": func(name string, r packagestest.Range, _ []string) { - data.Exported.Mark(name, r) - }, - "symbol": func(name string, r packagestest.Range, _ []string) { - data.Exported.Mark(name, r) - }, - }); err != nil { - t.Fatal(err) - } - - // Collect any data that needs to be used by subsequent tests. - if err := data.Exported.Expect(map[string]interface{}{ - "diag": data.collectDiagnostics, - "item": data.collectCompletionItems, - "complete": data.collectCompletions(CompletionDefault), - "unimported": data.collectCompletions(CompletionUnimported), - "deep": data.collectCompletions(CompletionDeep), - "fuzzy": data.collectCompletions(CompletionFuzzy), - "casesensitive": data.collectCompletions(CompletionCaseSensitive), - "rank": data.collectCompletions(CompletionRank), - "snippet": data.collectCompletionSnippets, - "fold": data.collectFoldingRanges, - "format": data.collectFormats, - "import": data.collectImports, - "godef": data.collectDefinitions, - "implementations": data.collectImplementations, - "typdef": data.collectTypeDefinitions, - "hover": data.collectHoverDefinitions, - "highlight": data.collectHighlights, - "refs": data.collectReferences, - "rename": data.collectRenames, - "prepare": data.collectPrepareRenames, - "symbol": data.collectSymbols, - "signature": data.collectSignatures, - "link": data.collectLinks, - "suggestedfix": data.collectSuggestedFixes, - }); err != nil { - t.Fatal(err) - } - for _, symbols := range data.Symbols { - for i := range symbols { - children := data.symbolsChildren[symbols[i].Name] - symbols[i].Children = children + "symbol": func(name string, r packagestest.Range, _ []string) { + datum.Exported.Mark(name, r) + }, + }); err != nil { + t.Fatal(err) } - } - // Collect names for the entries that require golden files. - if err := data.Exported.Expect(map[string]interface{}{ - "godef": data.collectDefinitionNames, - "hover": data.collectDefinitionNames, - "workspacesymbol": data.collectWorkspaceSymbols, - }); err != nil { - t.Fatal(err) + + // 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, + "fold": datum.collectFoldingRanges, + "format": datum.collectFormats, + "import": datum.collectImports, + "godef": datum.collectDefinitions, + "implementations": datum.collectImplementations, + "typdef": datum.collectTypeDefinitions, + "hover": datum.collectHoverDefinitions, + "highlight": datum.collectHighlights, + "refs": datum.collectReferences, + "rename": datum.collectRenames, + "prepare": datum.collectPrepareRenames, + "symbol": datum.collectSymbols, + "signature": datum.collectSignatures, + "link": datum.collectLinks, + "suggestedfix": datum.collectSuggestedFixes, + }); err != nil { + t.Fatal(err) + } + for _, symbols := range datum.Symbols { + for i := range symbols { + children := datum.symbolsChildren[symbols[i].Name] + symbols[i].Children = children + } + } + // Collect names for the entries that require golden files. + if err := datum.Exported.Expect(map[string]interface{}{ + "godef": datum.collectDefinitionNames, + "hover": datum.collectDefinitionNames, + "workspacesymbol": datum.collectWorkspaceSymbols, + }); err != nil { + t.Fatal(err) + } + + data = append(data, datum) } return data } @@ -1011,3 +1063,25 @@ func CopyFolderToTempDir(folder string) (string, error) { } return dst, nil } + +func testFolders(root string) ([]string, error) { + // Check if this only has one test directory. + if _, err := os.Stat(filepath.Join(filepath.FromSlash(root), "primarymod")); !os.IsNotExist(err) { + return []string{root}, nil + } + folders := []string{} + root = filepath.FromSlash(root) + // Get all test directories that are one level deeper than root. + if err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if !info.IsDir() { + return nil + } + if filepath.Dir(path) == root { + folders = append(folders, filepath.ToSlash(path)) + } + return nil + }); err != nil { + return nil, err + } + return folders, nil +}