fix: import resolution

This commit is contained in:
Shunsuke Shibayama 2024-03-12 23:05:19 +09:00
parent 0274b458b4
commit 24141ea3f3
4 changed files with 153 additions and 45 deletions

View file

@ -26,7 +26,7 @@ use erg_common::spawn::spawn_new_thread;
use erg_common::str::Str;
use erg_common::traits::{ExitStatus, New, Runnable, Stream};
use erg_parser::ast::{Expr, InlineModule, VarName, AST};
use erg_parser::ast::{ClassAttr, Expr, InlineModule, Record, RecordAttrOrIdent, VarName, AST};
use erg_parser::build_ast::{ASTBuildable, ASTBuilder as DefaultASTBuilder};
use erg_parser::parse::SimpleParser;
@ -440,9 +440,31 @@ impl<ASTBuilder: ASTBuildable, HIRBuilder: Buildable>
fn check_import(&mut self, expr: &mut Expr, cfg: &ErgConfig) -> ResolveResult<()> {
let mut errs = vec![];
match expr {
Expr::Call(call) if call.additional_operation().is_some_and(|op| op.is_import()) => {
if let Err(err) = self.register(expr, cfg) {
errs.extend(err);
Expr::Call(call) => {
for pos in call.args.pos_args.iter_mut() {
if let Err(err) = self.check_import(&mut pos.expr, cfg) {
errs.extend(err);
}
}
if let Some(var) = call.args.var_args.as_mut() {
if let Err(err) = self.check_import(&mut var.expr, cfg) {
errs.extend(err);
}
}
for kw in call.args.kw_args.iter_mut() {
if let Err(err) = self.check_import(&mut kw.expr, cfg) {
errs.extend(err);
}
}
if let Some(kw_var) = call.args.kw_var_args.as_mut() {
if let Err(err) = self.check_import(&mut kw_var.expr, cfg) {
errs.extend(err);
}
}
if call.additional_operation().is_some_and(|op| op.is_import()) {
if let Err(err) = self.register(expr, cfg) {
errs.extend(err);
}
}
}
Expr::Def(def) => {
@ -452,6 +474,80 @@ impl<ASTBuilder: ASTBuildable, HIRBuilder: Buildable>
}
}
}
Expr::ClassDef(class_def) => {
for expr in class_def.def.body.block.iter_mut() {
if let Err(err) = self.check_import(expr, cfg) {
errs.extend(err);
}
}
for methods in class_def.methods_list.iter_mut() {
for attr in methods.attrs.iter_mut() {
if let ClassAttr::Def(def) = attr {
for chunk in def.body.block.iter_mut() {
if let Err(err) = self.check_import(chunk, cfg) {
errs.extend(err);
}
}
}
}
}
}
Expr::Methods(methods) => {
for attr in methods.attrs.iter_mut() {
if let ClassAttr::Def(def) = attr {
for chunk in def.body.block.iter_mut() {
if let Err(err) = self.check_import(chunk, cfg) {
errs.extend(err);
}
}
}
}
}
Expr::PatchDef(patch_def) => {
for expr in patch_def.def.body.block.iter_mut() {
if let Err(err) = self.check_import(expr, cfg) {
errs.extend(err);
}
}
for methods in patch_def.methods_list.iter_mut() {
for attr in methods.attrs.iter_mut() {
if let ClassAttr::Def(def) = attr {
for chunk in def.body.block.iter_mut() {
if let Err(err) = self.check_import(chunk, cfg) {
errs.extend(err);
}
}
}
}
}
}
Expr::Record(Record::Normal(rec)) => {
for attr in rec.attrs.iter_mut() {
for chunk in attr.body.block.iter_mut() {
if let Err(err) = self.check_import(chunk, cfg) {
errs.extend(err);
}
}
}
}
Expr::Record(Record::Mixed(rec)) => {
for attr in rec.attrs.iter_mut() {
if let RecordAttrOrIdent::Attr(def) = attr {
for chunk in def.body.block.iter_mut() {
if let Err(err) = self.check_import(chunk, cfg) {
errs.extend(err);
}
}
}
}
}
Expr::Lambda(lambda) => {
for chunk in lambda.body.iter_mut() {
if let Err(err) = self.check_import(chunk, cfg) {
errs.extend(err);
}
}
}
Expr::Dummy(chunks) => {
for chunk in chunks.iter_mut() {
if let Err(err) = self.check_import(chunk, cfg) {

View file

@ -912,20 +912,6 @@ impl Context {
Visibility::BUILTIN_PUBLIC,
None,
);
let T = type_q(TY_T);
let list_t = no_var_func(
vec![],
vec![kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())]))],
array_t(T, TyParam::erased(Nat)),
)
.quantify();
self.register_builtin_py_impl(
FUNC_LIST,
list_t,
Immutable,
Visibility::BUILTIN_PUBLIC,
None,
);
}
pub(super) fn init_builtin_operators(&mut self) {

View file

@ -323,10 +323,10 @@ impl KwArg {
#[pyclass]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct Args {
pos_args: Vec<PosArg>,
pub(crate) var_args: Option<Box<PosArg>>,
kw_args: Vec<KwArg>,
pub(crate) kw_var_args: Option<Box<PosArg>>,
pub pos_args: Vec<PosArg>,
pub var_args: Option<Box<PosArg>>,
pub kw_args: Vec<KwArg>,
pub kw_var_args: Option<Box<PosArg>>,
// these are for ELS
pub paren: Option<(Token, Token)>,
}

View file

@ -768,6 +768,32 @@ impl Desugarer {
}
}
fn desugar_pattern_of_methods(&mut self, methods: Methods) -> Methods {
let mut new_attrs = Vec::with_capacity(methods.attrs.len());
for attr in methods.attrs.into_iter() {
match attr {
ClassAttr::Def(def) => {
let mut new = vec![];
self.desugar_def_pattern(def, &mut new);
let Expr::Def(def) = new.remove(0) else {
todo!("{new:?}")
};
new_attrs.push(ClassAttr::Def(def));
}
_ => {
new_attrs.push(attr);
}
}
}
Methods::new(
methods.id,
methods.class,
*methods.class_as_expr,
methods.vis,
ClassAttrs::from(new_attrs),
)
}
// TODO: nested function pattern
/// `[i, j] = [1, 2]` -> `i = 1; j = 2`
/// `[i, j] = l` -> `i = l[0]; j = l[1]`
@ -784,30 +810,26 @@ impl Desugarer {
Expr::Def(def) => {
self.desugar_def_pattern(def, &mut new);
}
Expr::ClassDef(class_def) => {
// self.desugar_def_pattern(class_def.def, &mut new);
let methods = class_def
.methods_list
.into_iter()
.map(|methods| self.desugar_pattern_of_methods(methods))
.collect();
new.push(Expr::ClassDef(ClassDef::new(class_def.def, methods)));
}
Expr::PatchDef(patch_def) => {
// self.desugar_def_pattern(patch_def.def, &mut new);
let methods = patch_def
.methods_list
.into_iter()
.map(|methods| self.desugar_pattern_of_methods(methods))
.collect();
new.push(Expr::PatchDef(PatchDef::new(patch_def.def, methods)));
}
Expr::Methods(methods) => {
let mut new_attrs = Vec::with_capacity(methods.attrs.len());
for attr in methods.attrs.into_iter() {
match attr {
ClassAttr::Def(def) => {
let mut new = vec![];
self.desugar_def_pattern(def, &mut new);
let Expr::Def(def) = new.remove(0) else {
todo!("{new:?}")
};
new_attrs.push(ClassAttr::Def(def));
}
_ => {
new_attrs.push(attr);
}
}
}
let methods = Methods::new(
methods.id,
methods.class,
*methods.class_as_expr,
methods.vis,
ClassAttrs::from(new_attrs),
);
let methods = self.desugar_pattern_of_methods(methods);
new.push(Expr::Methods(methods));
}
Expr::Dummy(dummy) => {
@ -815,6 +837,10 @@ impl Desugarer {
let new_dummy = self.desugar_pattern(dummy.into_iter());
new.push(Expr::Dummy(Dummy::new(loc, new_dummy)));
}
Expr::Compound(compound) => {
let new_compound = self.desugar_pattern(compound.into_iter());
new.push(Expr::Compound(Compound::new(new_compound)));
}
other => {
new.push(self.rec_desugar_lambda_pattern(other));
}