| # Gopls: Diagnostics |
| |
| Gopls continuously annotates all your open files of source code with a |
| variety of diagnostics. Every time you edit a file or make a |
| configuration change, gopls asynchronously recomputes these |
| diagnostics and sends them to the client using the LSP |
| [`publishDiagnostics`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification#textDocument_publishDiagnostics) |
| notification, giving you real-time feedback that reduces the cost of |
| common mistakes. |
| |
| Diagnostics come from two main sources: build errors and analysis findings. |
| |
| - **Build errors** are those that you would obtain from running `go |
| build`. Gopls doesn't actually run the compiler; that would be too |
| slow. Instead it runs `go list` (when needed) to compute the |
| metadata of the build, then processes those packages in a similar |
| manner to the compiler front-end: reading, scanning, and parsing the |
| source files, then type-checking them. Each of these steps can |
| produce errors that gopls will surface as a diagnostic. |
| |
| The `source` field of the LSP `Diagnostic` record indicates where |
| the diagnostic came from: those with source `"go list"` come from |
| the `go list` command, and those with source `"compiler"` come from |
| gopls' parsing or type checking phases, which are similar to those |
| used in the Go compiler. |
| |
|  |
| |
| The example above shows a `string + int` addition, causes the type |
| checker to report a `MismatchedTypes` error. The diagnostic contains |
| a link to the documentation about this class of type error. |
| |
| - **Analysis findings** come from the [**Go analysis |
| framework**](https://golang.org/x/tools/go/analysis), the system |
| used by `go vet` to apply a variety of additional static checks to |
| your Go code. The best-known example is the [`printf` |
| analyzer](https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/printf), |
| which reports calls to [`fmt.Printf`](https://pkg.go.dev/fmt#Printf) |
| where the format "verb" doesn't match the argument, such as |
| `fmt.Printf("%d", "three")`. |
| |
| Gopls provides dozens of analyzers aggregated from a variety of |
| suites. See [Analyzers](../analyzers.md) for the complete list. The |
| `source` field of each diagnostic produced by an analyzer records |
| the name of the analyzer that produced it. |
| |
|  |
| |
| The example above shows a `printf` formatting mistake. The diagnostic contains |
| a link to the documentation for the `printf` analyzer. |
| |
| ## Recomputation of diagnostics |
| |
| Diagnostics are automatically recomputed each time the source files |
| are edited. |
| |
| Build errors are updated immediately after each file is edited, |
| potentially after every keystroke. This ensures rapid feedback of |
| syntax and type errors while editing. |
| |
| Analysis diagnostics can be more expensive to compute than type |
| checking, so they are usually recomputed after a short idle period |
| following an edit. |
| The [`diagnosticsDelay`](../settings.md#diagnosticsDelay) setting determines |
| this period. |
| Alternatively, diagnostics may be triggered only after an edited file |
| is saved, using the |
| [`diagnosticsTrigger`](../settings.md#diagnosticsTrigger) setting. |
| |
| Gopls does not currently support "pull-based" diagnostics, which are |
| computed synchronously when requested by the client; see golang/go#53275. |
| |
| |
| ## Quick fixes |
| |
| Each analyzer diagnostic may suggest one or more alternative |
| ways to fix the problem by editing the code. |
| For example, when a `return` statement has too few operands, |
| the [`fillreturns`](../analyzers.md#fillreturns) analyzer |
| suggests a fix that heuristically fills in the missing ones |
| with suitable values. Applying the fix eliminates the build error. |
| |
|  |
| |
| The screenshot above shows VS Code's Quick Fix menu for an "unused |
| parameter" analysis diagnostic with two alternative fixes. |
| (See [Remove unused parameter](transformation.md#remove-unused-parameter) for more detail.) |
| |
| Suggested fixes that are indisputably safe are [code |
| actions](transformation.md#code-actions) whose kind is |
| `"source.fixAll"`. Many client editors have a shortcut to apply all |
| such fixes. |
| |
| TODO(adonovan): audit all the analyzers to ensure that their |
| documentation is up-to-date w.r.t. any fixes they suggest. |
| |
| Settings: |
| |
| - The [`diagnosticsDelay`](../settings.md#diagnosticsDelay) setting determines |
| the idle period after an edit before diagnostics are recomputed. |
| - The [`diagnosticsTriggerr`](../settings.md#diagnosticsTrigger) setting determines |
| what events cause recomputation of diagnostics. |
| - The [`linkTarget`](../settings.md#linkTarget) setting specifies |
| the base URI for Go package links in the Diagnostic.CodeDescription field. |
| |
| Client support: |
| - **VS Code**: Diagnostics appear as a red squiggly underline. |
| Hovering reveals the details, along with any suggested fixes. |
| - **Emacs + eglot**: Diagnostics appear as a red squiggly underline. |
| Hovering reveals the details. Use `M-x eglot-code-action-quickfix` |
| to apply available fixes; it will prompt if there are more than one. |
| - **Vim + coc.nvim**: ?? |
| - **CLI**: `gopls check file.go` |
| |
| <!-- |
| |
| dorky details and deletia: |
| |
| - The **vet suite**, of about thirty analyzers |
| designed to catch likely mistakes in your code. |
| |
| - **Type-error fixers**. These are gopls-specific analyzers that |
| enrich diagnostics from the type checker by suggesting fixes for |
| simple problems. |
| |
| For example, when a return statement has too few operands, the |
| [fillreturns](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/fillreturns) analyzer can heuristically fill in the missing ones |
| with suitable values. |
| |
| The actual diagnostics are produced by the type checker, |
| so these analyzers won't cause you to see any new diagnostics; |
| but they add fixes to existing ones. |
| (The user needs to know this because the settings expose it.) |
| |
| currently: fillreturns nonewvars noresultvalues stubmethods undeclaredname unusedvariable |
| |
| - **Simplifiers**. These are gopls-specific analyzers that |
| suggest ways to rewrite your code more simply. |
| They do not indicate a mistake in your code, |
| which is why they are not part of `go vet`. |
| |
| For example, the `simplifyrange` analyzer will eliminate the |
| unnecessary blank variable in `for _ = range v {...}`. |
| |
| currently: simplifycompositelit simplifyrange simplifyslice unusedparams infertypeargs |
| |
| - **Bug detectors**. Gopls has a suite of bug-detecting analyzers that |
| can't be part of vet for some reason. That might be because they |
| have dependencies that vet cannot have (e.g. nilness and |
| unusedwrite, which construct SSA), or because they are tightly |
| integrated with gopls (e.g. embeddirective, which produces lazy |
| fixes through the code action mechanism |
| [But others do that too: undeclaredname embeddirective unusedparams stubmethods] |
| |
| currently: atomicalign deepequalerrors nilness sortslice unusedwrite embeddirective |
| |
| - **staticcheck**: four suites: |
| |
| add(simple.Analyzers, nil) |
| add(staticcheck.Analyzers - SA5009, SA5011 |
| add(stylecheck.Analyzers, nil) |
| add(quickfix.Analyzers, nil) |
| |
| - **Experimental analyzers**. Gopls has some analyzers that are not |
| enabled by default, because they produce too high a rate of false |
| positives. For example, fieldalignment, shadow, useany. |
| |
| Note: fillstruct is not a real analyzer. |
| |
| --> |