fix: module cache bug

This commit is contained in:
Shunsuke Shibayama 2023-10-09 23:40:58 +09:00
parent c14a60e329
commit a31f23a093
5 changed files with 33 additions and 4 deletions

View file

@ -1,3 +1,5 @@
.neighbor = "defined in b.er"
.x = 1
.C = Class { .x = Int }

View file

@ -1,4 +1,4 @@
b = import "b"
{neighbor;} = import "b"
print! neighbor, b.x
print! neighbor, b.x, b.C.new({ .x = 1 }).x

View file

@ -37,7 +37,11 @@ pub enum ResolveError {
pub type ResolveResult<T> = Result<T, ResolveError>;
/// Resolve dependencies and build a package
/// Resolve dependencies and build a package.
/// This object should be a singleton.
///
/// Invariant condition: `build_module` must be idempotent.
/// That is, the only thing that may differ as a result of analyzing the same package is the elapsed time.
#[derive(Debug)]
pub struct PackageBuilder {
cfg: ErgConfig,
@ -105,7 +109,8 @@ impl Runnable for PackageBuilder {
impl Buildable for PackageBuilder {
fn inherit(cfg: ErgConfig, shared: SharedCompilerResource) -> Self {
Self::new(cfg, shared)
let mod_name = Str::from(cfg.input.file_stem());
Self::new_with_cache(cfg, mod_name, shared)
}
fn build(&mut self, src: String, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
self.build(src, mode)
@ -136,10 +141,17 @@ impl ContextProvider for PackageBuilder {
impl PackageBuilder {
pub fn new(cfg: ErgConfig, shared: SharedCompilerResource) -> Self {
Self::new_with_cache(cfg, "<module>".into(), shared)
}
/// For batch compilation mode, `mod_name` of the entry point must be `<module>`.
///
/// For ELS mode, `mod_name` must be the file name of the entry point.
pub fn new_with_cache(cfg: ErgConfig, mod_name: Str, shared: SharedCompilerResource) -> Self {
Self {
cfg: cfg.copy(),
shared: shared.clone(),
main_builder: HIRBuilder::new_with_cache(cfg, "<module>", shared),
main_builder: HIRBuilder::new_with_cache(cfg, mod_name, shared),
cyclic: vec![],
submodules: vec![],
asts: Dict::new(),
@ -238,6 +250,7 @@ impl PackageBuilder {
return Ok(());
};
let import_path = NormalizedPathBuf::from(import_path.clone());
self.shared.graph.add_node_if_none(&import_path);
let mut ast_builder = ASTBuilder::new(cfg.copy());
let mut ast = match ast_builder.build(src) {
Ok(art) => {

View file

@ -77,6 +77,16 @@ impl SharedCompilerResource {
self.warns.remove(path);
}
pub fn clear_path(&self, path: &NormalizedPathBuf) {
self.mod_cache.remove(path);
self.py_mod_cache.remove(path);
self.index.remove_path(path);
// self.graph.remove(path);
self.promises.remove(path);
self.errors.remove(path);
self.warns.remove(path);
}
pub fn rename_path(&self, old: &NormalizedPathBuf, new: NormalizedPathBuf) {
self.mod_cache.rename_path(old, new.clone());
self.py_mod_cache.rename_path(old, new.clone());

View file

@ -64,6 +64,7 @@ impl ModuleGraph {
.unwrap_or(false)
}
/// (usually) `path` is not contained
pub fn children(&self, path: &NormalizedPathBuf) -> Set<NormalizedPathBuf> {
self.0
.iter()
@ -72,6 +73,7 @@ impl ModuleGraph {
.collect()
}
/// (usually) `path` is not contained
fn parents(&self, path: &NormalizedPathBuf) -> Option<&Set<NormalizedPathBuf>> {
self.0.iter().find(|n| &n.id == path).map(|n| &n.depends_on)
}
@ -200,10 +202,12 @@ impl SharedModuleGraph {
self.0.borrow().depends_on(path, target)
}
/// (usually) `path` is not contained
pub fn children(&self, path: &NormalizedPathBuf) -> Set<NormalizedPathBuf> {
self.0.borrow().children(path)
}
/// (usually) `path` is not contained
pub fn ancestors(&self, path: &NormalizedPathBuf) -> Set<NormalizedPathBuf> {
self.0.borrow().ancestors(path)
}