@ -748,7 +748,7 @@ impl ExecutorContext {
|
||||
) = tokio::sync::mpsc::channel(1);
|
||||
|
||||
for module in modules {
|
||||
let Some((module_id, module_path, program)) = universe.get(&module) else {
|
||||
let Some((import_stmt, module_id, module_path, program)) = universe.get(&module) else {
|
||||
return Err(KclErrorWithOutputs::no_outputs(KclError::Internal(KclErrorDetails {
|
||||
message: format!("Module {module} not found in universe"),
|
||||
source_ranges: Default::default(),
|
||||
@ -760,6 +760,7 @@ impl ExecutorContext {
|
||||
let exec_state = exec_state.clone();
|
||||
let exec_ctxt = self.clone();
|
||||
let results_tx = results_tx.clone();
|
||||
let source_range = SourceRange::from(import_stmt);
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
{
|
||||
@ -769,13 +770,7 @@ impl ExecutorContext {
|
||||
let exec_ctxt = exec_ctxt;
|
||||
|
||||
let result = exec_ctxt
|
||||
.exec_module_from_ast(
|
||||
&program,
|
||||
module_id,
|
||||
&module_path,
|
||||
&mut exec_state,
|
||||
Default::default(),
|
||||
)
|
||||
.exec_module_from_ast(&program, module_id, &module_path, &mut exec_state, source_range)
|
||||
.await;
|
||||
|
||||
results_tx
|
||||
@ -791,13 +786,7 @@ impl ExecutorContext {
|
||||
let exec_ctxt = exec_ctxt;
|
||||
|
||||
let result = exec_ctxt
|
||||
.exec_module_from_ast(
|
||||
&program,
|
||||
module_id,
|
||||
&module_path,
|
||||
&mut exec_state,
|
||||
Default::default(),
|
||||
)
|
||||
.exec_module_from_ast(&program, module_id, &module_path, &mut exec_state, source_range)
|
||||
.await;
|
||||
|
||||
results_tx
|
||||
|
@ -8,19 +8,20 @@ use anyhow::Result;
|
||||
use crate::{
|
||||
errors::KclErrorDetails,
|
||||
modules::{ModulePath, ModuleRepr},
|
||||
parsing::ast::types::{ImportPath, Node as AstNode, NodeRef, Program},
|
||||
parsing::ast::types::{ImportPath, ImportStatement, Node as AstNode, NodeRef, Program},
|
||||
walk::{Node, Visitable},
|
||||
ExecState, ExecutorContext, KclError, ModuleId,
|
||||
};
|
||||
|
||||
/// Specific dependency between two modules. The 0th element of this tuple
|
||||
/// Specific dependency between two modules. The 0th element of this info
|
||||
/// is the "importing" module, the 1st is the "imported" module. The 0th
|
||||
/// module *depends on* the 1st module.
|
||||
type Dependency = (String, String);
|
||||
|
||||
type Graph = Vec<Dependency>;
|
||||
|
||||
type Universe = HashMap<String, (ModuleId, ModulePath, AstNode<Program>)>;
|
||||
type DependencyInfo = (AstNode<ImportStatement>, ModuleId, ModulePath, AstNode<Program>);
|
||||
type Universe = HashMap<String, DependencyInfo>;
|
||||
|
||||
/// Process a number of programs, returning the graph of dependencies.
|
||||
///
|
||||
@ -31,7 +32,7 @@ type Universe = HashMap<String, (ModuleId, ModulePath, AstNode<Program>)>;
|
||||
pub fn import_graph(progs: &Universe, ctx: &ExecutorContext) -> Result<Vec<Vec<String>>, KclError> {
|
||||
let mut graph = Graph::new();
|
||||
|
||||
for (name, (_, _, program)) in progs.iter() {
|
||||
for (name, (_, _, _, program)) in progs.iter() {
|
||||
graph.extend(
|
||||
import_dependencies(program, ctx)?
|
||||
.into_iter()
|
||||
@ -112,17 +113,15 @@ fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>, KclEr
|
||||
Ok(order)
|
||||
}
|
||||
|
||||
type ImportDependencies = Vec<(String, AstNode<ImportStatement>, ModulePath)>;
|
||||
|
||||
pub(crate) fn import_dependencies(
|
||||
prog: NodeRef<Program>,
|
||||
ctx: &ExecutorContext,
|
||||
) -> Result<Vec<(String, ImportPath, ModulePath)>, KclError> {
|
||||
) -> Result<ImportDependencies, KclError> {
|
||||
let ret = Arc::new(Mutex::new(vec![]));
|
||||
|
||||
fn walk(
|
||||
ret: Arc<Mutex<Vec<(String, ImportPath, ModulePath)>>>,
|
||||
node: Node<'_>,
|
||||
ctx: &ExecutorContext,
|
||||
) -> Result<(), KclError> {
|
||||
fn walk(ret: Arc<Mutex<ImportDependencies>>, node: Node<'_>, ctx: &ExecutorContext) -> Result<(), KclError> {
|
||||
if let Node::ImportStatement(is) = node {
|
||||
// We only care about Kcl imports for now.
|
||||
if let ImportPath::Kcl { filename } = &is.path {
|
||||
@ -137,7 +136,7 @@ pub(crate) fn import_dependencies(
|
||||
source_ranges: Default::default(),
|
||||
})
|
||||
})?
|
||||
.push((filename.to_string(), is.path.clone(), resolved_path));
|
||||
.push((filename.to_string(), is.clone(), resolved_path));
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,13 +166,13 @@ pub(crate) async fn import_universe(
|
||||
exec_state: &mut ExecState,
|
||||
) -> Result<(), KclError> {
|
||||
let modules = import_dependencies(prog, ctx)?;
|
||||
for (filename, import_path, module_path) in modules {
|
||||
for (filename, import_stmt, module_path) in modules {
|
||||
if out.contains_key(&filename) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let module_id = ctx
|
||||
.open_module(&import_path, &[], exec_state, Default::default())
|
||||
.open_module(&import_stmt.path, &[], exec_state, Default::default())
|
||||
.await?;
|
||||
|
||||
let program = {
|
||||
@ -192,7 +191,10 @@ pub(crate) async fn import_universe(
|
||||
program.clone()
|
||||
};
|
||||
|
||||
out.insert(filename.clone(), (module_id, module_path.clone(), program.clone()));
|
||||
out.insert(
|
||||
filename.clone(),
|
||||
(import_stmt.clone(), module_id, module_path.clone(), program.clone()),
|
||||
);
|
||||
Box::pin(import_universe(ctx, &program, out, exec_state)).await?;
|
||||
}
|
||||
|
||||
@ -202,6 +204,7 @@ pub(crate) async fn import_universe(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::parsing::ast::types::ImportSelector;
|
||||
|
||||
macro_rules! kcl {
|
||||
( $kcl:expr ) => {{
|
||||
@ -209,8 +212,18 @@ mod tests {
|
||||
}};
|
||||
}
|
||||
|
||||
fn into_module_tuple(program: AstNode<Program>) -> (ModuleId, ModulePath, AstNode<Program>) {
|
||||
(ModuleId::default(), ModulePath::Local { value: "".into() }, program)
|
||||
fn into_module_info(program: AstNode<Program>) -> DependencyInfo {
|
||||
(
|
||||
AstNode::no_src(ImportStatement {
|
||||
selector: ImportSelector::None { alias: None },
|
||||
path: ImportPath::Kcl { filename: "".into() },
|
||||
visibility: Default::default(),
|
||||
digest: None,
|
||||
}),
|
||||
ModuleId::default(),
|
||||
ModulePath::Local { value: "".into() },
|
||||
program,
|
||||
)
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -218,14 +231,14 @@ mod tests {
|
||||
let mut modules = HashMap::new();
|
||||
|
||||
let a = kcl!("");
|
||||
modules.insert("a.kcl".to_owned(), into_module_tuple(a));
|
||||
modules.insert("a.kcl".to_owned(), into_module_info(a));
|
||||
|
||||
let b = kcl!(
|
||||
"
|
||||
import \"a.kcl\"
|
||||
"
|
||||
);
|
||||
modules.insert("b.kcl".to_owned(), into_module_tuple(b));
|
||||
modules.insert("b.kcl".to_owned(), into_module_info(b));
|
||||
|
||||
let ctx = ExecutorContext::new_mock().await;
|
||||
let order = import_graph(&modules, &ctx).unwrap();
|
||||
@ -241,14 +254,14 @@ import \"a.kcl\"
|
||||
y = 2
|
||||
"
|
||||
);
|
||||
modules.insert("a.kcl".to_owned(), into_module_tuple(a));
|
||||
modules.insert("a.kcl".to_owned(), into_module_info(a));
|
||||
|
||||
let b = kcl!(
|
||||
"
|
||||
x = 1
|
||||
"
|
||||
);
|
||||
modules.insert("b.kcl".to_owned(), into_module_tuple(b));
|
||||
modules.insert("b.kcl".to_owned(), into_module_info(b));
|
||||
|
||||
let ctx = ExecutorContext::new_mock().await;
|
||||
let order = import_graph(&modules, &ctx).unwrap();
|
||||
@ -260,21 +273,21 @@ x = 1
|
||||
let mut modules = HashMap::new();
|
||||
|
||||
let a = kcl!("");
|
||||
modules.insert("a.kcl".to_owned(), into_module_tuple(a));
|
||||
modules.insert("a.kcl".to_owned(), into_module_info(a));
|
||||
|
||||
let b = kcl!(
|
||||
"
|
||||
import \"a.kcl\"
|
||||
"
|
||||
);
|
||||
modules.insert("b.kcl".to_owned(), into_module_tuple(b));
|
||||
modules.insert("b.kcl".to_owned(), into_module_info(b));
|
||||
|
||||
let c = kcl!(
|
||||
"
|
||||
import \"a.kcl\"
|
||||
"
|
||||
);
|
||||
modules.insert("c.kcl".to_owned(), into_module_tuple(c));
|
||||
modules.insert("c.kcl".to_owned(), into_module_info(c));
|
||||
|
||||
let ctx = ExecutorContext::new_mock().await;
|
||||
let order = import_graph(&modules, &ctx).unwrap();
|
||||
@ -293,14 +306,14 @@ import \"a.kcl\"
|
||||
import \"b.kcl\"
|
||||
"
|
||||
);
|
||||
modules.insert("a.kcl".to_owned(), into_module_tuple(a));
|
||||
modules.insert("a.kcl".to_owned(), into_module_info(a));
|
||||
|
||||
let b = kcl!(
|
||||
"
|
||||
import \"a.kcl\"
|
||||
"
|
||||
);
|
||||
modules.insert("b.kcl".to_owned(), into_module_tuple(b));
|
||||
modules.insert("b.kcl".to_owned(), into_module_info(b));
|
||||
|
||||
let ctx = ExecutorContext::new_mock().await;
|
||||
import_graph(&modules, &ctx).unwrap_err();
|
||||
|
Reference in New Issue
Block a user