mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 04:24:43 +00:00
fix: retry path resolution if failed
This commit is contained in:
parent
a9025507d3
commit
dab9def08a
2 changed files with 51 additions and 7 deletions
|
@ -2,6 +2,7 @@
|
|||
//!
|
||||
//! コマンドオプション(パーサー)を定義する
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io::{stdin, BufRead, BufReader, Read, Write};
|
||||
|
@ -319,6 +320,26 @@ impl Input {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn module_name(&self) -> String {
|
||||
match &self.kind {
|
||||
InputKind::File(filename) => {
|
||||
let file_stem = if filename.file_stem() == Some(OsStr::new("__init__")) {
|
||||
filename.parent().and_then(|p| p.file_stem())
|
||||
} else {
|
||||
filename.file_stem()
|
||||
};
|
||||
file_stem
|
||||
.and_then(|f| f.to_str())
|
||||
.unwrap_or("_")
|
||||
.to_string()
|
||||
}
|
||||
InputKind::REPL | InputKind::Pipe(_) => "<stdin>".to_string(),
|
||||
InputKind::DummyREPL(stdin) => stdin.name.clone(),
|
||||
InputKind::Str(_) => "<string>".to_string(),
|
||||
InputKind::Dummy => "<dummy>".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&mut self) -> String {
|
||||
match &mut self.kind {
|
||||
InputKind::File(filename) => {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use std::fmt;
|
||||
use std::io::BufRead;
|
||||
use std::fs::{metadata, remove_file, File};
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::option::Option;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{Command, Stdio};
|
||||
use std::time::SystemTime;
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use erg_common::config::ErgMode;
|
||||
use erg_common::consts::{ERG_MODE, PYTHON_MODE};
|
||||
|
@ -1953,15 +1955,22 @@ impl Context {
|
|||
Str::from(name)
|
||||
}
|
||||
|
||||
fn analysis_in_progress(path: &Path) -> bool {
|
||||
let Ok(meta) = metadata(path) else {
|
||||
return false;
|
||||
};
|
||||
!is_std_decl_path(path) && meta.len() == 0
|
||||
}
|
||||
|
||||
fn availability(path: &Path) -> Availability {
|
||||
let Ok(file) = std::fs::File::open(path) else {
|
||||
let Ok(file) = File::open(path) else {
|
||||
return Availability::NotFound;
|
||||
};
|
||||
if is_std_decl_path(path) {
|
||||
return Availability::Available;
|
||||
}
|
||||
let mut line = "".to_string();
|
||||
let Ok(_) = std::io::BufReader::new(file).read_line(&mut line) else {
|
||||
let Ok(_) = BufReader::new(file).read_line(&mut line) else {
|
||||
return Availability::Unreadable;
|
||||
};
|
||||
if line.is_empty() {
|
||||
|
@ -1970,7 +1979,7 @@ impl Context {
|
|||
let Ok(status) = line.parse::<PylyzerStatus>() else {
|
||||
return Availability::Available;
|
||||
};
|
||||
let Some(meta) = std::fs::metadata(&status.file).ok() else {
|
||||
let Some(meta) = metadata(&status.file).ok() else {
|
||||
return Availability::NotFound;
|
||||
};
|
||||
let dummy_hash = meta.len();
|
||||
|
@ -1987,6 +1996,12 @@ impl Context {
|
|||
if self.cfg.input.decl_file_is(&path) {
|
||||
return Ok(path);
|
||||
}
|
||||
for _ in 0..600 {
|
||||
if !Self::analysis_in_progress(&path) {
|
||||
break;
|
||||
}
|
||||
sleep(Duration::from_millis(100));
|
||||
}
|
||||
if matches!(Self::availability(&path), OutOfDate | NotFound | Unreadable) {
|
||||
let _ = self.try_gen_py_decl_file(__name__);
|
||||
}
|
||||
|
@ -2038,7 +2053,7 @@ impl Context {
|
|||
// 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")
|
||||
if let Ok(status) = Command::new("pylyzer")
|
||||
.arg("--dump-decl")
|
||||
.arg(path.to_str().unwrap())
|
||||
.stdout(out)
|
||||
|
@ -2047,7 +2062,15 @@ impl Context {
|
|||
.and_then(|mut child| child.wait())
|
||||
{
|
||||
if let Some(path) = self.cfg.input.resolve_decl_path(Path::new(&__name__[..])) {
|
||||
return Ok(path);
|
||||
let size = metadata(&path).unwrap().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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue