Skip to content

Commit

Permalink
Fix: lsp crash caused by vfs loader (#778)
Browse files Browse the repository at this point in the history
* bugfix: fix lsp crash caused by vfs loader

Signed-off-by: He1pa <[email protected]>

* test: add open-close file mock test for vfs

Signed-off-by: He1pa <[email protected]>

---------

Signed-off-by: He1pa <[email protected]>
  • Loading branch information
He1pa committed Oct 17, 2023
1 parent 83cc443 commit 6e02ee7
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 9 deletions.
4 changes: 2 additions & 2 deletions kclvm/tools/src/LSP/src/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ impl LanguageServerState {
if let Some(id) = self.vfs.read().file_id(&path.clone().into()) {
self.opened_files.remove(&id);
}
self.vfs_handle.invalidate(path);
self.loader.handle.invalidate(path);

Ok(())
}
Expand All @@ -127,7 +127,7 @@ impl LanguageServerState {
) -> anyhow::Result<()> {
for change in params.changes {
let path = from_lsp::abs_path(&change.uri)?;
self.vfs_handle.invalidate(path);
self.loader.handle.invalidate(path);
}
Ok(())
}
Expand Down
21 changes: 14 additions & 7 deletions kclvm/tools/src/LSP/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ use lsp_types::{
};
use parking_lot::RwLock;
use ra_ap_vfs::{FileId, Vfs};
use ra_ap_vfs_notify::NotifyHandle;
use std::collections::HashMap;
use std::{sync::Arc, time::Instant};

Expand All @@ -34,6 +33,11 @@ pub(crate) enum Event {
Lsp(lsp_server::Message),
}

pub(crate) struct Handle<H, C> {
pub(crate) handle: H,
pub(crate) _receiver: C,
}

/// State for the language server
pub(crate) struct LanguageServerState {
/// Channel to send language server messages to the client
Expand Down Expand Up @@ -67,7 +71,7 @@ pub(crate) struct LanguageServerState {
pub opened_files: IndexSet<FileId>,

/// The VFS loader
pub vfs_handle: Box<dyn ra_ap_vfs::loader::Handle>,
pub loader: Handle<Box<dyn ra_ap_vfs::loader::Handle>, Receiver<ra_ap_vfs::loader::Message>>,

/// The word index map
pub word_index_map: HashMap<Url, HashMap<String, Vec<Location>>>,
Expand Down Expand Up @@ -95,10 +99,13 @@ impl LanguageServerState {
) -> Self {
let (task_sender, task_receiver) = unbounded::<Task>();

let (vfs_sender, receiver) = unbounded::<ra_ap_vfs::loader::Message>();
let handle: NotifyHandle =
ra_ap_vfs::loader::Handle::spawn(Box::new(move |msg| vfs_sender.send(msg).unwrap()));
let handle = Box::new(handle) as Box<dyn ra_ap_vfs::loader::Handle>;
let loader = {
let (sender, _receiver) = unbounded::<ra_ap_vfs::loader::Message>();
let handle: ra_ap_vfs_notify::NotifyHandle =
ra_ap_vfs::loader::Handle::spawn(Box::new(move |msg| sender.send(msg).unwrap()));
let handle = Box::new(handle) as Box<dyn ra_ap_vfs::loader::Handle>;
Handle { handle, _receiver }
};

// build word index for all the workspace folders
// todo: async
Expand Down Expand Up @@ -127,8 +134,8 @@ impl LanguageServerState {
shutdown_requested: false,
analysis: Analysis::default(),
opened_files: IndexSet::new(),
vfs_handle: handle,
word_index_map,
loader,
}
}

Expand Down
45 changes: 45 additions & 0 deletions kclvm/tools/src/LSP/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,51 @@ fn notification_test() {
}
}

#[test]
fn close_file_test() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut path = root.clone();

path.push("src/test_data/diagnostics.k");

let path = path.to_str().unwrap();
let src = std::fs::read_to_string(path.clone()).unwrap();
let server = Project {}.server(InitializeParams::default());

// Mock open file
server.notification::<lsp_types::notification::DidOpenTextDocument>(
lsp_types::DidOpenTextDocumentParams {
text_document: TextDocumentItem {
uri: Url::from_file_path(path).unwrap(),
language_id: "KCL".to_string(),
version: 0,
text: src.clone(),
},
},
);

// Mock close file
server.notification::<lsp_types::notification::DidCloseTextDocument>(
lsp_types::DidCloseTextDocumentParams {
text_document: TextDocumentIdentifier {
uri: Url::from_file_path(path).unwrap(),
},
},
);

// Mock reopen file
server.notification::<lsp_types::notification::DidOpenTextDocument>(
lsp_types::DidOpenTextDocumentParams {
text_document: TextDocumentItem {
uri: Url::from_file_path(path).unwrap(),
language_id: "KCL".to_string(),
version: 0,
text: src,
},
},
);
}

#[test]
fn goto_def_test() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
Expand Down

0 comments on commit 6e02ee7

Please sign in to comment.