mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 04:09:05 +00:00
chore: add hir::Methods
This commit is contained in:
parent
234fa3ffeb
commit
21c937e633
14 changed files with 109 additions and 64 deletions
|
@ -186,7 +186,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
) -> Option<Vec<Str>> {
|
) -> Option<Vec<Str>> {
|
||||||
let ns = class_def.sig.ident().to_string_notype();
|
let ns = class_def.sig.ident().to_string_notype();
|
||||||
cur_ns.push(Str::from(ns));
|
cur_ns.push(Str::from(ns));
|
||||||
self.get_exprs_ns(cur_ns, class_def.methods.iter(), pos)
|
self.get_exprs_ns(cur_ns, class_def.all_methods(), pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_patch_def_ns(
|
fn get_patch_def_ns(
|
||||||
|
@ -282,7 +282,9 @@ impl<'a> HIRVisitor<'a> {
|
||||||
Expr::Tuple(tuple) => self.get_expr_from_tuple(expr, tuple, pos),
|
Expr::Tuple(tuple) => self.get_expr_from_tuple(expr, tuple, pos),
|
||||||
Expr::TypeAsc(type_asc) => self.get_expr(&type_asc.expr, pos),
|
Expr::TypeAsc(type_asc) => self.get_expr(&type_asc.expr, pos),
|
||||||
Expr::Dummy(dummy) => self.get_expr_from_dummy(dummy, pos),
|
Expr::Dummy(dummy) => self.get_expr_from_dummy(dummy, pos),
|
||||||
Expr::Compound(block) | Expr::Code(block) => self.get_expr_from_block(block, pos),
|
Expr::Compound(block) | Expr::Code(block) => {
|
||||||
|
self.get_expr_from_block(block.iter(), pos)
|
||||||
|
}
|
||||||
Expr::ReDef(redef) => self.get_expr_from_redef(expr, redef, pos),
|
Expr::ReDef(redef) => self.get_expr_from_redef(expr, redef, pos),
|
||||||
Expr::Import(_) => None,
|
Expr::Import(_) => None,
|
||||||
}
|
}
|
||||||
|
@ -362,7 +364,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> Option<&Expr> {
|
) -> Option<&Expr> {
|
||||||
self.return_expr_if_same(expr, def.sig.ident().raw.name.token(), pos)
|
self.return_expr_if_same(expr, def.sig.ident().raw.name.token(), pos)
|
||||||
.or_else(|| self.get_expr_from_block(&def.body.block, pos))
|
.or_else(|| self.get_expr_from_block(def.body.block.iter(), pos))
|
||||||
.or_else(|| self.return_expr_if_contains(expr, pos, def))
|
.or_else(|| self.return_expr_if_contains(expr, pos, def))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,12 +378,16 @@ impl<'a> HIRVisitor<'a> {
|
||||||
.require_or_sup
|
.require_or_sup
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|req_sup| self.get_expr(req_sup, pos))
|
.and_then(|req_sup| self.get_expr(req_sup, pos))
|
||||||
.or_else(|| self.get_expr_from_block(&class_def.methods, pos))
|
.or_else(|| self.get_expr_from_block(class_def.all_methods(), pos))
|
||||||
.or_else(|| self.return_expr_if_contains(expr, pos, class_def))
|
.or_else(|| self.return_expr_if_contains(expr, pos, class_def))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_expr_from_block<'e>(&'e self, block: &'e Block, pos: Position) -> Option<&Expr> {
|
fn get_expr_from_block<'e>(
|
||||||
for chunk in block.iter() {
|
&'e self,
|
||||||
|
block: impl Iterator<Item = &'e Expr>,
|
||||||
|
pos: Position,
|
||||||
|
) -> Option<&Expr> {
|
||||||
|
for chunk in block {
|
||||||
if let Some(expr) = self.get_expr(chunk, pos) {
|
if let Some(expr) = self.get_expr(chunk, pos) {
|
||||||
return Some(expr);
|
return Some(expr);
|
||||||
}
|
}
|
||||||
|
@ -396,7 +402,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
pos: Position,
|
pos: Position,
|
||||||
) -> Option<&Expr> {
|
) -> Option<&Expr> {
|
||||||
self.get_expr_from_acc(expr, &redef.attr, pos)
|
self.get_expr_from_acc(expr, &redef.attr, pos)
|
||||||
.or_else(|| self.get_expr_from_block(&redef.block, pos))
|
.or_else(|| self.get_expr_from_block(redef.block.iter(), pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_expr_from_dummy<'e>(&'e self, dummy: &'e Dummy, pos: Position) -> Option<&Expr> {
|
fn get_expr_from_dummy<'e>(&'e self, dummy: &'e Dummy, pos: Position) -> Option<&Expr> {
|
||||||
|
@ -416,7 +422,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
) -> Option<&Expr> {
|
) -> Option<&Expr> {
|
||||||
self.return_expr_if_same(expr, patch_def.sig.name().token(), pos)
|
self.return_expr_if_same(expr, patch_def.sig.name().token(), pos)
|
||||||
.or_else(|| self.get_expr(&patch_def.base, pos))
|
.or_else(|| self.get_expr(&patch_def.base, pos))
|
||||||
.or_else(|| self.get_expr_from_block(&patch_def.methods, pos))
|
.or_else(|| self.get_expr_from_block(patch_def.methods.iter(), pos))
|
||||||
.or_else(|| self.return_expr_if_contains(expr, pos, patch_def))
|
.or_else(|| self.return_expr_if_contains(expr, pos, patch_def))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +437,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
{
|
{
|
||||||
return Some(expr);
|
return Some(expr);
|
||||||
}
|
}
|
||||||
self.get_expr_from_block(&lambda.body, pos)
|
self.get_expr_from_block(lambda.body.iter(), pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_expr_from_array<'e>(
|
fn get_expr_from_array<'e>(
|
||||||
|
@ -487,7 +493,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
return Some(expr);
|
return Some(expr);
|
||||||
}
|
}
|
||||||
for field in record.attrs.iter() {
|
for field in record.attrs.iter() {
|
||||||
if let Some(expr) = self.get_expr_from_block(&field.body.block, pos) {
|
if let Some(expr) = self.get_expr_from_block(field.body.block.iter(), pos) {
|
||||||
return Some(expr);
|
return Some(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,7 +583,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
Expr::Tuple(tuple) => self.get_tuple_info(tuple, token),
|
Expr::Tuple(tuple) => self.get_tuple_info(tuple, token),
|
||||||
Expr::TypeAsc(type_asc) => self.get_tasc_info(type_asc, token),
|
Expr::TypeAsc(type_asc) => self.get_tasc_info(type_asc, token),
|
||||||
Expr::Dummy(dummy) => self.get_dummy_info(dummy, token),
|
Expr::Dummy(dummy) => self.get_dummy_info(dummy, token),
|
||||||
Expr::Compound(block) | Expr::Code(block) => self.get_block_info(block, token),
|
Expr::Compound(block) | Expr::Code(block) => self.get_block_info(block.iter(), token),
|
||||||
Expr::ReDef(redef) => self.get_redef_info(redef, token),
|
Expr::ReDef(redef) => self.get_redef_info(redef, token),
|
||||||
Expr::Import(_) => None,
|
Expr::Import(_) => None,
|
||||||
}
|
}
|
||||||
|
@ -690,7 +696,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
|
|
||||||
fn get_def_info(&self, def: &Def, token: &Token) -> Option<VarInfo> {
|
fn get_def_info(&self, def: &Def, token: &Token) -> Option<VarInfo> {
|
||||||
self.get_sig_info(&def.sig, token)
|
self.get_sig_info(&def.sig, token)
|
||||||
.or_else(|| self.get_block_info(&def.body.block, token))
|
.or_else(|| self.get_block_info(def.body.block.iter(), token))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_class_def_info(&self, class_def: &ClassDef, token: &Token) -> Option<VarInfo> {
|
fn get_class_def_info(&self, class_def: &ClassDef, token: &Token) -> Option<VarInfo> {
|
||||||
|
@ -699,17 +705,21 @@ impl<'a> HIRVisitor<'a> {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|req_sup| self.get_expr_info(req_sup, token))
|
.and_then(|req_sup| self.get_expr_info(req_sup, token))
|
||||||
.or_else(|| self.get_sig_info(&class_def.sig, token))
|
.or_else(|| self.get_sig_info(&class_def.sig, token))
|
||||||
.or_else(|| self.get_block_info(&class_def.methods, token))
|
.or_else(|| self.get_block_info(class_def.all_methods(), token))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_patch_def_info(&self, patch_def: &PatchDef, token: &Token) -> Option<VarInfo> {
|
fn get_patch_def_info(&self, patch_def: &PatchDef, token: &Token) -> Option<VarInfo> {
|
||||||
self.get_expr_info(&patch_def.base, token)
|
self.get_expr_info(&patch_def.base, token)
|
||||||
.or_else(|| self.get_sig_info(&patch_def.sig, token))
|
.or_else(|| self.get_sig_info(&patch_def.sig, token))
|
||||||
.or_else(|| self.get_block_info(&patch_def.methods, token))
|
.or_else(|| self.get_block_info(patch_def.methods.iter(), token))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_block_info(&self, block: &Block, token: &Token) -> Option<VarInfo> {
|
fn get_block_info<'e>(
|
||||||
for chunk in block.iter() {
|
&self,
|
||||||
|
block: impl Iterator<Item = &'e Expr>,
|
||||||
|
token: &Token,
|
||||||
|
) -> Option<VarInfo> {
|
||||||
|
for chunk in block {
|
||||||
if let Some(expr) = self.get_expr_info(chunk, token) {
|
if let Some(expr) = self.get_expr_info(chunk, token) {
|
||||||
return Some(expr);
|
return Some(expr);
|
||||||
}
|
}
|
||||||
|
@ -719,7 +729,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
|
|
||||||
fn get_redef_info(&self, redef: &ReDef, token: &Token) -> Option<VarInfo> {
|
fn get_redef_info(&self, redef: &ReDef, token: &Token) -> Option<VarInfo> {
|
||||||
self.get_acc_info(&redef.attr, token)
|
self.get_acc_info(&redef.attr, token)
|
||||||
.or_else(|| self.get_block_info(&redef.block, token))
|
.or_else(|| self.get_block_info(redef.block.iter(), token))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_dummy_info(&self, dummy: &Dummy, token: &Token) -> Option<VarInfo> {
|
fn get_dummy_info(&self, dummy: &Dummy, token: &Token) -> Option<VarInfo> {
|
||||||
|
@ -733,7 +743,7 @@ impl<'a> HIRVisitor<'a> {
|
||||||
|
|
||||||
fn get_lambda_info(&self, lambda: &Lambda, token: &Token) -> Option<VarInfo> {
|
fn get_lambda_info(&self, lambda: &Lambda, token: &Token) -> Option<VarInfo> {
|
||||||
self.get_params_info(&lambda.params, token)
|
self.get_params_info(&lambda.params, token)
|
||||||
.or_else(|| self.get_block_info(&lambda.body, token))
|
.or_else(|| self.get_block_info(lambda.body.iter(), token))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_array_info(&self, arr: &Array, token: &Token) -> Option<VarInfo> {
|
fn get_array_info(&self, arr: &Array, token: &Token) -> Option<VarInfo> {
|
||||||
|
|
|
@ -227,8 +227,7 @@ impl<'s, C: BuildRunnable, P: Parsable> InlayHintGenerator<'s, C, P> {
|
||||||
|
|
||||||
fn get_class_def_hint(&self, class_def: &ClassDef) -> Vec<InlayHint> {
|
fn get_class_def_hint(&self, class_def: &ClassDef) -> Vec<InlayHint> {
|
||||||
class_def
|
class_def
|
||||||
.methods
|
.all_methods()
|
||||||
.iter()
|
|
||||||
.flat_map(|expr| self.get_expr_hint(expr))
|
.flat_map(|expr| self.get_expr_hint(expr))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -163,7 +163,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
|
||||||
res.extend(symbol);
|
res.extend(symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for method in def.methods.iter() {
|
for method in def.all_methods() {
|
||||||
let symbol = self.symbol(method);
|
let symbol = self.symbol(method);
|
||||||
res.extend(symbol);
|
res.extend(symbol);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3339,7 +3339,7 @@ impl PyCodeGenerator {
|
||||||
log!(info "entered {}", fn_name!());
|
log!(info "entered {}", fn_name!());
|
||||||
let name = class.sig.ident().inspect().clone();
|
let name = class.sig.ident().inspect().clone();
|
||||||
self.unit_size += 1;
|
self.unit_size += 1;
|
||||||
let firstlineno = match class.methods.get(0).and_then(|def| def.ln_begin()) {
|
let firstlineno = match class.methods_list.get(0).and_then(|def| def.ln_begin()) {
|
||||||
Some(l) => l,
|
Some(l) => l,
|
||||||
None => class.sig.ln_begin().unwrap_or(0),
|
None => class.sig.ln_begin().unwrap_or(0),
|
||||||
};
|
};
|
||||||
|
@ -3362,8 +3362,9 @@ impl PyCodeGenerator {
|
||||||
if class.need_to_gen_new {
|
if class.need_to_gen_new {
|
||||||
self.emit_new_func(&class.sig, class.__new__);
|
self.emit_new_func(&class.sig, class.__new__);
|
||||||
}
|
}
|
||||||
if !class.methods.is_empty() {
|
let methods = ClassDef::take_all_methods(class.methods_list);
|
||||||
self.emit_simple_block(class.methods);
|
if !methods.is_empty() {
|
||||||
|
self.emit_simple_block(methods);
|
||||||
}
|
}
|
||||||
if self.stack_len() == init_stack_len {
|
if self.stack_len() == init_stack_len {
|
||||||
self.emit_load_const(ValueObj::None);
|
self.emit_load_const(ValueObj::None);
|
||||||
|
|
|
@ -1295,7 +1295,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::Expr::ClassDef(class_def) => {
|
hir::Expr::ClassDef(class_def) => {
|
||||||
for def in class_def.methods.iter_mut() {
|
for def in class_def.all_methods_mut() {
|
||||||
self.resolve_expr_t(def, qnames)?;
|
self.resolve_expr_t(def, qnames)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -3405,7 +3405,7 @@ impl Context {
|
||||||
candidates.collect()
|
candidates.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_class(&self, typ: &Type) -> bool {
|
pub fn is_class(&self, typ: &Type) -> bool {
|
||||||
match typ {
|
match typ {
|
||||||
Type::And(_l, _r) => false,
|
Type::And(_l, _r) => false,
|
||||||
Type::Never => true,
|
Type::Never => true,
|
||||||
|
@ -3429,7 +3429,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn is_trait(&self, typ: &Type) -> bool {
|
pub fn is_trait(&self, typ: &Type) -> bool {
|
||||||
match typ {
|
match typ {
|
||||||
Type::Never => false,
|
Type::Never => false,
|
||||||
Type::FreeVar(fv) if fv.is_linked() => self.is_class(&fv.crack()),
|
Type::FreeVar(fv) if fv.is_linked() => self.is_class(&fv.crack()),
|
||||||
|
|
|
@ -41,22 +41,22 @@ impl HIRDesugarer {
|
||||||
match chunk {
|
match chunk {
|
||||||
Expr::ClassDef(class_def) => {
|
Expr::ClassDef(class_def) => {
|
||||||
let class = Expr::Accessor(Accessor::Ident(class_def.sig.ident().clone()));
|
let class = Expr::Accessor(Accessor::Ident(class_def.sig.ident().clone()));
|
||||||
let methods = std::mem::take(class_def.methods.ref_mut_payload());
|
let mut static_members = vec![];
|
||||||
let (methods, static_members): (Vec<_>, Vec<_>) = methods
|
for methods_ in class_def.methods_list.iter_mut() {
|
||||||
.into_iter()
|
let block = std::mem::take(&mut methods_.defs);
|
||||||
.partition(|attr| matches!(attr, Expr::Def(def) if def.sig.is_subr()));
|
let (methods, statics): (Vec<_>, Vec<_>) = block
|
||||||
class_def.methods.extend(methods);
|
.into_iter()
|
||||||
let static_members = static_members
|
.partition(|attr| matches!(attr, Expr::Def(def) if def.sig.is_subr()));
|
||||||
.into_iter()
|
methods_.defs.extend(methods);
|
||||||
.map(|expr| match expr {
|
static_members.extend(statics.into_iter().map(|expr| match expr {
|
||||||
Expr::Def(def) => {
|
Expr::Def(def) => {
|
||||||
let acc = class.clone().attr(def.sig.into_ident());
|
let acc = class.clone().attr(def.sig.into_ident());
|
||||||
let redef = ReDef::new(acc, def.body.block);
|
let redef = ReDef::new(acc, def.body.block);
|
||||||
Expr::ReDef(redef)
|
Expr::ReDef(redef)
|
||||||
}
|
}
|
||||||
_ => expr,
|
_ => expr,
|
||||||
})
|
}));
|
||||||
.collect::<Vec<_>>();
|
}
|
||||||
if !static_members.is_empty() {
|
if !static_members.is_empty() {
|
||||||
*chunk = Expr::Compound(Block::new(
|
*chunk = Expr::Compound(Block::new(
|
||||||
[vec![std::mem::take(chunk)], static_members].concat(),
|
[vec![std::mem::take(chunk)], static_members].concat(),
|
||||||
|
|
|
@ -95,7 +95,7 @@ impl SideEffectChecker {
|
||||||
self.check_expr(req_sup);
|
self.check_expr(req_sup);
|
||||||
}
|
}
|
||||||
// TODO: grow
|
// TODO: grow
|
||||||
for def in class_def.methods.iter() {
|
for def in class_def.all_methods() {
|
||||||
self.check_expr(def);
|
self.check_expr(def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +324,7 @@ impl SideEffectChecker {
|
||||||
if let Some(req_sup) = &class_def.require_or_sup {
|
if let Some(req_sup) = &class_def.require_or_sup {
|
||||||
self.check_expr(req_sup);
|
self.check_expr(req_sup);
|
||||||
}
|
}
|
||||||
for def in class_def.methods.iter() {
|
for def in class_def.all_methods() {
|
||||||
self.check_expr(def);
|
self.check_expr(def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2301,14 +2301,19 @@ impl Def {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Methods {
|
pub struct Methods {
|
||||||
pub class: TypeSpec,
|
pub class: Type,
|
||||||
pub vis: Token, // `.` or `::`
|
pub impl_trait: Option<Type>,
|
||||||
pub defs: RecordAttrs, // TODO: allow declaration
|
pub defs: Block,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedDisplay for Methods {
|
impl NestedDisplay for Methods {
|
||||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
||||||
writeln!(f, "{}{}", self.class, self.vis.content)?;
|
writeln!(
|
||||||
|
f,
|
||||||
|
"{} {}",
|
||||||
|
self.class,
|
||||||
|
fmt_option!("|<: ", &self.impl_trait, "|"),
|
||||||
|
)?;
|
||||||
self.defs.fmt_nest(f, level + 1)
|
self.defs.fmt_nest(f, level + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2317,16 +2322,16 @@ impl NestedDisplay for Methods {
|
||||||
impl NoTypeDisplay for Methods {
|
impl NoTypeDisplay for Methods {
|
||||||
fn to_string_notype(&self) -> String {
|
fn to_string_notype(&self) -> String {
|
||||||
format!(
|
format!(
|
||||||
"{}{} {}",
|
"{} {} {}",
|
||||||
self.class,
|
self.class,
|
||||||
self.vis.content,
|
fmt_option!("|<: ", &self.impl_trait, "|"),
|
||||||
self.defs.to_string_notype()
|
self.defs.to_string_notype()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_display_from_nested!(Methods);
|
impl_display_from_nested!(Methods);
|
||||||
impl_locational!(Methods, class, defs);
|
impl_locational!(Methods, defs);
|
||||||
|
|
||||||
impl HasType for Methods {
|
impl HasType for Methods {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2348,8 +2353,12 @@ impl HasType for Methods {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Methods {
|
impl Methods {
|
||||||
pub const fn new(class: TypeSpec, vis: Token, defs: RecordAttrs) -> Self {
|
pub const fn new(class: Type, impl_trait: Option<Type>, defs: Block) -> Self {
|
||||||
Self { class, vis, defs }
|
Self {
|
||||||
|
class,
|
||||||
|
impl_trait,
|
||||||
|
defs,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2361,26 +2370,32 @@ pub struct ClassDef {
|
||||||
/// The type of `new` that is automatically defined if not defined
|
/// The type of `new` that is automatically defined if not defined
|
||||||
pub need_to_gen_new: bool,
|
pub need_to_gen_new: bool,
|
||||||
pub __new__: Type,
|
pub __new__: Type,
|
||||||
pub methods: Block,
|
pub methods_list: Vec<Methods>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NestedDisplay for ClassDef {
|
impl NestedDisplay for ClassDef {
|
||||||
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
|
||||||
self.sig.fmt_nest(f, level)?;
|
self.sig.fmt_nest(f, level)?;
|
||||||
writeln!(f, ":")?;
|
writeln!(f, ":")?;
|
||||||
self.methods.fmt_nest(f, level + 1)
|
fmt_lines(self.methods_list.iter(), f, level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
impl NoTypeDisplay for ClassDef {
|
impl NoTypeDisplay for ClassDef {
|
||||||
fn to_string_notype(&self) -> String {
|
fn to_string_notype(&self) -> String {
|
||||||
format!("{}: {}", self.sig, self.methods.to_string_notype())
|
let methods = self
|
||||||
|
.methods_list
|
||||||
|
.iter()
|
||||||
|
.map(|m| m.to_string_notype())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("\n");
|
||||||
|
format!("{}: {methods}", self.sig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_display_from_nested!(ClassDef);
|
impl_display_from_nested!(ClassDef);
|
||||||
impl_locational!(ClassDef, sig, lossy methods);
|
impl_locational!(ClassDef, sig, lossy methods_list);
|
||||||
|
|
||||||
impl HasType for ClassDef {
|
impl HasType for ClassDef {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -2408,7 +2423,7 @@ impl ClassDef {
|
||||||
require_or_sup: Option<Expr>,
|
require_or_sup: Option<Expr>,
|
||||||
need_to_gen_new: bool,
|
need_to_gen_new: bool,
|
||||||
__new__: Type,
|
__new__: Type,
|
||||||
methods: Block,
|
methods_list: Vec<Methods>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
obj,
|
obj,
|
||||||
|
@ -2416,9 +2431,25 @@ impl ClassDef {
|
||||||
require_or_sup: require_or_sup.map(Box::new),
|
require_or_sup: require_or_sup.map(Box::new),
|
||||||
need_to_gen_new,
|
need_to_gen_new,
|
||||||
__new__,
|
__new__,
|
||||||
methods,
|
methods_list,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn all_methods(&self) -> impl Iterator<Item = &Expr> {
|
||||||
|
self.methods_list.iter().flat_map(|m| m.defs.iter())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_methods_mut(&mut self) -> impl Iterator<Item = &mut Expr> {
|
||||||
|
self.methods_list.iter_mut().flat_map(|m| m.defs.iter_mut())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn take_all_methods(methods_list: Vec<Methods>) -> Block {
|
||||||
|
let mut joined = Block::empty();
|
||||||
|
for methods in methods_list {
|
||||||
|
joined.extend(methods.defs);
|
||||||
|
}
|
||||||
|
joined
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -197,7 +197,7 @@ impl<'a> HIRLinker<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::ClassDef(class_def) => {
|
Expr::ClassDef(class_def) => {
|
||||||
for def in class_def.methods.iter_mut() {
|
for def in class_def.all_methods_mut() {
|
||||||
Self::resolve_pymod_path(def);
|
Self::resolve_pymod_path(def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@ impl<'a> HIRLinker<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::ClassDef(class_def) => {
|
Expr::ClassDef(class_def) => {
|
||||||
for def in class_def.methods.iter_mut() {
|
for def in class_def.all_methods_mut() {
|
||||||
self.replace_import(def);
|
self.replace_import(def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ impl<ASTBuilder: ASTBuildable> GenericASTLowerer<ASTBuilder> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::Expr::ClassDef(class_def) => {
|
hir::Expr::ClassDef(class_def) => {
|
||||||
for chunk in class_def.methods.iter() {
|
for chunk in class_def.all_methods() {
|
||||||
if let Err(ws) = self.expr_use_check(chunk) {
|
if let Err(ws) = self.expr_use_check(chunk) {
|
||||||
warns.extend(ws);
|
warns.extend(ws);
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ impl<ASTBuilder: ASTBuildable> GenericASTLowerer<ASTBuilder> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::ClassDef(class_def) => {
|
Expr::ClassDef(class_def) => {
|
||||||
for chunk in class_def.methods.iter() {
|
for chunk in class_def.all_methods() {
|
||||||
self.check_doc_comment(chunk);
|
self.check_doc_comment(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ impl<ASTBuilder: ASTBuildable> GenericASTLowerer<ASTBuilder> {
|
||||||
fn warn_implicit_union_chunk(&mut self, chunk: &Expr) {
|
fn warn_implicit_union_chunk(&mut self, chunk: &Expr) {
|
||||||
match chunk {
|
match chunk {
|
||||||
Expr::ClassDef(class_def) => {
|
Expr::ClassDef(class_def) => {
|
||||||
for chunk in class_def.methods.iter() {
|
for chunk in class_def.all_methods() {
|
||||||
self.warn_implicit_union_chunk(chunk);
|
self.warn_implicit_union_chunk(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2097,8 +2097,9 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
||||||
fn lower_class_def(&mut self, class_def: ast::ClassDef) -> LowerResult<hir::ClassDef> {
|
fn lower_class_def(&mut self, class_def: ast::ClassDef) -> LowerResult<hir::ClassDef> {
|
||||||
log!(info "entered {}({class_def})", fn_name!());
|
log!(info "entered {}({class_def})", fn_name!());
|
||||||
let mut hir_def = self.lower_def(class_def.def)?;
|
let mut hir_def = self.lower_def(class_def.def)?;
|
||||||
let mut hir_methods = hir::Block::empty();
|
let mut hir_methods_list = vec![];
|
||||||
for methods in class_def.methods_list.into_iter() {
|
for methods in class_def.methods_list.into_iter() {
|
||||||
|
let mut hir_methods = hir::Block::empty();
|
||||||
let (class, impl_trait) = self
|
let (class, impl_trait) = self
|
||||||
.module
|
.module
|
||||||
.context
|
.context
|
||||||
|
@ -2198,7 +2199,9 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
||||||
if let Err(err) = self.check_trait_impl(impl_trait.clone(), &class) {
|
if let Err(err) = self.check_trait_impl(impl_trait.clone(), &class) {
|
||||||
self.errs.push(err);
|
self.errs.push(err);
|
||||||
}
|
}
|
||||||
self.check_collision_and_push(methods.id, class, impl_trait.map(|(t, _)| t));
|
let impl_trait = impl_trait.map(|(t, _)| t);
|
||||||
|
self.check_collision_and_push(methods.id, class.clone(), impl_trait.clone());
|
||||||
|
hir_methods_list.push(hir::Methods::new(class, impl_trait, hir_methods));
|
||||||
}
|
}
|
||||||
let class = self.module.context.gen_type(&hir_def.sig.ident().raw);
|
let class = self.module.context.gen_type(&hir_def.sig.ident().raw);
|
||||||
let Some(class_ctx) = self.module.context.get_nominal_type_ctx(&class) else {
|
let Some(class_ctx) = self.module.context.get_nominal_type_ctx(&class) else {
|
||||||
|
@ -2242,7 +2245,7 @@ impl<A: ASTBuildable> GenericASTLowerer<A> {
|
||||||
require_or_sup,
|
require_or_sup,
|
||||||
need_to_gen_new,
|
need_to_gen_new,
|
||||||
__new__.t.clone(),
|
__new__.t.clone(),
|
||||||
hir_methods,
|
hir_methods_list,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl OwnershipChecker {
|
||||||
if let Some(req_sup) = &class_def.require_or_sup {
|
if let Some(req_sup) = &class_def.require_or_sup {
|
||||||
self.check_expr(req_sup, Ownership::Owned, false);
|
self.check_expr(req_sup, Ownership::Owned, false);
|
||||||
}
|
}
|
||||||
for def in class_def.methods.iter() {
|
for def in class_def.all_methods() {
|
||||||
self.check_expr(def, Ownership::Owned, true);
|
self.check_expr(def, Ownership::Owned, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1112,7 +1112,8 @@ impl PyScriptGenerator {
|
||||||
code += &" ".repeat(self.level + 1);
|
code += &" ".repeat(self.level + 1);
|
||||||
code += &format!("def new(x): return {class_name}.__call__(x)\n");
|
code += &format!("def new(x): return {class_name}.__call__(x)\n");
|
||||||
}
|
}
|
||||||
code += &self.transpile_block(classdef.methods, Discard);
|
let methods = ClassDef::take_all_methods(classdef.methods_list);
|
||||||
|
code += &self.transpile_block(methods, Discard);
|
||||||
code
|
code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue