diff --git a/src/wasm-lib/kcl/src/executor.rs b/src/wasm-lib/kcl/src/executor.rs index 744e9dc22..81df6b349 100644 --- a/src/wasm-lib/kcl/src/executor.rs +++ b/src/wasm-lib/kcl/src/executor.rs @@ -16,7 +16,7 @@ use crate::{ errors::{KclError, KclErrorDetails}, fs::FileManager, settings::types::UnitLength, - std::{FnAsArg, FunctionKind, StdLib}, + std::{FnAsArg, StdLib}, }; #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)] @@ -1638,38 +1638,7 @@ impl ExecutorContext { if let Value::PipeExpression(pipe_expr) = &expression_statement.expression { pipe_expr.get_result(memory, &pipe_info, self).await?; } else if let Value::CallExpression(call_expr) = &expression_statement.expression { - let fn_name = call_expr.callee.name.to_string(); - let mut args: Vec = Vec::new(); - for arg in &call_expr.arguments { - let metadata = Metadata { - source_range: SourceRange([arg.start(), arg.end()]), - }; - let mem_item = self - .arg_into_mem_item(arg, memory, &pipe_info, &metadata, StatementKind::Expression) - .await?; - args.push(mem_item); - } - match self.stdlib.get_either(&call_expr.callee.name) { - FunctionKind::Core(func) => { - let args = crate::std::Args::new(args, call_expr.into(), self.clone(), memory.clone()); - let result = func.std_lib_fn()(args).await?; - memory.return_ = Some(ProgramReturn::Value(result)); - } - FunctionKind::Std(func) => { - let mut newmem = memory.clone(); - let result = self.inner_execute(func.program(), &mut newmem, BodyType::Block).await?; - memory.return_ = result.return_; - } - FunctionKind::UserDefined => { - // TODO: Why do we change the source range to - // the call expression instead of keeping the - // range of the callee? - let func = memory.get(&fn_name, call_expr.into())?; - let result = func.call_fn(args.clone(), self.clone()).await?; - - memory.return_ = result; - } - } + call_expr.execute(memory, &pipe_info, self).await?; } } BodyItem::VariableDeclaration(variable_declaration) => { diff --git a/src/wasm-lib/tests/executor/main.rs b/src/wasm-lib/tests/executor/main.rs index b187ee3ab..452e544a8 100644 --- a/src/wasm-lib/tests/executor/main.rs +++ b/src/wasm-lib/tests/executor/main.rs @@ -2813,3 +2813,41 @@ const example = extrude(10, exampleSketch) r#"type: KclErrorDetails { source_ranges: [SourceRange([100, 151])], message: "Cannot have a y constrained angle of 180 degrees" }"# ); } + +#[tokio::test(flavor = "multi_thread")] +async fn serial_test_error_inside_fn_also_has_source_range_of_call_site() { + let code = r#"fn someFunction = (something) => { + startSketchOn(something) +} + +someFunction('INVALID') +"#; + + let result = execute_and_snapshot(code, UnitLength::Mm).await; + assert!(result.is_err()); + assert_eq!( + result.err().unwrap().to_string(), + r#"semantic: KclErrorDetails { source_ranges: [SourceRange([37, 61]), SourceRange([65, 88])], message: "Argument at index 0 was supposed to be type kcl_lib::std::sketch::SketchData but wasn't" }"# + ); +} + +#[tokio::test(flavor = "multi_thread")] +async fn serial_test_error_inside_fn_also_has_source_range_of_call_site_recursive() { + let code = r#"fn someFunction = (something) => { + fn someNestedFunction = (something2) => { + startSketchOn(something2) + } + + someNestedFunction(something) +} + +someFunction('INVALID') +"#; + + let result = execute_and_snapshot(code, UnitLength::Mm).await; + assert!(result.is_err()); + assert_eq!( + result.err().unwrap().to_string(), + r#"semantic: KclErrorDetails { source_ranges: [SourceRange([89, 114]), SourceRange([126, 155]), SourceRange([159, 182])], message: "Argument at index 0 was supposed to be type kcl_lib::std::sketch::SketchData but wasn't" }"# + ); +}