Unify execution state into a single struct (#3877)
* Add ExecState that combines ProgramMemory and DynamicState * Remove unneeded clones * Add exec_state parameter to all KCL stdlib functions * Move pipe value into ExecState * Add test for pipe substitution not leaking into function calls * KCL: Better message on assertEqual function Also add a new no-visual test for performance testing. * Fix new array module to use ExecState --------- Co-authored-by: Adam Chalmers <adam.chalmers@zoo.dev>
This commit is contained in:
@ -269,7 +269,7 @@ fn do_stdlib_inner(
|
||||
let ty_string = rust_type_to_openapi_type(&ty_string);
|
||||
let required = !ty_ident.to_string().starts_with("Option <");
|
||||
|
||||
if ty_string != "Args" {
|
||||
if ty_string != "ExecState" && ty_string != "Args" {
|
||||
let schema = if ty_ident.to_string().starts_with("Vec < ")
|
||||
|| ty_ident.to_string().starts_with("Option <")
|
||||
|| ty_ident.to_string().starts_with('[')
|
||||
@ -387,11 +387,12 @@ fn do_stdlib_inner(
|
||||
#const_struct
|
||||
|
||||
fn #boxed_fn_name_ident(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<dyn std::future::Future<Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>> + Send>,
|
||||
Box<dyn std::future::Future<Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>> + Send + '_>,
|
||||
> {
|
||||
Box::pin(#fn_name_ident(args))
|
||||
Box::pin(#fn_name_ident(exec_state, args))
|
||||
}
|
||||
|
||||
impl #docs_crate::StdLibFn for #name_ident
|
||||
@ -662,6 +663,9 @@ fn clean_ty_string(t: &str) -> (String, proc_macro2::TokenStream) {
|
||||
.replace("mut", "")
|
||||
.replace("< 'a >", "")
|
||||
.replace(' ', "");
|
||||
if ty_string.starts_with("ExecState") {
|
||||
ty_string = "ExecState".to_string();
|
||||
}
|
||||
if ty_string.starts_with("Args") {
|
||||
ty_string = "Args".to_string();
|
||||
}
|
||||
|
@ -85,6 +85,32 @@ fn test_args_with_lifetime() {
|
||||
expectorate::assert_contents("tests/args_with_lifetime.gen", &get_text_fmt(&item).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_args_with_exec_state() {
|
||||
let (item, mut errors) = do_stdlib(
|
||||
quote! {
|
||||
name = "someFunction",
|
||||
},
|
||||
quote! {
|
||||
/// Docs
|
||||
/// ```
|
||||
/// someFunction()
|
||||
/// ```
|
||||
fn inner_some_function<'a>(
|
||||
exec_state: &mut ExecState,
|
||||
args: &Args,
|
||||
) -> i32 {
|
||||
3
|
||||
}
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
if let Some(e) = errors.pop() {
|
||||
panic!("{e}");
|
||||
}
|
||||
expectorate::assert_contents("tests/test_args_with_exec_state.gen", &get_text_fmt(&item).unwrap());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stdlib_line_to() {
|
||||
let (item, errors) = do_stdlib(
|
||||
|
@ -44,15 +44,17 @@ pub(crate) struct SomeFn {}
|
||||
#[doc = "Std lib function: someFn\nDocs"]
|
||||
pub(crate) const SomeFn: SomeFn = SomeFn {};
|
||||
fn boxed_someFn(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(someFn(args))
|
||||
Box::pin(someFn(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for SomeFn {
|
||||
|
@ -44,15 +44,17 @@ pub(crate) struct SomeFn {}
|
||||
#[doc = "Std lib function: someFn\nDocs"]
|
||||
pub(crate) const SomeFn: SomeFn = SomeFn {};
|
||||
fn boxed_someFn(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(someFn(args))
|
||||
Box::pin(someFn(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for SomeFn {
|
||||
|
@ -77,15 +77,17 @@ pub(crate) struct Show {}
|
||||
#[doc = "Std lib function: show\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Show: Show = Show {};
|
||||
fn boxed_show(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(show(args))
|
||||
Box::pin(show(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Show {
|
||||
|
@ -44,15 +44,17 @@ pub(crate) struct Show {}
|
||||
#[doc = "Std lib function: show\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Show: Show = Show {};
|
||||
fn boxed_show(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(show(args))
|
||||
Box::pin(show(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Show {
|
||||
|
@ -78,15 +78,17 @@ pub(crate) struct MyFunc {}
|
||||
#[doc = "Std lib function: myFunc\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const MyFunc: MyFunc = MyFunc {};
|
||||
fn boxed_my_func(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(my_func(args))
|
||||
Box::pin(my_func(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for MyFunc {
|
||||
|
@ -78,15 +78,17 @@ pub(crate) struct LineTo {}
|
||||
#[doc = "Std lib function: lineTo\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const LineTo: LineTo = LineTo {};
|
||||
fn boxed_line_to(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(line_to(args))
|
||||
Box::pin(line_to(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for LineTo {
|
||||
|
@ -77,15 +77,17 @@ pub(crate) struct Min {}
|
||||
#[doc = "Std lib function: min\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Min: Min = Min {};
|
||||
fn boxed_min(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(min(args))
|
||||
Box::pin(min(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Min {
|
||||
|
@ -44,15 +44,17 @@ pub(crate) struct Show {}
|
||||
#[doc = "Std lib function: show\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Show: Show = Show {};
|
||||
fn boxed_show(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(show(args))
|
||||
Box::pin(show(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Show {
|
||||
|
@ -44,15 +44,17 @@ pub(crate) struct Import {}
|
||||
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Import: Import = Import {};
|
||||
fn boxed_import(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(import(args))
|
||||
Box::pin(import(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Import {
|
||||
|
@ -44,15 +44,17 @@ pub(crate) struct Import {}
|
||||
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Import: Import = Import {};
|
||||
fn boxed_import(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(import(args))
|
||||
Box::pin(import(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Import {
|
||||
|
@ -44,15 +44,17 @@ pub(crate) struct Import {}
|
||||
#[doc = "Std lib function: import\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Import: Import = Import {};
|
||||
fn boxed_import(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(import(args))
|
||||
Box::pin(import(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Import {
|
||||
|
@ -44,15 +44,17 @@ pub(crate) struct Show {}
|
||||
#[doc = "Std lib function: show\nThis is some function.\nIt does shit."]
|
||||
pub(crate) const Show: Show = Show {};
|
||||
fn boxed_show(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(show(args))
|
||||
Box::pin(show(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for Show {
|
||||
|
134
src/wasm-lib/derive-docs/tests/test_args_with_exec_state.gen
Normal file
134
src/wasm-lib/derive-docs/tests/test_args_with_exec_state.gen
Normal file
@ -0,0 +1,134 @@
|
||||
#[cfg(test)]
|
||||
mod test_examples_some_function {
|
||||
#[tokio::test(flavor = "multi_thread")]
|
||||
async fn test_mock_example_some_function0() {
|
||||
let tokens = crate::token::lexer("someFunction()").unwrap();
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let ctx = crate::executor::ExecutorContext {
|
||||
engine: std::sync::Arc::new(Box::new(
|
||||
crate::engine::conn_mock::EngineConnection::new()
|
||||
.await
|
||||
.unwrap(),
|
||||
)),
|
||||
fs: std::sync::Arc::new(crate::fs::FileManager::new()),
|
||||
stdlib: std::sync::Arc::new(crate::std::StdLib::new()),
|
||||
settings: Default::default(),
|
||||
is_mock: true,
|
||||
};
|
||||
ctx.run(&program, None).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
|
||||
async fn kcl_test_example_some_function0() {
|
||||
let code = "someFunction()";
|
||||
let result =
|
||||
crate::test_server::execute_and_snapshot(code, crate::settings::types::UnitLength::Mm)
|
||||
.await
|
||||
.unwrap();
|
||||
twenty_twenty::assert_image(
|
||||
&format!("tests/outputs/{}.png", "serial_test_example_some_function0"),
|
||||
&result,
|
||||
0.99,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types, missing_docs)]
|
||||
#[doc = "Std lib function: someFunction\nDocs"]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, schemars :: JsonSchema, ts_rs :: TS)]
|
||||
#[ts(export)]
|
||||
pub(crate) struct SomeFunction {}
|
||||
|
||||
#[allow(non_upper_case_globals, missing_docs)]
|
||||
#[doc = "Std lib function: someFunction\nDocs"]
|
||||
pub(crate) const SomeFunction: SomeFunction = SomeFunction {};
|
||||
fn boxed_some_function(
|
||||
exec_state: &mut crate::executor::ExecState,
|
||||
args: crate::std::Args,
|
||||
) -> std::pin::Pin<
|
||||
Box<
|
||||
dyn std::future::Future<
|
||||
Output = anyhow::Result<crate::executor::KclValue, crate::errors::KclError>,
|
||||
> + Send
|
||||
+ '_,
|
||||
>,
|
||||
> {
|
||||
Box::pin(some_function(exec_state, args))
|
||||
}
|
||||
|
||||
impl crate::docs::StdLibFn for SomeFunction {
|
||||
fn name(&self) -> String {
|
||||
"someFunction".to_string()
|
||||
}
|
||||
|
||||
fn summary(&self) -> String {
|
||||
"Docs".to_string()
|
||||
}
|
||||
|
||||
fn description(&self) -> String {
|
||||
"".to_string()
|
||||
}
|
||||
|
||||
fn tags(&self) -> Vec<String> {
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn args(&self) -> Vec<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
||||
vec![]
|
||||
}
|
||||
|
||||
fn return_value(&self) -> Option<crate::docs::StdLibFnArg> {
|
||||
let mut settings = schemars::gen::SchemaSettings::openapi3();
|
||||
settings.inline_subschemas = true;
|
||||
let mut generator = schemars::gen::SchemaGenerator::new(settings);
|
||||
Some(crate::docs::StdLibFnArg {
|
||||
name: "".to_string(),
|
||||
type_: "i32".to_string(),
|
||||
schema: <i32>::json_schema(&mut generator),
|
||||
required: true,
|
||||
})
|
||||
}
|
||||
|
||||
fn unpublished(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn deprecated(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<String> {
|
||||
let code_blocks = vec!["someFunction()"];
|
||||
code_blocks
|
||||
.iter()
|
||||
.map(|cb| {
|
||||
let tokens = crate::token::lexer(cb).unwrap();
|
||||
let parser = crate::parser::Parser::new(tokens);
|
||||
let program = parser.ast().unwrap();
|
||||
let mut options: crate::ast::types::FormatOptions = Default::default();
|
||||
options.insert_final_newline = false;
|
||||
program.recast(&options, 0)
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
}
|
||||
|
||||
fn std_lib_fn(&self) -> crate::std::StdFn {
|
||||
boxed_some_function
|
||||
}
|
||||
|
||||
fn clone_box(&self) -> Box<dyn crate::docs::StdLibFn> {
|
||||
Box::new(self.clone())
|
||||
}
|
||||
}
|
||||
|
||||
#[doc = r" Docs"]
|
||||
#[doc = r" ```"]
|
||||
#[doc = r" someFunction()"]
|
||||
#[doc = r" ```"]
|
||||
fn inner_some_function<'a>(exec_state: &mut ExecState, args: &Args) -> i32 {
|
||||
3
|
||||
}
|
Reference in New Issue
Block a user