Skip to content

Commit 21c937e

Browse files
committed
chore: add hir::Methods
1 parent 234fa3f commit 21c937e

File tree

14 files changed

+109
-64
lines changed

14 files changed

+109
-64
lines changed

crates/els/hir_visitor.rs

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ impl<'a> HIRVisitor<'a> {
186186
) -> Option<Vec<Str>> {
187187
let ns = class_def.sig.ident().to_string_notype();
188188
cur_ns.push(Str::from(ns));
189-
self.get_exprs_ns(cur_ns, class_def.methods.iter(), pos)
189+
self.get_exprs_ns(cur_ns, class_def.all_methods(), pos)
190190
}
191191

192192
fn get_patch_def_ns(
@@ -282,7 +282,9 @@ impl<'a> HIRVisitor<'a> {
282282
Expr::Tuple(tuple) => self.get_expr_from_tuple(expr, tuple, pos),
283283
Expr::TypeAsc(type_asc) => self.get_expr(&type_asc.expr, pos),
284284
Expr::Dummy(dummy) => self.get_expr_from_dummy(dummy, pos),
285-
Expr::Compound(block) | Expr::Code(block) => self.get_expr_from_block(block, pos),
285+
Expr::Compound(block) | Expr::Code(block) => {
286+
self.get_expr_from_block(block.iter(), pos)
287+
}
286288
Expr::ReDef(redef) => self.get_expr_from_redef(expr, redef, pos),
287289
Expr::Import(_) => None,
288290
}
@@ -362,7 +364,7 @@ impl<'a> HIRVisitor<'a> {
362364
pos: Position,
363365
) -> Option<&Expr> {
364366
self.return_expr_if_same(expr, def.sig.ident().raw.name.token(), pos)
365-
.or_else(|| self.get_expr_from_block(&def.body.block, pos))
367+
.or_else(|| self.get_expr_from_block(def.body.block.iter(), pos))
366368
.or_else(|| self.return_expr_if_contains(expr, pos, def))
367369
}
368370

@@ -376,12 +378,16 @@ impl<'a> HIRVisitor<'a> {
376378
.require_or_sup
377379
.as_ref()
378380
.and_then(|req_sup| self.get_expr(req_sup, pos))
379-
.or_else(|| self.get_expr_from_block(&class_def.methods, pos))
381+
.or_else(|| self.get_expr_from_block(class_def.all_methods(), pos))
380382
.or_else(|| self.return_expr_if_contains(expr, pos, class_def))
381383
}
382384

383-
fn get_expr_from_block<'e>(&'e self, block: &'e Block, pos: Position) -> Option<&Expr> {
384-
for chunk in block.iter() {
385+
fn get_expr_from_block<'e>(
386+
&'e self,
387+
block: impl Iterator<Item = &'e Expr>,
388+
pos: Position,
389+
) -> Option<&Expr> {
390+
for chunk in block {
385391
if let Some(expr) = self.get_expr(chunk, pos) {
386392
return Some(expr);
387393
}
@@ -396,7 +402,7 @@ impl<'a> HIRVisitor<'a> {
396402
pos: Position,
397403
) -> Option<&Expr> {
398404
self.get_expr_from_acc(expr, &redef.attr, pos)
399-
.or_else(|| self.get_expr_from_block(&redef.block, pos))
405+
.or_else(|| self.get_expr_from_block(redef.block.iter(), pos))
400406
}
401407

402408
fn get_expr_from_dummy<'e>(&'e self, dummy: &'e Dummy, pos: Position) -> Option<&Expr> {
@@ -416,7 +422,7 @@ impl<'a> HIRVisitor<'a> {
416422
) -> Option<&Expr> {
417423
self.return_expr_if_same(expr, patch_def.sig.name().token(), pos)
418424
.or_else(|| self.get_expr(&patch_def.base, pos))
419-
.or_else(|| self.get_expr_from_block(&patch_def.methods, pos))
425+
.or_else(|| self.get_expr_from_block(patch_def.methods.iter(), pos))
420426
.or_else(|| self.return_expr_if_contains(expr, pos, patch_def))
421427
}
422428

@@ -431,7 +437,7 @@ impl<'a> HIRVisitor<'a> {
431437
{
432438
return Some(expr);
433439
}
434-
self.get_expr_from_block(&lambda.body, pos)
440+
self.get_expr_from_block(lambda.body.iter(), pos)
435441
}
436442

437443
fn get_expr_from_array<'e>(
@@ -487,7 +493,7 @@ impl<'a> HIRVisitor<'a> {
487493
return Some(expr);
488494
}
489495
for field in record.attrs.iter() {
490-
if let Some(expr) = self.get_expr_from_block(&field.body.block, pos) {
496+
if let Some(expr) = self.get_expr_from_block(field.body.block.iter(), pos) {
491497
return Some(expr);
492498
}
493499
}
@@ -577,7 +583,7 @@ impl<'a> HIRVisitor<'a> {
577583
Expr::Tuple(tuple) => self.get_tuple_info(tuple, token),
578584
Expr::TypeAsc(type_asc) => self.get_tasc_info(type_asc, token),
579585
Expr::Dummy(dummy) => self.get_dummy_info(dummy, token),
580-
Expr::Compound(block) | Expr::Code(block) => self.get_block_info(block, token),
586+
Expr::Compound(block) | Expr::Code(block) => self.get_block_info(block.iter(), token),
581587
Expr::ReDef(redef) => self.get_redef_info(redef, token),
582588
Expr::Import(_) => None,
583589
}
@@ -690,7 +696,7 @@ impl<'a> HIRVisitor<'a> {
690696

691697
fn get_def_info(&self, def: &Def, token: &Token) -> Option<VarInfo> {
692698
self.get_sig_info(&def.sig, token)
693-
.or_else(|| self.get_block_info(&def.body.block, token))
699+
.or_else(|| self.get_block_info(def.body.block.iter(), token))
694700
}
695701

696702
fn get_class_def_info(&self, class_def: &ClassDef, token: &Token) -> Option<VarInfo> {
@@ -699,17 +705,21 @@ impl<'a> HIRVisitor<'a> {
699705
.as_ref()
700706
.and_then(|req_sup| self.get_expr_info(req_sup, token))
701707
.or_else(|| self.get_sig_info(&class_def.sig, token))
702-
.or_else(|| self.get_block_info(&class_def.methods, token))
708+
.or_else(|| self.get_block_info(class_def.all_methods(), token))
703709
}
704710

705711
fn get_patch_def_info(&self, patch_def: &PatchDef, token: &Token) -> Option<VarInfo> {
706712
self.get_expr_info(&patch_def.base, token)
707713
.or_else(|| self.get_sig_info(&patch_def.sig, token))
708-
.or_else(|| self.get_block_info(&patch_def.methods, token))
714+
.or_else(|| self.get_block_info(patch_def.methods.iter(), token))
709715
}
710716

711-
fn get_block_info(&self, block: &Block, token: &Token) -> Option<VarInfo> {
712-
for chunk in block.iter() {
717+
fn get_block_info<'e>(
718+
&self,
719+
block: impl Iterator<Item = &'e Expr>,
720+
token: &Token,
721+
) -> Option<VarInfo> {
722+
for chunk in block {
713723
if let Some(expr) = self.get_expr_info(chunk, token) {
714724
return Some(expr);
715725
}
@@ -719,7 +729,7 @@ impl<'a> HIRVisitor<'a> {
719729

720730
fn get_redef_info(&self, redef: &ReDef, token: &Token) -> Option<VarInfo> {
721731
self.get_acc_info(&redef.attr, token)
722-
.or_else(|| self.get_block_info(&redef.block, token))
732+
.or_else(|| self.get_block_info(redef.block.iter(), token))
723733
}
724734

725735
fn get_dummy_info(&self, dummy: &Dummy, token: &Token) -> Option<VarInfo> {
@@ -733,7 +743,7 @@ impl<'a> HIRVisitor<'a> {
733743

734744
fn get_lambda_info(&self, lambda: &Lambda, token: &Token) -> Option<VarInfo> {
735745
self.get_params_info(&lambda.params, token)
736-
.or_else(|| self.get_block_info(&lambda.body, token))
746+
.or_else(|| self.get_block_info(lambda.body.iter(), token))
737747
}
738748

739749
fn get_array_info(&self, arr: &Array, token: &Token) -> Option<VarInfo> {

crates/els/inlay_hint.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,7 @@ impl<'s, C: BuildRunnable, P: Parsable> InlayHintGenerator<'s, C, P> {
227227

228228
fn get_class_def_hint(&self, class_def: &ClassDef) -> Vec<InlayHint> {
229229
class_def
230-
.methods
231-
.iter()
230+
.all_methods()
232231
.flat_map(|expr| self.get_expr_hint(expr))
233232
.collect()
234233
}

crates/els/symbol.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
163163
res.extend(symbol);
164164
}
165165
}
166-
for method in def.methods.iter() {
166+
for method in def.all_methods() {
167167
let symbol = self.symbol(method);
168168
res.extend(symbol);
169169
}

crates/erg_compiler/codegen.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3339,7 +3339,7 @@ impl PyCodeGenerator {
33393339
log!(info "entered {}", fn_name!());
33403340
let name = class.sig.ident().inspect().clone();
33413341
self.unit_size += 1;
3342-
let firstlineno = match class.methods.get(0).and_then(|def| def.ln_begin()) {
3342+
let firstlineno = match class.methods_list.get(0).and_then(|def| def.ln_begin()) {
33433343
Some(l) => l,
33443344
None => class.sig.ln_begin().unwrap_or(0),
33453345
};
@@ -3362,8 +3362,9 @@ impl PyCodeGenerator {
33623362
if class.need_to_gen_new {
33633363
self.emit_new_func(&class.sig, class.__new__);
33643364
}
3365-
if !class.methods.is_empty() {
3366-
self.emit_simple_block(class.methods);
3365+
let methods = ClassDef::take_all_methods(class.methods_list);
3366+
if !methods.is_empty() {
3367+
self.emit_simple_block(methods);
33673368
}
33683369
if self.stack_len() == init_stack_len {
33693370
self.emit_load_const(ValueObj::None);

crates/erg_compiler/context/generalize.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1295,7 +1295,7 @@ impl Context {
12951295
}
12961296
}
12971297
hir::Expr::ClassDef(class_def) => {
1298-
for def in class_def.methods.iter_mut() {
1298+
for def in class_def.all_methods_mut() {
12991299
self.resolve_expr_t(def, qnames)?;
13001300
}
13011301
Ok(())

crates/erg_compiler/context/inquire.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3405,7 +3405,7 @@ impl Context {
34053405
candidates.collect()
34063406
}
34073407

3408-
pub(crate) fn is_class(&self, typ: &Type) -> bool {
3408+
pub fn is_class(&self, typ: &Type) -> bool {
34093409
match typ {
34103410
Type::And(_l, _r) => false,
34113411
Type::Never => true,
@@ -3429,7 +3429,7 @@ impl Context {
34293429
}
34303430
}
34313431

3432-
pub(crate) fn is_trait(&self, typ: &Type) -> bool {
3432+
pub fn is_trait(&self, typ: &Type) -> bool {
34333433
match typ {
34343434
Type::Never => false,
34353435
Type::FreeVar(fv) if fv.is_linked() => self.is_class(&fv.crack()),

crates/erg_compiler/desugar_hir.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,22 +41,22 @@ impl HIRDesugarer {
4141
match chunk {
4242
Expr::ClassDef(class_def) => {
4343
let class = Expr::Accessor(Accessor::Ident(class_def.sig.ident().clone()));
44-
let methods = std::mem::take(class_def.methods.ref_mut_payload());
45-
let (methods, static_members): (Vec<_>, Vec<_>) = methods
46-
.into_iter()
47-
.partition(|attr| matches!(attr, Expr::Def(def) if def.sig.is_subr()));
48-
class_def.methods.extend(methods);
49-
let static_members = static_members
50-
.into_iter()
51-
.map(|expr| match expr {
44+
let mut static_members = vec![];
45+
for methods_ in class_def.methods_list.iter_mut() {
46+
let block = std::mem::take(&mut methods_.defs);
47+
let (methods, statics): (Vec<_>, Vec<_>) = block
48+
.into_iter()
49+
.partition(|attr| matches!(attr, Expr::Def(def) if def.sig.is_subr()));
50+
methods_.defs.extend(methods);
51+
static_members.extend(statics.into_iter().map(|expr| match expr {
5252
Expr::Def(def) => {
5353
let acc = class.clone().attr(def.sig.into_ident());
5454
let redef = ReDef::new(acc, def.body.block);
5555
Expr::ReDef(redef)
5656
}
5757
_ => expr,
58-
})
59-
.collect::<Vec<_>>();
58+
}));
59+
}
6060
if !static_members.is_empty() {
6161
*chunk = Expr::Compound(Block::new(
6262
[vec![std::mem::take(chunk)], static_members].concat(),

crates/erg_compiler/effectcheck.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ impl SideEffectChecker {
9595
self.check_expr(req_sup);
9696
}
9797
// TODO: grow
98-
for def in class_def.methods.iter() {
98+
for def in class_def.all_methods() {
9999
self.check_expr(def);
100100
}
101101
}
@@ -324,7 +324,7 @@ impl SideEffectChecker {
324324
if let Some(req_sup) = &class_def.require_or_sup {
325325
self.check_expr(req_sup);
326326
}
327-
for def in class_def.methods.iter() {
327+
for def in class_def.all_methods() {
328328
self.check_expr(def);
329329
}
330330
}

crates/erg_compiler/hir.rs

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2301,14 +2301,19 @@ impl Def {
23012301

23022302
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23032303
pub struct Methods {
2304-
pub class: TypeSpec,
2305-
pub vis: Token, // `.` or `::`
2306-
pub defs: RecordAttrs, // TODO: allow declaration
2304+
pub class: Type,
2305+
pub impl_trait: Option<Type>,
2306+
pub defs: Block,
23072307
}
23082308

23092309
impl NestedDisplay for Methods {
23102310
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
2311-
writeln!(f, "{}{}", self.class, self.vis.content)?;
2311+
writeln!(
2312+
f,
2313+
"{} {}",
2314+
self.class,
2315+
fmt_option!("|<: ", &self.impl_trait, "|"),
2316+
)?;
23122317
self.defs.fmt_nest(f, level + 1)
23132318
}
23142319
}
@@ -2317,16 +2322,16 @@ impl NestedDisplay for Methods {
23172322
impl NoTypeDisplay for Methods {
23182323
fn to_string_notype(&self) -> String {
23192324
format!(
2320-
"{}{} {}",
2325+
"{} {} {}",
23212326
self.class,
2322-
self.vis.content,
2327+
fmt_option!("|<: ", &self.impl_trait, "|"),
23232328
self.defs.to_string_notype()
23242329
)
23252330
}
23262331
}
23272332

23282333
impl_display_from_nested!(Methods);
2329-
impl_locational!(Methods, class, defs);
2334+
impl_locational!(Methods, defs);
23302335

23312336
impl HasType for Methods {
23322337
#[inline]
@@ -2348,8 +2353,12 @@ impl HasType for Methods {
23482353
}
23492354

23502355
impl Methods {
2351-
pub const fn new(class: TypeSpec, vis: Token, defs: RecordAttrs) -> Self {
2352-
Self { class, vis, defs }
2356+
pub const fn new(class: Type, impl_trait: Option<Type>, defs: Block) -> Self {
2357+
Self {
2358+
class,
2359+
impl_trait,
2360+
defs,
2361+
}
23532362
}
23542363
}
23552364

@@ -2361,26 +2370,32 @@ pub struct ClassDef {
23612370
/// The type of `new` that is automatically defined if not defined
23622371
pub need_to_gen_new: bool,
23632372
pub __new__: Type,
2364-
pub methods: Block,
2373+
pub methods_list: Vec<Methods>,
23652374
}
23662375

23672376
impl NestedDisplay for ClassDef {
23682377
fn fmt_nest(&self, f: &mut fmt::Formatter<'_>, level: usize) -> fmt::Result {
23692378
self.sig.fmt_nest(f, level)?;
23702379
writeln!(f, ":")?;
2371-
self.methods.fmt_nest(f, level + 1)
2380+
fmt_lines(self.methods_list.iter(), f, level)
23722381
}
23732382
}
23742383

23752384
// TODO
23762385
impl NoTypeDisplay for ClassDef {
23772386
fn to_string_notype(&self) -> String {
2378-
format!("{}: {}", self.sig, self.methods.to_string_notype())
2387+
let methods = self
2388+
.methods_list
2389+
.iter()
2390+
.map(|m| m.to_string_notype())
2391+
.collect::<Vec<_>>()
2392+
.join("\n");
2393+
format!("{}: {methods}", self.sig)
23792394
}
23802395
}
23812396

23822397
impl_display_from_nested!(ClassDef);
2383-
impl_locational!(ClassDef, sig, lossy methods);
2398+
impl_locational!(ClassDef, sig, lossy methods_list);
23842399

23852400
impl HasType for ClassDef {
23862401
#[inline]
@@ -2408,16 +2423,32 @@ impl ClassDef {
24082423
require_or_sup: Option<Expr>,
24092424
need_to_gen_new: bool,
24102425
__new__: Type,
2411-
methods: Block,
2426+
methods_list: Vec<Methods>,
24122427
) -> Self {
24132428
Self {
24142429
obj,
24152430
sig,
24162431
require_or_sup: require_or_sup.map(Box::new),
24172432
need_to_gen_new,
24182433
__new__,
2419-
methods,
2434+
methods_list,
2435+
}
2436+
}
2437+
2438+
pub fn all_methods(&self) -> impl Iterator<Item = &Expr> {
2439+
self.methods_list.iter().flat_map(|m| m.defs.iter())
2440+
}
2441+
2442+
pub fn all_methods_mut(&mut self) -> impl Iterator<Item = &mut Expr> {
2443+
self.methods_list.iter_mut().flat_map(|m| m.defs.iter_mut())
2444+
}
2445+
2446+
pub fn take_all_methods(methods_list: Vec<Methods>) -> Block {
2447+
let mut joined = Block::empty();
2448+
for methods in methods_list {
2449+
joined.extend(methods.defs);
24202450
}
2451+
joined
24212452
}
24222453
}
24232454

0 commit comments

Comments
 (0)