Skip to content

Map LSP documents by normalised FilePath#1252

Open
lionel- wants to merge 2 commits into
oak/salsa-15-file-path-refactorfrom
oak/salsa-16-document-wire-url
Open

Map LSP documents by normalised FilePath#1252
lionel- wants to merge 2 commits into
oak/salsa-15-file-path-refactorfrom
oak/salsa-16-document-wire-url

Conversation

@lionel-

@lionel- lionel- commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Branched from #1251
Progress towards #1212

See #1250 for more context.

  • WorldState now keys documents by normalised FilePath instead of Url. See state.rs. Keying by normalised paths will prevent bugs when matching to paths that don't come from the frontend, e.g. source() paths in user code.

  • The original Url sent by the LSP frontend is stored in Document. This is used in communications with the frontend so that we send back exact byte-for-byte Urls, preventing any file matching bugs that could be caused by our internal normalisation of file paths.

Unlike the DAP which has to deal with paths normalised by R, we never resolve symlinks on the LSP side. All matching is done on FilePath based on pure lexical normalisation of paths.

@lionel- lionel- force-pushed the oak/salsa-16-document-wire-url branch from 10e2102 to f6332d0 Compare June 3, 2026 12:12
@lionel- lionel- force-pushed the oak/salsa-15-file-path-refactor branch from 4ac9528 to e807fd2 Compare June 4, 2026 14:19
@lionel- lionel- force-pushed the oak/salsa-16-document-wire-url branch from f6332d0 to 14bacca Compare June 4, 2026 14:19

@DavisVaughan DavisVaughan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I really like the idea of this PR! But one blocking comment about Document that I'd like to resolve first

Comment on lines 84 to 93
pub(crate) fn get_document(&self, uri: &Url) -> anyhow::Result<&Document> {
if let Some(doc) = self.documents.get(uri) {
let key = FilePath::from_url(uri);
if let Some(doc) = self.documents.get(&key) {
Ok(doc)
} else {
Err(anyhow!("Can't find document for URI {uri}"))
}
}

pub(crate) fn get_document_mut(&mut self, uri: &Url) -> anyhow::Result<&mut Document> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I feel like these should take path: &FilePath. It would encourage conversion to FilePath at the LSP boundary

Comment on lines +19 to +22
/// Watched documents, keyed on the normalised [`FilePath`] form.
/// The verbatim editor URL is preserved on each [`Document::url`]
/// for wire output.
pub(crate) documents: HashMap<FilePath, Document>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I would like to advocate for the following strategy

pub(crate) documents: HashMap<FilePath, (Url, Document)>,
  • Document no longer knows about url. I think this is correct, as you should be able to create a Document without a corresponding url.
  • Document no longer has that weird PLACEHOLDER_URL hack, which i really do not like
  • insert_document() would be removed since we only .insert() in 1 place in production code, and then in a few tests, so the abstraction doesn't feel worth it

WorldState::get_document() and WorldState::get_document_mut() would then:

  • Take a path: FilePath as I mentioned elsewhere
  • Abstract over the (Url, Document) enum and just pull out the Document and return it

We would need to go update 2 direct usages of state.document.get() to be state.get_document(), but I think we should do that anyways.

This feels much much better to me, and I looked at all call sites of state.documents. and think it would work quite well

I am quite strongly against PLACEHOLDER_URL, so am going to block this pr until that is resolved

@lionel- lionel- force-pushed the oak/salsa-15-file-path-refactor branch from e807fd2 to 10deebe Compare June 10, 2026 14:32
@lionel- lionel- force-pushed the oak/salsa-16-document-wire-url branch from 14bacca to 7743983 Compare June 10, 2026 14:32
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.

2 participants