mirror of
https://github.com/mtshiba/pylyzer.git
synced 2025-07-07 17:45:00 +00:00
fix: misalignment of error display
This commit is contained in:
parent
8621139e64
commit
c1f37108a0
6 changed files with 108 additions and 80 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
|||
__pycache__/
|
||||
test*.py
|
||||
/site
|
||||
.venv
|
||||
|
|
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -145,23 +145,25 @@ checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
|||
|
||||
[[package]]
|
||||
name = "els"
|
||||
version = "0.1.58-nightly.4"
|
||||
version = "0.1.58-nightly.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82ca64c7e007a801f3c026026d4f7c65193ca2ccfab19018cf47b0946ed1de86"
|
||||
checksum = "73c6e882638db2b88b5a529d52c94c493b48a802bf418974ff2aadc9dea2383d"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"erg_compiler",
|
||||
"libc",
|
||||
"lsp-types",
|
||||
"molc",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"windows",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "erg_common"
|
||||
version = "0.6.46-nightly.4"
|
||||
version = "0.6.46-nightly.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c91d7308be743f27d0bcb6778d85d76bfad86fc54ae53ae5fab06b37bd54fd74"
|
||||
checksum = "168c67e9de97fa12ade0f27a8e4f0037efd0576285cbb13c19e8724129abac53"
|
||||
dependencies = [
|
||||
"backtrace-on-stack-overflow",
|
||||
"erg_proc_macros",
|
||||
|
@ -172,9 +174,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "erg_compiler"
|
||||
version = "0.6.46-nightly.4"
|
||||
version = "0.6.46-nightly.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2ca9d5eb0b29b60d7ac8d7d639add33a4b331b35e4739775f0bd0f1e94be764"
|
||||
checksum = "1c303d57ad8238b388bf90eb3660681668a8fb3c8b77fff2833b348b7a767617"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"erg_parser",
|
||||
|
@ -182,9 +184,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "erg_parser"
|
||||
version = "0.6.46-nightly.4"
|
||||
version = "0.6.46-nightly.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d0f70495239bd721afb1be7ba33c9146cbd7d4d578bd65fcb86e52561224e0"
|
||||
checksum = "f0f1c0508bb6aa189c7ded5f4a260537aa4d16a40018be64f3bd4f65d140b46b"
|
||||
dependencies = [
|
||||
"erg_common",
|
||||
"erg_proc_macros",
|
||||
|
@ -193,9 +195,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "erg_proc_macros"
|
||||
version = "0.6.46-nightly.4"
|
||||
version = "0.6.46-nightly.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61073a06b84b2e9c36b3645494102780936b560ba80f8c466cf2cdc374740f3e"
|
||||
checksum = "ef2f7b89cccd974d2ab3dc31b79417c2a6d53490c9c96dcc1ad9ed7513ef4bf7"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
|
|
|
@ -24,9 +24,9 @@ edition = "2021"
|
|||
repository = "https://github.com/mtshiba/pylyzer"
|
||||
|
||||
[workspace.dependencies]
|
||||
erg_common = { version = "0.6.46-nightly.4", features = ["py_compat", "els"] }
|
||||
erg_compiler = { version = "0.6.46-nightly.4", features = ["py_compat", "els"] }
|
||||
els = { version = "0.1.58-nightly.4", features = ["py_compat"] }
|
||||
erg_common = { version = "0.6.46-nightly.5", features = ["py_compat", "els"] }
|
||||
erg_compiler = { version = "0.6.46-nightly.5", features = ["py_compat", "els"] }
|
||||
els = { version = "0.1.58-nightly.5", features = ["py_compat"] }
|
||||
# rustpython-parser = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] }
|
||||
# rustpython-ast = { version = "0.3.0", features = ["all-nodes-with-ranges", "location"] }
|
||||
rustpython-parser = { git = "https://github.com/RustPython/Parser", version = "0.4.0", features = ["all-nodes-with-ranges", "location"] }
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::path::Path;
|
|||
|
||||
use erg_common::config::ErgConfig;
|
||||
use erg_common::dict::Dict as HashMap;
|
||||
use erg_common::error::Location as ErgLocation;
|
||||
use erg_common::fresh::FRESH_GEN;
|
||||
use erg_common::set::Set as HashSet;
|
||||
use erg_common::traits::{Locational, Stream};
|
||||
|
@ -140,6 +141,17 @@ fn escape_name(name: String) -> String {
|
|||
}
|
||||
}
|
||||
|
||||
fn quoted_symbol(sym: &str, lineno: u32, col_begin: u32) -> Token {
|
||||
let col_end = col_begin + sym.chars().count() as u32;
|
||||
Token {
|
||||
kind: TokenKind::StrLit,
|
||||
content: format!("\"{sym}\"").into(),
|
||||
lineno,
|
||||
col_begin,
|
||||
col_end,
|
||||
}
|
||||
}
|
||||
|
||||
fn op_to_token(op: Operator) -> Token {
|
||||
let (kind, cont) = match op {
|
||||
Operator::Add => (TokenKind::Plus, "+"),
|
||||
|
@ -164,7 +176,7 @@ pub fn pyloc_to_ergloc(range: PySourceRange) -> erg_common::error::Location {
|
|||
range.start.row.get(),
|
||||
range.start.column.to_zero_indexed(),
|
||||
range.end.unwrap().row.get(),
|
||||
range.end.unwrap().column.get(),
|
||||
range.end.unwrap().column.to_zero_indexed(),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -726,7 +738,7 @@ impl ASTConverter {
|
|||
loc.row.get(),
|
||||
loc.column.to_zero_indexed(),
|
||||
);
|
||||
Identifier::new(VisModifierSpec::Public(dot), name)
|
||||
Identifier::new(VisModifierSpec::Public(dot.loc()), name)
|
||||
}
|
||||
|
||||
// TODO: module member mangling
|
||||
|
@ -744,7 +756,7 @@ impl ASTConverter {
|
|||
loc.row.get(),
|
||||
loc.column.to_zero_indexed(),
|
||||
);
|
||||
Identifier::new(VisModifierSpec::Public(dot), name)
|
||||
Identifier::new(VisModifierSpec::Public(dot.loc()), name)
|
||||
}
|
||||
|
||||
// Duplicate param names will result in an error at the parser. So we don't need to check it here.
|
||||
|
@ -849,9 +861,10 @@ impl ASTConverter {
|
|||
|
||||
fn param_pattern_to_var(pat: ParamPattern) -> VarPattern {
|
||||
match pat {
|
||||
ParamPattern::VarName(name) => {
|
||||
VarPattern::Ident(Identifier::new(VisModifierSpec::Public(DOT), name))
|
||||
}
|
||||
ParamPattern::VarName(name) => VarPattern::Ident(Identifier::new(
|
||||
VisModifierSpec::Public(ErgLocation::Unknown),
|
||||
name,
|
||||
)),
|
||||
ParamPattern::Discard(token) => VarPattern::Discard(token),
|
||||
other => todo!("{other}"),
|
||||
}
|
||||
|
@ -887,7 +900,7 @@ impl ASTConverter {
|
|||
let tmp = FRESH_GEN.fresh_varname();
|
||||
let tmp_name = VarName::from_str_and_line(tmp, expr.location().row.get());
|
||||
let tmp_expr = Expr::Accessor(Accessor::Ident(Identifier::new(
|
||||
VisModifierSpec::Public(DOT),
|
||||
VisModifierSpec::Public(ErgLocation::Unknown),
|
||||
tmp_name.clone(),
|
||||
)));
|
||||
let mut block = vec![];
|
||||
|
@ -991,7 +1004,7 @@ impl ASTConverter {
|
|||
TokenKind::UBar,
|
||||
"_",
|
||||
loc.row.get(),
|
||||
loc.column.get() - 1,
|
||||
loc.column.to_zero_indexed(),
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -1365,8 +1378,8 @@ impl ASTConverter {
|
|||
.into_iter()
|
||||
.map(|elem| self.convert_type_spec(elem))
|
||||
.collect();
|
||||
let parens = Self::gen_enclosure_tokens(TokenKind::LParen, tuple.range);
|
||||
let tuple = TupleTypeSpec::new(Some(parens), tys);
|
||||
let (l, r) = Self::gen_enclosure_tokens(TokenKind::LParen, tuple.range);
|
||||
let tuple = TupleTypeSpec::new(Some((l.loc(), r.loc())), tys);
|
||||
TypeSpec::Tuple(tuple)
|
||||
}
|
||||
_ => Self::gen_dummy_type_spec(args.location()),
|
||||
|
@ -1527,14 +1540,18 @@ impl ASTConverter {
|
|||
}
|
||||
py_ast::Constant::Complex { real: _, imag: _ } => Expr::Dummy(Dummy::new(None, vec![])),
|
||||
py_ast::Constant::Str(value) => {
|
||||
let kind = if const_
|
||||
.range
|
||||
.end
|
||||
.is_some_and(|end| end.row != const_.range.start.row)
|
||||
{
|
||||
TokenKind::DocComment
|
||||
} else {
|
||||
TokenKind::StrLit
|
||||
};
|
||||
let value = format!("\"{value}\"");
|
||||
// column - 2 because of the quotes
|
||||
let token = Token::new(
|
||||
TokenKind::StrLit,
|
||||
value,
|
||||
loc.row.get(),
|
||||
loc.column.to_zero_indexed(),
|
||||
);
|
||||
let token = Token::new(kind, value, loc.row.get(), loc.column.to_zero_indexed());
|
||||
Expr::Literal(Literal::new(token))
|
||||
}
|
||||
py_ast::Constant::Bool(b) => {
|
||||
|
@ -1646,7 +1663,7 @@ impl ASTConverter {
|
|||
.and_then(|last| last.col_end())
|
||||
.unwrap_or(function.col_end().unwrap_or(0) + 1)
|
||||
},
|
||||
|loc| loc.row.get(),
|
||||
|loc| loc.column.to_zero_indexed().saturating_sub(1),
|
||||
);
|
||||
let paren = {
|
||||
let lp = Token::new(
|
||||
|
@ -1656,7 +1673,7 @@ impl ASTConverter {
|
|||
function.col_end().unwrap_or(0),
|
||||
);
|
||||
let rp = Token::new(TokenKind::RParen, ")", loc.row.get(), last_col);
|
||||
(lp, rp)
|
||||
(lp.loc(), rp.loc())
|
||||
};
|
||||
let args = Args::new(pos_args, var_args, kw_args, kw_var, Some(paren));
|
||||
function.call_expr(args)
|
||||
|
@ -1816,7 +1833,7 @@ impl ASTConverter {
|
|||
.into_iter()
|
||||
.map(|ex| PosArg::new(self.convert_expr(ex)))
|
||||
.collect::<Vec<_>>();
|
||||
let elems = Args::pos_only(elements, Some((l, r)));
|
||||
let elems = Args::pos_only(elements, Some((l.loc(), r.loc())));
|
||||
Expr::Tuple(Tuple::Normal(NormalTuple::new(elems)))
|
||||
}
|
||||
py_ast::Expr::Subscript(subs) => {
|
||||
|
@ -2021,7 +2038,7 @@ impl ASTConverter {
|
|||
*base_type = Some(Expr::Record(record));
|
||||
}
|
||||
let call_ident = Identifier::new(
|
||||
VisModifierSpec::Public(DOT),
|
||||
VisModifierSpec::Public(ErgLocation::Unknown),
|
||||
VarName::from_static("__call__"),
|
||||
);
|
||||
let class_ident = Identifier::public_with_line(
|
||||
|
@ -2046,8 +2063,10 @@ impl ASTConverter {
|
|||
params,
|
||||
Some(class_spec),
|
||||
));
|
||||
let unreachable_acc =
|
||||
Identifier::new(VisModifierSpec::Public(DOT), VarName::from_static("exit"));
|
||||
let unreachable_acc = Identifier::new(
|
||||
VisModifierSpec::Public(ErgLocation::Unknown),
|
||||
VarName::from_static("exit"),
|
||||
);
|
||||
let body = Expr::Accessor(Accessor::Ident(unreachable_acc)).call_expr(Args::empty());
|
||||
let body = DefBody::new(EQUAL, Block::new(vec![body]), DefId(0));
|
||||
let def = Def::new(sig, body);
|
||||
|
@ -2056,7 +2075,7 @@ impl ASTConverter {
|
|||
|
||||
fn gen_default_init(&self, line: usize) -> Def {
|
||||
let call_ident = Identifier::new(
|
||||
VisModifierSpec::Public(DOT),
|
||||
VisModifierSpec::Public(ErgLocation::Unknown),
|
||||
VarName::from_static("__call__"),
|
||||
);
|
||||
let params = Params::empty();
|
||||
|
@ -2071,8 +2090,10 @@ impl ASTConverter {
|
|||
params,
|
||||
Some(class_spec),
|
||||
));
|
||||
let unreachable_acc =
|
||||
Identifier::new(VisModifierSpec::Public(DOT), VarName::from_static("exit"));
|
||||
let unreachable_acc = Identifier::new(
|
||||
VisModifierSpec::Public(ErgLocation::Unknown),
|
||||
VarName::from_static("exit"),
|
||||
);
|
||||
let body = Expr::Accessor(Accessor::Ident(unreachable_acc)).call_expr(Args::empty());
|
||||
let body = DefBody::new(EQUAL, Block::new(vec![body]), DefId(0));
|
||||
Def::new(sig, body)
|
||||
|
@ -2172,7 +2193,7 @@ impl ASTConverter {
|
|||
DefId(self.block_id_counter),
|
||||
class,
|
||||
class_as_expr,
|
||||
VisModifierSpec::Public(DOT),
|
||||
VisModifierSpec::Public(ErgLocation::Unknown),
|
||||
attrs,
|
||||
);
|
||||
(base_type, vec![methods])
|
||||
|
@ -2556,7 +2577,10 @@ impl ASTConverter {
|
|||
let tmp = FRESH_GEN.fresh_varname();
|
||||
let tmp_name =
|
||||
VarName::from_str_and_line(tmp, tuple.location().row.get());
|
||||
let tmp_ident = Identifier::new(VisModifierSpec::Public(DOT), tmp_name);
|
||||
let tmp_ident = Identifier::new(
|
||||
VisModifierSpec::Public(ErgLocation::Unknown),
|
||||
tmp_name,
|
||||
);
|
||||
let tmp_expr = Expr::Accessor(Accessor::Ident(tmp_ident.clone()));
|
||||
let sig = Signature::Var(VarSignature::new(
|
||||
VarPattern::Ident(tmp_ident),
|
||||
|
@ -2792,29 +2816,28 @@ impl ASTConverter {
|
|||
assert_acc.call_expr(args)
|
||||
}
|
||||
py_ast::Stmt::Import(import) => {
|
||||
let loc = import.location();
|
||||
let import_loc = import.location();
|
||||
let mut imports = vec![];
|
||||
for name in import.names {
|
||||
let import_acc = Expr::Accessor(Accessor::Ident(
|
||||
self.convert_ident("__import__".to_string(), loc),
|
||||
self.convert_ident("__import__".to_string(), import_loc),
|
||||
));
|
||||
let cont = if name.asname.is_some() {
|
||||
format!("\"{}\"", name.name.replace('.', "/"))
|
||||
let sym = if name.asname.is_some() {
|
||||
name.name.replace('.', "/")
|
||||
} else {
|
||||
format!("\"{}\"", name.name.split('.').next().unwrap())
|
||||
name.name.split('.').next().unwrap().to_string()
|
||||
};
|
||||
let mod_name = Expr::Literal(Literal::new(Token::new(
|
||||
TokenKind::StrLit,
|
||||
cont,
|
||||
let mod_name = Expr::Literal(Literal::new(quoted_symbol(
|
||||
&sym,
|
||||
name.location().row.get(),
|
||||
name.location().column.get() - 1,
|
||||
name.location().column.to_zero_indexed(),
|
||||
)));
|
||||
let call = import_acc.call1(mod_name);
|
||||
let loc = name.location();
|
||||
let name_loc = name.location();
|
||||
let def = if let Some(alias) = name.asname {
|
||||
self.register_name_info(&alias, NameKind::Variable);
|
||||
let var = VarSignature::new(
|
||||
VarPattern::Ident(self.convert_ident(alias.to_string(), loc)),
|
||||
VarPattern::Ident(self.convert_ident(alias.to_string(), name_loc)),
|
||||
None,
|
||||
);
|
||||
Def::new(
|
||||
|
@ -2841,7 +2864,8 @@ impl ASTConverter {
|
|||
}
|
||||
// from module import foo, bar
|
||||
py_ast::Stmt::ImportFrom(import_from) => {
|
||||
let loc = import_from.location();
|
||||
let mut loc = import_from.location();
|
||||
loc.column = loc.column.saturating_add(5);
|
||||
self.convert_from_import(import_from.module, import_from.names, loc)
|
||||
}
|
||||
py_ast::Stmt::Try(try_) => {
|
||||
|
@ -2881,14 +2905,9 @@ impl ASTConverter {
|
|||
let import_acc = Expr::Accessor(Accessor::Ident(
|
||||
self.convert_ident("__import__".to_string(), location),
|
||||
));
|
||||
let cont = if module == "." {
|
||||
"\"__init__\"".to_string()
|
||||
} else {
|
||||
format!("\"{module}\"")
|
||||
};
|
||||
let mod_name = Expr::Literal(Literal::new(Token::new(
|
||||
TokenKind::StrLit,
|
||||
cont,
|
||||
let sym = if module == "." { "__init__" } else { &module };
|
||||
let mod_name = Expr::Literal(Literal::new(quoted_symbol(
|
||||
sym,
|
||||
location.row.get(),
|
||||
location.column.to_zero_indexed(),
|
||||
)));
|
||||
|
@ -2935,14 +2954,9 @@ impl ASTConverter {
|
|||
.map(|s| s.replace('.', "/"))
|
||||
.unwrap_or_else(|| ".".to_string());
|
||||
let module_path = Path::new(&module);
|
||||
let cont = if module == "." {
|
||||
"\"__init__\"".to_string()
|
||||
} else {
|
||||
format!("\"{module}\"")
|
||||
};
|
||||
let mod_name = Expr::Literal(Literal::new(Token::new(
|
||||
TokenKind::StrLit,
|
||||
cont,
|
||||
let sym = if module == "." { "__init__" } else { &module };
|
||||
let mod_name = Expr::Literal(Literal::new(quoted_symbol(
|
||||
sym,
|
||||
location.row.get(),
|
||||
location.column.to_zero_indexed(),
|
||||
)));
|
||||
|
@ -2952,6 +2966,10 @@ impl ASTConverter {
|
|||
if names.len() == 1 && names[0].name.as_str() == "*" {
|
||||
return self.convert_glob_import(location, module);
|
||||
}
|
||||
let names_range = PySourceRange {
|
||||
start: names[0].location(),
|
||||
end: names[names.len() - 1].end_location(),
|
||||
};
|
||||
for name in names {
|
||||
let name_path = self
|
||||
.cfg
|
||||
|
@ -2975,10 +2993,9 @@ impl ASTConverter {
|
|||
}
|
||||
let mod_name = path.file_name().unwrap();
|
||||
if name.name.as_str() == mod_name.to_string_lossy().trim_end_matches(".py") {
|
||||
let cont = format!("\"{module}/{}\"", name.name);
|
||||
let mod_name = Expr::Literal(Literal::new(Token::new(
|
||||
TokenKind::StrLit,
|
||||
cont,
|
||||
let sym = format!("{module}/{}", name.name);
|
||||
let mod_name = Expr::Literal(Literal::new(quoted_symbol(
|
||||
&sym,
|
||||
location.row.get(),
|
||||
location.column.to_zero_indexed(),
|
||||
)));
|
||||
|
@ -2998,7 +3015,8 @@ impl ASTConverter {
|
|||
}
|
||||
let no_import = imports.is_empty();
|
||||
let attrs = VarRecordAttrs::new(imports);
|
||||
let pat = VarRecordPattern::new(Token::DUMMY, attrs, Token::DUMMY);
|
||||
let braces = pyloc_to_ergloc(names_range);
|
||||
let pat = VarRecordPattern::new(braces, attrs);
|
||||
let var = VarSignature::new(VarPattern::Record(pat), None);
|
||||
let def = Expr::Def(Def::new(
|
||||
Signature::Var(var),
|
||||
|
|
|
@ -127,7 +127,7 @@ impl DeclFileGenerator {
|
|||
let decl = format!(".{class_name}: ClassType");
|
||||
self.code += &decl;
|
||||
self.code.push('\n');
|
||||
if let GenTypeObj::Subclass(class) = &def.obj {
|
||||
if let GenTypeObj::Subclass(class) = def.obj.as_ref() {
|
||||
let sup = class
|
||||
.sup
|
||||
.as_ref()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use erg_common::error::ErrorKind;
|
||||
use erg_common::log;
|
||||
use erg_common::style::remove_style;
|
||||
use erg_common::style::{remove_style, StyledStr};
|
||||
// use erg_common::style::{remove_style, StyledString, Color};
|
||||
use erg_compiler::context::ModuleContext;
|
||||
use erg_compiler::error::{CompileError, CompileErrors};
|
||||
|
@ -13,11 +13,18 @@ pub(crate) fn filter_errors(ctx: &ModuleContext, errors: CompileErrors) -> Compi
|
|||
}
|
||||
|
||||
fn handle_name_error(error: CompileError) -> Option<CompileError> {
|
||||
if error.core.main_message.contains("is already declared")
|
||||
|| error
|
||||
.core
|
||||
.main_message
|
||||
.contains("cannot be assigned more than once")
|
||||
let main = &error.core.main_message;
|
||||
if main.contains("is already declared")
|
||||
|| main.contains("cannot be assigned more than once")
|
||||
|| {
|
||||
main.contains(" is not defined") && {
|
||||
let name = StyledStr::destyle(main.trim_end_matches(" is not defined"));
|
||||
error
|
||||
.core
|
||||
.get_hint()
|
||||
.is_some_and(|hint| hint.contains(name))
|
||||
}
|
||||
}
|
||||
{
|
||||
None
|
||||
} else {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue