Skip to content

Commit 60763ce

Browse files
authored
feat: parse file preserve symlink path (#2030)
Signed-off-by: Peefy <xpf6677@163.com>
1 parent 5f67490 commit 60763ce

File tree

4 files changed

+33
-8
lines changed

4 files changed

+33
-8
lines changed

crates/api/src/service/service_impl.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ impl KclServiceImpl {
180180
/// assert_eq!(result.deps.len(), 2);
181181
/// ```
182182
pub fn parse_file(&self, args: &ParseFileArgs) -> anyhow::Result<ParseFileResult> {
183-
let file = canonicalize_input_file(&args.path, "");
183+
let file = canonicalize_input_file(&args.path, "", false);
184184
let result = parse_single_file(&file, transform_str_para(&args.source))?;
185185
let ast_json = serde_json::to_string(&result.module)?;
186186

crates/parser/src/entry.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ pub fn get_compile_entries_from_paths(
302302
let mut k_code_queue = VecDeque::from(opts.k_code_list.clone());
303303
let file_paths = expand_input_files(file_paths);
304304
for file in &file_paths {
305-
let file = canonicalize_input_file(file, &opts.work_dir);
305+
let file = canonicalize_input_file(file, &opts.work_dir, opts.preserve_symlink_paths);
306306
let path = ModRelativePath::from(file.to_string());
307307

308308
// If the path is a [`ModRelativePath`] with prefix '${<package_name>:KCL_MOD}',
@@ -425,12 +425,17 @@ fn get_main_files_from_pkg_path(
425425
}
426426
}
427427

428-
match PathBuf::from(s.clone()).canonicalize() {
429-
Ok(path) => {
430-
path_list.push(path.to_str().unwrap().to_string());
428+
// When preserve_symlink_paths is true, don't canonicalize (resolves symlinks)
429+
if opts.preserve_symlink_paths {
430+
path_list.push(s);
431+
} else {
432+
match PathBuf::from(s.clone()).canonicalize() {
433+
Ok(path) => {
434+
path_list.push(path.to_str().unwrap().to_string());
435+
}
436+
// path from virtual file system
437+
Err(_) => path_list.push(s),
431438
}
432-
// path from virtual file system
433-
Err(_) => path_list.push(s),
434439
}
435440

436441
// get k files
@@ -525,7 +530,18 @@ fn is_ignored_file(filename: &str) -> bool {
525530
}
526531

527532
/// Normalize the input file with the working directory and replace ${KCL_MOD} with the module root path.
528-
pub fn canonicalize_input_file(file: &str, work_dir: &str) -> String {
533+
pub fn canonicalize_input_file(file: &str, work_dir: &str, preserve_symlink_paths: bool) -> String {
534+
// If preserve_symlink_paths is true, don't canonicalize (resolves symlinks)
535+
if preserve_symlink_paths {
536+
if !std::path::Path::new(file).is_absolute() {
537+
return std::path::Path::new(work_dir)
538+
.join(file)
539+
.to_string_lossy()
540+
.to_string();
541+
}
542+
return file.to_string();
543+
}
544+
529545
let path = std::path::Path::new(file);
530546
let is_absolute = path.is_absolute();
531547
// If the input file or path is a relative path and it is not a absolute path in the KCL module VFS,

crates/parser/src/lib.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,11 @@ pub struct LoadProgramOptions {
264264
pub load_packages: bool,
265265
/// Whether to load plugins
266266
pub load_plugins: bool,
267+
/// Whether to preserve symlink paths instead of resolving them.
268+
/// When true, file paths are used as-is without canonicalization.
269+
/// This is important for LSP and other tools that need to maintain
270+
/// the original file paths as provided by the user/editor.
271+
pub preserve_symlink_paths: bool,
267272
}
268273

269274
impl Default for LoadProgramOptions {
@@ -276,6 +281,7 @@ impl Default for LoadProgramOptions {
276281
mode: ParseMode::ParseComments,
277282
load_packages: true,
278283
load_plugins: false,
284+
preserve_symlink_paths: false,
279285
}
280286
}
281287
}

crates/tools/src/LSP/src/compile.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ pub fn compile(
4343
// Ignore the kcl plugin sematic check.
4444
let mut opts = opts.unwrap_or_default();
4545
opts.load_plugins = true;
46+
// Preserve symlink paths for LSP - don't resolve symlinks to maintain
47+
// the original file paths as provided by the editor
48+
opts.preserve_symlink_paths = true;
4649
// Get input files code from vfs
4750
let normalized_files = match get_normalized_k_files_from_paths(files, &opts) {
4851
Ok(file_list) => file_list,

0 commit comments

Comments
 (0)