Skip to content

Commit

Permalink
feat: add api list_variables to select variable (#1214)
Browse files Browse the repository at this point in the history
* feat: add api list_variables to select variable

Signed-off-by: zongz <[email protected]>

* fix: add test case with format expr

Signed-off-by: zongz <[email protected]>

---------

Signed-off-by: zongz <[email protected]>
  • Loading branch information
zong-zhe authored Apr 11, 2024
1 parent e3113fc commit 04c11a9
Show file tree
Hide file tree
Showing 16 changed files with 887 additions and 1 deletion.
2 changes: 2 additions & 0 deletions kclvm/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions kclvm/api/src/capi_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,15 @@ fn test_c_api_list_options() {
);
}

#[test]
fn test_c_api_list_variables() {
test_c_api_without_wrapper::<ListVariablesArgs, ListVariablesResult>(
"KclvmService.ListVariables",
"list-variables.json",
"list-variables.response.json",
);
}

#[test]
fn test_c_api_parse_file() {
test_c_api_without_wrapper::<ParseFileArgs, ParseFileResult>(
Expand Down
26 changes: 26 additions & 0 deletions kclvm/api/src/service/capi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ pub(crate) fn kclvm_get_service_fn_ptr_by_name(name: &str) -> u64 {
"KclvmService.ParseProgram" => parse_program as *const () as u64,
"KclvmService.LoadPackage" => load_package as *const () as u64,
"KclvmService.ListOptions" => list_options as *const () as u64,
"KclvmService.ListVariables" => list_variables as *const () as u64,
"KclvmService.ExecProgram" => exec_program as *const () as u64,
"KclvmService.BuildProgram" => build_program as *const () as u64,
"KclvmService.ExecArtifact" => exec_artifact as *const () as u64,
Expand Down Expand Up @@ -297,6 +298,31 @@ pub(crate) fn list_options(
call!(serv, args, result_len, ParseProgramArgs, list_options)
}

/// list_variables provides users with the ability to parse kcl program and get all variables
/// calling information.
///
/// # Parameters
///
/// `serv`: [*mut kclvm_service]
/// The pointer of &\[[KclvmServiceImpl]]
///
///
/// `args`: [*const c_char]
/// the items and compile parameters selected by the user in the KCL CLI
/// serialized as protobuf byte sequence
///
/// # Returns
///
/// result: [*const c_char]
/// Result of the call serialized as protobuf byte sequence
pub(crate) fn list_variables(
serv: *mut kclvm_service,
args: *const c_char,
result_len: *mut usize,
) -> *const c_char {
call!(serv, args, result_len, ListVariablesArgs, list_variables)
}

/// exec_program provides users with the ability to execute KCL code
///
/// # Parameters
Expand Down
8 changes: 8 additions & 0 deletions kclvm/api/src/service/jsonrpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ fn register_kclvm_service(io: &mut IoHandler) {
};
futures::future::ready(catch!(kclvm_service_impl, args, list_options))
});
io.add_method("KclvmService.ListVariables", |params: Params| {
let kclvm_service_impl = KclvmServiceImpl::default();
let args: ListVariablesArgs = match params.parse() {
Ok(val) => val,
Err(err) => return futures::future::ready(Err(err)),
};
futures::future::ready(catch!(kclvm_service_impl, args, list_variables))
});
io.add_method("KclvmService.ExecProgram", |params: Params| {
let kclvm_service_impl = KclvmServiceImpl::default();
let args: ExecProgramArgs = match params.parse() {
Expand Down
50 changes: 50 additions & 0 deletions kclvm/api/src/service/service_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use kclvm_query::get_schema_type;
use kclvm_query::override_file;
use kclvm_query::query::get_full_schema_type;
use kclvm_query::query::CompilationOptions;
use kclvm_query::selector::list_variables;
use kclvm_query::GetSchemaOption;
use kclvm_runner::{build_program, exec_artifact, exec_program};
use kclvm_sema::core::global_state::GlobalState;
Expand Down Expand Up @@ -321,6 +322,55 @@ impl KclvmServiceImpl {
})
}

/// list_variables provides users with the ability to parse kcl program and get all variables by specs.
///
/// # Examples
///
/// ```
/// use kclvm_api::service::service_impl::KclvmServiceImpl;
/// use kclvm_api::gpyrpc::*;
/// use std::path::Path;
///
/// let serv = KclvmServiceImpl::default();
/// let args = &ListVariablesArgs {
/// file: Path::new(".").join("src").join("testdata").join("variables").join("main.k").canonicalize().unwrap().display().to_string(),
/// specs: vec!["a".to_string()]
/// };
/// let result = serv.list_variables(args).unwrap();
/// assert_eq!(result.variables.len(), 1);
/// assert_eq!(result.variables.get("a").unwrap().value, "1");
/// ```
pub fn list_variables(&self, args: &ListVariablesArgs) -> anyhow::Result<ListVariablesResult> {
let k_file = args.file.to_string();
let specs = args.specs.clone();

let select_res = list_variables(k_file, specs)?;

let variables: HashMap<String, Variable> = select_res
.select_result
.iter()
.map(|(key, value)| {
(
key.clone(),
Variable {
value: value.to_string(),
},
)
})
.collect();

let unsupported_codes: Vec<String> = select_res
.unsupported
.iter()
.map(|code| code.code.to_string())
.collect();

return Ok(ListVariablesResult {
variables,
unsupported_codes,
});
}

/// Execute KCL file with args. **Note that it is not thread safe.**
///
/// # Examples
Expand Down
4 changes: 4 additions & 0 deletions kclvm/api/src/testdata/list-variables.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"file": "./src/testdata/variables/main.k",
"specs": ["a"]
}
1 change: 1 addition & 0 deletions kclvm/api/src/testdata/list-variables.response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"variables":{"a":{"value":"1"}},"unsupported_codes":[]}
1 change: 1 addition & 0 deletions kclvm/api/src/testdata/variables/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
a = 1
2 changes: 2 additions & 0 deletions kclvm/loader/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ kclvm-ast-pretty = { path = "../ast_pretty" }
kclvm-parser = {path = "../parser"}
kclvm-sema = {path = "../sema"}
kclvm-error = {path = "../error"}
kclvm-query = {path = "../query"}
maplit = "1.0.2"

[dev-dependencies]
insta = "1.8.0"
72 changes: 72 additions & 0 deletions kclvm/loader/src/test_data/test_list_variables/supported.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
a = 1
a1 = 2
a3 = 3m

b1 = True
b2 = False

s1 = "Hello"

array1 = [1, 2, 3]

dict1 = {"a": 1, "b": 2}
dict2 = {
"a": 1
"b": {
"c": 2
"d": 3
}
}

schema A:
name: str
ids: [int]
data?: {str: {str: {str: int}}}

sha = A {
name: "Hello"
ids: [1, 2, 3]
data: {
"a": {
"b": {
"c": 2
}
}
}
}

schema B:
a: A

shb = B {
a: {
name: "HelloB"
ids: [4, 5, 6]
data: {
"d": {
"e": {
"f": 3
}
}
}
}
}

schema UnificationConf:
name: str

uconfa = UnificationConf{
name = "a"
}

uconfa : UnificationConf {
name = "b"
}

schema C:
a: A

c = C {
a: {name: "Hello"}
a: {ids: [7, 8, 9]}
}
18 changes: 18 additions & 0 deletions kclvm/loader/src/test_data/test_list_variables/unsupported.k
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
list = [ _x for _x in range(20) if _x % 2 == 0]
list1 = [i if i > 2 else i + 1 for i in [1,2,3]]


dict = {str(i): 2 * i for i in range(3)}

func = lambda x: int, y: int -> int { x + y }

schema IfSchema:
trueValue?: int
falseValue?: int

if_schema = IfSchema {
if True :
trueValue: 1
else :
falseValue: 2
}
Loading

0 comments on commit 04c11a9

Please sign in to comment.