go/analysis: add SuggestedFix to Diagnostic

This change is uploaded for discussion.

This adds a SuggestedFix field to Diagnostic that can be used
to prepare refactorings or to surface fixes for diagnostics
when they're shown by the LSP.

Change-Id: Icad3bb78540b55df1707955139c889f612d1084f
Reviewed-on: https://go-review.googlesource.com/c/tools/+/181941
Run-TryBot: Michael Matloob <matloob@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Dominik Honnef <dominik@honnef.co>
Reviewed-by: Rebecca Stambler <rstambler@golang.org>
diff --git a/go/analysis/analysis.go b/go/analysis/analysis.go
index 19e1e42..e375484 100644
--- a/go/analysis/analysis.go
+++ b/go/analysis/analysis.go
@@ -211,18 +211,3 @@
 type Fact interface {
 	AFact() // dummy method to avoid type errors
 }
-
-// A Diagnostic is a message associated with a source location or range.
-//
-// An Analyzer may return a variety of diagnostics; the optional Category,
-// which should be a constant, may be used to classify them.
-// It is primarily intended to make it easy to look up documentation.
-//
-// If End is provided, the diagnostic is specified to apply to the range between
-// Pos and End.
-type Diagnostic struct {
-	Pos      token.Pos
-	End      token.Pos // optional
-	Category string    // optional
-	Message  string
-}
diff --git a/go/analysis/diagnostic.go b/go/analysis/diagnostic.go
new file mode 100644
index 0000000..e7debe9
--- /dev/null
+++ b/go/analysis/diagnostic.go
@@ -0,0 +1,20 @@
+// +build !experimental
+
+package analysis
+
+import "go/token"
+
+// A Diagnostic is a message associated with a source location or range.
+//
+// An Analyzer may return a variety of diagnostics; the optional Category,
+// which should be a constant, may be used to classify them.
+// It is primarily intended to make it easy to look up documentation.
+//
+// If End is provided, the diagnostic is specified to apply to the range between
+// Pos and End.
+type Diagnostic struct {
+	Pos      token.Pos
+	End      token.Pos // optional
+	Category string    // optional
+	Message  string
+}
diff --git a/go/analysis/diagnostic_experimental.go b/go/analysis/diagnostic_experimental.go
new file mode 100644
index 0000000..2e9ebb2
--- /dev/null
+++ b/go/analysis/diagnostic_experimental.go
@@ -0,0 +1,41 @@
+// +build experimental
+
+package analysis
+
+import "go/token"
+
+// A Diagnostic is a message associated with a source location or range.
+//
+// An Analyzer may return a variety of diagnostics; the optional Category,
+// which should be a constant, may be used to classify them.
+// It is primarily intended to make it easy to look up documentation.
+//
+// If End is provided, the diagnostic is specified to apply to the range between
+// Pos and End.
+type Diagnostic struct {
+	Pos      token.Pos
+	End      token.Pos // optional
+	Category string    // optional
+	Message  string
+
+	// TODO(matloob): Should multiple SuggestedFixes be allowed for a diagnostic?
+	SuggestedFixes []SuggestedFix // optional
+}
+
+// A SuggestedFix is a code change associated with a Diagnostic that a user can choose
+// to apply to their code. Usually the SuggestedFix is meant to fix the issue flagged
+// by the diagnostic.
+type SuggestedFix struct {
+	// A description for this suggested fix to be shown to a user deciding
+	// whether to accept it.
+	Message   string
+	TextEdits []TextEdit
+}
+
+// A TextEdit represents the replacement of the code between Pos and End with the new text.
+type TextEdit struct {
+	// For a pure insertion, End can either be set to Pos or token.NoPos.
+	Pos     token.Pos
+	End     token.Pos
+	NewText []byte
+}