Skip to content

Commit

Permalink
feat: lsp completion for external pkg in kcl.mod (#1448)
Browse files Browse the repository at this point in the history
* feat: lsp completion for external pkg in kcl.mod

Signed-off-by: he1pa <18012015693@163.com>

* use entry cache metadata. update some ut snapshot fmt

Signed-off-by: he1pa <18012015693@163.com>

---------

Signed-off-by: he1pa <18012015693@163.com>
  • Loading branch information
He1pa committed Jun 27, 2024
1 parent a6f91c4 commit 39cdc71
Show file tree
Hide file tree
Showing 56 changed files with 352 additions and 258 deletions.
34 changes: 19 additions & 15 deletions kclvm/driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use std::{
io::{self, ErrorKind},
path::{Path, PathBuf},
};
use toolchain::{fill_pkg_maps_for_k_file, Toolchain};
use toolchain::{fill_pkg_maps_for_k_file, Metadata, Toolchain};
use walkdir::WalkDir;

/// Expand the single file pattern to a list of files.
Expand Down Expand Up @@ -162,25 +162,28 @@ pub fn lookup_compile_unit(tool: &dyn Toolchain, file: &str, load_pkg: bool) ->
match canonicalize_input_files(&files, work_dir, true) {
Ok(kcl_paths) => {
// 1. find the kcl.mod path
let _ = fill_pkg_maps_for_k_file(tool, file.into(), &mut load_opt);
(kcl_paths, Some(load_opt))
let metadata =
fill_pkg_maps_for_k_file(tool, file.into(), &mut load_opt)
.unwrap_or(None);
(kcl_paths, Some(load_opt), metadata)
}
Err(_) => (vec![file.to_string()], None),
Err(_) => (vec![file.to_string()], None, None),
}
}
Err(_) => (vec![file.to_string()], None),
Err(_) => (vec![file.to_string()], None, None),
}
}
Ok(CompileUnitPath::ModFile(dir)) => match load_mod_file(&dir) {
Ok(mod_file) => {
let mut load_opt = kclvm_parser::LoadProgramOptions::default();
let _ = fill_pkg_maps_for_k_file(tool, file.into(), &mut load_opt);
let metadata =
fill_pkg_maps_for_k_file(tool, file.into(), &mut load_opt).unwrap_or(None);
if let Some(files) = mod_file.get_entries() {
let work_dir = dir.to_string_lossy().to_string();
load_opt.work_dir = work_dir.clone();
match canonicalize_input_files(&files, work_dir, true) {
Ok(kcl_paths) => (kcl_paths, Some(load_opt)),
Err(_) => (vec![file.to_string()], None),
Ok(kcl_paths) => (kcl_paths, Some(load_opt), metadata),
Err(_) => (vec![file.to_string()], None, None),
}
} else {
if load_pkg {
Expand All @@ -189,34 +192,35 @@ pub fn lookup_compile_unit(tool: &dyn Toolchain, file: &str, load_pkg: bool) ->
if ext == KCL_FILE_EXTENSION && path.is_file() {
if let Some(parent) = path.parent() {
if let Ok(files) = get_kcl_files(parent, false) {
return (files, Some(load_opt));
return (files, Some(load_opt), metadata);
}
}
}
}
}
(vec![file.to_string()], Some(load_opt))
(vec![file.to_string()], Some(load_opt), metadata)
}
}
Err(_) => (vec![file.to_string()], None),
Err(_) => (vec![file.to_string()], None, None),
},
Ok(CompileUnitPath::NotFound) | Err(_) => {
let mut load_opt = kclvm_parser::LoadProgramOptions::default();
let _ = fill_pkg_maps_for_k_file(tool, file.into(), &mut load_opt);
let metadata =
fill_pkg_maps_for_k_file(tool, file.into(), &mut load_opt).unwrap_or(None);

if load_pkg {
let path = Path::new(file);
if let Some(ext) = path.extension() {
if ext == KCL_FILE_EXTENSION && path.is_file() {
if let Some(parent) = path.parent() {
if let Ok(files) = get_kcl_files(parent, false) {
return (files, Some(load_opt));
return (files, Some(load_opt), metadata);
}
}
}
}
}
(vec![file.to_string()], Some(load_opt))
(vec![file.to_string()], Some(load_opt), metadata)
}
}
}
Expand All @@ -243,7 +247,7 @@ fn lookup_kcl_yaml(dir: &Path) -> io::Result<PathBuf> {
}
}

pub type CompileUnitOptions = (Vec<String>, Option<LoadProgramOptions>);
pub type CompileUnitOptions = (Vec<String>, Option<LoadProgramOptions>, Option<Metadata>);

/// CompileUnitPath is the kcl program default entries that are defined
/// in the config files.
Expand Down
13 changes: 6 additions & 7 deletions kclvm/driver/src/toolchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,21 +176,20 @@ pub(crate) fn fill_pkg_maps_for_k_file(
tool: &dyn Toolchain,
k_file_path: PathBuf,
opts: &mut LoadProgramOptions,
) -> Result<()> {
) -> Result<Option<Metadata>> {
match lookup_the_nearest_file_dir(k_file_path, KCL_MOD_FILE) {
Some(mod_dir) => {
let metadata = tool.fetch_metadata(mod_dir.canonicalize()?)?;
let maps: HashMap<String, String> = metadata
.packages
.into_iter()
.map(|(name, pkg)| (name, pkg.manifest_path.display().to_string()))
.iter()
.map(|(name, pkg)| (name.clone(), pkg.manifest_path.display().to_string()))
.collect();
opts.package_maps.extend(maps);
Ok(Some(metadata))
}
None => return Ok(()),
};

Ok(())
None => Ok(None),
}
}

/// [`get_real_path_from_external`] will ask for the local path for [`pkg_name`] with subdir [`pkgpath`].
Expand Down
Loading

0 comments on commit 39cdc71

Please sign in to comment.