// Diagnostic implements the textDocument/diagnostic LSP request, reporting // diagnostics for the given file. // // This is a work in progress. // TODO(rfindley): // - support RelatedDocuments? If so, how? Maybe include other package diagnostics? // - support resultID (=snapshot ID) // - support multiple views // - add orphaned file diagnostics // - support go.mod, go.work files func (s *server) Diagnostic(ctx context.Context, params *protocol.DocumentDiagnosticParams) (*protocol.DocumentDiagnosticReport, error) { … } type fileDiagnostics … type viewDiagnostics … type viewSet … type diagMap … func sortDiagnostics(d []*cache.Diagnostic) { … } func (s *server) diagnoseChangedViews(ctx context.Context, modID uint64, lastChange map[*cache.View][]protocol.DocumentURI, cause ModificationSource) { … } // diagnoseSnapshot computes and publishes diagnostics for the given snapshot. // // If delay is non-zero, computing diagnostics does not start until after this // delay has expired, to allow work to be cancelled by subsequent changes. // // If changedURIs is non-empty, it is a set of recently changed files that // should be diagnosed immediately, and onDisk reports whether these file // changes came from a change to on-disk files. // // If the provided context is cancelled, diagnostics may be partially // published. Therefore, the provided context should only be cancelled if there // will be a subsequent operation to make diagnostics consistent. In general, // if an operation creates a new snapshot, it is responsible for ensuring that // snapshot (or a subsequent snapshot in the same View) is eventually // diagnosed. func (s *server) diagnoseSnapshot(ctx context.Context, snapshot *cache.Snapshot, changedURIs []protocol.DocumentURI, delay time.Duration) { … } func (s *server) diagnoseChangedFiles(ctx context.Context, snapshot *cache.Snapshot, uris []protocol.DocumentURI) (diagMap, error) { … } func (s *server) diagnose(ctx context.Context, snapshot *cache.Snapshot) (diagMap, error) { … } func (s *server) gcDetailsDiagnostics(ctx context.Context, snapshot *cache.Snapshot, toDiagnose map[metadata.PackageID]*metadata.Package) (diagMap, error) { … } // mustPublishDiagnostics marks the uri as needing publication, independent of // whether the published contents have changed. // // This can be used for ensuring gopls publishes diagnostics after certain file // events. func (s *server) mustPublishDiagnostics(uri protocol.DocumentURI) { … } const WorkspaceLoadFailure … // updateCriticalErrorStatus updates the critical error progress notification // based on err. // // If err is nil, or if there are no open files, it clears any existing error // progress report. func (s *server) updateCriticalErrorStatus(ctx context.Context, snapshot *cache.Snapshot, err *cache.InitializationError) { … } // updateDiagnostics records the result of diagnosing a snapshot, and publishes // any diagnostics that need to be updated on the client. func (s *server) updateDiagnostics(ctx context.Context, snapshot *cache.Snapshot, diagnostics diagMap, final bool) { … } // updateOrphanedFileDiagnostics records and publishes orphaned file // diagnostics as a given modification time. func (s *server) updateOrphanedFileDiagnostics(ctx context.Context, modID uint64, diagnostics diagMap) error { … } // publishFileDiagnosticsLocked publishes a fileDiagnostics value, while holding s.diagnosticsMu. // // If the publication succeeds, it updates f.publishedHash and f.mustPublish. func (s *server) publishFileDiagnosticsLocked(ctx context.Context, views viewSet, uri protocol.DocumentURI, version int32, f *fileDiagnostics) error { … } func toProtocolDiagnostics(diagnostics []*cache.Diagnostic) []protocol.Diagnostic { … } func (s *server) shouldIgnoreError(snapshot *cache.Snapshot, err error) bool { … }