mirror of https://github.com/mtshiba/pylyzer
Add `NameInfo::defined_block_id`
This commit is contained in:
parent
2590cd6ab4
commit
4c99de6125
|
|
@ -0,0 +1,20 @@
|
||||||
|
repos:
|
||||||
|
- repo: local
|
||||||
|
hooks:
|
||||||
|
- id: rustfmt
|
||||||
|
name: rustfmt
|
||||||
|
description: Check if all files follow the rustfmt style
|
||||||
|
entry: cargo fmt --all
|
||||||
|
language: system
|
||||||
|
pass_filenames: false
|
||||||
|
- id: cargo-test
|
||||||
|
name: Cargo test
|
||||||
|
entry: cargo test
|
||||||
|
language: system
|
||||||
|
pass_filenames: false
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.3.0
|
||||||
|
hooks:
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: check-merge-conflict
|
||||||
|
|
@ -206,7 +206,7 @@ checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "els"
|
name = "els"
|
||||||
version = "0.1.13-nightly.0"
|
version = "0.1.13-nightly.0"
|
||||||
source = "git+https://github.com/erg-lang/erg-language-server?branch=main#ba96e0d1e86f496600b659c4a3fd70ec215587f3"
|
source = "git+https://github.com/erg-lang/erg-language-server?branch=main#8cef57fb31a5c1505f23041b2720925650f18539"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"erg_common",
|
"erg_common",
|
||||||
"erg_compiler",
|
"erg_compiler",
|
||||||
|
|
@ -227,7 +227,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "erg_common"
|
name = "erg_common"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/erg-lang/erg?branch=main#16b50347d4e97b9b193e068a2d5fdba2340771ab"
|
source = "git+https://github.com/erg-lang/erg?branch=main#ee8492eb4205e4ea479d9b7c804a471b61797559"
|
||||||
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"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/erg-lang/erg?branch=main#16b50347d4e97b9b193e068a2d5fdba2340771ab"
|
source = "git+https://github.com/erg-lang/erg?branch=main#ee8492eb4205e4ea479d9b7c804a471b61797559"
|
||||||
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"
|
version = "0.6.0"
|
||||||
source = "git+https://github.com/erg-lang/erg?branch=main#16b50347d4e97b9b193e068a2d5fdba2340771ab"
|
source = "git+https://github.com/erg-lang/erg?branch=main#ee8492eb4205e4ea479d9b7c804a471b61797559"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"erg_common",
|
"erg_common",
|
||||||
"unicode-xid 0.2.4",
|
"unicode-xid 0.2.4",
|
||||||
|
|
@ -716,18 +716,18 @@ checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.151"
|
version = "1.0.152"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0"
|
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.151"
|
version = "1.0.152"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8"
|
checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
||||||
use erg_common::switch_lang;
|
|
||||||
use erg_common::config::Input;
|
use erg_common::config::Input;
|
||||||
use erg_common::error::{Location, ErrorCore, ErrorKind, SubMessage};
|
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
|
||||||
|
use erg_common::switch_lang;
|
||||||
use erg_compiler::error::CompileError;
|
use erg_compiler::error::CompileError;
|
||||||
|
|
||||||
pub(crate) fn reassign_func_error(
|
pub(crate) fn reassign_func_error(
|
||||||
|
|
@ -27,11 +27,7 @@ pub(crate) fn reassign_func_error(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn self_not_found_error(
|
pub(crate) fn self_not_found_error(input: Input, loc: Location, caused_by: String) -> CompileError {
|
||||||
input: Input,
|
|
||||||
loc: Location,
|
|
||||||
caused_by: String,
|
|
||||||
) -> CompileError {
|
|
||||||
CompileError::new(
|
CompileError::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(loc)],
|
vec![SubMessage::only_loc(loc)],
|
||||||
|
|
@ -50,11 +46,7 @@ pub(crate) fn self_not_found_error(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn init_var_error(
|
pub(crate) fn init_var_error(input: Input, loc: Location, caused_by: String) -> CompileError {
|
||||||
input: Input,
|
|
||||||
loc: Location,
|
|
||||||
caused_by: String,
|
|
||||||
) -> CompileError {
|
|
||||||
CompileError::new(
|
CompileError::new(
|
||||||
ErrorCore::new(
|
ErrorCore::new(
|
||||||
vec![SubMessage::only_loc(loc)],
|
vec![SubMessage::only_loc(loc)],
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
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_common::log;
|
||||||
|
use erg_compiler::hir::{Expr, HIR};
|
||||||
use erg_compiler::ty::HasType;
|
use erg_compiler::ty::HasType;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
|
@ -31,7 +31,11 @@ fn escape_type(typ: String) -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_decl_er(hir: HIR, status: CheckStatus) -> DeclFile {
|
pub fn gen_decl_er(hir: HIR, status: CheckStatus) -> DeclFile {
|
||||||
let mut code = if status.is_failed() { "# failed\n".to_string() } else { "# succeed\n".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) => {
|
||||||
|
|
@ -55,7 +59,11 @@ pub fn gen_decl_er(hir: HIR, status: CheckStatus) -> DeclFile {
|
||||||
|
|
||||||
pub fn dump_decl_er(input: Input, hir: HIR, status: CheckStatus) {
|
pub fn dump_decl_er(input: Input, hir: HIR, status: CheckStatus) {
|
||||||
let file = gen_decl_er(hir, status);
|
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__");
|
||||||
let pycache_dir = path.as_path();
|
let pycache_dir = path.as_path();
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
mod convert;
|
mod convert;
|
||||||
mod gen_decl;
|
|
||||||
mod error;
|
mod error;
|
||||||
|
mod gen_decl;
|
||||||
|
|
||||||
pub use convert::*;
|
pub use convert::*;
|
||||||
pub use gen_decl::*;
|
pub use gen_decl::*;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
|
use erg_common::config::ErgConfig;
|
||||||
|
use erg_common::error::{ErrorCore, ErrorKind, MultiErrorDisplay};
|
||||||
|
use erg_common::style::{BLUE, GREEN, RED, RESET, YELLOW};
|
||||||
use erg_common::traits::{Runnable, Stream};
|
use erg_common::traits::{Runnable, Stream};
|
||||||
use erg_common::style::{GREEN, BLUE, RED, YELLOW, RESET};
|
use erg_compiler::artifact::{BuildRunnable, Buildable, CompleteArtifact, IncompleteArtifact};
|
||||||
use erg_common::config::{ErgConfig};
|
|
||||||
use erg_common::error::{MultiErrorDisplay, ErrorCore, ErrorKind};
|
|
||||||
use erg_compiler::artifact::{BuildRunnable, CompleteArtifact, IncompleteArtifact, Buildable};
|
|
||||||
use erg_compiler::context::Context;
|
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::{CompileError, CompileErrors};
|
||||||
use erg_compiler::lower::ASTLowerer;
|
use erg_compiler::lower::ASTLowerer;
|
||||||
use py2erg::{CheckStatus, ShadowingMode};
|
|
||||||
use py2erg::dump_decl_er;
|
use py2erg::dump_decl_er;
|
||||||
|
use py2erg::{CheckStatus, ShadowingMode};
|
||||||
use rustpython_parser::parser;
|
use rustpython_parser::parser;
|
||||||
|
|
||||||
use crate::handle_err;
|
use crate::handle_err;
|
||||||
|
|
@ -22,13 +22,10 @@ pub struct PythonAnalyzer {
|
||||||
impl Runnable for PythonAnalyzer {
|
impl Runnable for PythonAnalyzer {
|
||||||
type Err = CompileError;
|
type Err = CompileError;
|
||||||
type Errs = CompileErrors;
|
type Errs = CompileErrors;
|
||||||
const NAME: &'static str = "Python Analyzer";
|
const NAME: &'static str = "Python Analyzer";
|
||||||
fn new(cfg: ErgConfig) -> Self {
|
fn new(cfg: ErgConfig) -> Self {
|
||||||
let checker = ASTLowerer::new(cfg.clone());
|
let checker = ASTLowerer::new(cfg.clone());
|
||||||
Self {
|
Self { checker, cfg }
|
||||||
checker,
|
|
||||||
cfg,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cfg(&self) -> &ErgConfig {
|
fn cfg(&self) -> &ErgConfig {
|
||||||
|
|
@ -74,7 +71,11 @@ impl PythonAnalyzer {
|
||||||
Runnable::new(cfg)
|
Runnable::new(cfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn analyze(&mut self, py_code: String, mode: &str) -> Result<CompleteArtifact, IncompleteArtifact> {
|
pub fn analyze(
|
||||||
|
&mut self,
|
||||||
|
py_code: String,
|
||||||
|
mode: &str,
|
||||||
|
) -> Result<CompleteArtifact, IncompleteArtifact> {
|
||||||
let filename = self.cfg.input.filename();
|
let filename = self.cfg.input.filename();
|
||||||
let py_program = parser::parse_program(&py_code).map_err(|err| {
|
let py_program = parser::parse_program(&py_code).map_err(|err| {
|
||||||
let core = ErrorCore::new(
|
let core = ErrorCore::new(
|
||||||
|
|
@ -82,9 +83,9 @@ impl PythonAnalyzer {
|
||||||
err.to_string(),
|
err.to_string(),
|
||||||
0,
|
0,
|
||||||
ErrorKind::SyntaxError,
|
ErrorKind::SyntaxError,
|
||||||
erg_common::error::Location::Line(err.location.row())
|
erg_common::error::Location::Line(err.location.row()),
|
||||||
);
|
);
|
||||||
let err = CompileError::new(core, self.cfg.input.clone(), "".into());
|
let err = CompileError::new(core, self.cfg.input.clone(), "".into());
|
||||||
IncompleteArtifact::new(None, CompileErrors::from(err), CompileErrors::empty())
|
IncompleteArtifact::new(None, CompileErrors::from(err), CompileErrors::empty())
|
||||||
})?;
|
})?;
|
||||||
let shadowing = if cfg!(feature = "debug") {
|
let shadowing = if cfg!(feature = "debug") {
|
||||||
|
|
@ -99,11 +100,16 @@ impl PythonAnalyzer {
|
||||||
match self.checker.lower(erg_ast, mode) {
|
match self.checker.lower(erg_ast, mode) {
|
||||||
Ok(mut artifact) => {
|
Ok(mut artifact) => {
|
||||||
artifact.warns.extend(warns);
|
artifact.warns.extend(warns);
|
||||||
artifact.warns = handle_err::filter_errors(self.checker.get_mod_ctx(), artifact.warns);
|
artifact.warns =
|
||||||
|
handle_err::filter_errors(self.checker.get_mod_ctx(), artifact.warns);
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
Ok(artifact)
|
Ok(artifact)
|
||||||
} else {
|
} else {
|
||||||
Err(IncompleteArtifact::new(Some(artifact.object), errors, artifact.warns))
|
Err(IncompleteArtifact::new(
|
||||||
|
Some(artifact.object),
|
||||||
|
errors,
|
||||||
|
artifact.warns,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(iart) => {
|
Err(iart) => {
|
||||||
|
|
@ -123,32 +129,52 @@ impl PythonAnalyzer {
|
||||||
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!("{YELLOW}Found {} warnings{RESET}: {}", artifact.warns.len(), self.cfg.input.filename());
|
println!(
|
||||||
|
"{YELLOW}Found {} warnings{RESET}: {}",
|
||||||
|
artifact.warns.len(),
|
||||||
|
self.cfg.input.filename()
|
||||||
|
);
|
||||||
artifact.warns.fmt_all_stderr();
|
artifact.warns.fmt_all_stderr();
|
||||||
}
|
}
|
||||||
println!("{GREEN}All checks OK{RESET}: {}", self.cfg.input.filename());
|
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, CheckStatus::Succeed);
|
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!("{YELLOW}Found {} warnings{RESET}: {}", artifact.warns.len(), self.cfg.input.filename());
|
println!(
|
||||||
|
"{YELLOW}Found {} warnings{RESET}: {}",
|
||||||
|
artifact.warns.len(),
|
||||||
|
self.cfg.input.filename()
|
||||||
|
);
|
||||||
artifact.warns.fmt_all_stderr();
|
artifact.warns.fmt_all_stderr();
|
||||||
}
|
}
|
||||||
let code = if artifact.errors.is_empty() {
|
let code = if artifact.errors.is_empty() {
|
||||||
println!("{GREEN}All checks OK{RESET}: {}", self.cfg.input.filename());
|
println!("{GREEN}All checks OK{RESET}: {}", self.cfg.input.filename());
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
println!("{RED}Found {} errors{RESET}: {}", artifact.errors.len(), self.cfg.input.filename());
|
println!(
|
||||||
|
"{RED}Found {} errors{RESET}: {}",
|
||||||
|
artifact.errors.len(),
|
||||||
|
self.cfg.input.filename()
|
||||||
|
);
|
||||||
artifact.errors.fmt_all_stderr();
|
artifact.errors.fmt_all_stderr();
|
||||||
1
|
1
|
||||||
};
|
};
|
||||||
// Even if type checking fails, some APIs are still valid, so generate a file
|
// Even if type checking fails, some APIs are still valid, so generate a file
|
||||||
if self.cfg.output_dir.is_some() {
|
if self.cfg.output_dir.is_some() {
|
||||||
dump_decl_er(self.cfg.input.clone(), artifact.object.unwrap(), CheckStatus::Failed);
|
dump_decl_er(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
artifact.object.unwrap(),
|
||||||
|
CheckStatus::Failed,
|
||||||
|
);
|
||||||
println!("A declaration file has been generated to __pycache__ directory.");
|
println!("A declaration file has been generated to __pycache__ directory.");
|
||||||
}
|
}
|
||||||
std::process::exit(code);
|
std::process::exit(code);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
use erg_common::error::ErrorKind;
|
use erg_common::error::ErrorKind;
|
||||||
use erg_common::log;
|
use erg_common::log;
|
||||||
// use erg_common::style::{remove_style, StyledString, Color};
|
// use erg_common::style::{remove_style, StyledString, Color};
|
||||||
use erg_compiler::error::{CompileErrors, CompileError};
|
|
||||||
use erg_compiler::context::Context;
|
use erg_compiler::context::Context;
|
||||||
|
use erg_compiler::error::{CompileError, CompileErrors};
|
||||||
|
|
||||||
pub(crate) fn filter_errors(ctx: &Context, errors: CompileErrors) -> CompileErrors {
|
pub(crate) fn filter_errors(ctx: &Context, errors: CompileErrors) -> CompileErrors {
|
||||||
errors.into_iter().filter_map(|error| filter_error(ctx, error)).collect()
|
errors
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|error| filter_error(ctx, error))
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_error(_ctx: &Context, error: CompileError) -> Option<CompileError> {
|
fn filter_error(_ctx: &Context, error: CompileError) -> Option<CompileError> {
|
||||||
|
|
@ -18,7 +21,10 @@ fn filter_error(_ctx: &Context, error: CompileError) -> Option<CompileError> {
|
||||||
ErrorKind::VisibilityError => None,
|
ErrorKind::VisibilityError => None,
|
||||||
// exclude doc strings
|
// exclude doc strings
|
||||||
ErrorKind::UnusedWarning => {
|
ErrorKind::UnusedWarning => {
|
||||||
let code = error.input.reread_lines(error.core.loc.ln_begin().unwrap(), error.core.loc.ln_end().unwrap());
|
let code = error.input.reread_lines(
|
||||||
|
error.core.loc.ln_begin().unwrap(),
|
||||||
|
error.core.loc.ln_end().unwrap(),
|
||||||
|
);
|
||||||
if code[0].trim().starts_with("\"\"\"") {
|
if code[0].trim().starts_with("\"\"\"") {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
mod handle_err;
|
|
||||||
mod analyze;
|
mod analyze;
|
||||||
|
mod handle_err;
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
@ -7,13 +7,16 @@ use std::str::FromStr;
|
||||||
|
|
||||||
use analyze::PythonAnalyzer;
|
use analyze::PythonAnalyzer;
|
||||||
use els::Server;
|
use els::Server;
|
||||||
use erg_common::config::{Input, ErgConfig};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_common::spawn::exec_new_thread;
|
use erg_common::spawn::exec_new_thread;
|
||||||
|
|
||||||
pub fn parse_args() -> ErgConfig {
|
pub fn parse_args() -> ErgConfig {
|
||||||
let mut args = env::args();
|
let mut args = env::args();
|
||||||
args.next(); // "pylyzer"
|
args.next(); // "pylyzer"
|
||||||
let mut cfg = ErgConfig{ python_compatible_mode: true, ..ErgConfig::default() };
|
let mut cfg = ErgConfig {
|
||||||
|
python_compatible_mode: true,
|
||||||
|
..ErgConfig::default()
|
||||||
|
};
|
||||||
while let Some(arg) = args.next() {
|
while let Some(arg) = args.next() {
|
||||||
match &arg[..] {
|
match &arg[..] {
|
||||||
"--" => {
|
"--" => {
|
||||||
|
|
|
||||||
|
|
@ -15,8 +15,14 @@ for i in [1, 2, 3]:
|
||||||
j = i + "aa"
|
j = i + "aa"
|
||||||
print(j)
|
print(j)
|
||||||
|
|
||||||
|
i: int # OK
|
||||||
|
i = 1
|
||||||
|
i: str # ERR
|
||||||
|
i = "aa" if True else "bb"
|
||||||
|
i: str # OK
|
||||||
|
|
||||||
while "aaa": # ERR
|
while "aaa": # ERR
|
||||||
print("invalid")
|
i += 1 # ERR
|
||||||
break
|
break
|
||||||
|
|
||||||
class C:
|
class C:
|
||||||
|
|
@ -27,9 +33,3 @@ print(dic["c"]) # ERR
|
||||||
|
|
||||||
a = [1, 2, 3]
|
a = [1, 2, 3]
|
||||||
print(a[4]) # ERR
|
print(a[4]) # ERR
|
||||||
|
|
||||||
i: int # OK
|
|
||||||
i = 1
|
|
||||||
i: str # ERR
|
|
||||||
i = "aa" if True else "bb"
|
|
||||||
i: str # OK
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use erg_common::traits::Stream;
|
|
||||||
use erg_common::config::{ErgConfig, Input};
|
use erg_common::config::{ErgConfig, Input};
|
||||||
use erg_compiler::artifact::{IncompleteArtifact, CompleteArtifact};
|
use erg_common::traits::Stream;
|
||||||
|
use erg_compiler::artifact::{CompleteArtifact, IncompleteArtifact};
|
||||||
use pylyzer::PythonAnalyzer;
|
use pylyzer::PythonAnalyzer;
|
||||||
|
|
||||||
pub fn exec_analyzer(file_path: &'static str) -> Result<CompleteArtifact, IncompleteArtifact> {
|
pub fn exec_analyzer(file_path: &'static str) -> Result<CompleteArtifact, IncompleteArtifact> {
|
||||||
let cfg = ErgConfig { python_compatible_mode: true, input: Input::File(PathBuf::from(file_path)), ..Default::default() };
|
let cfg = ErgConfig {
|
||||||
|
python_compatible_mode: true,
|
||||||
|
input: Input::File(PathBuf::from(file_path)),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
let mut analyzer = PythonAnalyzer::new(cfg);
|
let mut analyzer = PythonAnalyzer::new(cfg);
|
||||||
let py_code = analyzer.cfg.input.read();
|
let py_code = analyzer.cfg.input.read();
|
||||||
analyzer.analyze(py_code, "exec")
|
analyzer.analyze(py_code, "exec")
|
||||||
|
|
@ -27,7 +31,7 @@ pub fn expect(file_path: &'static str, warns: usize, errors: usize) {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exec_test() {
|
fn exec_test() {
|
||||||
expect("tests/test.py", 0, 9);
|
expect("tests/test.py", 0, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue