Skip to content

Conversation

@jakebailey
Copy link
Member

This uses LSP push diags to send ProgramDiagnostics when present, removing them when a project is closed. The actual implementation of it seems fine, but the testing is pretty annoying.

There are unit tests for this, but fourslash cannot handle client-initiated anything except the two hardcoded init ones. So, I'm just forcibly disabling those via an init option set for fourslash. Nasty but making fourslash more like a real LSP client is going to take a lot of work.

Also, we have program diags that are not associated with files at all. I've just hacked it so that these diags get reported at a zero position.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements push diagnostics for program-level diagnostics in tsconfig.json files. When TypeScript program diagnostics are generated (e.g., configuration errors), they are now pushed to the client via LSP's textDocument/publishDiagnostics notification, associated with the tsconfig.json file. Diagnostics are cleared when projects are closed.

Key changes:

  • Added PublishDiagnostics method to the Client interface and implemented it in the LSP server
  • Added diagnostic publishing logic that tracks project changes and sends/clears diagnostics accordingly
  • Refactored diagnostic conversion to support both pull and push diagnostic scenarios
  • Added DisablePushDiagnostics option for testing, particularly for fourslash tests which don't handle unsolicited server notifications

Reviewed Changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/project/client.go Added PublishDiagnostics method to the Client interface
internal/project/session.go Added DisablePushDiagnostics field, implemented publishProgramDiagnostics and publishProjectDiagnostics methods to send program diagnostics, added nil client check
internal/project/snapshot_test.go Added noopClient implementation for snapshot tests that now require a Client
internal/project/refcounting_test.go Updated to provide noopClient to session initialization
internal/project/project_test.go Added comprehensive TestPushDiagnostics test suite covering initial publishing, clearing on project removal, updates on program changes, and exclusion of inferred projects
internal/lsp/server.go Implemented PublishDiagnostics method, added extraction of disablePushDiagnostics from initialization options
internal/ls/lsconv/converters.go Added DiagnosticToLSPPull and DiagnosticToLSPPush functions to handle different client capability sets, added support for diagnostics without associated files
internal/ls/diagnostics.go Refactored to use the new DiagnosticToLSPPull function from lsconv package
internal/fourslash/fourslash.go Added disablePushDiagnostics: true to initialization options to prevent fourslash tests from receiving unsolicited notifications
internal/testutil/projecttestutil/clientmock_generated.go Generated mock updated with PublishDiagnostics method and associated tracking

Comment on lines -736 to -740
if s.initializeParams != nil && s.initializeParams.InitializationOptions != nil && *s.initializeParams.InitializationOptions != nil {
// handle userPreferences from initializationOptions
userPreferences := s.session.NewUserPreferences()
userPreferences.Parse(*s.initializeParams.InitializationOptions)
s.session.InitializeWithConfig(userPreferences)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this code was unused

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@andrewbranch
Copy link
Member

Can a single-file edit that results in a fast program clone affect program diagnostics? If not, we could gate the collection on project.ProgramUpdateKind > ProgramUpdateKindCloned to avoid doing it on every keystroke.

@jakebailey
Copy link
Member Author

No, I don't believe it can, since we check if a file's important bits change before doing the easy fast clone for that reason. I can do that.

Copy link
Member

@andrewbranch andrewbranch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉

@jakebailey
Copy link
Member Author

This is still failing the API tests, I'm trying to figure out why ☹️

@jakebailey
Copy link
Member Author

It's the client nil check; just dropped that since there's a flag that enables the push diags... the API is a little weird given it's sort of a language server sort of not.

@jakebailey jakebailey added this pull request to the merge queue Nov 18, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Nov 18, 2025
@jakebailey jakebailey added this pull request to the merge queue Nov 18, 2025
Merged via the queue into main with commit 5bec4c3 Nov 18, 2025
22 checks passed
@jakebailey jakebailey deleted the jabaile/lsp-prog-diags branch November 18, 2025 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants