From 94c0e83e4d9587583f79c077e79377e9e4899829 Mon Sep 17 00:00:00 2001 From: peefy Date: Fri, 17 Nov 2023 14:45:28 +0800 Subject: [PATCH] feat: add kcl mod metadata fetch for the driver crate. Signed-off-by: peefy --- .gitignore | 2 +- kclvm/driver/src/lib.rs | 4 +- .../src/{kpm_metadata.rs => mod_metadata.rs} | 44 +++++++++++++++++-- .../src/test_data/kpm_metadata/kcl.mod.lock | 7 --- .../{kpm_metadata => mod_metadata}/kcl.mod | 0 .../subdir/main.k | 0 kclvm/driver/src/tests.rs | 12 ++--- kclvm/tools/src/LSP/src/completion.rs | 7 ++- kclvm/tools/src/LSP/src/request.rs | 11 ++--- kclvm/tools/src/LSP/src/state.rs | 2 +- kclvm/tools/src/LSP/src/tests.rs | 22 +++++----- kclvm/tools/src/LSP/src/util.rs | 24 +--------- 12 files changed, 73 insertions(+), 62 deletions(-) rename kclvm/driver/src/{kpm_metadata.rs => mod_metadata.rs} (77%) delete mode 100644 kclvm/driver/src/test_data/kpm_metadata/kcl.mod.lock rename kclvm/driver/src/test_data/{kpm_metadata => mod_metadata}/kcl.mod (100%) rename kclvm/driver/src/test_data/{kpm_metadata => mod_metadata}/subdir/main.k (100%) diff --git a/.gitignore b/.gitignore index 9595591e4..0d57d4d98 100644 --- a/.gitignore +++ b/.gitignore @@ -94,5 +94,5 @@ _a.out_*.* llvm* llvm-* -# kpm +# KCL mod lock file !.mod.lock diff --git a/kclvm/driver/src/lib.rs b/kclvm/driver/src/lib.rs index d9595b6ae..13aa9d9f2 100644 --- a/kclvm/driver/src/lib.rs +++ b/kclvm/driver/src/lib.rs @@ -1,6 +1,6 @@ use anyhow::Result; pub mod arguments; -pub mod kpm_metadata; +pub mod mod_metadata; pub const DEFAULT_PROJECT_FILE: &str = "project.yaml"; #[cfg(test)] @@ -15,7 +15,7 @@ use kclvm_config::{ }; use kclvm_parser::LoadProgramOptions; use kclvm_utils::path::PathPrefix; -use kpm_metadata::fill_pkg_maps_for_k_file; +use mod_metadata::fill_pkg_maps_for_k_file; use std::{ fs::read_dir, io::{self, ErrorKind}, diff --git a/kclvm/driver/src/kpm_metadata.rs b/kclvm/driver/src/mod_metadata.rs similarity index 77% rename from kclvm/driver/src/kpm_metadata.rs rename to kclvm/driver/src/mod_metadata.rs index a8d615fa2..e90002896 100644 --- a/kclvm/driver/src/kpm_metadata.rs +++ b/kclvm/driver/src/mod_metadata.rs @@ -15,7 +15,7 @@ pub(crate) fn fill_pkg_maps_for_k_file( // 1. find the kcl.mod dir for the kcl package contains 'k_file_path'. match lookup_the_nearest_file_dir(k_file_path, MANIFEST_FILE) { Some(mod_dir) => { - // 2. call `kpm metadata`. + // 2. get the module metadata. let metadata = fetch_metadata(mod_dir.canonicalize()?)?; // 3. fill the external packages local paths into compilation option [`LoadProgramOptions`]. let maps: HashMap = metadata @@ -32,7 +32,7 @@ pub(crate) fn fill_pkg_maps_for_k_file( } #[derive(Deserialize, Serialize, Default, Debug, Clone)] -/// [`Metadata`] is the metadata of the current KCL package, +/// [`Metadata`] is the metadata of the current KCL module, /// currently only the mapping between the name and path of the external dependent package is included. pub struct Metadata { pub packages: HashMap, @@ -55,8 +55,17 @@ impl Metadata { } } -/// [`fetch_metadata`] will call `kpm metadata` to obtain the metadata. +/// [`fetch_metadata`] returns the KCL module metadata. +#[inline] pub fn fetch_metadata(manifest_path: PathBuf) -> Result { + fetch_mod_metadata(manifest_path.clone()).or(fetch_kpm_metadata(manifest_path)) +} + +/// [`fetch_kpm_metadata`] will call `kpm metadata` to obtain the metadata. +/// +/// TODO: this function will be removed at kcl v0.8.0 for the command migration +/// `kpm -> kcl mod`. +pub(crate) fn fetch_kpm_metadata(manifest_path: PathBuf) -> Result { use std::result::Result::Ok; match Command::new(kpm()) .arg("metadata") @@ -78,6 +87,30 @@ pub fn fetch_metadata(manifest_path: PathBuf) -> Result { } } +/// [`fetch_mod_metadata`] will call `kcl mod metadata` to obtain the metadata. +pub(crate) fn fetch_mod_metadata(manifest_path: PathBuf) -> Result { + use std::result::Result::Ok; + match Command::new(kcl()) + .arg("mod") + .arg("metadata") + .current_dir(manifest_path) + .output() + { + Ok(output) => { + if !output.status.success() { + bail!( + "fetch metadata failed with error: {}", + String::from_utf8_lossy(&output.stderr) + ); + } + Ok(Metadata::parse( + String::from_utf8_lossy(&output.stdout).to_string(), + )?) + } + Err(err) => bail!("fetch metadata failed with error: {}", err), + } +} + /// [`lookup_the_nearest_file_dir`] will start from [`from`] and search for file [`the_nearest_file`] in the parent directories. /// If found, it will return the [`Some`] of [`the_nearest_file`] file path. If not found, it will return [`None`] pub(crate) fn lookup_the_nearest_file_dir( @@ -99,6 +132,11 @@ pub(crate) fn lookup_the_nearest_file_dir( } } +/// [`kcl`] will return the path for executable kcl binary. +pub fn kcl() -> PathBuf { + get_path_for_executable("kcl") +} + /// [`kpm`] will return the path for executable kpm binary. pub fn kpm() -> PathBuf { get_path_for_executable("kpm") diff --git a/kclvm/driver/src/test_data/kpm_metadata/kcl.mod.lock b/kclvm/driver/src/test_data/kpm_metadata/kcl.mod.lock deleted file mode 100644 index 64e81ba70..000000000 --- a/kclvm/driver/src/test_data/kpm_metadata/kcl.mod.lock +++ /dev/null @@ -1,7 +0,0 @@ -[dependencies] - [dependencies.kcl4] - name = "kcl4" - full_name = "kcl4_v0.0.1" - version = "v0.0.1" - sum = "cpyqJwwjqCvast6QNAiYuevgAIEH1p72OqctwGHU79Q=" - url = "test_url" diff --git a/kclvm/driver/src/test_data/kpm_metadata/kcl.mod b/kclvm/driver/src/test_data/mod_metadata/kcl.mod similarity index 100% rename from kclvm/driver/src/test_data/kpm_metadata/kcl.mod rename to kclvm/driver/src/test_data/mod_metadata/kcl.mod diff --git a/kclvm/driver/src/test_data/kpm_metadata/subdir/main.k b/kclvm/driver/src/test_data/mod_metadata/subdir/main.k similarity index 100% rename from kclvm/driver/src/test_data/kpm_metadata/subdir/main.k rename to kclvm/driver/src/test_data/mod_metadata/subdir/main.k diff --git a/kclvm/driver/src/tests.rs b/kclvm/driver/src/tests.rs index 3849582ae..5f1c8b92b 100644 --- a/kclvm/driver/src/tests.rs +++ b/kclvm/driver/src/tests.rs @@ -7,7 +7,7 @@ use kclvm_parser::LoadProgramOptions; use walkdir::WalkDir; use crate::arguments::parse_key_value_pair; -use crate::kpm_metadata::{fetch_metadata, fill_pkg_maps_for_k_file, lookup_the_nearest_file_dir}; +use crate::mod_metadata::{fetch_metadata, fill_pkg_maps_for_k_file, lookup_the_nearest_file_dir}; use crate::{canonicalize_input_files, expand_input_files}; #[test] @@ -202,7 +202,7 @@ fn test_fill_pkg_maps_for_k_file() { let path = PathBuf::from(".") .join("src") .join("test_data") - .join("kpm_metadata") + .join("mod_metadata") .join("subdir") .join("main.k"); @@ -220,7 +220,7 @@ fn test_fill_pkg_maps_for_k_file() { assert_eq!(format!("{:?}", opts.package_maps), "{}"); let res = fill_pkg_maps_for_k_file(path.clone(), &mut opts); - assert!(res.is_ok()); + assert!(res.is_ok(), "{}", res.err().unwrap()); let vendor_home = get_vendor_home(); let pkg_maps = opts.package_maps.clone(); @@ -248,7 +248,7 @@ fn test_lookup_the_nearest_file_dir() { let path = PathBuf::from(".") .join("src") .join("test_data") - .join("kpm_metadata"); + .join("mod_metadata"); let result = lookup_the_nearest_file_dir(path.clone(), "kcl.mod"); assert_eq!(result.is_some(), true); assert_eq!( @@ -270,7 +270,7 @@ fn test_fetch_metadata() { let path = PathBuf::from(".") .join("src") .join("test_data") - .join("kpm_metadata"); + .join("mod_metadata"); let vendor_path = PathBuf::from(".") .join("src") @@ -284,7 +284,7 @@ fn test_fetch_metadata() { let vendor_home = get_vendor_home(); let metadata = fetch_metadata(path.clone()); - assert_eq!(metadata.is_err(), false); + assert_eq!(metadata.is_err(), false, "{}", metadata.err().unwrap()); let pkgs = metadata.unwrap().packages.clone(); assert_eq!(pkgs.len(), 1); assert!(pkgs.get("kcl4").is_some()); diff --git a/kclvm/tools/src/LSP/src/completion.rs b/kclvm/tools/src/LSP/src/completion.rs index 07eb148f4..1a23a622e 100644 --- a/kclvm/tools/src/LSP/src/completion.rs +++ b/kclvm/tools/src/LSP/src/completion.rs @@ -21,7 +21,7 @@ use std::{fs, path::Path}; use crate::goto_def::find_def_with_gs; use indexmap::IndexSet; use kclvm_ast::ast::{Expr, ImportStmt, Program, Stmt}; -use kclvm_ast::pos::GetPos; + use kclvm_ast::MAIN_PKG; use kclvm_config::modfile::KCL_FILE_EXTENSION; use kclvm_sema::core::global_state::GlobalState; @@ -33,9 +33,8 @@ use kclvm_sema::resolver::scope::ProgramScope; use kclvm_sema::ty::{FunctionType, SchemaType, Type}; use lsp_types::{CompletionItem, CompletionItemKind}; -use crate::goto_def::{find_def, Definition}; use crate::util::get_real_path_from_external; -use crate::util::{inner_most_expr_in_stmt, is_in_docstring, is_in_schema_expr}; +use crate::util::{inner_most_expr_in_stmt, is_in_docstring}; #[derive(Debug, Clone, PartialEq, Hash, Eq)] pub enum KCLCompletionItemKind { @@ -890,7 +889,7 @@ mod tests { }; let got = completion(None, &program, &pos, &prog_scope, &gs).unwrap(); - let got_labels: Vec = match &got { + let _got_labels: Vec = match &got { CompletionResponse::Array(arr) => arr.iter().map(|item| item.label.clone()).collect(), CompletionResponse::List(_) => panic!("test failed"), }; diff --git a/kclvm/tools/src/LSP/src/request.rs b/kclvm/tools/src/LSP/src/request.rs index f019fd608..cde19cbf0 100644 --- a/kclvm/tools/src/LSP/src/request.rs +++ b/kclvm/tools/src/LSP/src/request.rs @@ -1,6 +1,6 @@ use anyhow::{anyhow, Ok}; use crossbeam_channel::Sender; -use kclvm_ast::pos::GetPos; + use kclvm_sema::info::is_valid_kcl_name; use lsp_types::{Location, TextEdit}; use ra_ap_vfs::VfsPath; @@ -291,9 +291,9 @@ pub(crate) fn handle_rename( // 3. return the workspaceEdit to rename all the references with the new name let mut workspace_edit = lsp_types::WorkspaceEdit::default(); - let changes = locations - .into_iter() - .fold(HashMap::new(), |mut map, location| { + let changes = locations.into_iter().fold( + HashMap::new(), + |mut map: HashMap>, location| { let uri = location.uri; map.entry(uri.clone()) .or_insert_with(Vec::new) @@ -302,7 +302,8 @@ pub(crate) fn handle_rename( new_text: new_name.clone(), }); map - }); + }, + ); workspace_edit.changes = Some(changes); anyhow::Ok(Some(workspace_edit)) } diff --git a/kclvm/tools/src/LSP/src/state.rs b/kclvm/tools/src/LSP/src/state.rs index f9fd26f97..80e07f2fe 100644 --- a/kclvm/tools/src/LSP/src/state.rs +++ b/kclvm/tools/src/LSP/src/state.rs @@ -4,7 +4,7 @@ use crate::db::AnalysisDatabase; 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 crossbeam_channel::{select, unbounded, Receiver, Sender}; -use indexmap::{IndexMap, IndexSet}; +use indexmap::IndexSet; use lsp_server::{ReqQueue, Response}; use lsp_types::Url; use lsp_types::{ diff --git a/kclvm/tools/src/LSP/src/tests.rs b/kclvm/tools/src/LSP/src/tests.rs index f1a3e527a..dbb7824d1 100644 --- a/kclvm/tools/src/LSP/src/tests.rs +++ b/kclvm/tools/src/LSP/src/tests.rs @@ -642,7 +642,7 @@ fn notification_test() { path.push("src/test_data/diagnostics.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); // Mock open file @@ -691,7 +691,7 @@ fn close_file_test() { path.push("src/test_data/diagnostics.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); // Mock open file @@ -776,7 +776,7 @@ fn cancel_test() { path.push("src/test_data/goto_def_test/goto_def.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); // Mock open file @@ -822,7 +822,7 @@ fn goto_def_test() { path.push("src/test_data/goto_def_test/goto_def.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); // Mock open file @@ -879,7 +879,7 @@ fn complete_test() { path.push("src/test_data/completion_test/dot/completion.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); // Mock open file @@ -947,7 +947,7 @@ fn hover_test() { path.push("src/test_data/hover_test/hover.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); // Mock open file @@ -1004,7 +1004,7 @@ fn hover_assign_in_lambda_test() { path.push("src/test_data/hover_test/assign_in_lambda.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); // Mock open file @@ -1057,7 +1057,7 @@ fn formatting_test() { path.push("src/test_data/format/format_range.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let server = Project {}.server(InitializeParams::default()); // Mock open file @@ -1546,7 +1546,7 @@ fn find_refs_test() { path.push("src/test_data/find_refs_test/main.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let mut initialize_params = InitializeParams::default(); initialize_params.workspace_folders = Some(vec![WorkspaceFolder { uri: Url::from_file_path(root.clone()).unwrap(), @@ -1636,7 +1636,7 @@ fn find_refs_with_file_change_test() { path.push("src/test_data/find_refs_test/main.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let mut initialize_params = InitializeParams::default(); initialize_params.workspace_folders = Some(vec![WorkspaceFolder { uri: Url::from_file_path(root.clone()).unwrap(), @@ -1739,7 +1739,7 @@ fn rename_test() { main_path.push("src/test_data/rename_test/main.k"); let path = path.to_str().unwrap(); - let src = std::fs::read_to_string(path.clone()).unwrap(); + let src = std::fs::read_to_string(path).unwrap(); let mut initialize_params = InitializeParams::default(); initialize_params.workspace_folders = Some(vec![WorkspaceFolder { uri: Url::from_file_path(root.clone()).unwrap(), diff --git a/kclvm/tools/src/LSP/src/util.rs b/kclvm/tools/src/LSP/src/util.rs index 3fab6c3cb..73896013b 100644 --- a/kclvm/tools/src/LSP/src/util.rs +++ b/kclvm/tools/src/LSP/src/util.rs @@ -1,12 +1,11 @@ use indexmap::{IndexMap, IndexSet}; use kclvm_ast::ast::{ - ConfigEntry, Expr, Identifier, Node, NodeRef, PosTuple, Program, SchemaExpr, SchemaStmt, Stmt, - Type, + ConfigEntry, Expr, Identifier, Node, NodeRef, PosTuple, Program, SchemaStmt, Stmt, Type, }; use kclvm_ast::pos::ContainsPos; use kclvm_ast::MAIN_PKG; use kclvm_config::modfile::KCL_FILE_EXTENSION; -use kclvm_driver::kpm_metadata::fetch_metadata; +use kclvm_driver::mod_metadata::fetch_metadata; use kclvm_driver::{get_kcl_files, lookup_compile_unit}; use kclvm_error::Diagnostic; use kclvm_error::Position as KCLPos; @@ -595,25 +594,6 @@ fn inner_most_expr_in_config_entry( } } -pub(crate) fn is_in_schema_expr( - program: &Program, - pos: &KCLPos, -) -> Option<(Node, SchemaExpr)> { - match program.pos_to_stmt(pos) { - Some(node) => { - let parent_expr = inner_most_expr_in_stmt(&node.node, pos, None).1; - match parent_expr { - Some(expr) => match expr.node { - Expr::Schema(schema) => Some((node, schema)), - _ => None, - }, - None => None, - } - } - None => None, - } -} - pub(crate) fn is_in_docstring( program: &Program, pos: &KCLPos,