diff --git a/.github/workflows/windows_test.yaml b/.github/workflows/windows_test.yaml index a3574ef56..f0ac20701 100644 --- a/.github/workflows/windows_test.yaml +++ b/.github/workflows/windows_test.yaml @@ -61,7 +61,7 @@ jobs: working-directory: . # Rust unit test - - run: cargo test -r -p kclvm-* + - run: cargo test --workspace -r -- --nocapture working-directory: ./kclvm - uses: actions/upload-artifact@v4 diff --git a/kclvm/Cargo.lock b/kclvm/Cargo.lock index 122b5f8ce..86fc40eaf 100644 --- a/kclvm/Cargo.lock +++ b/kclvm/Cargo.lock @@ -2047,6 +2047,7 @@ dependencies = [ "kclvm-error", "kclvm-parser", "kclvm-sema", + "kclvm-utils", "maplit", "pretty_assertions", "serde", diff --git a/kclvm/ast/src/ast.rs b/kclvm/ast/src/ast.rs index 581899afc..9f89c35ea 100644 --- a/kclvm/ast/src/ast.rs +++ b/kclvm/ast/src/ast.rs @@ -58,13 +58,19 @@ pub struct Pos(String, u64, u64, u64, u64); impl From for Pos { fn from(value: PosTuple) -> Self { - Self(value.0, value.1, value.2, value.3, value.4) + Self( + value.0.adjust_canonicalization(), + value.1, + value.2, + value.3, + value.4, + ) } } impl From for PosTuple { fn from(val: Pos) -> Self { - (val.0, val.1, val.2, val.3, val.4) + (val.0.adjust_canonicalization(), val.1, val.2, val.3, val.4) } } @@ -72,12 +78,12 @@ impl From for Range { fn from(val: Pos) -> Self { ( Position { - filename: val.0.clone(), + filename: val.0.clone().adjust_canonicalization(), line: val.1, column: Some(val.2), }, Position { - filename: val.0, + filename: val.0.adjust_canonicalization(), line: val.3, column: Some(val.4), }, @@ -220,7 +226,7 @@ impl Node { Self { id, node, - filename: pos.0.clone(), + filename: pos.0.clone().adjust_canonicalization(), line: pos.1, column: pos.2, end_line: pos.3, @@ -232,7 +238,7 @@ impl Node { Self { id: AstIndex::default(), node, - filename: pos.0.clone(), + filename: pos.0.clone().adjust_canonicalization(), line: pos.1, column: pos.2, end_line: pos.3, @@ -242,7 +248,7 @@ impl Node { pub fn pos(&self) -> PosTuple { ( - self.filename.clone(), + self.filename.clone().adjust_canonicalization(), self.line, self.column, self.end_line, @@ -251,7 +257,7 @@ impl Node { } pub fn set_pos(&mut self, pos: PosTuple) { - self.filename = pos.0.clone(); + self.filename = pos.0.clone().adjust_canonicalization(); self.line = pos.1; self.column = pos.2; self.end_line = pos.3; diff --git a/kclvm/parser/src/entry.rs b/kclvm/parser/src/entry.rs index 2b53f85dc..56d9ca927 100644 --- a/kclvm/parser/src/entry.rs +++ b/kclvm/parser/src/entry.rs @@ -8,6 +8,7 @@ use kclvm_utils::path::{is_absolute, is_dir, path_exist}; use std::collections::VecDeque; use std::fs; use std::path::Path; +use std::path::PathBuf; use crate::LoadProgramOptions; @@ -424,7 +425,13 @@ fn get_main_files_from_pkg_path( } } - path_list.push(s); + match PathBuf::from(s.clone()).canonicalize() { + Ok(path) => { + path_list.push(path.to_str().unwrap().to_string()); + } + // path from virtual file system + Err(_) => path_list.push(s), + } // get k files let mut k_files: Vec = Vec::new(); diff --git a/kclvm/parser/src/parser/mod.rs b/kclvm/parser/src/parser/mod.rs index 77d29c6c9..3e635f976 100644 --- a/kclvm/parser/src/parser/mod.rs +++ b/kclvm/parser/src/parser/mod.rs @@ -32,6 +32,7 @@ use kclvm_ast::token::{CommentKind, Token, TokenKind}; use kclvm_ast::token_stream::{Cursor, TokenStream}; use kclvm_error::ParseErrorMessage; use kclvm_span::symbol::Symbol; +use kclvm_utils::path::PathPrefix; /// The parser is built on top of the [`kclvm_parser::lexer`], and ordering KCL tokens /// [`kclvm_ast::token`] to KCL ast nodes [`kclvm_ast::ast`]. @@ -86,7 +87,8 @@ impl<'a> Parser<'a> { let filename = kclvm_utils::path::convert_windows_drive_letter(&format!( "{}", lo.file.name.prefer_remapped() - )); + )) + .adjust_canonicalization(); ( filename, @@ -197,7 +199,8 @@ impl<'a> Parser<'a> { let hi = sess.lookup_char_pos(tok.span.hi()); let filename = kclvm_utils::path::convert_windows_drive_letter( &format!("{}", lo.file.name.prefer_remapped()), - ); + ) + .adjust_canonicalization(); let node = kclvm_ast::ast::Node { id: kclvm_ast::ast::AstIndex::default(), diff --git a/kclvm/query/Cargo.toml b/kclvm/query/Cargo.toml index 10e40eae7..86f5020bd 100644 --- a/kclvm/query/Cargo.toml +++ b/kclvm/query/Cargo.toml @@ -16,6 +16,7 @@ kclvm-ast-pretty = {path = "../ast_pretty"} kclvm-parser = {path = "../parser"} kclvm-sema = {path = "../sema"} kclvm-error = {path = "../error"} +kclvm-utils ={ path = "../utils"} serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" fancy-regex = "0.7.1" diff --git a/kclvm/query/src/tests.rs b/kclvm/query/src/tests.rs index 401cdde2c..f18de5142 100644 --- a/kclvm/query/src/tests.rs +++ b/kclvm/query/src/tests.rs @@ -6,6 +6,7 @@ use crate::{ }; use kclvm_error::{DiagnosticId, ErrorKind, Level}; use kclvm_parser::parse_file_force_errors; +use kclvm_utils::path::PathPrefix; use pretty_assertions::assert_eq; use selector::ListOptions; @@ -887,8 +888,12 @@ fn test_overridefile_with_invalid_kcl() { "expected one of [\"=\"] got eof" ); assert_eq!( - result.parse_errors[0].messages[0].range.0.filename, - simple_path.display().to_string() + result.parse_errors[0].messages[0] + .range + .0 + .filename + .adjust_canonicalization(), + simple_path.display().to_string().adjust_canonicalization() ); assert_eq!(result.parse_errors[0].messages[0].range.0.line, 1); assert_eq!(result.parse_errors[0].messages[0].range.0.column, Some(8)); diff --git a/kclvm/tools/benches/proc_macro_crate/src/lib.rs b/kclvm/tools/benches/proc_macro_crate/src/lib.rs index 6452dc46b..b03050131 100644 --- a/kclvm/tools/benches/proc_macro_crate/src/lib.rs +++ b/kclvm/tools/benches/proc_macro_crate/src/lib.rs @@ -16,8 +16,8 @@ pub fn bench_test(_attr: TokenStream, item: TokenStream) -> TokenStream { let end_time = std::time::Instant::now(); let time = (end_time - start_time).as_micros(); println!("{} took {} μs", stringify!(#fn_name), (end_time - start_time).as_micros()); - // 200 ms - assert!(time < 200000, "Bench mark test failed"); + // 400 ms + assert!(time < 400000, "Bench mark test failed"); result } }; diff --git a/kclvm/tools/src/LSP/src/compile.rs b/kclvm/tools/src/LSP/src/compile.rs index ffe93a3f9..65b7d9cdf 100644 --- a/kclvm/tools/src/LSP/src/compile.rs +++ b/kclvm/tools/src/LSP/src/compile.rs @@ -1,5 +1,3 @@ -use std::collections::HashSet; - use indexmap::IndexSet; use kclvm_ast::ast::Program; use kclvm_driver::{lookup_compile_workspace, toolchain}; @@ -14,6 +12,8 @@ use kclvm_sema::{ namer::Namer, resolver::{resolve_program_with_opts, scope::KCLScopeCache}, }; +use std::collections::HashSet; +use std::path::PathBuf; use crate::{ state::{KCLGlobalStateCache, KCLVfs}, @@ -149,7 +149,12 @@ pub fn compile_with_params( IndexSet, anyhow::Result<(Program, GlobalState)>, ) { - let file = params.file.clone().unwrap(); + let file = PathBuf::from(params.file.clone().unwrap()) + .canonicalize() + .unwrap() + .to_str() + .unwrap() + .to_string(); // Lookup compile workspace from the cursor file. let (mut files, opts, _) = lookup_compile_workspace(&toolchain::default(), &file, true); if !files.contains(&file) { diff --git a/kclvm/tools/src/LSP/src/completion.rs b/kclvm/tools/src/LSP/src/completion.rs index 8f22771d1..6fbabc1a0 100644 --- a/kclvm/tools/src/LSP/src/completion.rs +++ b/kclvm/tools/src/LSP/src/completion.rs @@ -15,9 +15,6 @@ //! + new line //! + schema init -use std::io; -use std::{fs, path::Path}; - use crate::goto_def::{find_def, find_symbol}; use indexmap::IndexSet; use kclvm_ast::ast::{self, ImportStmt, Program, Stmt}; @@ -26,6 +23,8 @@ use kclvm_config::modfile::KCL_FILE_EXTENSION; use kclvm_driver::get_kcl_files; use kclvm_driver::toolchain::{get_real_path_from_external, Metadata, Toolchain}; use kclvm_sema::core::global_state::GlobalState; +use std::io; +use std::{fs, path::Path}; use kclvm_error::Position as KCLPos; use kclvm_sema::builtin::{BUILTIN_FUNCTIONS, STANDARD_SYSTEM_MODULES}; @@ -34,6 +33,7 @@ use kclvm_sema::core::scope::{LocalSymbolScopeKind, ScopeKind}; use kclvm_sema::core::symbol::SymbolKind; use kclvm_sema::resolver::doc::{parse_schema_doc_string, SchemaDoc}; use kclvm_sema::ty::{FunctionType, SchemaType, Type, TypeKind}; +use kclvm_utils::path::PathPrefix; use lsp_types::{CompletionItem, CompletionItemKind, InsertTextFormat}; use crate::util::{inner_most_expr_in_stmt, is_in_docstring}; @@ -252,7 +252,6 @@ fn completion_dot( if symbol.is_none() { symbol = find_symbol(pos, gs, false); } - let def = match symbol { Some(symbol_ref) => { if let SymbolKind::Unresolved = symbol_ref.get_kind() { @@ -472,7 +471,6 @@ fn completion_import_stmt( line: pos.line, column: Some(0), }; - if let Some(node) = program.pos_to_stmt(line_start_pos) { if let Stmt::Import(_) = node.node { completions.extend(completion_import_builtin_pkg()); @@ -527,7 +525,9 @@ fn completion_import_internal_pkg( } else { // internal module let path = entry.path(); - if path.to_str().unwrap_or("") == line_start_pos.filename { + if path.to_str().unwrap_or("").adjust_canonicalization() + == line_start_pos.filename.adjust_canonicalization() + { continue; } if let Some(extension) = path.extension() { diff --git a/kclvm/tools/src/LSP/src/document_symbol.rs b/kclvm/tools/src/LSP/src/document_symbol.rs index 883472cb0..882fb9d45 100644 --- a/kclvm/tools/src/LSP/src/document_symbol.rs +++ b/kclvm/tools/src/LSP/src/document_symbol.rs @@ -1,5 +1,3 @@ -use std::path::Path; - use kclvm_ast::MAIN_PKG; use kclvm_error::Position; use kclvm_sema::core::global_state::GlobalState; @@ -28,57 +26,48 @@ pub fn document_symbol(file: &str, gs: &GlobalState) -> Option { let symbol_range = symbol.get_range(); // filter current file symbols - if let Ok(canonicalized_path) = - Path::new(&symbol_range.0.filename).canonicalize() - { - if canonicalized_path.eq(Path::new(file)) { - match def.get_kind() { - KCLSymbolKind::Schema => { - match &mut symbol_to_document_symbol(symbol) { - Some(schema_symbol) => { - let module_info = gs - .get_packages() - .get_module_info(&dummy_pos.filename); - let attrs = symbol.get_all_attributes( - gs.get_symbols(), - module_info, - ); - let mut children = vec![]; - - for attr in attrs { - match gs.get_symbols().get_symbol(attr) - { - Some(attr_symbol) => { - match symbol_to_document_symbol( - attr_symbol, - ) { - Some(symbol) => { - children.push(symbol) - } - None => {} + if symbol_range.0.filename == file { + match def.get_kind() { + KCLSymbolKind::Schema => { + match &mut symbol_to_document_symbol(symbol) { + Some(schema_symbol) => { + let module_info = gs + .get_packages() + .get_module_info(&dummy_pos.filename); + let attrs = symbol.get_all_attributes( + gs.get_symbols(), + module_info, + ); + let mut children = vec![]; + + for attr in attrs { + match gs.get_symbols().get_symbol(attr) { + Some(attr_symbol) => { + match symbol_to_document_symbol( + attr_symbol, + ) { + Some(symbol) => { + children.push(symbol) } + None => {} } - None => {} } + None => {} } - - schema_symbol.children = Some(children); - schema_symbol.name = format!( - "schema {}", - schema_symbol.name - ); - document_symbols - .push(schema_symbol.clone()); } - None => {} + + schema_symbol.children = Some(children); + schema_symbol.name = + format!("schema {}", schema_symbol.name); + document_symbols.push(schema_symbol.clone()); } + None => {} } - _ => { - if let Some(symbol) = - symbol_to_document_symbol(symbol) - { - document_symbols.push(symbol) - } + } + _ => { + if let Some(symbol) = symbol_to_document_symbol(symbol) + { + document_symbols.push(symbol) } } } diff --git a/kclvm/tools/src/LSP/src/find_refs.rs b/kclvm/tools/src/LSP/src/find_refs.rs index 9d5b492cd..8d42fb560 100644 --- a/kclvm/tools/src/LSP/src/find_refs.rs +++ b/kclvm/tools/src/LSP/src/find_refs.rs @@ -76,7 +76,12 @@ mod tests { for loc in resp { let url = file_path_from_url(&loc.uri).unwrap(); let got_path = Path::new(&url); - let relative_path = got_path.strip_prefix(root_path.clone()).unwrap(); + let relative_path = got_path + .strip_prefix(root_path.clone()) + .unwrap() + .display() + .to_string() + .replace("\\", "/"); res.push_str(&format!( "path: {:?}, range: {:?}\n", relative_path, loc.range diff --git a/kclvm/tools/src/LSP/src/goto_def.rs b/kclvm/tools/src/LSP/src/goto_def.rs index 4ccb68e55..c04af0109 100644 --- a/kclvm/tools/src/LSP/src/goto_def.rs +++ b/kclvm/tools/src/LSP/src/goto_def.rs @@ -18,6 +18,7 @@ use lsp_types::GotoDefinitionResponse; pub fn goto_def(kcl_pos: &KCLPos, gs: &GlobalState) -> Option { let mut res = IndexSet::new(); let def = find_def(kcl_pos, gs, true); + match def { Some(def_ref) => match gs.get_symbols().get_symbol(def_ref) { Some(def) => match def_ref.get_kind() { @@ -50,7 +51,7 @@ pub fn goto_def(kcl_pos: &KCLPos, gs: &GlobalState) -> Option Option { - if exact { + let def = if exact { match gs.look_up_exact_symbol(kcl_pos) { Some(symbol_ref) => match gs.get_symbols().get_symbol(symbol_ref) { Some(symbol) => symbol.get_definition(), @@ -66,15 +67,18 @@ pub(crate) fn find_def(kcl_pos: &KCLPos, gs: &GlobalState, exact: bool) -> Optio }, None => None, } - } + }; + + def } pub(crate) fn find_symbol(kcl_pos: &KCLPos, gs: &GlobalState, exact: bool) -> Option { - if exact { + let res = if exact { gs.look_up_exact_symbol(kcl_pos) } else { gs.look_up_closest_symbol(kcl_pos) - } + }; + res } // Convert kcl position to GotoDefinitionResponse. This function will convert to @@ -126,21 +130,33 @@ mod tests { } fn fmt_resp(resp: &Option) -> String { - let root_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let root_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .canonicalize() + .unwrap(); match resp { Some(resp) => match resp { lsp_types::GotoDefinitionResponse::Scalar(loc) => { let url = file_path_from_url(&loc.uri).unwrap(); - let got_path = Path::new(&url); - let relative_path = got_path.strip_prefix(root_path).unwrap(); + let got_path = Path::new(&url).canonicalize().unwrap(); + let relative_path = got_path + .strip_prefix(root_path) + .unwrap() + .display() + .to_string() + .replace("\\", "/"); format!("path: {:?}, range: {:?}", relative_path, loc.range) } lsp_types::GotoDefinitionResponse::Array(vec_location) => { let mut res = String::new(); for loc in vec_location { let url = file_path_from_url(&loc.uri).unwrap(); - let got_path = Path::new(&url); - let relative_path = got_path.strip_prefix(root_path.clone()).unwrap(); + let got_path = Path::new(&url).canonicalize().unwrap(); + let relative_path = got_path + .strip_prefix(root_path.clone()) + .unwrap() + .display() + .to_string() + .replace("\\", "/"); res.push_str(&format!( "path: {:?}, range: {:?}\n", relative_path, loc.range @@ -152,8 +168,13 @@ mod tests { let mut res = String::new(); for loc in vec_location_link { let url = file_path_from_url(&loc.target_uri).unwrap(); - let got_path = Path::new(&url); - let relative_path = got_path.strip_prefix(root_path.clone()).unwrap(); + let got_path = Path::new(&url).canonicalize().unwrap(); + let relative_path = got_path + .strip_prefix(root_path.clone()) + .unwrap() + .display() + .to_string() + .replace("\\", "/"); res.push_str(&format!( "path: {:?}, range: {:?}\n", relative_path, loc.target_selection_range diff --git a/kclvm/tools/src/LSP/src/hover.rs b/kclvm/tools/src/LSP/src/hover.rs index b94cc7bb2..d0ab05ae5 100644 --- a/kclvm/tools/src/LSP/src/hover.rs +++ b/kclvm/tools/src/LSP/src/hover.rs @@ -17,6 +17,7 @@ enum MarkedStringType { /// Specifically, the doc for schema and schema attr(todo) pub fn hover(kcl_pos: &KCLPos, gs: &GlobalState) -> Option { let mut docs: Vec<(String, MarkedStringType)> = vec![]; + let def = find_def(kcl_pos, gs, true); match def { Some(def_ref) => match gs.get_symbols().get_symbol(def_ref) { diff --git a/kclvm/tools/src/LSP/src/quick_fix.rs b/kclvm/tools/src/LSP/src/quick_fix.rs index 161bd698f..80020012e 100644 --- a/kclvm/tools/src/LSP/src/quick_fix.rs +++ b/kclvm/tools/src/LSP/src/quick_fix.rs @@ -176,8 +176,8 @@ mod tests { #[bench_test] fn quick_fix_test() { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let mut test_file = path.clone(); - test_file.push("src/test_data/quick_fix.k"); + let test_file = path.clone(); + let test_file = test_file.join("src").join("test_data").join("quick_fix.k"); let file = test_file.to_str().unwrap(); let diags = compile_with_params(Params { diff --git a/kclvm/tools/src/LSP/src/rename.rs b/kclvm/tools/src/LSP/src/rename.rs index c0a7623b5..6a0c74fea 100644 --- a/kclvm/tools/src/LSP/src/rename.rs +++ b/kclvm/tools/src/LSP/src/rename.rs @@ -55,19 +55,18 @@ pub fn rename_symbol_on_code( ) -> Result> { // prepare a vfs from given file_paths let vfs = KCLVfs::default(); + let f = if source_codes.keys().all(|path| path.starts_with("/")) { + VfsPath::new_virtual_path + } else { + VfsPath::new_real_path + }; + for (filepath, code) in &source_codes { - vfs.write().set_file_contents( - VfsPath::new_virtual_path(filepath.clone()), - Some(code.as_bytes().to_vec()), - ); + vfs.write() + .set_file_contents(f(filepath.clone()), Some(code.as_bytes().to_vec())); } - let changes: HashMap> = rename_symbol( - pkg_root, - vfs, - symbol_path, - new_name, - VfsPath::new_virtual_path, - )?; + let changes: HashMap> = + rename_symbol(pkg_root, vfs, symbol_path, new_name, f)?; apply_rename_changes(&changes, source_codes) } @@ -655,13 +654,13 @@ e = a["abc"] #[test] fn test_rename() { - let mut root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - root.push("src/test_data/rename_test/"); + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let root = root.join("src").join("test_data").join("rename_test"); - let mut main_path = root.clone(); - let mut base_path = root.clone(); - base_path.push("base/person.k"); - main_path.push("config.k"); + let main_path = root.clone(); + let base_path = root.clone(); + let base_path = base_path.join("base").join("person.k"); + let main_path = main_path.join("config.k"); let base_path = base_path.to_str().unwrap(); let main_path = main_path.to_str().unwrap(); @@ -670,7 +669,7 @@ e = a["abc"] for path in [base_path, main_path] { let content = fs::read_to_string(path).unwrap(); vfs.write().set_file_contents( - VfsPath::new_virtual_path(path.to_string()), + VfsPath::new_real_path(path.to_string()), Some(content.into_bytes()), ); } @@ -680,7 +679,7 @@ e = a["abc"] vfs.clone(), "base:Person", "NewPerson".to_string(), - VfsPath::new_virtual_path, + VfsPath::new_real_path, ) { assert_eq!(changes.len(), 2); assert!(changes.contains_key(base_path)); @@ -699,7 +698,7 @@ e = a["abc"] vfs.clone(), "base:Person.name", "new_name".to_string(), - VfsPath::new_virtual_path, + VfsPath::new_real_path, ) { assert_eq!(changes.len(), 2); assert!(changes.contains_key(base_path)); @@ -763,13 +762,17 @@ Bob = vars.Person { #[test] fn test_rename_symbol_on_file() { - let mut root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - root.push("src/test_data/rename_test/rename_on_file"); - - let mut main_path = root.clone(); - let mut base_path = root.clone(); - base_path.push("base/person.k"); - main_path.push("config.k"); + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let root = root + .join("src") + .join("test_data") + .join("rename_test") + .join("rename_on_file"); + + let main_path = root.clone(); + let base_path = root.clone(); + let main_path = main_path.join("config.k"); + let base_path = base_path.join("base").join("person.k"); let base_path_string = base_path.to_str().unwrap().to_string(); let main_path_string = main_path.to_str().unwrap().to_string(); @@ -823,15 +826,15 @@ e = a["abc"]"# #[test] fn test_rename_symbol_on_code() { - let mut root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - root.push("src/test_data/rename_test/"); + let root = root.join("src").join("test_data").join("rename_test"); - let mut base_path = root.clone(); - let mut main_path = root.clone(); + let base_path = root.clone(); + let main_path = root.clone(); - base_path.push("base/person.k"); - main_path.push("config.k"); + let base_path = base_path.join("base").join("person.k"); + let main_path = main_path.join("config.k"); let base_path_string = base_path.to_str().unwrap().to_string(); let main_path_string = main_path.to_str().unwrap().to_string(); diff --git a/kclvm/tools/src/LSP/src/tests.rs b/kclvm/tools/src/LSP/src/tests.rs index 010783158..676b58df0 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -7,6 +7,7 @@ use kclvm_driver::toolchain; use kclvm_driver::toolchain::Metadata; use kclvm_driver::WorkSpaceKind; use kclvm_sema::core::global_state::GlobalState; +use kclvm_utils::path::PathPrefix; use kclvm_sema::resolver::scope::KCLScopeCache; use lsp_server::RequestId; @@ -101,7 +102,10 @@ pub(crate) fn compare_goto_res( match res.unwrap() { lsp_types::GotoDefinitionResponse::Scalar(loc) => { let got_path = file_path_from_url(&loc.uri).unwrap(); - assert_eq!(got_path, pos.0.to_string()); + assert_eq!( + got_path.adjust_canonicalization(), + pos.0.to_string().adjust_canonicalization() + ); let (got_start, got_end) = (loc.range.start, loc.range.end); @@ -127,10 +131,13 @@ pub(crate) fn compile_test_file( testfile: &str, ) -> (String, Program, IndexSet, GlobalState) { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let mut test_file = path; - test_file.push(testfile); - - let file = test_file.to_str().unwrap().to_string(); + let file = path + .join(testfile) + .canonicalize() + .unwrap() + .display() + .to_string() + .adjust_canonicalization(); let (diags, compile_res) = compile_with_params(Params { file: Some(file.clone()), @@ -153,10 +160,14 @@ pub(crate) fn compile_test_file_and_metadata( Option, ) { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let mut test_file = path; - test_file.push(testfile); - let file = test_file.to_str().unwrap().to_string(); + let file = path + .join(testfile) + .canonicalize() + .unwrap() + .display() + .to_string() + .adjust_canonicalization(); let metadata = lookup_compile_workspace(&toolchain::default(), &file, true).2; let (diags, compile_res) = compile_with_params(Params { @@ -430,7 +441,7 @@ fn file_path_from_url_test() { let url = Url::parse("file:///c%3A/Users/abc/Desktop/%E4%B8%AD%E6%96%87/ab%20c/abc.k").unwrap(); let path = file_path_from_url(&url).unwrap(); - assert_eq!(path, "c:\\Users\\abc\\Desktop\\中文\\ab c\\abc.k"); + assert_eq!(path, "C:\\Users\\abc\\Desktop\\中文\\ab c\\abc.k"); } else { let url = Url::parse("file:///Users/abc/Desktop/%E4%B8%AD%E6%96%87/ab%20c/abc.k").unwrap(); let path = file_path_from_url(&url).unwrap(); @@ -453,7 +464,7 @@ fn goto_import_pkg_with_line_test() { let (file, _program, _, gs) = compile_test_file("src/test_data/goto_def_with_line_test/main_pkg/main.k"); let pos = KCLPos { - filename: file, + filename: file.adjust_canonicalization(), line: 1, column: Some(27), }; @@ -468,7 +479,8 @@ fn goto_import_pkg_with_line_test() { .canonicalize() .unwrap() .display() - .to_string(); + .to_string() + .adjust_canonicalization(); assert_eq!(got_path, expected_path) } _ => { @@ -522,7 +534,7 @@ fn complete_import_external_file_test() { .unwrap(); let pos = KCLPos { - filename: path.to_string(), + filename: path.to_string().adjust_canonicalization(), line: 1, column: Some(11), }; @@ -584,7 +596,7 @@ fn goto_import_external_file_test() { // test goto import file: import .pkg.schema_def let pos = KCLPos { - filename: path.to_string(), + filename: path.to_string().adjust_canonicalization(), line: 1, column: Some(57), }; @@ -932,9 +944,12 @@ fn cancel_test() { #[test] fn goto_def_test() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let mut path = root.clone(); - - path.push("src/test_data/goto_def_test/goto_def.k"); + let path = root.clone(); + let path = path + .join("src") + .join("test_data") + .join("goto_def_test") + .join("goto_def.k"); let path = path.to_str().unwrap(); let src = std::fs::read_to_string(path).unwrap(); @@ -989,9 +1004,13 @@ fn goto_def_test() { #[test] fn complete_test() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let mut path = root.clone(); - - path.push("src/test_data/completion_test/dot/completion.k"); + let path = root.clone(); + let path = path + .join("src") + .join("test_data") + .join("completion_test") + .join("dot") + .join("completion.k"); let path = path.to_str().unwrap(); let src = std::fs::read_to_string(path).unwrap(); @@ -1057,10 +1076,14 @@ fn complete_test() { #[test] fn complete_with_version_test() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let mut path = root.clone(); - - path.push("src/test_data/completion_test/newline/newline_with_version/newline_with_version.k"); - + let path = root.clone(); + let path = path + .join("src") + .join("test_data") + .join("completion_test") + .join("newline") + .join("newline_with_version") + .join("newline_with_version.k"); let path = path.to_str().unwrap(); let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); @@ -1144,11 +1167,13 @@ fn complete_with_version_test() { #[test] fn hover_test() { let root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); - let mut path = root.clone(); - - path.push("src/test_data/hover_test/hover.k"); - + let path = root + .join("src") + .join("test_data") + .join("hover_test") + .join("hover.k"); let path = path.to_str().unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); @@ -1403,8 +1428,12 @@ fn konfig_path() -> PathBuf { #[test] fn konfig_goto_def_test_base() { let konfig_path = konfig_path(); - let mut base_path = konfig_path.clone(); - base_path.push("appops/nginx-example/base/base.k"); + let base_path = konfig_path + .clone() + .join("appops") + .join("nginx-example") + .join("base") + .join("base.k"); let base_path_str = base_path.to_str().unwrap().to_string(); let (_program, gs) = compile_with_params(Params { file: Some(base_path_str.clone()), @@ -1418,13 +1447,20 @@ fn konfig_goto_def_test_base() { // schema def let pos = KCLPos { - filename: base_path_str.clone(), + filename: base_path_str.clone().adjust_canonicalization(), line: 7, column: Some(30), }; let res = goto_def(&pos, &gs); - let mut expected_path = konfig_path.clone(); - expected_path.push("base/pkg/kusion_models/kube/frontend/server.k"); + let expected_path = konfig_path + .clone() + .join("base") + .join("pkg") + .join("kusion_models") + .join("kube") + .join("frontend") + .join("server.k"); + compare_goto_res( res, (&expected_path.to_str().unwrap().to_string(), 12, 7, 12, 13), @@ -1432,13 +1468,20 @@ fn konfig_goto_def_test_base() { // schema def let pos = KCLPos { - filename: base_path_str.clone(), + filename: base_path_str.clone().adjust_canonicalization(), line: 9, column: Some(32), }; let res = goto_def(&pos, &gs); - let mut expected_path = konfig_path.clone(); - expected_path.push("base/pkg/kusion_models/kube/frontend/container/container.k"); + let expected_path = konfig_path + .clone() + .join("base") + .join("pkg") + .join("kusion_models") + .join("kube") + .join("frontend") + .join("container") + .join("container.k"); compare_goto_res( res, (&expected_path.to_str().unwrap().to_string(), 5, 7, 5, 11), @@ -1446,13 +1489,19 @@ fn konfig_goto_def_test_base() { // schema attr let pos = KCLPos { - filename: base_path_str.clone(), + filename: base_path_str.clone().adjust_canonicalization(), line: 9, column: Some(9), }; let res = goto_def(&pos, &gs); - let mut expected_path = konfig_path.clone(); - expected_path.push("base/pkg/kusion_models/kube/frontend/server.k"); + let expected_path = konfig_path + .clone() + .join("base") + .join("pkg") + .join("kusion_models") + .join("kube") + .join("frontend") + .join("server.k"); compare_goto_res( res, ( @@ -1466,13 +1515,20 @@ fn konfig_goto_def_test_base() { // schema attr let pos = KCLPos { - filename: base_path_str.clone(), + filename: base_path_str.clone().adjust_canonicalization(), line: 10, column: Some(10), }; let res = goto_def(&pos, &gs); - let mut expected_path = konfig_path.clone(); - expected_path.push("base/pkg/kusion_models/kube/frontend/container/container.k"); + let expected_path = konfig_path + .clone() + .join("base") + .join("pkg") + .join("kusion_models") + .join("kube") + .join("frontend") + .join("container") + .join("container.k"); compare_goto_res( res, (&expected_path.to_str().unwrap().to_string(), 69, 4, 69, 9), @@ -1480,13 +1536,21 @@ fn konfig_goto_def_test_base() { // import pkg let pos = KCLPos { - filename: base_path_str.clone(), + filename: base_path_str.clone().adjust_canonicalization(), line: 2, column: Some(49), }; let res = goto_def(&pos, &gs); - let mut expected_path = konfig_path.clone(); - expected_path.push("base/pkg/kusion_models/kube/frontend/service/service.k"); + + let expected_path = konfig_path + .clone() + .join("base") + .join("pkg") + .join("kusion_models") + .join("kube") + .join("frontend") + .join("service") + .join("service.k"); compare_goto_res( res, (&expected_path.to_str().unwrap().to_string(), 0, 0, 0, 0), @@ -1496,8 +1560,12 @@ fn konfig_goto_def_test_base() { #[test] fn konfig_goto_def_test_main() { let konfig_path = konfig_path(); - let mut main_path = konfig_path.clone(); - main_path.push("appops/nginx-example/dev/main.k"); + let main_path = konfig_path + .clone() + .join("appops") + .join("nginx-example") + .join("dev") + .join("main.k"); let main_path_str = main_path.to_str().unwrap().to_string(); let (_program, gs) = compile_with_params(Params { file: Some(main_path_str.clone()), @@ -1511,13 +1579,19 @@ fn konfig_goto_def_test_main() { // schema def let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 6, column: Some(31), }; let res = goto_def(&pos, &gs); - let mut expected_path = konfig_path.clone(); - expected_path.push("base/pkg/kusion_models/kube/frontend/server.k"); + let expected_path = konfig_path + .clone() + .join("base") + .join("pkg") + .join("kusion_models") + .join("kube") + .join("frontend") + .join("server.k"); compare_goto_res( res, (&expected_path.to_str().unwrap().to_string(), 12, 7, 12, 13), @@ -1525,13 +1599,19 @@ fn konfig_goto_def_test_main() { // schema attr let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 7, column: Some(14), }; let res = goto_def(&pos, &gs); - let mut expected_path = konfig_path.clone(); - expected_path.push("base/pkg/kusion_models/kube/frontend/server.k"); + let expected_path = konfig_path + .clone() + .join("base") + .join("pkg") + .join("kusion_models") + .join("kube") + .join("frontend") + .join("server.k"); compare_goto_res( res, ( @@ -1545,13 +1625,19 @@ fn konfig_goto_def_test_main() { // import pkg let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 2, column: Some(61), }; let res = goto_def(&pos, &gs); - let mut expected_path = konfig_path.clone(); - expected_path.push("base/pkg/kusion_models/kube/templates/resource.k"); + let expected_path = konfig_path + .clone() + .join("base") + .join("pkg") + .join("kusion_models") + .join("kube") + .join("templates") + .join("resource.k"); compare_goto_res( res, (&expected_path.to_str().unwrap().to_string(), 0, 0, 0, 0), @@ -1561,8 +1647,12 @@ fn konfig_goto_def_test_main() { #[test] fn konfig_completion_test_main() { let konfig_path = konfig_path(); - let mut main_path = konfig_path.clone(); - main_path.push("appops/nginx-example/dev/main.k"); + let main_path = konfig_path + .clone() + .join("appops") + .join("nginx-example") + .join("dev") + .join("main.k"); let main_path_str = main_path.to_str().unwrap().to_string(); let (program, gs) = compile_with_params(Params { file: Some(main_path_str.clone()), @@ -1576,7 +1666,7 @@ fn konfig_completion_test_main() { // pkg's definition(schema) completion let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 6, column: Some(27), }; @@ -1595,7 +1685,7 @@ fn konfig_completion_test_main() { // schema attr completion let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 7, column: Some(4), }; @@ -1640,7 +1730,7 @@ fn konfig_completion_test_main() { // import path completion let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 1, column: Some(35), }; @@ -1675,8 +1765,13 @@ fn konfig_completion_test_main() { #[test] fn konfig_hover_test_main() { let konfig_path = konfig_path(); - let mut main_path = konfig_path.clone(); - main_path.push("appops/nginx-example/dev/main.k"); + let main_path = konfig_path + .clone() + .join("appops") + .join("nginx-example") + .join("dev") + .join("main.k"); + let main_path_str = main_path.to_str().unwrap().to_string(); let (_program, gs) = compile_with_params(Params { file: Some(main_path_str.clone()), @@ -1690,7 +1785,7 @@ fn konfig_hover_test_main() { // schema def hover let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 6, column: Some(32), }; @@ -1712,7 +1807,7 @@ fn konfig_hover_test_main() { // schema attr def hover let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 7, column: Some(15), }; @@ -1737,7 +1832,7 @@ fn konfig_hover_test_main() { // variable hover let pos = KCLPos { - filename: main_path_str.clone(), + filename: main_path_str.clone().adjust_canonicalization(), line: 6, column: Some(3), }; @@ -2010,10 +2105,10 @@ fn rename_test() { .join("src") .join("test_data") .join("rename_test"); - let mut path = root.clone(); - let mut main_path = root.clone(); - path.push("pkg/vars.k"); - main_path.push("main.k"); + let path = root.clone(); + let main_path = root.clone(); + let path = path.join("pkg").join("vars.k"); + let main_path = main_path.join("main.k"); let path = path.to_str().unwrap(); let src = std::fs::read_to_string(path).unwrap(); @@ -2111,7 +2206,8 @@ fn compile_unit_test() { let path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut test_file = path.clone(); test_file.push("src/test_data/compile_unit/b.k"); - let file = test_file.to_str().unwrap(); + let p = test_file.canonicalize().unwrap(); + let file = p.to_str().unwrap().adjust_canonicalization(); let prog = compile_with_params(Params { file: Some(file.to_string()), @@ -2401,5 +2497,8 @@ fn init_workspace_sema_token_test() { fn pkg_mod_test() { let (_file, _program, diags, _gs) = compile_test_file("src/test_data/workspace/pkg_mod_test/test/main.k"); + for diag in diags.iter().filter(|diag| diag.is_error()) { + println!("{:?}", diag); + } assert_eq!(diags.iter().filter(|diag| diag.is_error()).count(), 0); } diff --git a/kclvm/tools/src/LSP/src/to_lsp.rs b/kclvm/tools/src/LSP/src/to_lsp.rs index f33126dcd..b95615f77 100644 --- a/kclvm/tools/src/LSP/src/to_lsp.rs +++ b/kclvm/tools/src/LSP/src/to_lsp.rs @@ -4,6 +4,7 @@ use kclvm_error::DiagnosticId; use kclvm_error::Level; use kclvm_error::Message; use kclvm_error::Position as KCLPos; +use kclvm_utils::path::PathPrefix; use lsp_types::*; use serde_json::json; @@ -143,7 +144,7 @@ pub(crate) fn kcl_diag_to_lsp_diags_by_file( ) -> Vec { let mut diags = vec![]; for (idx, msg) in diag.messages.iter().enumerate() { - if msg.range.0.filename == file_name { + if msg.range.0.filename.adjust_canonicalization() == file_name.adjust_canonicalization() { let mut related_msg = diag.messages.clone(); related_msg.remove(idx); let code = if diag.code.is_some() {