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:
@ -34,9 +34,9 @@ pub(crate) type Universe = HashMap<String, DependencyInfo>;
|
||||
pub fn import_graph(progs: &Universe, ctx: &ExecutorContext) -> Result<Vec<Vec<String>>, KclError> {
|
||||
let mut graph = Graph::new();
|
||||
|
||||
for (name, (_, _, _, repr)) in progs.iter() {
|
||||
for (name, (_, _, path, repr)) in progs.iter() {
|
||||
graph.extend(
|
||||
import_dependencies(repr, ctx)?
|
||||
import_dependencies(path, repr, ctx)?
|
||||
.into_iter()
|
||||
.map(|(dependency, _, _)| (name.clone(), dependency))
|
||||
.collect::<Vec<_>>(),
|
||||
@ -120,17 +120,26 @@ fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>, KclEr
|
||||
|
||||
type ImportDependencies = Vec<(String, AstNode<ImportStatement>, ModulePath)>;
|
||||
|
||||
pub(crate) fn import_dependencies(repr: &ModuleRepr, ctx: &ExecutorContext) -> Result<ImportDependencies, KclError> {
|
||||
pub(crate) fn import_dependencies(
|
||||
path: &ModulePath,
|
||||
repr: &ModuleRepr,
|
||||
ctx: &ExecutorContext,
|
||||
) -> Result<ImportDependencies, KclError> {
|
||||
let ModuleRepr::Kcl(prog, _) = repr else {
|
||||
// It has no dependencies, so return an empty list.
|
||||
return Ok(vec![]);
|
||||
};
|
||||
|
||||
let ret = Arc::new(Mutex::new(vec![]));
|
||||
fn walk(ret: Arc<Mutex<ImportDependencies>>, node: Node<'_>, ctx: &ExecutorContext) -> Result<(), KclError> {
|
||||
fn walk(
|
||||
ret: Arc<Mutex<ImportDependencies>>,
|
||||
node: Node<'_>,
|
||||
import_from: &ModulePath,
|
||||
ctx: &ExecutorContext,
|
||||
) -> Result<(), KclError> {
|
||||
if let Node::ImportStatement(is) = node {
|
||||
// We only care about Kcl and Foreign imports for now.
|
||||
let resolved_path = ModulePath::from_import_path(&is.path, &ctx.settings.project_directory);
|
||||
let resolved_path = ModulePath::from_import_path(&is.path, &ctx.settings.project_directory, import_from)?;
|
||||
match &is.path {
|
||||
ImportPath::Kcl { filename } => {
|
||||
// We need to lock the mutex to push the dependency.
|
||||
@ -160,13 +169,13 @@ pub(crate) fn import_dependencies(repr: &ModuleRepr, ctx: &ExecutorContext) -> R
|
||||
}
|
||||
|
||||
for child in node.children().iter() {
|
||||
walk(ret.clone(), *child, ctx)?;
|
||||
walk(ret.clone(), *child, import_from, ctx)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
walk(ret.clone(), prog.into(), ctx)?;
|
||||
walk(ret.clone(), prog.into(), path, ctx)?;
|
||||
|
||||
let ret = ret.lock().map_err(|err| {
|
||||
KclError::Internal(KclErrorDetails::new(
|
||||
@ -182,11 +191,12 @@ pub(crate) fn import_dependencies(repr: &ModuleRepr, ctx: &ExecutorContext) -> R
|
||||
/// only `repr`'s non-transitive imports.
|
||||
pub(crate) async fn import_universe(
|
||||
ctx: &ExecutorContext,
|
||||
path: &ModulePath,
|
||||
repr: &ModuleRepr,
|
||||
out: &mut Universe,
|
||||
exec_state: &mut ExecState,
|
||||
) -> Result<UniverseMap, KclError> {
|
||||
let modules = import_dependencies(repr, ctx)?;
|
||||
let modules = import_dependencies(path, repr, ctx)?;
|
||||
let mut module_imports = HashMap::new();
|
||||
for (filename, import_stmt, module_path) in modules {
|
||||
match &module_path {
|
||||
@ -208,7 +218,7 @@ pub(crate) async fn import_universe(
|
||||
let source_range = SourceRange::from(&import_stmt);
|
||||
let attrs = &import_stmt.outer_attrs;
|
||||
let module_id = ctx
|
||||
.open_module(&import_stmt.path, attrs, exec_state, source_range)
|
||||
.open_module(&import_stmt.path, attrs, &module_path, exec_state, source_range)
|
||||
.await?;
|
||||
|
||||
let repr = {
|
||||
@ -221,8 +231,8 @@ pub(crate) async fn import_universe(
|
||||
module_info.repr.clone()
|
||||
};
|
||||
|
||||
out.insert(filename, (import_stmt, module_id, module_path, repr.clone()));
|
||||
Box::pin(import_universe(ctx, &repr, out, exec_state)).await?;
|
||||
out.insert(filename, (import_stmt, module_id, module_path.clone(), repr.clone()));
|
||||
Box::pin(import_universe(ctx, &module_path, &repr, out, exec_state)).await?;
|
||||
}
|
||||
|
||||
Ok(module_imports)
|
||||
|
Reference in New Issue
Block a user