wip
This commit is contained in:
@ -144,15 +144,23 @@ impl ExecutorContext {
|
|||||||
|
|
||||||
/// Execute an AST's program.
|
/// Execute an AST's program.
|
||||||
#[async_recursion]
|
#[async_recursion]
|
||||||
pub(super) async fn load_all_modules<'a>(
|
pub(super) async fn preload_all_modules<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
modules: &mut HashMap<String, crate::parsing::ast::types::Program>,
|
modules: &mut HashMap<String, Program>,
|
||||||
program: NodeRef<'a, crate::parsing::ast::types::Program>,
|
program: NodeRef<'a, Program>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
) -> Result<(), KclError> {
|
) -> Result<(), KclError> {
|
||||||
for statement in &program.body {
|
for statement in &program.body {
|
||||||
match statement {
|
match statement {
|
||||||
BodyItem::ImportStatement(import_stmt) => {
|
BodyItem::ImportStatement(import_stmt) => {
|
||||||
|
let path_str = import_stmt.path.to_string();
|
||||||
|
|
||||||
|
if modules.contains_key(&path_str) {
|
||||||
|
// don't waste our time if we've already loaded the
|
||||||
|
// module.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let source_range = SourceRange::from(import_stmt);
|
let source_range = SourceRange::from(import_stmt);
|
||||||
let attrs = &import_stmt.outer_attrs;
|
let attrs = &import_stmt.outer_attrs;
|
||||||
let module_id = self
|
let module_id = self
|
||||||
@ -176,7 +184,9 @@ impl ExecutorContext {
|
|||||||
progn.clone()
|
progn.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
self.load_all_modules(modules, &progn, exec_state).await?;
|
modules.insert(path_str, progn.clone().inner);
|
||||||
|
|
||||||
|
self.preload_all_modules(modules, &progn, exec_state).await?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
@ -188,7 +198,7 @@ impl ExecutorContext {
|
|||||||
#[async_recursion]
|
#[async_recursion]
|
||||||
pub(super) async fn exec_block<'a>(
|
pub(super) async fn exec_block<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
program: NodeRef<'a, crate::parsing::ast::types::Program>,
|
program: NodeRef<'a, Program>,
|
||||||
exec_state: &mut ExecState,
|
exec_state: &mut ExecState,
|
||||||
body_type: BodyType,
|
body_type: BodyType,
|
||||||
) -> Result<Option<KclValue>, KclError> {
|
) -> Result<Option<KclValue>, KclError> {
|
||||||
@ -2007,9 +2017,11 @@ impl FunctionSource {
|
|||||||
mod test {
|
mod test {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
execution::{memory::Stack, parse_execute},
|
execution::{memory::Stack, parse_execute, ContextType},
|
||||||
parsing::ast::types::{DefaultParamVal, Identifier, Parameter},
|
parsing::ast::types::{DefaultParamVal, Identifier, Parameter},
|
||||||
};
|
};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::task::JoinSet;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_assign_args_to_params() {
|
fn test_assign_args_to_params() {
|
||||||
@ -2118,7 +2130,7 @@ mod test {
|
|||||||
// Run each test.
|
// Run each test.
|
||||||
let func_expr = &Node::no_src(FunctionExpression {
|
let func_expr = &Node::no_src(FunctionExpression {
|
||||||
params,
|
params,
|
||||||
body: crate::parsing::ast::types::Program::empty(),
|
body: Program::empty(),
|
||||||
return_type: None,
|
return_type: None,
|
||||||
digest: None,
|
digest: None,
|
||||||
});
|
});
|
||||||
@ -2214,7 +2226,7 @@ a = foo()
|
|||||||
|
|
||||||
#[tokio::test(flavor = "multi_thread")]
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
async fn load_all_modules() {
|
async fn load_all_modules() {
|
||||||
let mut universe = HashMap::<String, NodeRef<'_, Program>>::new();
|
let mut universe = HashMap::<String, Node<Program>>::new();
|
||||||
|
|
||||||
// program a.kcl
|
// program a.kcl
|
||||||
let programa = r#"
|
let programa = r#"
|
||||||
@ -2223,7 +2235,7 @@ a = 1
|
|||||||
let programa = crate::parsing::parse_str(&programa, ModuleId::default())
|
let programa = crate::parsing::parse_str(&programa, ModuleId::default())
|
||||||
.parse_errs_as_err()
|
.parse_errs_as_err()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
universe.insert("a.kcl".to_owned(), (&programa).into());
|
universe.insert("a.kcl".to_owned(), programa);
|
||||||
|
|
||||||
// program b.kcl
|
// program b.kcl
|
||||||
let programb = r#"
|
let programb = r#"
|
||||||
@ -2232,7 +2244,7 @@ import 'a.kcl' as x
|
|||||||
let programb = crate::parsing::parse_str(&programb, ModuleId::default())
|
let programb = crate::parsing::parse_str(&programb, ModuleId::default())
|
||||||
.parse_errs_as_err()
|
.parse_errs_as_err()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
universe.insert("b.kcl".to_owned(), (&programb).into());
|
universe.insert("b.kcl".to_owned(), programb);
|
||||||
|
|
||||||
// program c.kcl
|
// program c.kcl
|
||||||
let programc = r#"
|
let programc = r#"
|
||||||
@ -2241,13 +2253,64 @@ import 'a.kcl'
|
|||||||
let programc = crate::parsing::parse_str(&programc, ModuleId::default())
|
let programc = crate::parsing::parse_str(&programc, ModuleId::default())
|
||||||
.parse_errs_as_err()
|
.parse_errs_as_err()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
universe.insert("c.kcl".to_owned(), (&programc).into());
|
universe.insert("c.kcl".to_owned(), programc);
|
||||||
|
|
||||||
// ok we have all the "files" loaded, let's do a sort and concurrent
|
// ok we have all the "files" loaded, let's do a sort and concurrent
|
||||||
// run here.
|
// run here.
|
||||||
|
|
||||||
for modules in crate::walk::import_graph(universe).into_iter() {
|
let exec_ctxt = ExecutorContext {
|
||||||
//
|
engine: Arc::new(Box::new(
|
||||||
|
crate::engine::conn_mock::EngineConnection::new()
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
KclError::Internal(crate::errors::KclErrorDetails {
|
||||||
|
message: format!("Failed to create mock engine connection: {}", err),
|
||||||
|
source_ranges: vec![SourceRange::default()],
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.unwrap(),
|
||||||
|
)),
|
||||||
|
fs: Arc::new(crate::fs::FileManager::new()),
|
||||||
|
stdlib: Arc::new(crate::std::StdLib::new()),
|
||||||
|
settings: Default::default(),
|
||||||
|
context_type: ContextType::Mock,
|
||||||
|
};
|
||||||
|
let mut exec_state = ExecState::new(&exec_ctxt.settings);
|
||||||
|
|
||||||
|
eprintln!("{:?}", universe);
|
||||||
|
for modules in crate::walk::import_graph(&universe).unwrap().into_iter() {
|
||||||
|
eprintln!("Spawning {:?}", modules);
|
||||||
|
|
||||||
|
let mut set = JoinSet::new();
|
||||||
|
for module in modules {
|
||||||
|
eprintln!("{:?}", universe.get(&module));
|
||||||
|
|
||||||
|
let program = universe.get(&module).unwrap().clone();
|
||||||
|
let module = module.clone();
|
||||||
|
let mut exec_state = exec_state.clone();
|
||||||
|
let exec_ctxt = exec_ctxt.clone();
|
||||||
|
|
||||||
|
set.spawn(async move {
|
||||||
|
let module = module;
|
||||||
|
let mut exec_state = exec_state;
|
||||||
|
let exec_ctxt = exec_ctxt;
|
||||||
|
let program = program;
|
||||||
|
|
||||||
|
// do we need to do anything with the result here?
|
||||||
|
let _ = exec_ctxt
|
||||||
|
.run(
|
||||||
|
&crate::Program {
|
||||||
|
ast: program.clone(),
|
||||||
|
original_file_contents: "".to_owned(),
|
||||||
|
},
|
||||||
|
&mut exec_state,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
set.join_all().await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use std::{
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
parsing::ast::types::{ImportPath, NodeRef, Program},
|
parsing::ast::types::{ImportPath, Node as AstNode, NodeRef, Program},
|
||||||
walk::{Node, Visitable},
|
walk::{Node, Visitable},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -23,7 +23,7 @@ type Graph = Vec<Dependency>;
|
|||||||
/// run concurrently. Each "stage" is blocking in this model, which will
|
/// run concurrently. Each "stage" is blocking in this model, which will
|
||||||
/// change in the future. Don't use this function widely, yet.
|
/// change in the future. Don't use this function widely, yet.
|
||||||
#[allow(clippy::iter_over_hash_type)]
|
#[allow(clippy::iter_over_hash_type)]
|
||||||
pub fn import_graph(progs: HashMap<String, NodeRef<'_, Program>>) -> Result<Vec<Vec<String>>> {
|
pub fn import_graph(progs: &HashMap<String, AstNode<Program>>) -> Result<Vec<Vec<String>>> {
|
||||||
let mut graph = Graph::new();
|
let mut graph = Graph::new();
|
||||||
|
|
||||||
for (name, program) in progs.iter() {
|
for (name, program) in progs.iter() {
|
||||||
@ -101,7 +101,7 @@ fn topsort(all_modules: &[&str], graph: Graph) -> Result<Vec<Vec<String>>> {
|
|||||||
Ok(order)
|
Ok(order)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn import_dependencies(prog: NodeRef<'_, Program>) -> Result<Vec<String>> {
|
pub(crate) fn import_dependencies(prog: NodeRef<Program>) -> Result<Vec<String>> {
|
||||||
let ret = Arc::new(Mutex::new(vec![]));
|
let ret = Arc::new(Mutex::new(vec![]));
|
||||||
|
|
||||||
fn walk(ret: Arc<Mutex<Vec<String>>>, node: Node<'_>) {
|
fn walk(ret: Arc<Mutex<Vec<String>>>, node: Node<'_>) {
|
||||||
@ -140,16 +140,16 @@ mod tests {
|
|||||||
let mut modules = HashMap::new();
|
let mut modules = HashMap::new();
|
||||||
|
|
||||||
let a = kcl!("");
|
let a = kcl!("");
|
||||||
modules.insert("a.kcl".to_owned(), &a);
|
modules.insert("a.kcl".to_owned(), a);
|
||||||
|
|
||||||
let b = kcl!(
|
let b = kcl!(
|
||||||
"
|
"
|
||||||
import \"a.kcl\"
|
import \"a.kcl\"
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
modules.insert("b.kcl".to_owned(), &b);
|
modules.insert("b.kcl".to_owned(), b);
|
||||||
|
|
||||||
let order = import_graph(modules).unwrap();
|
let order = import_graph(&modules).unwrap();
|
||||||
assert_eq!(vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned()]], order);
|
assert_eq!(vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned()]], order);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,16 +162,16 @@ import \"a.kcl\"
|
|||||||
y = 2
|
y = 2
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
modules.insert("a.kcl".to_owned(), &a);
|
modules.insert("a.kcl".to_owned(), a);
|
||||||
|
|
||||||
let b = kcl!(
|
let b = kcl!(
|
||||||
"
|
"
|
||||||
x = 1
|
x = 1
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
modules.insert("b.kcl".to_owned(), &b);
|
modules.insert("b.kcl".to_owned(), b);
|
||||||
|
|
||||||
let order = import_graph(modules).unwrap();
|
let order = import_graph(&modules).unwrap();
|
||||||
assert_eq!(vec![vec!["a.kcl".to_owned(), "b.kcl".to_owned()]], order);
|
assert_eq!(vec![vec!["a.kcl".to_owned(), "b.kcl".to_owned()]], order);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -180,23 +180,23 @@ x = 1
|
|||||||
let mut modules = HashMap::new();
|
let mut modules = HashMap::new();
|
||||||
|
|
||||||
let a = kcl!("");
|
let a = kcl!("");
|
||||||
modules.insert("a.kcl".to_owned(), &a);
|
modules.insert("a.kcl".to_owned(), a);
|
||||||
|
|
||||||
let b = kcl!(
|
let b = kcl!(
|
||||||
"
|
"
|
||||||
import \"a.kcl\"
|
import \"a.kcl\"
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
modules.insert("b.kcl".to_owned(), &b);
|
modules.insert("b.kcl".to_owned(), b);
|
||||||
|
|
||||||
let c = kcl!(
|
let c = kcl!(
|
||||||
"
|
"
|
||||||
import \"a.kcl\"
|
import \"a.kcl\"
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
modules.insert("c.kcl".to_owned(), &c);
|
modules.insert("c.kcl".to_owned(), c);
|
||||||
|
|
||||||
let order = import_graph(modules).unwrap();
|
let order = import_graph(&modules).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned(), "c.kcl".to_owned()]],
|
vec![vec!["a.kcl".to_owned()], vec!["b.kcl".to_owned(), "c.kcl".to_owned()]],
|
||||||
order
|
order
|
||||||
@ -212,15 +212,15 @@ import \"a.kcl\"
|
|||||||
import \"b.kcl\"
|
import \"b.kcl\"
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
modules.insert("a.kcl".to_owned(), &a);
|
modules.insert("a.kcl".to_owned(), a);
|
||||||
|
|
||||||
let b = kcl!(
|
let b = kcl!(
|
||||||
"
|
"
|
||||||
import \"a.kcl\"
|
import \"a.kcl\"
|
||||||
"
|
"
|
||||||
);
|
);
|
||||||
modules.insert("b.kcl".to_owned(), &b);
|
modules.insert("b.kcl".to_owned(), b);
|
||||||
|
|
||||||
import_graph(modules).unwrap_err();
|
import_graph(&modules).unwrap_err();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user