fix source code ranges for function calls (#3163)
This commit is contained in:
@ -16,7 +16,7 @@ use crate::{
|
|||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
fs::FileManager,
|
fs::FileManager,
|
||||||
settings::types::UnitLength,
|
settings::types::UnitLength,
|
||||||
std::{FnAsArg, FunctionKind, StdLib},
|
std::{FnAsArg, StdLib},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema)]
|
#[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 {
|
if let Value::PipeExpression(pipe_expr) = &expression_statement.expression {
|
||||||
pipe_expr.get_result(memory, &pipe_info, self).await?;
|
pipe_expr.get_result(memory, &pipe_info, self).await?;
|
||||||
} else if let Value::CallExpression(call_expr) = &expression_statement.expression {
|
} else if let Value::CallExpression(call_expr) = &expression_statement.expression {
|
||||||
let fn_name = call_expr.callee.name.to_string();
|
call_expr.execute(memory, &pipe_info, self).await?;
|
||||||
let mut args: Vec<MemoryItem> = 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BodyItem::VariableDeclaration(variable_declaration) => {
|
BodyItem::VariableDeclaration(variable_declaration) => {
|
||||||
|
@ -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" }"#
|
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" }"#
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user