-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[ty] Refactor Range to/from TextRange conversion as prep for notebook support
#21230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Diagnostic diff on typing conformance testsNo changes detected when running ty on typing conformance tests ✅ |
|
| &line_index, | ||
| db, | ||
| file, | ||
| snapshot.url(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit unfortunate that we need the url here but the file isn't unique enough (the file maps to the entire notebook). We need the url to lookup the corresponding cell within the notebook.
| let range = edit | ||
| .range() | ||
| .as_lsp_range(db, file, snapshot.encoding()) | ||
| .to_local_range(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using to_local_range here is technically incorrect. In fact, it's very likely that the importer adds the import to the very first cell within the notebook, in which case the edit is not local to a single cell.
However, fixing this requires changes to the importer and they're substantial enough to justify a separate PR
4b69dd8 to
1114c07
Compare
| .range() | ||
| .to_lsp_range(&source, &line_index, snapshot.encoding()); | ||
| .as_lsp_range(db, file, snapshot.encoding()) | ||
| .to_local_range(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to limit the document_highlights to the current cell. This seems very unfortunate as the highlights are very likely to be cross cell but the LSP protocol doesn't allow us to specify a URI. Again, I think this is best done in a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't something that requires to be investigated right now but I tested Pylance and it seems to be able to highlight a symbol across multiple cells in a notebook.
Screen.Recording.2025-11-04.at.15.48.55.mov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure this is something Pylance does (although it could because it isn't an LSP).
But I don't see a highlight request for cells at all and the highlighting is also incorrect, suggesting it's just a simple name matching:
Screen.Recording.2025-11-04.at.15.58.25.mov
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It could mean that we should return Option from to_location but I've to revisit this when being further along with the notebook integration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense.
| range: symbol | ||
| .full_range | ||
| .as_lsp_range(db, file, encoding) | ||
| .to_local_range(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here: We need to limit the document symbol request to the current cell. But I'd prefer doing that in a separate PR
|
|
||
| for token in &*semantic_token_data { | ||
| let lsp_range = token.range().to_lsp_range(&source, &line_index, encoding); | ||
| let lsp_range = token |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'll need to limit the semantic tokens to a single range but I'll do this in a separate PR
61afb54 to
a62875f
Compare
|
Seems like something that maybe @dhruvmanila would be a good candidate to review? |
dhruvmanila
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Introduce new infrastructure to support converting positions and ranges
for documents that may map to multiple URIs (like notebook cells):
- Add Db trait with document() and notebook_document() queries
- Provides access to document metadata needed for conversion
- notebook_document() returns notebook info for a file if it exists
- Add LspRange and LspPosition types for deferred LSP conversion
- Stores file, offset/range, db reference, and encoding
- Allows callers to choose conversion strategy:
* to_local_range()/to_local_position(): For use within same document/cell
* to_location(): For cross-document references with URI
- Critical for notebooks where one file maps to multiple cell URIs
- Update conversion traits (RangeExt, PositionExt, etc.)
- Add methods to create LspRange/LspPosition from internal types
- Support both notebook cells and regular files
This infrastructure prepares the codebase for notebook support where
position/range conversions must account for cell boundaries and URIs.
5662955 to
44ad219
Compare
Range to/from TextRange conversion as prep for notebook support
* main: (188 commits) [ty] Discover site-packages from the environment that ty is installed in (astral-sh#21286) [ty] Make special cases for `UnionType` slightly narrower (astral-sh#21276) Require ignore 0.4.24 in `Cargo.toml` (astral-sh#21292) [ty] Favour imported symbols over builtin symbols (astral-sh#21285) docs: revise Ruff setup instructions for Zed editor (astral-sh#20935) [ty] Update salsa (astral-sh#21281) [syntax-error]: no binding for nonlocal PLE0117 as a semantic syntax error (astral-sh#21032) [ty] Constraining a typevar with itself (possibly via union or intersection) (astral-sh#21273) [`ruff`] Fix false positives on starred arguments (`RUF057`) (astral-sh#21256) [ty] Simplify unions containing multiple type variables during inference (astral-sh#21275) [ty] Add `ty_server::Db` trait (astral-sh#21241) [ty] Refactor `Range` to/from `TextRange` conversion as prep for notebook support (astral-sh#21230) [ty] Fix playground crash when file name includes path separator (astral-sh#21151) [`refurb`] Fix false negative for underscores before sign in `Decimal` constructor (`FURB157`) (astral-sh#21190) [ty] Allow values of type `None` in type expressions (astral-sh#21263) Run codspeed benchmarks with `profiling` profile (astral-sh#21261) [ty] Update expected diagnostic count in benchmarks (astral-sh#21269) Avoid extra parentheses for long `match` patterns with `as` captures (astral-sh#21176) [ty] Update salsa (astral-sh#21265) [ty] `dict` is not assignable to `TypedDict` (astral-sh#21238) ...
Summary
This PR changes the signature of the
TextSize<->PositionandTextRange<->Rangeconversion methods in preparation for notebook support.According to the LSP specification, each Notebook consists of many
TextDocuments. However, ty internally concatenates all cells to a single text document. That means, offsets coming from ty need to be mapped back to their corresponding cell, and then to the offset within the cell. The same applies for LSP offsets: The cell-relative offset needs to be converted to an absolute offset into the concatenated notebook document.This PR doesn't implement the logic itself for mapping between the different offsets but it refactors the call-sites and the methods used for those conversions to add the required logic in a follow-up PR.
The most important change is that we now pass
dbandFileto the conversion methods. This will allow us to query the notebook to resolve the cell metadata (offset per cell, etc).Test Plan
Existing tests. I tested different LSP features and they seem to work fine