diff --git a/crates/erg_common/config.rs b/crates/erg_common/config.rs index be706528..8fa97f4f 100644 --- a/crates/erg_common/config.rs +++ b/crates/erg_common/config.rs @@ -179,6 +179,7 @@ pub struct ErgConfig { pub packages: ArcArray, pub effect_check: bool, pub ownership_check: bool, + pub use_pylyzer: bool, } impl Default for ErgConfig { @@ -206,6 +207,7 @@ impl Default for ErgConfig { packages: ArcArray::from([]), effect_check: true, ownership_check: true, + use_pylyzer: false, } } } @@ -340,6 +342,9 @@ impl ErgConfig { None, )); } + "--use-pylyzer" => { + cfg.use_pylyzer = true; + } "--use-local-package" => { let name = args .next() diff --git a/crates/erg_compiler/build_package.rs b/crates/erg_compiler/build_package.rs index d7a25f26..fc16f952 100644 --- a/crates/erg_compiler/build_package.rs +++ b/crates/erg_compiler/build_package.rs @@ -630,36 +630,39 @@ impl if self.cfg.input.path() == path.as_path() { return Ok(path); } - let (out, err) = if self.cfg.mode == ErgMode::LanguageServer || self.cfg.quiet_repl { - (Stdio::null(), Stdio::null()) - } else { - (Stdio::inherit(), Stdio::inherit()) - }; - // pylyzer is a static analysis tool for Python (https://github.com/mtshiba/pylyzer). - // It can convert a Python script to an Erg AST for code analysis. - // There is also an option to output the analysis result as `d.er`. Use this if the system have pylyzer installed. - // A type definition file may be generated even if not all type checks succeed. - if let Ok(status) = Command::new("pylyzer") - .arg("--dump-decl") - .arg(path.to_str().unwrap_or_default()) - .stdout(out) - .stderr(err) - .spawn() - .and_then(|mut child| child.wait()) - { - if let Some(path) = self - .cfg - .input - .resolve_decl_path(Path::new(&__name__[..]), &self.cfg) + if self.cfg.use_pylyzer { + let (out, err) = if self.cfg.mode == ErgMode::LanguageServer || self.cfg.quiet_repl { - let size = metadata(&path).or(Err(()))?.len(); - // if pylyzer crashed - if !status.success() && size == 0 { - // The presence of the decl file indicates that the analysis is in progress or completed, - // so if pylyzer crashes in the middle of the analysis, delete the file. - remove_file(&path).unwrap(); - } else { - return Ok(path); + (Stdio::null(), Stdio::null()) + } else { + (Stdio::inherit(), Stdio::inherit()) + }; + // pylyzer is a static analysis tool for Python (https://github.com/mtshiba/pylyzer). + // It can convert a Python script to an Erg AST for code analysis. + // There is also an option to output the analysis result as `d.er`. Use this if the system have pylyzer installed. + // A type definition file may be generated even if not all type checks succeed. + if let Ok(status) = Command::new("pylyzer") + .arg("--dump-decl") + .arg(path.to_str().unwrap_or_default()) + .stdout(out) + .stderr(err) + .spawn() + .and_then(|mut child| child.wait()) + { + if let Some(path) = self + .cfg + .input + .resolve_decl_path(Path::new(&__name__[..]), &self.cfg) + { + let size = metadata(&path).or(Err(()))?.len(); + // if pylyzer crashed + if !status.success() && size == 0 { + // The presence of the decl file indicates that the analysis is in progress or completed, + // so if pylyzer crashes in the middle of the analysis, delete the file. + remove_file(&path).unwrap(); + } else { + return Ok(path); + } } } } diff --git a/crates/erg_compiler/module/graph.rs b/crates/erg_compiler/module/graph.rs index 65412e73..93e2288c 100644 --- a/crates/erg_compiler/module/graph.rs +++ b/crates/erg_compiler/module/graph.rs @@ -1,5 +1,6 @@ use std::fmt; +use erg_common::consts::DEBUG_MODE; use erg_common::pathutil::NormalizedPathBuf; use erg_common::set; use erg_common::set::Set; @@ -95,6 +96,12 @@ impl ModuleGraph { } pub fn add_node_if_none(&mut self, path: &NormalizedPathBuf) { + if path.is_dir() { + if DEBUG_MODE { + panic!("path is a directory: {path}"); + } + return; + } if self.0.iter().all(|n| &n.id != path) { let node = Node::new(path.clone(), (), set! {}); self.0.push(node); @@ -107,6 +114,12 @@ impl ModuleGraph { referrer: &NormalizedPathBuf, depends_on: NormalizedPathBuf, ) -> Result<(), IncRefError> { + if depends_on.is_dir() { + if DEBUG_MODE { + panic!("path is a directory: {depends_on}"); + } + return Ok(()); + } self.add_node_if_none(referrer); if referrer == &depends_on { return Ok(());