Skip to content

Commit

Permalink
feat: add mod metadata fetch
Browse files Browse the repository at this point in the history
Signed-off-by: peefy <[email protected]>
  • Loading branch information
Peefy committed Nov 17, 2023
1 parent 68b1f8b commit b1050e8
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,5 @@ _a.out_*.*
llvm*
llvm-*

# kpm
# KCL mod lock file
!.mod.lock
46 changes: 42 additions & 4 deletions kclvm/driver/src/kpm_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, String> = metadata
Expand All @@ -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<String, Package>,
Expand All @@ -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<Metadata> {
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<Metadata> {
use std::result::Result::Ok;
match Command::new(kpm())
.arg("metadata")
Expand All @@ -78,6 +87,30 @@ pub fn fetch_metadata(manifest_path: PathBuf) -> Result<Metadata> {
}
}

/// [`fetch_mod_metadata`] will call `kcl mod metadata` to obtain the metadata.
pub(crate) fn fetch_mod_metadata(manifest_path: PathBuf) -> Result<Metadata> {
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(
Expand All @@ -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")
Expand All @@ -108,7 +146,7 @@ pub fn kpm() -> PathBuf {
pub fn get_path_for_executable(executable_name: &'static str) -> PathBuf {
// The current implementation checks $PATH for an executable to use:
// `<executable_name>`
// example: for kpm, this tries just `kpm`, which will succeed if `kpm` is on the $PATH
// example: for <executable_name>, this tries just <executable_name>, which will succeed if <executable_name> is on the $PATH

if lookup_in_path(executable_name) {
return executable_name.into();
Expand Down
7 changes: 3 additions & 4 deletions kclvm/tools/src/LSP/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -890,7 +889,7 @@ mod tests {
};

let got = completion(None, &program, &pos, &prog_scope, &gs).unwrap();
let got_labels: Vec<String> = match &got {
let _got_labels: Vec<String> = match &got {
CompletionResponse::Array(arr) => arr.iter().map(|item| item.label.clone()).collect(),
CompletionResponse::List(_) => panic!("test failed"),
};
Expand Down
11 changes: 6 additions & 5 deletions kclvm/tools/src/LSP/src/request.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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<lsp_types::Url, Vec<TextEdit>>, location| {
let uri = location.uri;
map.entry(uri.clone())
.or_insert_with(Vec::new)
Expand All @@ -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))
}
Expand Down
2 changes: 1 addition & 1 deletion kclvm/tools/src/LSP/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down
22 changes: 11 additions & 11 deletions kclvm/tools/src/LSP/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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(),
Expand Down
22 changes: 1 addition & 21 deletions kclvm/tools/src/LSP/src/util.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
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;
Expand Down Expand Up @@ -595,25 +594,6 @@ fn inner_most_expr_in_config_entry(
}
}

pub(crate) fn is_in_schema_expr(
program: &Program,
pos: &KCLPos,
) -> Option<(Node<Stmt>, 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,
Expand Down

0 comments on commit b1050e8

Please sign in to comment.