diff --git a/kclvm/sema/src/core/symbol.rs b/kclvm/sema/src/core/symbol.rs index a15855dea..65740a607 100644 --- a/kclvm/sema/src/core/symbol.rs +++ b/kclvm/sema/src/core/symbol.rs @@ -25,7 +25,7 @@ pub trait Symbol { data: &Self::SymbolData, module_info: Option<&ModuleInfo>, ) -> Option; - fn has_attribue( + fn has_attribute( &self, name: &str, data: &Self::SymbolData, @@ -667,7 +667,7 @@ impl Symbol for SchemaSymbol { result } - fn has_attribue( + fn has_attribute( &self, name: &str, data: &Self::SymbolData, @@ -821,7 +821,7 @@ impl Symbol for ValueSymbol { result } - fn has_attribue( + fn has_attribute( &self, name: &str, data: &Self::SymbolData, @@ -953,7 +953,7 @@ impl Symbol for AttributeSymbol { result } - fn has_attribue( + fn has_attribute( &self, name: &str, data: &Self::SymbolData, @@ -1067,7 +1067,7 @@ impl Symbol for PackageSymbol { result } - fn has_attribue( + fn has_attribute( &self, name: &str, _data: &Self::SymbolData, @@ -1192,7 +1192,7 @@ impl Symbol for TypeAliasSymbol { result } - fn has_attribue( + fn has_attribute( &self, name: &str, data: &Self::SymbolData, @@ -1307,7 +1307,7 @@ impl Symbol for RuleSymbol { vec![] } - fn has_attribue( + fn has_attribute( &self, _name: &str, _data: &Self::SymbolData, @@ -1440,7 +1440,7 @@ impl Symbol for UnresolvedSymbol { vec![] } - fn has_attribue( + fn has_attribute( &self, name: &str, data: &Self::SymbolData, diff --git a/kclvm/tools/src/LSP/src/find_refs.rs b/kclvm/tools/src/LSP/src/find_refs.rs index 2a57390b5..22929e78b 100644 --- a/kclvm/tools/src/LSP/src/find_refs.rs +++ b/kclvm/tools/src/LSP/src/find_refs.rs @@ -1,8 +1,9 @@ -use crate::from_lsp::kcl_pos; +use crate::from_lsp::{file_path_from_url, kcl_pos}; use crate::goto_def::{find_def_with_gs, goto_definition_with_gs}; use crate::to_lsp::lsp_location; use crate::util::{parse_param_and_compile, Param}; +use anyhow::Result; use kclvm_ast::ast::Program; use kclvm_error::Position as KCLPos; use kclvm_parser::KCLModuleCache; @@ -76,34 +77,45 @@ pub(crate) fn find_refs_from_def Result<(), anyhow::Error>>( .filter(|ref_loc| { // from location to real def // return if the real def location matches the def_loc - let file_path = ref_loc.uri.path().to_string(); - match parse_param_and_compile( - Param { - file: file_path.clone(), - module_cache: module_cache.clone(), - }, - vfs.clone(), - ) { - Ok((prog, _, _, gs)) => { - let ref_pos = kcl_pos(&file_path, ref_loc.range.start); - if *ref_loc == def_loc && !include_declaration { - return false; - } - // find def from the ref_pos - if let Some(real_def) = goto_definition_with_gs(&prog, &ref_pos, &gs) { - match real_def { - lsp_types::GotoDefinitionResponse::Scalar(real_def_loc) => { - real_def_loc == def_loc + match file_path_from_url(&ref_loc.uri) { + Ok(file_path) => { + match parse_param_and_compile( + Param { + file: file_path.clone(), + module_cache: module_cache.clone(), + }, + vfs.clone(), + ) { + Ok((prog, _, _, gs)) => { + let ref_pos = kcl_pos(&file_path, ref_loc.range.start); + if *ref_loc == def_loc && !include_declaration { + return false; } - _ => false, + // find def from the ref_pos + if let Some(real_def) = + goto_definition_with_gs(&prog, &ref_pos, &gs) + { + match real_def { + lsp_types::GotoDefinitionResponse::Scalar( + real_def_loc, + ) => real_def_loc == def_loc, + _ => false, + } + } else { + false + } + } + Err(err) => { + let _ = logger(format!( + "{file_path} compilation failed: {}", + err.to_string() + )); + false } - } else { - false } } - Err(_) => { - let file_path = def_loc.uri.path(); - let _ = logger(format!("{file_path} compilation failed")); + Err(err) => { + let _ = logger(format!("compilation failed: {}", err.to_string())); false } } diff --git a/kclvm/tools/src/LSP/src/goto_def.rs b/kclvm/tools/src/LSP/src/goto_def.rs index 7cc5d310a..8350ddd42 100644 --- a/kclvm/tools/src/LSP/src/goto_def.rs +++ b/kclvm/tools/src/LSP/src/goto_def.rs @@ -98,7 +98,10 @@ fn positions_to_goto_def_resp( #[cfg(test)] mod tests { use super::goto_definition_with_gs; - use crate::tests::{compare_goto_res, compile_test_file}; + use crate::{ + from_lsp::file_path_from_url, + tests::{compare_goto_res, compile_test_file}, + }; use indexmap::IndexSet; use kclvm_error::Position as KCLPos; use proc_macro_crate::bench_test; @@ -130,7 +133,7 @@ mod tests { lsp_types::GotoDefinitionResponse::Array(arr) => { assert_eq!(expected_files.len(), arr.len()); for loc in arr { - let got_path = loc.uri.path().to_string(); + let got_path = file_path_from_url(&loc.uri).unwrap(); assert!(expected_files.contains(&got_path)); } } @@ -159,7 +162,7 @@ mod tests { let res = goto_definition_with_gs(&program, &pos, &gs); match res.unwrap() { lsp_types::GotoDefinitionResponse::Scalar(loc) => { - let got_path = loc.uri.path(); + let got_path = file_path_from_url(&loc.uri).unwrap(); assert_eq!(got_path, expected_path.to_str().unwrap()) } _ => { @@ -195,7 +198,7 @@ mod tests { lsp_types::GotoDefinitionResponse::Array(arr) => { assert_eq!(expected_files.len(), arr.len()); for loc in arr { - let got_path = loc.uri.path().to_string(); + let got_path = file_path_from_url(&loc.uri).unwrap(); assert!(expected_files.contains(&got_path)); } } diff --git a/kclvm/tools/src/LSP/src/notification.rs b/kclvm/tools/src/LSP/src/notification.rs index c4313e892..deb10f807 100644 --- a/kclvm/tools/src/LSP/src/notification.rs +++ b/kclvm/tools/src/LSP/src/notification.rs @@ -100,8 +100,8 @@ impl LanguageServerState { let old_word_index = build_word_index_for_file_content(old_text, &text_document.uri, true); let new_word_index = build_word_index_for_file_content(text.clone(), &text_document.uri, true); - let binding = text_document.uri.path(); - let file_path = Path::new(binding); //todo rename + let binding = from_lsp::file_path_from_url(&text_document.uri)?; + let file_path = Path::new(&binding); //todo rename let word_index_map = &mut *self.word_index_map.write(); for (key, value) in word_index_map { let workspace_folder_path = Path::new(key.path()); diff --git a/kclvm/tools/src/LSP/src/state.rs b/kclvm/tools/src/LSP/src/state.rs index 8c00b5708..6839b97e3 100644 --- a/kclvm/tools/src/LSP/src/state.rs +++ b/kclvm/tools/src/LSP/src/state.rs @@ -1,8 +1,10 @@ use crate::analysis::Analysis; use crate::config::Config; use crate::db::AnalysisDatabase; +use crate::from_lsp::file_path_from_url; use crate::to_lsp::{kcl_diag_to_lsp_diags, url}; use crate::util::{build_word_index, get_file_name, parse_param_and_compile, to_json, Param}; +use anyhow::Result; use crossbeam_channel::{select, unbounded, Receiver, Sender}; use indexmap::IndexSet; use kclvm_parser::KCLModuleCache; @@ -119,7 +121,7 @@ impl LanguageServerState { _config: config, vfs: Arc::new(RwLock::new(Default::default())), thread_pool: threadpool::ThreadPool::default(), - task_sender, + task_sender: task_sender.clone(), task_receiver, shutdown_requested: false, analysis: Analysis::default(), @@ -130,9 +132,11 @@ impl LanguageServerState { }; let word_index_map = state.word_index_map.clone(); - state - .thread_pool - .execute(move || build_word_index_map(word_index_map, initialize_params, true)); + state.thread_pool.execute(move || { + if let Err(err) = build_word_index_map(word_index_map, initialize_params, true) { + log_message(err.to_string(), &task_sender); + } + }); state } @@ -335,18 +339,19 @@ fn build_word_index_map( word_index_map: Arc>>>>, initialize_params: InitializeParams, prune: bool, -) { +) -> Result<()> { if let Some(workspace_folders) = initialize_params.workspace_folders { for folder in workspace_folders { - let path = folder.uri.path(); + let path = file_path_from_url(&folder.uri)?; if let Ok(word_index) = build_word_index(path.to_string(), prune) { word_index_map.write().insert(folder.uri, word_index); } } } else if let Some(root_uri) = initialize_params.root_uri { - let path = root_uri.path(); + let path = file_path_from_url(&root_uri)?; if let Ok(word_index) = build_word_index(path.to_string(), prune) { word_index_map.write().insert(root_uri, word_index); } } + Ok(()) } diff --git a/kclvm/tools/src/LSP/src/test_data/goto_def_test/kcl.mod b/kclvm/tools/src/LSP/src/test_data/goto_def_test/kcl.mod new file mode 100644 index 000000000..e69de29bb diff --git a/kclvm/tools/src/LSP/src/test_data/hover_test/kcl.mod b/kclvm/tools/src/LSP/src/test_data/hover_test/kcl.mod new file mode 100644 index 000000000..e69de29bb diff --git a/kclvm/tools/src/LSP/src/tests.rs b/kclvm/tools/src/LSP/src/tests.rs index c1e97b1f5..72622ea29 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -72,14 +72,20 @@ use crate::to_lsp::kcl_diag_to_lsp_diags; use crate::util::to_json; use crate::util::{apply_document_changes, parse_param_and_compile, Param}; +macro_rules! wait_async_compile { + () => { + thread::sleep(Duration::from_secs(2)); + }; +} + pub(crate) fn compare_goto_res( res: Option, pos: (&String, u32, u32, u32, u32), ) { match res.unwrap() { lsp_types::GotoDefinitionResponse::Scalar(loc) => { - let got_path = loc.uri.path(); - assert_eq!(got_path, pos.0); + let got_path = file_path_from_url(&loc.uri).unwrap(); + assert_eq!(got_path, pos.0.to_string()); let (got_start, got_end) = (loc.range.start, loc.range.end); @@ -843,7 +849,7 @@ fn goto_def_test() { }, ); - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let id = server.next_request_id.get(); server.next_request_id.set(id.wrapping_add(1)); @@ -900,7 +906,7 @@ fn complete_test() { }, }, ); - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let id = server.next_request_id.get(); server.next_request_id.set(id.wrapping_add(1)); @@ -969,7 +975,7 @@ fn hover_test() { }, }, ); - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let id = server.next_request_id.get(); server.next_request_id.set(id.wrapping_add(1)); @@ -1027,7 +1033,7 @@ fn hover_assign_in_lambda_test() { }, }, ); - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let id = server.next_request_id.get(); server.next_request_id.set(id.wrapping_add(1)); @@ -1570,7 +1576,7 @@ fn find_refs_test() { let server = Project {}.server(initialize_params); // Wait for async build word_index_map - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let url = Url::from_file_path(path).unwrap(); @@ -1586,7 +1592,7 @@ fn find_refs_test() { }, ); - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let id = server.next_request_id.get(); server.next_request_id.set(id.wrapping_add(1)); @@ -1665,7 +1671,7 @@ fn find_refs_with_file_change_test() { let server = Project {}.server(initialize_params); // Wait for async build word_index_map - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let url = Url::from_file_path(path).unwrap(); @@ -1708,7 +1714,7 @@ p2 = Person { }], }, ); - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let id = server.next_request_id.get(); server.next_request_id.set(id.wrapping_add(1)); // Mock trigger find references @@ -1773,7 +1779,7 @@ fn rename_test() { let server = Project {}.server(initialize_params); // Wait for async build word_index_map - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let url = Url::from_file_path(path).unwrap(); let main_url = Url::from_file_path(main_path).unwrap(); @@ -1789,7 +1795,7 @@ fn rename_test() { }, }, ); - thread::sleep(Duration::from_secs(1)); + wait_async_compile!(); let id = server.next_request_id.get(); server.next_request_id.set(id.wrapping_add(1));