mirror of https://github.com/mtshiba/pylyzer
Update: generate type definition files even in errors
This commit is contained in:
parent
d5485229cc
commit
f0cf267da2
|
|
@ -227,7 +227,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "erg_common"
|
name = "erg_common"
|
||||||
version = "0.6.0-beta.4"
|
version = "0.6.0-beta.4"
|
||||||
source = "git+https://github.com/erg-lang/erg?branch=main#46418987c1e6bf24baa774827cb1e4be8fe25b67"
|
source = "git+https://github.com/erg-lang/erg?branch=main#1c607cfe5ba87b0dc37c4a3393629c023d85e317"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"libc",
|
"libc",
|
||||||
|
|
@ -237,7 +237,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "erg_compiler"
|
name = "erg_compiler"
|
||||||
version = "0.6.0-beta.4"
|
version = "0.6.0-beta.4"
|
||||||
source = "git+https://github.com/erg-lang/erg?branch=main#46418987c1e6bf24baa774827cb1e4be8fe25b67"
|
source = "git+https://github.com/erg-lang/erg?branch=main#1c607cfe5ba87b0dc37c4a3393629c023d85e317"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"erg_common",
|
"erg_common",
|
||||||
"erg_parser",
|
"erg_parser",
|
||||||
|
|
@ -246,7 +246,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "erg_parser"
|
name = "erg_parser"
|
||||||
version = "0.6.0-beta.4"
|
version = "0.6.0-beta.4"
|
||||||
source = "git+https://github.com/erg-lang/erg?branch=main#46418987c1e6bf24baa774827cb1e4be8fe25b67"
|
source = "git+https://github.com/erg-lang/erg?branch=main#1c607cfe5ba87b0dc37c4a3393629c023d85e317"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"erg_common",
|
"erg_common",
|
||||||
"unicode-xid 0.2.4",
|
"unicode-xid 0.2.4",
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,26 @@
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use erg_common::log;
|
||||||
use erg_common::config::Input;
|
use erg_common::config::Input;
|
||||||
use erg_compiler::hir::{HIR, Expr};
|
use erg_compiler::hir::{HIR, Expr};
|
||||||
use erg_compiler::ty::HasType;
|
use erg_compiler::ty::HasType;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum CheckStatus {
|
||||||
|
Succeed,
|
||||||
|
Failed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CheckStatus {
|
||||||
|
pub const fn is_succeed(&self) -> bool {
|
||||||
|
matches!(self, CheckStatus::Succeed)
|
||||||
|
}
|
||||||
|
pub const fn is_failed(&self) -> bool {
|
||||||
|
matches!(self, CheckStatus::Failed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct DeclFile {
|
pub struct DeclFile {
|
||||||
pub filename: String,
|
pub filename: String,
|
||||||
pub code: String,
|
pub code: String,
|
||||||
|
|
@ -14,8 +30,8 @@ fn escape_type(typ: String) -> String {
|
||||||
typ.replace('%', "Type_")
|
typ.replace('%', "Type_")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_decl_er(hir: HIR) -> DeclFile {
|
pub fn gen_decl_er(hir: HIR, status: CheckStatus) -> DeclFile {
|
||||||
let mut code = "".to_string();
|
let mut code = if status.is_failed() { "# failed\n".to_string() } else { "# succeed\n".to_string() };
|
||||||
for chunk in hir.module.into_iter() {
|
for chunk in hir.module.into_iter() {
|
||||||
match chunk {
|
match chunk {
|
||||||
Expr::Def(def) => {
|
Expr::Def(def) => {
|
||||||
|
|
@ -32,12 +48,13 @@ pub fn gen_decl_er(hir: HIR) -> DeclFile {
|
||||||
}
|
}
|
||||||
code.push('\n');
|
code.push('\n');
|
||||||
}
|
}
|
||||||
|
log!("code:\n{code}");
|
||||||
let filename = hir.name.replace(".py", ".d.er");
|
let filename = hir.name.replace(".py", ".d.er");
|
||||||
DeclFile { filename, code }
|
DeclFile { filename, code }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dump_decl_er(input: Input, hir: HIR) {
|
pub fn dump_decl_er(input: Input, hir: HIR, status: CheckStatus) {
|
||||||
let file = gen_decl_er(hir);
|
let file = gen_decl_er(hir, status);
|
||||||
let mut path = if let Input::File(path) = input { path } else { PathBuf::new() };
|
let mut path = if let Input::File(path) = input { path } else { PathBuf::new() };
|
||||||
path.pop();
|
path.pop();
|
||||||
path.push("__pycache__");
|
path.push("__pycache__");
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use erg_common::traits::{Runnable, Stream};
|
use erg_common::traits::{Runnable, Stream};
|
||||||
|
use erg_common::style::{GREEN, BLUE, RED, YELLOW, RESET};
|
||||||
use erg_common::config::{ErgConfig};
|
use erg_common::config::{ErgConfig};
|
||||||
use erg_common::error::{MultiErrorDisplay, ErrorCore, ErrorKind};
|
use erg_common::error::{MultiErrorDisplay, ErrorCore, ErrorKind};
|
||||||
use erg_compiler::artifact::{BuildRunnable, CompleteArtifact, IncompleteArtifact, Buildable};
|
use erg_compiler::artifact::{BuildRunnable, CompleteArtifact, IncompleteArtifact, Buildable};
|
||||||
|
|
@ -6,7 +7,7 @@ use erg_compiler::context::Context;
|
||||||
use erg_compiler::erg_parser::ast::AST;
|
use erg_compiler::erg_parser::ast::AST;
|
||||||
use erg_compiler::error::{CompileErrors, CompileError};
|
use erg_compiler::error::{CompileErrors, CompileError};
|
||||||
use erg_compiler::lower::ASTLowerer;
|
use erg_compiler::lower::ASTLowerer;
|
||||||
use py2erg::ShadowingMode;
|
use py2erg::{CheckStatus, ShadowingMode};
|
||||||
use py2erg::dump_decl_er;
|
use py2erg::dump_decl_er;
|
||||||
use rustpython_parser::parser;
|
use rustpython_parser::parser;
|
||||||
|
|
||||||
|
|
@ -118,33 +119,39 @@ impl PythonAnalyzer {
|
||||||
pub fn run(&mut self) {
|
pub fn run(&mut self) {
|
||||||
let filename = self.cfg.input.filename();
|
let filename = self.cfg.input.filename();
|
||||||
let py_code = self.cfg.input.read();
|
let py_code = self.cfg.input.read();
|
||||||
println!("Start checking: {filename}");
|
println!("{BLUE}Start checking{RESET}: {filename}");
|
||||||
match self.analyze(py_code, "exec") {
|
match self.analyze(py_code, "exec") {
|
||||||
Ok(artifact) => {
|
Ok(artifact) => {
|
||||||
if !artifact.warns.is_empty() {
|
if !artifact.warns.is_empty() {
|
||||||
println!("Found warnings: {}", artifact.warns.len());
|
println!("{YELLOW}Found {} warnings{RESET}: {}", artifact.warns.len(), self.cfg.input.filename());
|
||||||
artifact.warns.fmt_all_stderr();
|
artifact.warns.fmt_all_stderr();
|
||||||
}
|
}
|
||||||
println!("All checks OK.");
|
println!("{GREEN}All checks OK{RESET}: {}", self.cfg.input.filename());
|
||||||
if self.cfg.output_dir.is_some() {
|
if self.cfg.output_dir.is_some() {
|
||||||
dump_decl_er(self.cfg.input.clone(), artifact.object);
|
dump_decl_er(self.cfg.input.clone(), artifact.object, CheckStatus::Succeed);
|
||||||
println!("A declaration file has been generated to __pycache__ directory.");
|
println!("A declaration file has been generated to __pycache__ directory.");
|
||||||
}
|
}
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
}
|
}
|
||||||
Err(artifact) => {
|
Err(artifact) => {
|
||||||
if !artifact.warns.is_empty() {
|
if !artifact.warns.is_empty() {
|
||||||
println!("Found warnings: {}", artifact.warns.len());
|
println!("{YELLOW}Found {} warnings{RESET}: {}", artifact.warns.len(), self.cfg.input.filename());
|
||||||
artifact.warns.fmt_all_stderr();
|
artifact.warns.fmt_all_stderr();
|
||||||
}
|
}
|
||||||
if artifact.errors.is_empty() {
|
let code = if artifact.errors.is_empty() {
|
||||||
println!("All checks OK.");
|
println!("{GREEN}All checks OK{RESET}: {}", self.cfg.input.filename());
|
||||||
std::process::exit(0);
|
0
|
||||||
} else {
|
} else {
|
||||||
println!("Found errors: {}", artifact.errors.len());
|
println!("{RED}Found {} errors{RESET}: {}", artifact.errors.len(), self.cfg.input.filename());
|
||||||
artifact.errors.fmt_all_stderr();
|
artifact.errors.fmt_all_stderr();
|
||||||
std::process::exit(1);
|
1
|
||||||
|
};
|
||||||
|
// Even if type checking fails, some APIs are still valid, so generate a file
|
||||||
|
if self.cfg.output_dir.is_some() {
|
||||||
|
dump_decl_er(self.cfg.input.clone(), artifact.object.unwrap(), CheckStatus::Failed);
|
||||||
|
println!("A declaration file has been generated to __pycache__ directory.");
|
||||||
}
|
}
|
||||||
|
std::process::exit(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue