internal/lsp: do not show errors for code actions on go.mod files

This change keys the supported code actions map by file kind, so that we
can extend it more easily for go.mod files.

Change-Id: Ic28f91bd517700cf070281b1c4d4ded14a702790
Reviewed-on: https://go-review.googlesource.com/c/tools/+/189039
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
diff --git a/internal/lsp/code_action.go b/internal/lsp/code_action.go
index 4447532..feae17b 100644
--- a/internal/lsp/code_action.go
+++ b/internal/lsp/code_action.go
@@ -18,29 +18,35 @@
 )
 
 func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) {
+	uri := span.NewURI(params.TextDocument.URI)
+	view := s.session.ViewOf(uri)
+	f, m, err := getSourceFile(ctx, view, uri)
+	if err != nil {
+		return nil, err
+	}
+
+	// Determine the supported actions for this file kind.
+	fileKind := f.Handle(ctx).Kind()
+	supportedCodeActions, ok := s.supportedCodeActions[fileKind]
+	if !ok {
+		return nil, fmt.Errorf("no supported code actions for %v file kind", fileKind)
+	}
 
 	// The Only field of the context specifies which code actions the client wants.
 	// If Only is empty, assume that the client wants all of the possible code actions.
 	var wanted map[protocol.CodeActionKind]bool
 	if len(params.Context.Only) == 0 {
-		wanted = s.supportedCodeActions
+		wanted = supportedCodeActions
 	} else {
 		wanted = make(map[protocol.CodeActionKind]bool)
 		for _, only := range params.Context.Only {
-			wanted[only] = s.supportedCodeActions[only]
+			wanted[only] = supportedCodeActions[only]
 		}
 	}
-
-	uri := span.NewURI(params.TextDocument.URI)
 	if len(wanted) == 0 {
 		return nil, fmt.Errorf("no supported code action to execute for %s, wanted %v", uri, params.Context.Only)
 	}
 
-	view := s.session.ViewOf(uri)
-	gof, m, err := getGoFile(ctx, view, uri)
-	if err != nil {
-		return nil, err
-	}
 	spn, err := m.RangeSpan(params.Range)
 	if err != nil {
 		return nil, err
@@ -58,6 +64,10 @@
 		// First, add the quick fixes reported by go/analysis.
 		// TODO: Enable this when this actually works. For now, it's needless work.
 		if s.wantSuggestedFixes {
+			gof, ok := f.(source.GoFile)
+			if !ok {
+				return nil, fmt.Errorf("%s is not a Go file", f.URI())
+			}
 			qf, err := quickFixes(ctx, view, gof)
 			if err != nil {
 				log.Error(ctx, "quick fixes failed", err, telemetry.File.Of(uri))
diff --git a/internal/lsp/general.go b/internal/lsp/general.go
index f1f9351..3bedf96 100644
--- a/internal/lsp/general.go
+++ b/internal/lsp/general.go
@@ -42,9 +42,13 @@
 	// Default to using synopsis as a default for hover information.
 	s.hoverKind = source.SynopsisDocumentation
 
-	s.supportedCodeActions = map[protocol.CodeActionKind]bool{
-		protocol.SourceOrganizeImports: true,
-		protocol.QuickFix:              true,
+	s.supportedCodeActions = map[source.FileKind]map[protocol.CodeActionKind]bool{
+		source.Go: {
+			protocol.SourceOrganizeImports: true,
+			protocol.QuickFix:              true,
+		},
+		source.Mod: {},
+		source.Sum: {},
 	}
 
 	s.setClientCapabilities(params.Capabilities)
diff --git a/internal/lsp/lsp_test.go b/internal/lsp/lsp_test.go
index 5b563cd..6f270ee 100644
--- a/internal/lsp/lsp_test.go
+++ b/internal/lsp/lsp_test.go
@@ -52,10 +52,13 @@
 		server: &Server{
 			session:     session,
 			undelivered: make(map[span.URI][]source.Diagnostic),
-			supportedCodeActions: map[protocol.CodeActionKind]bool{
-				protocol.SourceOrganizeImports: true,
-				protocol.QuickFix:              true,
-			},
+			supportedCodeActions: map[source.FileKind]map[protocol.CodeActionKind]bool{
+				source.Go: {
+					protocol.SourceOrganizeImports: true,
+					protocol.QuickFix:              true,
+				},
+				source.Mod: {},
+				source.Sum: {}},
 			hoverKind: source.SynopsisDocumentation,
 		},
 		data: data,
diff --git a/internal/lsp/server.go b/internal/lsp/server.go
index 26d2c21..6ab758b 100644
--- a/internal/lsp/server.go
+++ b/internal/lsp/server.go
@@ -89,7 +89,7 @@
 	disabledAnalyses              map[string]struct{}
 	wantSuggestedFixes            bool
 
-	supportedCodeActions map[protocol.CodeActionKind]bool
+	supportedCodeActions map[source.FileKind]map[protocol.CodeActionKind]bool
 
 	textDocumentSyncKind protocol.TextDocumentSyncKind