internal/lsp: fix and add a test for non-workspace module mode

This issue was reported on Slack. We need to run more tests in the
default mode, but this is a quick fix.

Change-Id: Ic29d0332aa0410b6e80f77d894c8c007c7f251fa
Reviewed-on: https://go-review.googlesource.com/c/tools/+/258657
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: Heschi Kreinick <heschi@google.com>
diff --git a/gopls/internal/regtest/workspace_test.go b/gopls/internal/regtest/workspace_test.go
index 77d55be..9b76436 100644
--- a/gopls/internal/regtest/workspace_test.go
+++ b/gopls/internal/regtest/workspace_test.go
@@ -119,6 +119,38 @@
 	}
 }
 
+// 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
diff --git a/internal/lsp/cache/session.go b/internal/lsp/cache/session.go
index 4986c00..44792f2 100644
--- a/internal/lsp/cache/session.go
+++ b/internal/lsp/cache/session.go
@@ -251,6 +251,14 @@
 func findWorkspaceModules(ctx context.Context, root span.URI, options *source.Options) (map[span.URI]*moduleRoot, error) {
 	// Walk the view's folder to find all modules in the view.
 	modules := make(map[span.URI]*moduleRoot)
+	if !options.ExperimentalWorkspaceModule {
+		path := filepath.Join(root.Filename(), "go.mod")
+		if info, _ := os.Stat(path); info != nil {
+			m := newModule(ctx, span.URIFromPath(path))
+			modules[m.rootURI] = m
+		}
+		return modules, nil
+	}
 	return modules, filepath.Walk(root.Filename(), func(path string, info os.FileInfo, err error) error {
 		if err != nil {
 			// Probably a permission error. Keep looking.
@@ -272,11 +280,6 @@
 			m := newModule(ctx, span.URIFromPath(path))
 			modules[m.rootURI] = m
 		}
-		// If we are not using experimental workspace modules, don't continue
-		// the search past the view's root.
-		if !options.ExperimentalWorkspaceModule {
-			return filepath.SkipDir
-		}
 		return nil
 	})
 }
diff --git a/internal/lsp/fake/editor.go b/internal/lsp/fake/editor.go
index 38546af..a15a947 100644
--- a/internal/lsp/fake/editor.go
+++ b/internal/lsp/fake/editor.go
@@ -84,6 +84,12 @@
 
 	// 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
 }
 
 // NewEditor Creates a new Editor.
@@ -193,9 +199,11 @@
 	if e.Config.EnableStaticcheck {
 		config["staticcheck"] = true
 	}
-	// Default to using the experimental workspace module mode.
-	config["experimentalWorkspaceModule"] = true
-
+	// Default to using the experimental workspace module mode, unless
+	// explicitly configured.
+	if !e.Config.WithoutExperimentalWorkspaceModule {
+		config["experimentalWorkspaceModule"] = true
+	}
 	return config
 }