mirror of https://github.com/mtshiba/pylyzer
Merge pull request #37 from youknowone/trial
upgrade rustpython-parser (not going to be finished)
This commit is contained in:
commit
58c1245b72
File diff suppressed because it is too large
Load Diff
10
Cargo.toml
10
Cargo.toml
|
|
@ -22,10 +22,11 @@ edition = "2021"
|
|||
repository = "https://github.com/mtshiba/pylyzer"
|
||||
|
||||
[workspace.dependencies]
|
||||
erg_common = { version = "0.6.14-nightly.4", features = ["py_compat", "els"] }
|
||||
erg_compiler = { version = "0.6.14-nightly.4", features = ["py_compat", "els"] }
|
||||
els = { version = "0.1.26-nightly.4", features = ["py_compat"] }
|
||||
rustpython-parser = "0.1.2"
|
||||
erg_common = { version = "0.6.15-nightly.0", features = ["py_compat", "els"] }
|
||||
erg_compiler = { version = "0.6.15-nightly.0", features = ["py_compat", "els"] }
|
||||
els = { version = "0.1.27-nightly.0", features = ["py_compat"] }
|
||||
rustpython-parser = { git = "https://github.com/RustPython/Parser", version = "0.2.0", features = ["all-nodes-with-ranges", "location"] }
|
||||
rustpython-ast = { git = "https://github.com/RustPython/Parser", version = "0.2.0", features = ["all-nodes-with-ranges", "location"] }
|
||||
# erg_compiler = { git = "https://github.com/erg-lang/erg", branch = "main", features = ["py_compat", "els"] }
|
||||
# erg_common = { git = "https://github.com/erg-lang/erg", branch = "main", features = ["py_compat", "els"] }
|
||||
# els = { git = "https://github.com/erg-lang/erg", branch = "main", features = ["py_compat"] }
|
||||
|
|
@ -45,6 +46,7 @@ erg_compiler = { workspace = true }
|
|||
erg_common = { workspace = true }
|
||||
els = { workspace = true }
|
||||
rustpython-parser = { workspace = true }
|
||||
rustpython-ast = { workspace = true }
|
||||
py2erg = { version = "0.0.31", path = "./crates/py2erg" }
|
||||
|
||||
[lib]
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ debug = ["erg_compiler/debug", "erg_common/debug"]
|
|||
|
||||
[dependencies]
|
||||
rustpython-parser = { workspace = true }
|
||||
rustpython-ast = { workspace = true }
|
||||
erg_common = { workspace = true }
|
||||
erg_compiler = { workspace = true }
|
||||
|
||||
|
|
|
|||
|
|
@ -1,131 +1,10 @@
|
|||
use erg_common::log;
|
||||
use rustpython_parser::ast::{
|
||||
BooleanOperator, Comparison, ExpressionType, Keyword, Number, StringGroup,
|
||||
};
|
||||
use rustpython_parser::ast::located::Expr;
|
||||
|
||||
pub fn number_to_string(num: &Number) -> String {
|
||||
match num {
|
||||
Number::Integer { value } => value.to_string(),
|
||||
Number::Float { value } => value.to_string(),
|
||||
Number::Complex { real, imag } => format!("{real}+{imag}j"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn keyword_length(keyword: &Keyword) -> usize {
|
||||
if let Some(name) = &keyword.name {
|
||||
name.len() + 1 + length(&keyword.value.node)
|
||||
} else {
|
||||
length(&keyword.value.node)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn string_length(string: &StringGroup) -> usize {
|
||||
match string {
|
||||
StringGroup::Constant { value } => value.len(),
|
||||
StringGroup::Joined { values } => values.iter().map(string_length).sum(),
|
||||
other => {
|
||||
log!(err "{other:?}");
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn comp_to_string(comp: &Comparison) -> String {
|
||||
match comp {
|
||||
Comparison::In => "in".to_string(),
|
||||
Comparison::NotIn => "not in".to_string(),
|
||||
Comparison::Is => "is".to_string(),
|
||||
Comparison::IsNot => "is not".to_string(),
|
||||
Comparison::Less => "<".to_string(),
|
||||
Comparison::Greater => ">".to_string(),
|
||||
Comparison::Equal => "==".to_string(),
|
||||
Comparison::NotEqual => "!=".to_string(),
|
||||
Comparison::LessOrEqual => "<=".to_string(),
|
||||
Comparison::GreaterOrEqual => ">=".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn length(expr: &ExpressionType) -> usize {
|
||||
pub fn accessor_name(expr: Expr) -> Option<String> {
|
||||
match expr {
|
||||
ExpressionType::Identifier { name } => name.len(),
|
||||
ExpressionType::Number { value } => number_to_string(value).len(),
|
||||
ExpressionType::String { value } => string_length(value),
|
||||
ExpressionType::Attribute { value, name } => length(&value.node) + name.len() + 1,
|
||||
ExpressionType::Subscript { a, b } => length(&a.node) + length(&b.node) + 2,
|
||||
ExpressionType::Tuple { elements }
|
||||
| ExpressionType::List { elements }
|
||||
| ExpressionType::Set { elements } => {
|
||||
if let (Some(first), Some(last)) = (elements.first(), elements.last()) {
|
||||
2 + last.location.column() - first.location.column()
|
||||
} else {
|
||||
2
|
||||
}
|
||||
}
|
||||
ExpressionType::Call {
|
||||
function,
|
||||
args,
|
||||
keywords,
|
||||
} => {
|
||||
let args_len = if let (Some(first), Some(last)) = (args.first(), args.last()) {
|
||||
last.location.column() - first.location.column()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
let kw_len = if let (Some(first), Some(last)) = (keywords.first(), keywords.last()) {
|
||||
last.value.location.column() - first.value.location.column()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
length(&function.node) + args_len + kw_len + 2 // ()
|
||||
}
|
||||
ExpressionType::Unop { op: _, a } => 1 + length(&a.node),
|
||||
ExpressionType::Binop { a, op: _, b } => length(&a.node) + 3 + length(&b.node),
|
||||
ExpressionType::BoolOp { op, values } => match op {
|
||||
BooleanOperator::And => values
|
||||
.iter()
|
||||
.map(|elem| length(&elem.node))
|
||||
.fold(0, |acc, x| acc + x + 3),
|
||||
BooleanOperator::Or => values
|
||||
.iter()
|
||||
.map(|elem| length(&elem.node))
|
||||
.fold(0, |acc, x| acc + x + 2),
|
||||
},
|
||||
ExpressionType::Compare { vals, ops } => vals
|
||||
.iter()
|
||||
.zip(ops.iter())
|
||||
.map(|(elem, op)| length(&elem.node) + comp_to_string(op).len())
|
||||
.fold(0, |acc, x| acc + x + 2),
|
||||
ExpressionType::IfExpression { test, body, orelse } => {
|
||||
// x if y else z
|
||||
length(&test.node) + 4 + length(&body.node) + 6 + length(&orelse.node)
|
||||
}
|
||||
ExpressionType::Lambda { args: _, body } => {
|
||||
// lambda x: y
|
||||
// TODO:
|
||||
7 + 1 + length(&body.node)
|
||||
}
|
||||
ExpressionType::Await { value } => 5 + length(&value.node),
|
||||
ExpressionType::Yield { value } => 5 + value.as_ref().map(|x| length(&x.node)).unwrap_or(0),
|
||||
ExpressionType::NamedExpression { left, right } => {
|
||||
// x := y
|
||||
length(&left.node) + 4 + length(&right.node)
|
||||
}
|
||||
ExpressionType::Starred { value } => 1 + length(&value.node),
|
||||
ExpressionType::False => 5,
|
||||
ExpressionType::True | ExpressionType::None => 4,
|
||||
ExpressionType::Ellipsis => 8,
|
||||
other => {
|
||||
log!(err "{other:?}");
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn accessor_name(expr: ExpressionType) -> Option<String> {
|
||||
match expr {
|
||||
ExpressionType::Identifier { name } => Some(name),
|
||||
ExpressionType::Attribute { value, name } => {
|
||||
accessor_name(value.node).map(|value| format!("{value}.{name}"))
|
||||
Expr::Name(name) => Some(name.id.to_string()),
|
||||
Expr::Attribute(attr) => {
|
||||
accessor_name(*attr.value).map(|value| format!("{value}.{}", attr.attr))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,272 +0,0 @@
|
|||
use rustpython_parser::ast::{
|
||||
BooleanOperator, Comparison, Comprehension, ComprehensionKind, ExpressionType, Keyword,
|
||||
Located, Number, Operator, Parameter, Parameters, StringGroup, UnaryOperator, Varargs,
|
||||
};
|
||||
|
||||
fn clone_number(num: &Number) -> Number {
|
||||
match num {
|
||||
Number::Integer { value } => Number::Integer {
|
||||
value: value.clone(),
|
||||
},
|
||||
Number::Float { value } => Number::Float { value: *value },
|
||||
Number::Complex { real, imag } => Number::Complex {
|
||||
real: *real,
|
||||
imag: *imag,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_string_group(group: &StringGroup) -> StringGroup {
|
||||
match group {
|
||||
StringGroup::Constant { value } => StringGroup::Constant {
|
||||
value: value.clone(),
|
||||
},
|
||||
StringGroup::FormattedValue {
|
||||
value,
|
||||
conversion,
|
||||
spec,
|
||||
} => StringGroup::FormattedValue {
|
||||
value: Box::new(clone_loc_expr(value)),
|
||||
conversion: *conversion,
|
||||
spec: spec.as_deref().map(|sp| Box::new(clone_string_group(sp))),
|
||||
},
|
||||
StringGroup::Joined { values } => StringGroup::Joined {
|
||||
values: values.iter().map(clone_string_group).collect::<Vec<_>>(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_unary_op(op: &UnaryOperator) -> UnaryOperator {
|
||||
match op {
|
||||
UnaryOperator::Not => UnaryOperator::Not,
|
||||
UnaryOperator::Inv => UnaryOperator::Inv,
|
||||
UnaryOperator::Pos => UnaryOperator::Pos,
|
||||
UnaryOperator::Neg => UnaryOperator::Neg,
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_bin_op(op: &Operator) -> Operator {
|
||||
match op {
|
||||
Operator::Add => Operator::Add,
|
||||
Operator::Sub => Operator::Sub,
|
||||
Operator::Mult => Operator::Mult,
|
||||
Operator::MatMult => Operator::MatMult,
|
||||
Operator::Div => Operator::Div,
|
||||
Operator::Mod => Operator::Mod,
|
||||
Operator::Pow => Operator::Pow,
|
||||
Operator::LShift => Operator::LShift,
|
||||
Operator::RShift => Operator::RShift,
|
||||
Operator::BitOr => Operator::BitOr,
|
||||
Operator::BitXor => Operator::BitXor,
|
||||
Operator::BitAnd => Operator::BitAnd,
|
||||
Operator::FloorDiv => Operator::FloorDiv,
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_comp_op(op: &Comparison) -> Comparison {
|
||||
match op {
|
||||
Comparison::Equal => Comparison::Equal,
|
||||
Comparison::NotEqual => Comparison::NotEqual,
|
||||
Comparison::Less => Comparison::Less,
|
||||
Comparison::LessOrEqual => Comparison::LessOrEqual,
|
||||
Comparison::Greater => Comparison::Greater,
|
||||
Comparison::GreaterOrEqual => Comparison::GreaterOrEqual,
|
||||
Comparison::Is => Comparison::Is,
|
||||
Comparison::IsNot => Comparison::IsNot,
|
||||
Comparison::In => Comparison::In,
|
||||
Comparison::NotIn => Comparison::NotIn,
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_bool_op(op: &BooleanOperator) -> BooleanOperator {
|
||||
match op {
|
||||
BooleanOperator::And => BooleanOperator::And,
|
||||
BooleanOperator::Or => BooleanOperator::Or,
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_param(param: &Parameter) -> Parameter {
|
||||
Parameter {
|
||||
location: param.location,
|
||||
arg: param.arg.clone(),
|
||||
annotation: param
|
||||
.annotation
|
||||
.as_deref()
|
||||
.map(|a| Box::new(clone_loc_expr(a))),
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_varargs(varargs: &Varargs) -> Varargs {
|
||||
match varargs {
|
||||
Varargs::None => Varargs::None,
|
||||
Varargs::Unnamed => Varargs::Unnamed,
|
||||
Varargs::Named(name) => Varargs::Named(clone_param(name)),
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_params(params: &Parameters) -> Parameters {
|
||||
Parameters {
|
||||
posonlyargs_count: params.posonlyargs_count,
|
||||
args: params.args.iter().map(clone_param).collect::<Vec<_>>(),
|
||||
vararg: clone_varargs(¶ms.vararg),
|
||||
kwonlyargs: params
|
||||
.kwonlyargs
|
||||
.iter()
|
||||
.map(clone_param)
|
||||
.collect::<Vec<_>>(),
|
||||
kw_defaults: params
|
||||
.kw_defaults
|
||||
.iter()
|
||||
.map(|def| def.as_ref().map(clone_loc_expr))
|
||||
.collect::<Vec<_>>(),
|
||||
kwarg: clone_varargs(¶ms.kwarg),
|
||||
defaults: params
|
||||
.defaults
|
||||
.iter()
|
||||
.map(clone_loc_expr)
|
||||
.collect::<Vec<_>>(),
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_kw(keyword: &Keyword) -> Keyword {
|
||||
Keyword {
|
||||
name: keyword.name.clone(),
|
||||
value: clone_loc_expr(&keyword.value),
|
||||
}
|
||||
}
|
||||
|
||||
fn clone_comprehension_kind(kind: &ComprehensionKind) -> ComprehensionKind {
|
||||
match kind {
|
||||
ComprehensionKind::Dict { key, value } => ComprehensionKind::Dict {
|
||||
key: clone_loc_expr(key),
|
||||
value: clone_loc_expr(value),
|
||||
},
|
||||
ComprehensionKind::List { element } => ComprehensionKind::List {
|
||||
element: clone_loc_expr(element),
|
||||
},
|
||||
ComprehensionKind::Set { element } => ComprehensionKind::Set {
|
||||
element: clone_loc_expr(element),
|
||||
},
|
||||
ComprehensionKind::GeneratorExpression { element } => {
|
||||
ComprehensionKind::GeneratorExpression {
|
||||
element: clone_loc_expr(element),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_loc_expr(expr: &Located<ExpressionType>) -> Located<ExpressionType> {
|
||||
Located {
|
||||
node: clone_expr(&expr.node),
|
||||
location: expr.location,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone_expr(expr: &ExpressionType) -> ExpressionType {
|
||||
match expr {
|
||||
ExpressionType::None => ExpressionType::None,
|
||||
ExpressionType::Ellipsis => ExpressionType::Ellipsis,
|
||||
ExpressionType::True => ExpressionType::True,
|
||||
ExpressionType::False => ExpressionType::False,
|
||||
ExpressionType::Identifier { name } => ExpressionType::Identifier { name: name.clone() },
|
||||
ExpressionType::Number { value } => ExpressionType::Number {
|
||||
value: clone_number(value),
|
||||
},
|
||||
ExpressionType::String { value } => ExpressionType::String {
|
||||
value: clone_string_group(value),
|
||||
},
|
||||
ExpressionType::Attribute { value, name } => ExpressionType::Attribute {
|
||||
value: Box::new(clone_loc_expr(value)),
|
||||
name: name.clone(),
|
||||
},
|
||||
ExpressionType::Subscript { a, b } => ExpressionType::Subscript {
|
||||
a: Box::new(clone_loc_expr(a)),
|
||||
b: Box::new(clone_loc_expr(b)),
|
||||
},
|
||||
ExpressionType::Slice { elements } => ExpressionType::Slice {
|
||||
elements: elements.iter().map(clone_loc_expr).collect::<Vec<_>>(),
|
||||
},
|
||||
ExpressionType::Bytes { value } => ExpressionType::Bytes {
|
||||
value: value.clone(),
|
||||
},
|
||||
ExpressionType::Call {
|
||||
function,
|
||||
args,
|
||||
keywords,
|
||||
} => ExpressionType::Call {
|
||||
function: Box::new(clone_loc_expr(function)),
|
||||
args: args.iter().map(clone_loc_expr).collect::<Vec<_>>(),
|
||||
keywords: keywords.iter().map(clone_kw).collect::<Vec<_>>(),
|
||||
},
|
||||
ExpressionType::Unop { op, a } => ExpressionType::Unop {
|
||||
op: clone_unary_op(op),
|
||||
a: Box::new(clone_loc_expr(a)),
|
||||
},
|
||||
ExpressionType::Binop { a, op, b } => ExpressionType::Binop {
|
||||
a: Box::new(clone_loc_expr(a)),
|
||||
op: clone_bin_op(op),
|
||||
b: Box::new(clone_loc_expr(b)),
|
||||
},
|
||||
ExpressionType::Compare { vals, ops } => ExpressionType::Compare {
|
||||
ops: ops.iter().map(clone_comp_op).collect::<Vec<_>>(),
|
||||
vals: vals.iter().map(clone_loc_expr).collect::<Vec<_>>(),
|
||||
},
|
||||
ExpressionType::BoolOp { op, values } => ExpressionType::BoolOp {
|
||||
op: clone_bool_op(op),
|
||||
values: values.iter().map(clone_loc_expr).collect::<Vec<_>>(),
|
||||
},
|
||||
ExpressionType::Lambda { args, body } => ExpressionType::Lambda {
|
||||
args: Box::new(clone_params(args)),
|
||||
body: Box::new(clone_loc_expr(body)),
|
||||
},
|
||||
ExpressionType::IfExpression { test, body, orelse } => ExpressionType::IfExpression {
|
||||
test: Box::new(clone_loc_expr(test)),
|
||||
body: Box::new(clone_loc_expr(body)),
|
||||
orelse: Box::new(clone_loc_expr(orelse)),
|
||||
},
|
||||
ExpressionType::Dict { elements } => ExpressionType::Dict {
|
||||
elements: elements
|
||||
.iter()
|
||||
.map(|(key, value)| (key.as_ref().map(clone_loc_expr), clone_loc_expr(value)))
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
ExpressionType::Set { elements } => ExpressionType::Set {
|
||||
elements: elements.iter().map(clone_loc_expr).collect::<Vec<_>>(),
|
||||
},
|
||||
ExpressionType::List { elements } => ExpressionType::List {
|
||||
elements: elements.iter().map(clone_loc_expr).collect::<Vec<_>>(),
|
||||
},
|
||||
ExpressionType::Tuple { elements } => ExpressionType::Tuple {
|
||||
elements: elements.iter().map(clone_loc_expr).collect::<Vec<_>>(),
|
||||
},
|
||||
ExpressionType::Yield { value } => ExpressionType::Yield {
|
||||
value: value.as_ref().map(|val| Box::new(clone_loc_expr(val))),
|
||||
},
|
||||
ExpressionType::YieldFrom { value } => ExpressionType::YieldFrom {
|
||||
value: Box::new(clone_loc_expr(value)),
|
||||
},
|
||||
ExpressionType::Await { value } => ExpressionType::Await {
|
||||
value: Box::new(clone_loc_expr(value)),
|
||||
},
|
||||
ExpressionType::NamedExpression { left, right } => ExpressionType::NamedExpression {
|
||||
left: Box::new(clone_loc_expr(left)),
|
||||
right: Box::new(clone_loc_expr(right)),
|
||||
},
|
||||
ExpressionType::Starred { value } => ExpressionType::Starred {
|
||||
value: Box::new(clone_loc_expr(value)),
|
||||
},
|
||||
ExpressionType::Comprehension { kind, generators } => ExpressionType::Comprehension {
|
||||
kind: Box::new(clone_comprehension_kind(kind)),
|
||||
generators: generators
|
||||
.iter()
|
||||
.map(|gen| Comprehension {
|
||||
location: gen.location,
|
||||
target: clone_loc_expr(&gen.target),
|
||||
iter: clone_loc_expr(&gen.iter),
|
||||
ifs: gen.ifs.iter().map(clone_loc_expr).collect::<Vec<_>>(),
|
||||
is_async: gen.is_async,
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
},
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
|||
use erg_common::config::Input;
|
||||
use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage};
|
||||
use erg_common::io::Input;
|
||||
use erg_common::switch_lang;
|
||||
use erg_compiler::error::CompileError;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::fs::File;
|
||||
use std::io::{BufWriter, Write};
|
||||
|
||||
use erg_common::config::Input;
|
||||
use erg_common::io::Input;
|
||||
use erg_common::log;
|
||||
use erg_compiler::context::register::{CheckStatus, PylyzerStatus};
|
||||
use erg_compiler::hir::{Expr, HIR};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
pub mod ast_util;
|
||||
mod clone;
|
||||
mod convert;
|
||||
mod error;
|
||||
mod gen_decl;
|
||||
|
|
|
|||
|
|
@ -8,32 +8,45 @@ use erg_compiler::artifact::{BuildRunnable, Buildable, CompleteArtifact, Incompl
|
|||
use erg_compiler::context::register::CheckStatus;
|
||||
use erg_compiler::context::ModuleContext;
|
||||
use erg_compiler::erg_parser::ast::{Module, AST};
|
||||
use erg_compiler::erg_parser::error::ParseErrors;
|
||||
use erg_compiler::erg_parser::error::{
|
||||
CompleteArtifact as ParseArtifact, IncompleteArtifact as IncompleteParseArtifact, ParseErrors,
|
||||
};
|
||||
use erg_compiler::erg_parser::parse::Parsable;
|
||||
use erg_compiler::error::{CompileError, CompileErrors};
|
||||
use erg_compiler::lower::ASTLowerer;
|
||||
use erg_compiler::module::SharedCompilerResource;
|
||||
use py2erg::{dump_decl_er, reserve_decl_er, ShadowingMode};
|
||||
use rustpython_parser::parser;
|
||||
use rustpython_ast::source_code::RandomLocator;
|
||||
use rustpython_ast::{Fold, ModModule};
|
||||
use rustpython_parser::{Parse, ParseErrorType};
|
||||
|
||||
use crate::handle_err;
|
||||
|
||||
pub struct SimplePythonParser {}
|
||||
|
||||
impl Parsable for SimplePythonParser {
|
||||
fn parse(code: String) -> Result<Module, ParseErrors> {
|
||||
let py_program = parser::parse_program(&code).map_err(|_err| ParseErrors::empty())?;
|
||||
fn parse(code: String) -> Result<ParseArtifact, IncompleteParseArtifact<Module, ParseErrors>> {
|
||||
let py_program = ModModule::parse(&code, "<stdin>").map_err(|_err| ParseErrors::empty())?;
|
||||
let mut locator = RandomLocator::new(&code);
|
||||
// let mut locator = LinearLocator::new(&code);
|
||||
let py_program = locator
|
||||
.fold(py_program)
|
||||
.map_err(|_err| ParseErrors::empty())?;
|
||||
let shadowing = if cfg!(feature = "debug") {
|
||||
ShadowingMode::Visible
|
||||
} else {
|
||||
ShadowingMode::Invisible
|
||||
};
|
||||
let converter = py2erg::ASTConverter::new(ErgConfig::default(), shadowing);
|
||||
let IncompleteArtifact{ object: Some(erg_module), errors, .. } = converter.convert_program(py_program) else { unreachable!() };
|
||||
let IncompleteArtifact{ object: Some(erg_module), errors, warns } = converter.convert_program(py_program) else { unreachable!() };
|
||||
if errors.is_empty() {
|
||||
Ok(erg_module)
|
||||
Ok(ParseArtifact::new(erg_module, warns.into()))
|
||||
} else {
|
||||
Err(ParseErrors::empty())
|
||||
Err(IncompleteParseArtifact::new(
|
||||
Some(erg_module),
|
||||
warns.into(),
|
||||
errors.into(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -109,17 +122,30 @@ impl PythonAnalyzer {
|
|||
mode: &str,
|
||||
) -> Result<CompleteArtifact, IncompleteArtifact> {
|
||||
let filename = self.cfg.input.filename();
|
||||
let py_program = parser::parse_program(&py_code).map_err(|err| {
|
||||
let py_program = ModModule::parse(&py_code, &filename).map_err(|err| {
|
||||
let mut locator = RandomLocator::new(&py_code);
|
||||
// let mut locator = LinearLocator::new(&py_code);
|
||||
let err = locator.locate_error::<_, ParseErrorType>(err);
|
||||
let msg = err.to_string();
|
||||
let loc = err.location.unwrap();
|
||||
let core = ErrorCore::new(
|
||||
vec![],
|
||||
err.to_string(),
|
||||
msg,
|
||||
0,
|
||||
ErrorKind::SyntaxError,
|
||||
erg_common::error::Location::Line(err.location.row() as u32),
|
||||
erg_common::error::Location::range(
|
||||
loc.row.get(),
|
||||
loc.column.to_zero_indexed(),
|
||||
loc.row.get(),
|
||||
loc.column.to_zero_indexed(),
|
||||
),
|
||||
);
|
||||
let err = CompileError::new(core, self.cfg.input.clone(), "".into());
|
||||
IncompleteArtifact::new(None, CompileErrors::from(err), CompileErrors::empty())
|
||||
})?;
|
||||
let mut locator = RandomLocator::new(&py_code);
|
||||
// let mut locator = LinearLocator::new(&py_code);
|
||||
let py_program = locator.fold(py_program).unwrap();
|
||||
let shadowing = if cfg!(feature = "debug") {
|
||||
ShadowingMode::Visible
|
||||
} else {
|
||||
|
|
@ -155,7 +181,7 @@ impl PythonAnalyzer {
|
|||
}
|
||||
|
||||
pub fn run(&mut self) {
|
||||
if self.cfg.output_dir.is_some() {
|
||||
if self.cfg.dist_dir.is_some() {
|
||||
reserve_decl_er(self.cfg.input.clone());
|
||||
}
|
||||
let py_code = self.cfg.input.read();
|
||||
|
|
@ -169,13 +195,13 @@ impl PythonAnalyzer {
|
|||
artifact.warns.len(),
|
||||
self.cfg.input.unescaped_filename()
|
||||
);
|
||||
artifact.warns.fmt_all_stderr();
|
||||
artifact.warns.write_all_stderr();
|
||||
}
|
||||
println!(
|
||||
"{GREEN}All checks OK{RESET}: {}",
|
||||
self.cfg.input.unescaped_filename()
|
||||
);
|
||||
if self.cfg.output_dir.is_some() {
|
||||
if self.cfg.dist_dir.is_some() {
|
||||
dump_decl_er(
|
||||
self.cfg.input.clone(),
|
||||
artifact.object,
|
||||
|
|
@ -192,7 +218,7 @@ impl PythonAnalyzer {
|
|||
artifact.warns.len(),
|
||||
self.cfg.input.unescaped_filename()
|
||||
);
|
||||
artifact.warns.fmt_all_stderr();
|
||||
artifact.warns.write_all_stderr();
|
||||
}
|
||||
let code = if artifact.errors.is_empty() {
|
||||
println!(
|
||||
|
|
@ -206,11 +232,11 @@ impl PythonAnalyzer {
|
|||
artifact.errors.len(),
|
||||
self.cfg.input.unescaped_filename()
|
||||
);
|
||||
artifact.errors.fmt_all_stderr();
|
||||
artifact.errors.write_all_stderr();
|
||||
1
|
||||
};
|
||||
// Even if type checking fails, some APIs are still valid, so generate a file
|
||||
if self.cfg.output_dir.is_some() {
|
||||
if self.cfg.dist_dir.is_some() {
|
||||
dump_decl_er(
|
||||
self.cfg.input.clone(),
|
||||
artifact.object.unwrap(),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ use std::env;
|
|||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
|
||||
use erg_common::config::{ErgConfig, ErgMode, Input};
|
||||
use erg_common::config::{ErgConfig, ErgMode};
|
||||
use erg_common::io::Input;
|
||||
use erg_common::switch_lang;
|
||||
|
||||
fn command_message() -> &'static str {
|
||||
|
|
@ -94,7 +95,7 @@ pub(crate) fn parse_args() -> ErgConfig {
|
|||
cfg.quiet_repl = true;
|
||||
}
|
||||
"--dump-decl" => {
|
||||
cfg.output_dir = Some("");
|
||||
cfg.dist_dir = Some("");
|
||||
}
|
||||
"--verbose" => {
|
||||
cfg.verbose = args
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use erg_common::config::{ErgConfig, Input};
|
||||
use erg_common::config::ErgConfig;
|
||||
use erg_common::io::Input;
|
||||
use erg_common::spawn::exec_new_thread;
|
||||
use erg_common::traits::Stream;
|
||||
use erg_compiler::artifact::{CompleteArtifact, IncompleteArtifact};
|
||||
|
|
|
|||
Loading…
Reference in New Issue