Skip to content

Commit 7870ecb

Browse files
committed
incremental compile!
1 parent 6831c2b commit 7870ecb

File tree

1 file changed

+90
-28
lines changed

1 file changed

+90
-28
lines changed

src/build.rs

Lines changed: 90 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub enum SourceType {
4040
#[derive(Debug, Clone)]
4141
pub struct Module {
4242
pub dirty: bool,
43+
pub interface_dirty: bool,
4344
pub source_type: SourceType,
4445
pub namespace: Option<String>,
4546
pub file_path: String,
@@ -109,10 +110,10 @@ fn remove_compile_assets(
109110

110111
pub fn cleanup_previous_build(
111112
packages: &AHashMap<String, Package>,
112-
all_modules: &AHashMap<String, Module>,
113+
all_modules: &mut AHashMap<String, Module>,
113114
root_path: &str,
114115
) -> (usize, usize) {
115-
let mut ast_modules: AHashMap<String, (String, String, Option<String>, SystemTime)> =
116+
let mut ast_modules: AHashMap<String, (String, String, Option<String>, SystemTime, String)> =
116117
AHashMap::new();
117118
let mut ast_rescript_file_locations = AHashSet::new();
118119

@@ -162,6 +163,7 @@ pub fn cleanup_previous_build(
162163
package.name.to_owned(),
163164
package.namespace.to_owned(),
164165
entry.metadata().unwrap().modified().unwrap(),
166+
ast_file_path,
165167
),
166168
);
167169
let _ = ast_rescript_file_locations.insert(res_file_path);
@@ -193,9 +195,10 @@ pub fn cleanup_previous_build(
193195

194196
diff.par_iter().for_each(|res_file_location| {
195197
let _ = std::fs::remove_file(helpers::change_extension(res_file_location, "mjs"));
196-
let (_module_name, package_name, package_namespace, _last_modified) = ast_modules
197-
.get(&res_file_location.to_string())
198-
.expect("Could not find module name for ast file");
198+
let (_module_name, package_name, package_namespace, _last_modified, _ast_file_path) =
199+
ast_modules
200+
.get(&res_file_location.to_string())
201+
.expect("Could not find module name for ast file");
199202
remove_compile_assets(
200203
res_file_location,
201204
package_name,
@@ -204,6 +207,51 @@ pub fn cleanup_previous_build(
204207
);
205208
});
206209

210+
ast_rescript_file_locations
211+
.intersection(&rescript_file_locations)
212+
.into_iter()
213+
.for_each(|res_file_location| {
214+
let (module_name, _package_name, _package_namespace, ast_last_modified, ast_file_path) =
215+
ast_modules
216+
.get(res_file_location)
217+
.expect("Could not find module name for ast file");
218+
219+
let is_interface = match Path::new(ast_file_path)
220+
.extension()
221+
.map(|s| s.to_str().unwrap())
222+
{
223+
Some("ast") => false,
224+
Some("iast") => true,
225+
_ => panic!("Unknown extension"),
226+
};
227+
228+
let module_last_modified = if is_interface {
229+
all_modules
230+
.get(module_name)
231+
.expect("Could not find module for ast file")
232+
.interface_last_modified
233+
.expect("Could not find last modified for module")
234+
} else {
235+
all_modules
236+
.get(module_name)
237+
.expect("Could not find module for ast file")
238+
.last_modified
239+
.expect("Could not find last modified for module")
240+
};
241+
242+
if ast_last_modified > &module_last_modified {
243+
if let Some(module) = all_modules.get_mut(module_name) {
244+
if is_interface {
245+
module.interface_dirty = false;
246+
module.asti_path = Some(ast_file_path.to_string());
247+
} else {
248+
module.dirty = false;
249+
module.ast_path = Some(ast_file_path.to_string());
250+
}
251+
}
252+
}
253+
});
254+
207255
(diff_len, ast_rescript_file_locations.len())
208256
}
209257

@@ -387,14 +435,15 @@ fn gen_mlmap(
387435
file.to_string()
388436
}
389437

390-
pub fn generate_asts(
391-
version: String,
438+
pub fn generate_asts<'a>(
439+
version: &str,
392440
project_root: &str,
393-
mut modules: AHashMap<String, Module>,
394-
all_modules: AHashSet<String>,
395-
) -> AHashMap<String, Module> {
441+
mut modules: &'a mut AHashMap<String, Module>,
442+
all_modules: &AHashSet<String>,
443+
) {
396444
modules
397445
.par_iter()
446+
.filter(|(_, module)| module.dirty || module.interface_dirty)
398447
.map(|(module_name, metadata)| {
399448
debug!("Generating AST for module: {}", module_name);
400449
match metadata.source_type {
@@ -451,17 +500,15 @@ pub fn generate_asts(
451500
.collect::<Vec<(String, String, Option<String>, AHashSet<String>)>>()
452501
.into_iter()
453502
.for_each(|(module_name, ast_path, asti_path, deps)| {
454-
modules.entry(module_name).and_modify(|module| {
503+
if let Some(module) = modules.get_mut(&module_name) {
455504
module.ast_path = Some(ast_path);
456505
module.asti_path = asti_path;
457506
module.deps = deps;
458-
});
507+
}
459508
});
460-
461-
modules
462509
}
463510

464-
pub fn parse(
511+
pub fn parse_packages(
465512
project_root: &str,
466513
packages: AHashMap<String, package_tree::Package>,
467514
) -> (AHashSet<String>, AHashMap<String, Module>) {
@@ -511,7 +558,8 @@ pub fn parse(
511558
Module {
512559
file_path: mlmap.to_owned(),
513560
interface_file_path: None,
514-
dirty: true,
561+
dirty: false,
562+
interface_dirty: false,
515563
source_type: SourceType::MlMap,
516564
namespace: None,
517565
ast_path: Some(mlmap.to_owned()),
@@ -550,11 +598,14 @@ pub fn parse(
550598
panic!("Unable to continue... See log output above...");
551599
}
552600
module.file_path = file.to_owned();
601+
module.last_modified = Some(metadata.modified().unwrap());
602+
module.dirty = true;
553603
})
554604
.or_insert(Module {
555605
file_path: file.to_owned(),
556606
interface_file_path: None,
557607
dirty: true,
608+
interface_dirty: false,
558609
source_type: SourceType::SourceFile,
559610
namespace,
560611
ast_path: None,
@@ -567,11 +618,16 @@ pub fn parse(
567618
} else {
568619
modules
569620
.entry(module_name.to_string())
570-
.and_modify(|module| module.interface_file_path = Some(file.to_owned()))
621+
.and_modify(|module| {
622+
module.interface_file_path = Some(file.to_owned());
623+
module.interface_last_modified = Some(metadata.modified().unwrap());
624+
module.interface_dirty = true;
625+
})
571626
.or_insert(Module {
572627
file_path: "".to_string(),
573628
interface_file_path: Some(file.to_owned()),
574-
dirty: true,
629+
dirty: false,
630+
interface_dirty: true,
575631
source_type: SourceType::SourceFile,
576632
namespace,
577633
ast_path: None,
@@ -795,7 +851,7 @@ pub fn build(path: &str) -> AHashMap<std::string::String, Module> {
795851
LOOKING_GLASS
796852
);
797853
let _ = stdout().flush();
798-
let (all_modules, modules) = parse(&project_root, packages.to_owned());
854+
let (all_modules, mut modules) = parse_packages(&project_root, packages.to_owned());
799855
let timing_source_files_elapsed = timing_source_files.elapsed();
800856
println!(
801857
"{}\r{} {}Found source files in {:.2}s",
@@ -811,7 +867,8 @@ pub fn build(path: &str) -> AHashMap<std::string::String, Module> {
811867
SWEEP
812868
);
813869
let timing_cleanup = Instant::now();
814-
let (diff_cleanup, total_cleanup) = cleanup_previous_build(&packages, &modules, &project_root);
870+
let (diff_cleanup, total_cleanup) =
871+
cleanup_previous_build(&packages, &mut modules, &project_root);
815872
let timing_cleanup_elapsed = timing_cleanup.elapsed();
816873
println!(
817874
"{}\r{} {}Cleaned {}/{} {:.2}s",
@@ -831,12 +888,7 @@ pub fn build(path: &str) -> AHashMap<std::string::String, Module> {
831888
let _ = stdout().flush();
832889

833890
let timing_ast = Instant::now();
834-
let modules = generate_asts(
835-
rescript_version.to_string(),
836-
&project_root,
837-
modules,
838-
all_modules,
839-
);
891+
let _ = generate_asts(&rescript_version, &project_root, &mut modules, &all_modules);
840892
let timing_ast_elapsed = timing_ast.elapsed();
841893
println!(
842894
"{}\r{} {}Parsed source files in {:.2}s",
@@ -857,10 +909,20 @@ pub fn build(path: &str) -> AHashMap<std::string::String, Module> {
857909
);
858910
let start_compiling = Instant::now();
859911

860-
let mut compiled_modules = AHashSet::<String>::new();
912+
// let mut compiled_modules = AHashSet::<String>::new();
913+
let mut compiled_modules = modules
914+
.iter()
915+
.filter_map(|(module_name, module)| {
916+
if module.dirty || module.interface_dirty {
917+
None
918+
} else {
919+
Some(module_name.to_owned())
920+
}
921+
})
922+
.collect::<AHashSet<String>>();
861923

862924
let mut loop_count = 0;
863-
let mut files_total_count = 0;
925+
let mut files_total_count = compiled_modules.len();
864926
let mut files_current_loop_count;
865927
let mut compile_errors = "".to_string();
866928
let total_modules = modules.len();

0 commit comments

Comments
 (0)