gopls: add regtest mode for experiments, like workspace module tests

This CL adds another regtest mode for trying out experiments, like the
workspace module mode. Before this CL, we lost coverage for default
mode when we turned experimental module mode on by default.

Removed TestNoWorkspaceModule, as it was just a placeholder until this
mode was available.

Change-Id: Ie3e4c2daec3e635c188bafa25b33dd178da875a3
Reviewed-on: https://go-review.googlesource.com/c/tools/+/258518
Trust: Rebecca Stambler <rstambler@golang.org>
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
gopls-CI: kokoro <noreply+kokoro@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Findley <rfindley@google.com>
diff --git a/gopls/internal/regtest/diagnostics_test.go b/gopls/internal/regtest/diagnostics_test.go
index d9450c0..109561a 100644
--- a/gopls/internal/regtest/diagnostics_test.go
+++ b/gopls/internal/regtest/diagnostics_test.go
@@ -282,9 +282,9 @@
 	})
 
 	t.Run("without workspace module", func(t *testing.T) {
-		withOptions(EditorConfig{
-			WithoutExperimentalWorkspaceModule: true,
-		}).run(t, noMod, func(t *testing.T, env *Env) {
+		withOptions(
+			WithModes(WithoutExperiments),
+		).run(t, noMod, func(t *testing.T, env *Env) {
 			env.Await(
 				env.DiagnosticAtRegexp("main.go", `"mod.com/bob"`),
 			)
diff --git a/gopls/internal/regtest/modfile_test.go b/gopls/internal/regtest/modfile_test.go
index 71e8729..49469bf 100644
--- a/gopls/internal/regtest/modfile_test.go
+++ b/gopls/internal/regtest/modfile_test.go
@@ -587,9 +587,9 @@
 			Env: map[string]string{
 				"GOFLAGS": "-mod=readonly",
 			},
-			WithoutExperimentalWorkspaceModule: true,
 		},
 		WithProxyFiles(proxy),
+		WithModes(WithoutExperiments),
 	).run(t, mod, func(t *testing.T, env *Env) {
 		env.OpenFile("main.go")
 		original := env.ReadWorkspaceFile("go.mod")
@@ -639,6 +639,7 @@
 `
 	withOptions(
 		WithProxyFiles(workspaceProxy),
+		WithModes(Experimental),
 	).run(t, mod, func(t *testing.T, env *Env) {
 		env.Await(
 			env.DiagnosticAtRegexp("a/go.mod", "example.com v1.2.3"),
diff --git a/gopls/internal/regtest/runner.go b/gopls/internal/regtest/runner.go
index feffdc4..9f8a779 100644
--- a/gopls/internal/regtest/runner.go
+++ b/gopls/internal/regtest/runner.go
@@ -28,6 +28,7 @@
 	"golang.org/x/tools/internal/lsp/fake"
 	"golang.org/x/tools/internal/lsp/lsprpc"
 	"golang.org/x/tools/internal/lsp/protocol"
+	"golang.org/x/tools/internal/lsp/source"
 )
 
 // Mode is a bitmask that defines for which execution modes a test should run.
@@ -43,9 +44,16 @@
 	Forwarded
 	// SeparateProcess forwards connection to a shared separate gopls process.
 	SeparateProcess
+	// Experimental enables all of the experimental configurations that are
+	// being developed. Currently, it enables the workspace module.
+	Experimental
+	// WithoutExperiments are the modes that run without experimental features,
+	// like the workspace module. These should be used for tests that only work
+	// in the default modes.
+	WithoutExperiments = Singleton | Forwarded
 	// NormalModes are the global default execution modes, when unmodified by
 	// test flags or by individual test options.
-	NormalModes = Singleton
+	NormalModes = Singleton | Experimental
 )
 
 // A Runner runs tests in gopls execution environments, as specified by its
@@ -218,6 +226,7 @@
 		{"singleton", Singleton, singletonServer},
 		{"forwarded", Forwarded, r.forwardedServer},
 		{"separate_process", SeparateProcess, r.separateProcessServer},
+		{"experimental_workspace_module", Experimental, experimentalWorkspaceModule},
 	}
 
 	for _, tc := range tests {
@@ -333,6 +342,14 @@
 	return lsprpc.NewStreamServer(cache.New(ctx, hooks.Options), false)
 }
 
+func experimentalWorkspaceModule(ctx context.Context, t *testing.T) jsonrpc2.StreamServer {
+	options := func(o *source.Options) {
+		hooks.Options(o)
+		o.ExperimentalWorkspaceModule = true
+	}
+	return lsprpc.NewStreamServer(cache.New(ctx, options), false)
+}
+
 func (r *Runner) forwardedServer(ctx context.Context, t *testing.T) jsonrpc2.StreamServer {
 	ts := r.getTestServer()
 	return lsprpc.NewForwarder("tcp", ts.Addr)
diff --git a/gopls/internal/regtest/vendor_test.go b/gopls/internal/regtest/vendor_test.go
index b34ac33..7f11d4a 100644
--- a/gopls/internal/regtest/vendor_test.go
+++ b/gopls/internal/regtest/vendor_test.go
@@ -40,9 +40,7 @@
 `
 	// TODO(rstambler): Remove this when golang/go#41819 is resolved.
 	withOptions(
-		EditorConfig{
-			WithoutExperimentalWorkspaceModule: true,
-		},
+		WithModes(WithoutExperiments),
 		WithProxyFiles(basicProxy),
 	).run(t, pkgThatUsesVendoring, func(t *testing.T, env *Env) {
 		env.OpenFile("a/a1.go")
diff --git a/gopls/internal/regtest/workspace_test.go b/gopls/internal/regtest/workspace_test.go
index 5a4c029..35027e8 100644
--- a/gopls/internal/regtest/workspace_test.go
+++ b/gopls/internal/regtest/workspace_test.go
@@ -121,38 +121,6 @@
 	}
 }
 
-// Tests that basic functionality works without ExperimentalWorkspaceModule.
-func TestNoWorkspaceModule(t *testing.T) {
-	const mod = `
--- go.mod --
-module mod.com
-
-go 1.14
--- main.go --
-package main
-
-import "mod.com/pkg/inner"
-
-func main() {
-	inner.Hi()
-}
--- pkg/inner/inner.go --
-package inner
-
-func Hi() {}
-`
-	withOptions(
-		EditorConfig{
-			WithoutExperimentalWorkspaceModule: true,
-		},
-	).run(t, mod, func(t *testing.T, env *Env) {
-		env.OpenFile("main.go")
-		env.Await(
-			NoDiagnostics("main.go"),
-		)
-	})
-}
-
 // Make sure that analysis diagnostics are cleared for the whole package when
 // the only opened file is closed. This test was inspired by the experience in
 // VS Code, where clicking on a reference result triggers a
@@ -230,6 +198,7 @@
 `
 	withOptions(
 		WithProxyFiles(workspaceModuleProxy),
+		WithModes(Experimental),
 	).run(t, multiModule, func(t *testing.T, env *Env) {
 		env.Await(
 			env.DiagnosticAtRegexp("moda/a/a.go", "x"),
@@ -271,6 +240,7 @@
 `
 	withOptions(
 		WithProxyFiles(workspaceModuleProxy),
+		WithModes(Experimental),
 	).run(t, multiModule, func(t *testing.T, env *Env) {
 		env.OpenFile("moda/a/a.go")
 
@@ -313,6 +283,7 @@
 }
 `
 	withOptions(
+		WithModes(Experimental),
 		WithProxyFiles(workspaceModuleProxy),
 	).run(t, multiModule, func(t *testing.T, env *Env) {
 		env.OpenFile("moda/a/a.go")
@@ -375,6 +346,7 @@
 `
 	withOptions(
 		WithProxyFiles(workspaceModuleProxy),
+		WithModes(Experimental),
 	).run(t, multiModule, func(t *testing.T, env *Env) {
 		env.OpenFile("modb/go.mod")
 		env.Await(
@@ -430,6 +402,7 @@
 `
 	withOptions(
 		WithProxyFiles(workspaceModuleProxy),
+		WithModes(Experimental),
 	).run(t, multiModule, func(t *testing.T, env *Env) {
 		env.OpenFile("moda/a/a.go")
 		original, _ := env.GoToDefinition("moda/a/a.go", env.RegexpSearch("moda/a/a.go", "Hello"))
diff --git a/internal/lsp/fake/editor.go b/internal/lsp/fake/editor.go
index f983062..5e977a4 100644
--- a/internal/lsp/fake/editor.go
+++ b/internal/lsp/fake/editor.go
@@ -85,12 +85,6 @@
 	// EnableStaticcheck enables staticcheck analyzers.
 	EnableStaticcheck bool
 
-	// WithoutExperimentalWorkspaceModule disables the experimental workspace
-	// module.
-	// TODO(rstambler): This mode is temporary and should be removed when
-	// golang.org/cl/258518 is merged.
-	WithoutExperimentalWorkspaceModule bool
-
 	// AllExperiments sets the "allExperiments" configuration, which enables
 	// all of gopls's opt-in settings.
 	AllExperiments bool
@@ -203,12 +197,6 @@
 	if e.Config.EnableStaticcheck {
 		config["staticcheck"] = true
 	}
-	// Default to using the experimental workspace module mode, unless
-	// explicitly configured.
-	if !e.Config.WithoutExperimentalWorkspaceModule {
-		config["experimentalWorkspaceModule"] = true
-	}
-
 	if e.Config.AllExperiments {
 		config["allExperiments"] = true
 	}
@@ -217,6 +205,7 @@
 	// default... and probably change to the new settings name.
 	// config["experimentalDiagnosticsDelay"] = "10ms"
 
+	// ExperimentalWorkspaceModule is only set as a mode, not a configuration.
 	return config
 }