mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-13 05:38:46 +00:00
Merge #6785
6785: Fix "no value set for FileTextQuery(FileId(..))" r=jonas-schievink a=jonas-schievink Fixes https://github.com/rust-analyzer/rust-analyzer/issues/6622 Let's hope I got it right this time, but I feel like I slowly begin to understand the main loop logic. bors r+ Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
commit
243ba330dd
3 changed files with 19 additions and 8 deletions
|
@ -73,7 +73,7 @@ fn load(
|
||||||
}
|
}
|
||||||
vfs::loader::Message::Loaded { files } => {
|
vfs::loader::Message::Loaded { files } => {
|
||||||
for (path, contents) in files {
|
for (path, contents) in files {
|
||||||
vfs.set_file_contents(path.into(), contents)
|
vfs.set_file_contents(path.into(), contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,7 +255,7 @@ impl GlobalState {
|
||||||
for (path, contents) in files {
|
for (path, contents) in files {
|
||||||
let path = VfsPath::from(path);
|
let path = VfsPath::from(path);
|
||||||
if !self.mem_docs.contains_key(&path) {
|
if !self.mem_docs.contains_key(&path) {
|
||||||
vfs.set_file_contents(path, contents)
|
vfs.set_file_contents(path, contents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -503,11 +503,21 @@ impl GlobalState {
|
||||||
{
|
{
|
||||||
log::error!("duplicate DidOpenTextDocument: {}", path)
|
log::error!("duplicate DidOpenTextDocument: {}", path)
|
||||||
}
|
}
|
||||||
this.vfs
|
let changed = this
|
||||||
|
.vfs
|
||||||
.write()
|
.write()
|
||||||
.0
|
.0
|
||||||
.set_file_contents(path, Some(params.text_document.text.into_bytes()));
|
.set_file_contents(path, Some(params.text_document.text.into_bytes()));
|
||||||
this.maybe_update_diagnostics();
|
|
||||||
|
// If the VFS contents are unchanged, update diagnostics, since `handle_event`
|
||||||
|
// won't see any changes. This avoids missing diagnostics when opening a file.
|
||||||
|
//
|
||||||
|
// If the file *was* changed, `handle_event` will already recompute and send
|
||||||
|
// diagnostics. We can't do it here, since the *current* file contents might be
|
||||||
|
// unset in salsa, since the VFS change hasn't been applied to the database yet.
|
||||||
|
if !changed {
|
||||||
|
this.maybe_update_diagnostics();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?
|
})?
|
||||||
|
|
|
@ -103,18 +103,19 @@ impl Vfs {
|
||||||
(file_id, path)
|
(file_id, path)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) {
|
pub fn set_file_contents(&mut self, path: VfsPath, contents: Option<Vec<u8>>) -> bool {
|
||||||
let file_id = self.alloc_file_id(path);
|
let file_id = self.alloc_file_id(path);
|
||||||
let change_kind = match (&self.get(file_id), &contents) {
|
let change_kind = match (&self.get(file_id), &contents) {
|
||||||
(None, None) => return,
|
(None, None) => return false,
|
||||||
(None, Some(_)) => ChangeKind::Create,
|
(None, Some(_)) => ChangeKind::Create,
|
||||||
(Some(_), None) => ChangeKind::Delete,
|
(Some(_), None) => ChangeKind::Delete,
|
||||||
(Some(old), Some(new)) if old == new => return,
|
(Some(old), Some(new)) if old == new => return false,
|
||||||
(Some(_), Some(_)) => ChangeKind::Modify,
|
(Some(_), Some(_)) => ChangeKind::Modify,
|
||||||
};
|
};
|
||||||
|
|
||||||
*self.get_mut(file_id) = contents;
|
*self.get_mut(file_id) = contents;
|
||||||
self.changes.push(ChangedFile { file_id, change_kind })
|
self.changes.push(ChangedFile { file_id, change_kind });
|
||||||
|
true
|
||||||
}
|
}
|
||||||
pub fn has_changes(&self) -> bool {
|
pub fn has_changes(&self) -> bool {
|
||||||
!self.changes.is_empty()
|
!self.changes.is_empty()
|
||||||
|
|
Loading…
Reference in a new issue