Skip to content

Comments

[ty] Track open files in the server#19264

Merged
dhruvmanila merged 10 commits intomainfrom
dhruv/workspace-diagnostics-in-virtual-files
Jul 18, 2025
Merged

[ty] Track open files in the server#19264
dhruvmanila merged 10 commits intomainfrom
dhruv/workspace-diagnostics-in-virtual-files

Conversation

@dhruvmanila
Copy link
Member

@dhruvmanila dhruvmanila commented Jul 10, 2025

Summary

This PR updates the server to keep track of open files both system and virtual files.

This is done by updating the project by adding the file in the open file set in didOpen notification and removing it in didClose notification.

This does mean that for workspace diagnostics, ty will only check open files because the behavior of different diagnostic builder is to first check is_file_open and only add diagnostics for open files. So, this required updating the is_file_open model to be should_check_file model which validates whether the file needs to be checked based on the CheckMode. If the check mode is open files only then it will check whether the file is open. If it's all files then it'll return true by default.

Closes: astral-sh/ty#619

Test Plan

Before

There are two files in the project: __init__.py and diagnostics.py.

In the video, I'm demonstrating the old behavior where making changes to the (open) diagnostics.py file results in re-parsing the file:

Screen.Recording.2025-07-15.at.11.07.01.mov

After

Same setup as above.

In the video, I'm demonstrating the new behavior where making changes to the (open) diagnostics.py file doesn't result in re-parting the file:

Screen.Recording.2025-07-15.at.11.07.44.mov

@dhruvmanila dhruvmanila added server Related to the LSP server ty Multi-file analysis & type inference labels Jul 10, 2025
@dhruvmanila dhruvmanila force-pushed the dhruv/workspace-diagnostics-in-virtual-files branch 3 times, most recently from 6f768c0 to 1f21e75 Compare July 10, 2025 16:45
@github-actions
Copy link
Contributor

github-actions bot commented Jul 10, 2025

mypy_primer results

No ecosystem changes detected ✅
No memory usage changes detected ✅

Comment on lines 56 to 57
// TODO: Why do we require this? Because this doesn't do anything as `File` doesn't
// exists for the system path and this event will not create it either.
Copy link
Member

Choose a reason for hiding this comment

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

I think we need it to bump the file revision. Before the event: the file's revision is the timestamp on disk. After opening it, the revision is the document version.

@dhruvmanila

This comment was marked as resolved.

@dhruvmanila dhruvmanila force-pushed the dhruv/workspace-diagnostics-in-virtual-files branch 2 times, most recently from 1cc96b9 to bf3212e Compare July 12, 2025 03:17
@dhruvmanila dhruvmanila force-pushed the dhruv/workspace-diagnostics-in-virtual-files branch from bf3212e to 8d5ef98 Compare July 14, 2025 08:48
@dhruvmanila dhruvmanila changed the base branch from main to dhruv/virtual-files-in-project-db July 14, 2025 08:48
@dhruvmanila dhruvmanila changed the title [ty] Consider virtual files for workspace diagnostics [ty] Track open files in the server Jul 14, 2025
@github-actions
Copy link
Contributor

github-actions bot commented Jul 14, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

Indexed(files::Indexed<'a>),
Indexed {
files: files::Indexed<'a>,
virtual_files: Option<Box<[File]>>,
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 does not seem useful at all because VS Code also sends us the textDocument/diagnostic request for open files and virtual files are always open. So, we could possibly just remove this field and all should still be fine.

Copy link
Member

Choose a reason for hiding this comment

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

Hmm, that's interesting. It would certainly simplify things a bit. Can you try if skipping over the virtual files still works as expected?

Copy link
Member Author

Choose a reason for hiding this comment

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

I've removed this special handling for virtual files.

I tested out Zed which also supports virtual files but it seems that it doesn't send any notification to the client about it's existence.

Screen.Recording.2025-07-16.at.17.32.44.mov

Zed seems to be sending a didClose for the new other.py and then a didOpen which is what caused the error in the above video. I'm not sure why though. But, it does send a FileChangeType::Created which seems fine but then why is it sending a didClose event?

// Send:
{"jsonrpc":"2.0","method":"workspace/didChangeWatchedFiles","params":{"changes":[{"uri":"file:///Users/dhruv/playground/ty-server/src/ty_server/other.py","type":1}]}}

// Send:
{"jsonrpc":"2.0","method":"textDocument/didClose","params":{"textDocument":{"uri":"file:///Users/dhruv/playground/ty-server/src/ty_server/other.py"}}}

// Send:
{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file:///Users/dhruv/playground/ty-server/src/ty_server/other.py","languageId":"python","version":0,"text":"x"}}}

Neovim also has virtual file support but it has it's own issues: #15392

@dhruvmanila dhruvmanila force-pushed the dhruv/virtual-files-in-project-db branch from c14535c to 993d565 Compare July 14, 2025 13:57
@dhruvmanila dhruvmanila force-pushed the dhruv/workspace-diagnostics-in-virtual-files branch from 854decd to e649866 Compare July 14, 2025 14:04
dhruvmanila added a commit that referenced this pull request Jul 14, 2025
## Summary

Previously, the virtual files were being added to the default database
that's present on the session. This is wrong because the default
database is for any files that don't belong to any project i.e., they're
outside of any projects managed by the server. Virtual files are neither
part of the project nor it is outside the projects. This was not the
intention as in the initial version, virtual files were being added to
the only project database managed by the server.

This PR fixes this by reverting back to the original behavior where
virtual files will be added to the only project database present. When
support for multiple workspace and project is added, this will require
updating (astral-sh/ty#794).

This is required for #19264 because workspace diagnostics doesn't check
the default project database yet. Ideally, the default db should be
checked as well.

The implementation of this PR means that virtual files are now being
included for workspace diagnostics but it doesn't work completely e.g.,
if I save an untitled file the diagnostics disappears but it doesn't
appear back for the (now) saved file on disk as shown in the following
video demonstration:



https://github.com/user-attachments/assets/123e8d20-1e95-4c7d-b7eb-eb65be8c476e
Base automatically changed from dhruv/virtual-files-in-project-db to main July 14, 2025 14:47
@dhruvmanila dhruvmanila force-pushed the dhruv/workspace-diagnostics-in-virtual-files branch from e649866 to 93a44b3 Compare July 14, 2025 14:48
@dhruvmanila dhruvmanila marked this pull request as ready for review July 15, 2025 05:39
@dhruvmanila dhruvmanila added the internal An internal refactor or improvement label Jul 15, 2025
@AlexWaygood AlexWaygood removed their request for review July 15, 2025 07:17
Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Thank you. I think the should_check_file implementation is currently incorrect as it also returns true for third party files, which we don't want. It might be worth adding a CLI test for it.

I also think that we should remove the implicit behavior where setting open_files to Some changes the check mode. I think this is confusing now where we also have an explicit check mode. Instead, check should always do whatever is configured by CheckMode. This may require updating the benchmarks and ty_wasm to explicitly set CheckMode

Indexed(files::Indexed<'a>),
Indexed {
files: files::Indexed<'a>,
virtual_files: Option<Box<[File]>>,
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, that's interesting. It would certainly simplify things a bit. Can you try if skipping over the virtual files still works as expected?

@sharkdp sharkdp removed their request for review July 16, 2025 06:10
@dhruvmanila
Copy link
Member Author

Post review changes

  • Update should_check_file to check whether the file exists in the indexed file set in AllFiles check mode. This will avoid any third party files to be checked in this mode
  • Remove the check_mode field from the ProjectMetadata, instead expose a method set_check_mode from ProjectDatabase that updates the Project's check mode
  • Update the default check mode to be AllFiles and update the server code to set the check mode as per the diagnostic mode, update the wasm and benchmark code to always use the OpenFiles check mode
  • Update the logic to check if a file is open or not to only check whether it's explicitly in the open file set and avoid checking the indexed file set
  • Remove virtual file handling in ProjectFiles as it isn't required because editors send a textDocument/diagnostic request for open files and virtual files are always open
  • Use ChangeEvent::Created in the didOpen handler for system path to notify the Project that there might be a new file that's added in the project so the Indexed file set should be updated accordingly

@dhruvmanila dhruvmanila requested a review from MichaReiser July 16, 2025 12:14
- Update `should_check_file` to check whether the file exists in the
  indexed file set in `AllFiles` check mode. This will avoid any third
  party files to be checked in this mode
- Remove the `check_mode` field from the `ProjectMetadata`, instead
  expose a method `set_check_mode` from `ProjectDatabase` that updates
  the `Project`'s check mode
- Update the default check mode to be `AllFiles` and update the server
  code to set the check mode as per the diagnostic mode, update the wasm
  and benchmark code to always use the `OpenFiles` check mode
- Update the logic to check if a file is open or not to only check
  whether it's explicitly in the open file set and avoid checking the
  indexed file set
- Expand comments
@dhruvmanila dhruvmanila force-pushed the dhruv/workspace-diagnostics-in-virtual-files branch from 398bbb7 to b4d826b Compare July 17, 2025 15:03
@dhruvmanila dhruvmanila force-pushed the dhruv/workspace-diagnostics-in-virtual-files branch from 29831c6 to 4d0df12 Compare July 18, 2025 09:45
@dhruvmanila
Copy link
Member Author

Test cases

  • Open a virtual file, save it as system file
  • Delete the system file while it's open
  • Delete the system file while it's open but the editor focus is in a different file
  • Add an import that references a non-existant file, create a virtual file and save it with the same name as the import references
Screen.Recording.2025-07-18.at.15.24.30.mov

@dhruvmanila dhruvmanila requested a review from MichaReiser July 18, 2025 10:03
Copy link
Member

@MichaReiser MichaReiser left a comment

Choose a reason for hiding this comment

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

Uff, that was tricky. Thank you for seeing this through!

@dhruvmanila dhruvmanila merged commit 99d0ac6 into main Jul 18, 2025
37 checks passed
@dhruvmanila dhruvmanila deleted the dhruv/workspace-diagnostics-in-virtual-files branch July 18, 2025 14:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

internal An internal refactor or improvement server Related to the LSP server ty Multi-file analysis & type inference

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Track open files in server

2 participants