Skip to content

Commit 2cf1f8e

Browse files
committed
Merge #356: Optimize DependencyMapBuilder for multiple entry roots
b31c413 feat: optimize `DependencyMapBuilder` for several entry roots (LesterEvSe) Pull request description: Introduce a new `ValidatedDeps` structure and remove `entry_root` from `DependencyMapBuilder`. This also optimizes the build algorithm complexity from `O(n²)` to `O(n log n)`. Finally, this refactors the tests to accommodate the new functionality and adds helper macros to make testing more convenient. ACKs for top commit: KyrylR: ACK b31c413; successfully ran local tests Tree-SHA512: f72603e6e7033d21dcc34bb7796dccd2fb118147e07cfee7c302474c8021c9852fb305f4cf513b987600f0d6cb52d00d7d05a9e62b7bd1466e3c6108e60ad6e9
2 parents ffa948e + b31c413 commit 2cf1f8e

5 files changed

Lines changed: 309 additions & 258 deletions

File tree

src/ast.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,6 @@ impl Program {
10741074
})
10751075
}
10761076

1077-
// Put this helper function inside your impl block or just above your logic
10781077
fn extract_single_main(items: &[Item]) -> Result<Option<Expression>, Error> {
10791078
let mut main_expr = None;
10801079

src/driver/mod.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,7 @@ struct CurrentModule {
397397
#[cfg(test)]
398398
pub(crate) mod tests {
399399
use super::*;
400-
use crate::resolution::tests::canon;
401-
use crate::resolution::DependencyMapBuilder;
400+
use crate::resolution::tests::{build_map, canon};
402401
use crate::test_utils::TempWorkspace;
403402

404403
/// Initializes a raw graph environment for testing, explicitly allowing for and capturing failure states.
@@ -437,11 +436,8 @@ pub(crate) mod tests {
437436
let lib_dir = canon(&ws.create_dir("workspace/libs/lib"));
438437

439438
// Set up the dependency map for imports (e.g. `use lib::...`)
440-
let map = DependencyMapBuilder::new(workspace_dir.clone())
441-
.add_dependency(workspace_dir.clone(), "lib".to_string(), lib_dir.clone())
442-
.build()
443-
.expect("Failed to create dependency map");
444-
let map = Arc::new(map);
439+
let map =
440+
Arc::new(build_map(&workspace_dir, &[(&workspace_dir, "lib", &lib_dir)]).unwrap());
445441

446442
let mut root_file_path = None;
447443
let mut root_content = String::new();

src/lib.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ pub trait ArbitraryOfType: Sized {
422422
pub(crate) mod tests {
423423
use crate::ast::{CoreJetHinter, ElementsJetHinter, JetHinter};
424424
use crate::parse::ParseFromStr;
425-
use crate::resolution::tests::canon;
425+
use crate::resolution::tests::{build_map, canon};
426426
use crate::resolution::DependencyMapBuilder;
427427
use crate::source::CanonPath;
428428
use crate::test_utils::TempWorkspace;
@@ -471,15 +471,15 @@ pub(crate) mod tests {
471471
{
472472
let parent = prog_path.as_ref().parent().unwrap();
473473
let canon_root = canon(parent);
474-
let mut builder = DependencyMapBuilder::new(canon_root);
474+
let mut builder = DependencyMapBuilder::new();
475475

476476
for (context, alias, target) in dependencies {
477477
let context = canon(context.as_ref());
478478
let target = canon(target.as_ref());
479479

480-
builder = builder.add_dependency(context, alias.into(), target);
480+
builder.add_dependency(context, alias.into(), target);
481481
}
482-
builder.build().unwrap()
482+
builder.build(canon_root).unwrap()
483483
}
484484

485485
pub(crate) struct TestCase<T> {
@@ -871,7 +871,7 @@ pub(crate) mod tests {
871871
let main_path = root.join(MAIN);
872872
let canon_root = CanonPath::canonicalize(&root).unwrap();
873873

874-
let dependency_map = DependencyMapBuilder::new(canon_root).build().unwrap();
874+
let dependency_map = build_map(&canon_root, &[]).unwrap();
875875

876876
TestCase::<TemplateProgram>::template_deps(&main_path, &dependency_map)
877877
.with_arguments(Arguments::default())
@@ -1352,19 +1352,15 @@ mod error_tests {
13521352
use super::*;
13531353

13541354
use crate::ast::ElementsJetHinter;
1355-
use crate::resolution::tests::canon;
1356-
use crate::resolution::DependencyMapBuilder;
1355+
use crate::resolution::tests::{build_map, canon};
13571356
use crate::source::CanonPath;
13581357
use crate::test_utils::TempWorkspace;
13591358

13601359
fn dependency_map(root_dir: &Path, drp: &str, lib_dir: &Path) -> DependencyMap {
13611360
let context = CanonPath::canonicalize(root_dir).unwrap();
13621361
let target = CanonPath::canonicalize(lib_dir).unwrap();
13631362

1364-
DependencyMapBuilder::new(context.clone())
1365-
.add_dependency(context, drp.into(), target)
1366-
.build()
1367-
.unwrap()
1363+
build_map(&context, &[(&context, drp, &target)]).unwrap()
13681364
}
13691365

13701366
fn source_file(path: &Path) -> CanonSourceFile {
@@ -1455,7 +1451,8 @@ mod error_tests {
14551451
#[cfg(test)]
14561452
mod functional_tests {
14571453
use crate::ast::ElementsJetHinter;
1458-
use crate::resolution::{DependencyMap, DependencyMapBuilder};
1454+
use crate::resolution::tests::build_map;
1455+
use crate::resolution::DependencyMap;
14591456
use crate::source::{CanonPath, CanonSourceFile};
14601457
use crate::tests::{flatten_multidep_test, run_dependency_test, run_multidep_test};
14611458
use crate::{Arguments, CompiledProgram};
@@ -1664,12 +1661,9 @@ mod functional_tests {
16641661
let lib_canon = CanonPath::canonicalize(&lib_dir).unwrap();
16651662

16661663
// 3. Set up the dependency maps
1667-
let dependency_map = DependencyMapBuilder::new(root_canon.clone())
1668-
.add_dependency(root_canon.clone(), "lib".to_string(), lib_canon)
1669-
.build()
1670-
.unwrap();
1664+
let dependency_map = build_map(&root_canon, &[(&root_canon, "lib", &lib_canon)]).unwrap();
16711665

1672-
let no_dependency_map = DependencyMapBuilder::new(root_canon).build().unwrap();
1666+
let no_dependency_map = build_map(&root_canon, &[]).unwrap();
16731667

16741668
// Compile both programs reading directly from the file system
16751669
let poisoned = compile_with_deps(&poisoned_main, &dependency_map);

src/main.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
135135
.and_then(|p| CanonPath::canonicalize(p).ok())
136136
.ok_or("Failed to determine project root directory from entry file")?;
137137

138-
let mut builder = DependencyMapBuilder::new(canon_root.clone());
138+
let mut builder = DependencyMapBuilder::new();
139139

140140
for arg in dep_args {
141141
let (left_side, path_str) = arg.split_once('=').unwrap_or_else(|| {
@@ -157,11 +157,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
157157
};
158158

159159
let target_path = CanonPath::canonicalize(Path::new(path_str))?;
160-
161-
builder = builder.add_dependency(context_path, alias.to_string(), target_path);
160+
builder.add_dependency(context_path, alias.to_string(), target_path);
162161
}
163162

164-
let dependencies = match builder.build() {
163+
let dependencies = match builder.build(canon_root.clone()) {
165164
Ok(map) => map,
166165
Err(e) => {
167166
eprintln!("Error: {e}");

0 commit comments

Comments
 (0)