Add KCL importing relative to where you're importing from (#7125)

* add test

Signed-off-by: Jess Frazelle <github@jessfraz.com>

* Add importing relative to where you're importing from

* Update output

* Remove runtime panics

* Change to debug_assert

---------

Signed-off-by: Jess Frazelle <github@jessfraz.com>
Co-authored-by: Jess Frazelle <github@jessfraz.com>
This commit is contained in:
Jonathan Tran
2025-05-20 20:47:32 -04:00
committed by GitHub
parent 38a73a603b
commit 4212b95232
19 changed files with 459 additions and 58 deletions

View File

@ -86,7 +86,7 @@ impl ExecutorContext {
) -> Result<(Option<KclValue>, EnvironmentRef, Vec<String>), KclError> {
crate::log::log(format!("enter module {path} {}", exec_state.stack()));
let mut local_state = ModuleState::new(path.std_path(), exec_state.stack().memory.clone(), Some(module_id));
let mut local_state = ModuleState::new(path.clone(), exec_state.stack().memory.clone(), Some(module_id));
if !preserve_mem {
std::mem::swap(&mut exec_state.mod_local, &mut local_state);
}
@ -139,8 +139,13 @@ impl ExecutorContext {
let source_range = SourceRange::from(import_stmt);
let attrs = &import_stmt.outer_attrs;
let module_path = ModulePath::from_import_path(
&import_stmt.path,
&self.settings.project_directory,
&exec_state.mod_local.path,
)?;
let module_id = self
.open_module(&import_stmt.path, attrs, exec_state, source_range)
.open_module(&import_stmt.path, attrs, &module_path, exec_state, source_range)
.await?;
match &import_stmt.selector {
@ -298,9 +303,9 @@ impl ExecutorContext {
let impl_kind = annotations::get_impl(&ty.outer_attrs, metadata.source_range)?.unwrap_or_default();
match impl_kind {
annotations::Impl::Rust => {
let std_path = match &exec_state.mod_local.std_path {
Some(p) => p,
None => {
let std_path = match &exec_state.mod_local.path {
ModulePath::Std { value } => value,
ModulePath::Local { .. } | ModulePath::Main => {
return Err(KclError::Semantic(KclErrorDetails::new(
"User-defined types are not yet supported.".to_owned(),
vec![metadata.source_range],
@ -420,16 +425,15 @@ impl ExecutorContext {
&self,
path: &ImportPath,
attrs: &[Node<Annotation>],
resolved_path: &ModulePath,
exec_state: &mut ExecState,
source_range: SourceRange,
) -> Result<ModuleId, KclError> {
let resolved_path = ModulePath::from_import_path(path, &self.settings.project_directory);
match path {
ImportPath::Kcl { .. } => {
exec_state.global.mod_loader.cycle_check(&resolved_path, source_range)?;
exec_state.global.mod_loader.cycle_check(resolved_path, source_range)?;
if let Some(id) = exec_state.id_for_module(&resolved_path) {
if let Some(id) = exec_state.id_for_module(resolved_path) {
return Ok(id);
}
@ -440,12 +444,12 @@ impl ExecutorContext {
exec_state.add_id_to_source(id, source.clone());
// TODO handle parsing errors properly
let parsed = crate::parsing::parse_str(&source.source, id).parse_errs_as_err()?;
exec_state.add_module(id, resolved_path, ModuleRepr::Kcl(parsed, None));
exec_state.add_module(id, resolved_path.clone(), ModuleRepr::Kcl(parsed, None));
Ok(id)
}
ImportPath::Foreign { .. } => {
if let Some(id) = exec_state.id_for_module(&resolved_path) {
if let Some(id) = exec_state.id_for_module(resolved_path) {
return Ok(id);
}
@ -455,11 +459,11 @@ impl ExecutorContext {
exec_state.add_path_to_source_id(resolved_path.clone(), id);
let format = super::import::format_from_annotations(attrs, path, source_range)?;
let geom = super::import::import_foreign(path, format, exec_state, self, source_range).await?;
exec_state.add_module(id, resolved_path, ModuleRepr::Foreign(geom, None));
exec_state.add_module(id, resolved_path.clone(), ModuleRepr::Foreign(geom, None));
Ok(id)
}
ImportPath::Std { .. } => {
if let Some(id) = exec_state.id_for_module(&resolved_path) {
if let Some(id) = exec_state.id_for_module(resolved_path) {
return Ok(id);
}
@ -471,7 +475,7 @@ impl ExecutorContext {
let parsed = crate::parsing::parse_str(&source.source, id)
.parse_errs_as_err()
.unwrap();
exec_state.add_module(id, resolved_path, ModuleRepr::Kcl(parsed, None));
exec_state.add_module(id, resolved_path.clone(), ModuleRepr::Kcl(parsed, None));
Ok(id)
}
}
@ -632,7 +636,7 @@ impl ExecutorContext {
.unwrap_or(false);
if rust_impl {
if let Some(std_path) = &exec_state.mod_local.std_path {
if let ModulePath::Std { value: std_path } = &exec_state.mod_local.path {
let (func, props) = crate::std::std_fn(std_path, statement_kind.expect_name());
KclValue::Function {
value: FunctionSource::Std {