def/async def: parses signature, compiles body, emits MakeFunction/MakeCoroutine+decorators+StoreName. */
(&mut self, decorators: u16, is_async: bool)
| 522 | |
| 523 | /* def/async def: parses signature, compiles body, emits MakeFunction/MakeCoroutine+decorators+StoreName. */ |
| 524 | pub(super) fn func_def_inner(&mut self, decorators: u16, is_async: bool) { |
| 525 | // Missing name: non-syncing diagnostic + synthetic name so signature+body still parse. |
| 526 | let fname = if matches!(self.peek(), Some(TokenType::Name)) { |
| 527 | self.advance_text() |
| 528 | } else { |
| 529 | self.diag_at_peek("expected function name"); |
| 530 | "<missing>".to_string() |
| 531 | }; |
| 532 | let (params, defaults) = self.parse_params(); |
| 533 | let body = self.compile_body(¶ms); |
| 534 | |
| 535 | // Propagate free names to parent chunk so nested defs capture grandparent vars. |
| 536 | let param_slots: crate::util::fx::FxHashSet<String> = params.iter() |
| 537 | .map(|p| s!(str super::types::param_base_name(p), "_0")).collect(); |
| 538 | for name in &body.names { |
| 539 | if !param_slots.contains(name.as_str()) { |
| 540 | self.chunk.push_name(name); |
| 541 | } |
| 542 | } |
| 543 | |
| 544 | let fi = self.chunk.functions.len() as u16; |
| 545 | let name_slot = self.push_ssa_name(&fname, self.current_version(&fname) + 1); |
| 546 | self.chunk.functions.push((params, body, defaults, name_slot)); |
| 547 | self.chunk.emit(if is_async { OpCode::MakeCoroutine } else { OpCode::MakeFunction }, fi); |
| 548 | |
| 549 | for _ in 0..decorators { |
| 550 | let pos = self.last_end as u32; |
| 551 | self.chunk.emit(OpCode::Call, 1); |
| 552 | self.chunk.record_call_pos(pos); |
| 553 | } |
| 554 | |
| 555 | let ver = self.increment_version(&fname); |
| 556 | let i = self.push_ssa_name(&fname, ver); |
| 557 | self.chunk.emit(OpCode::StoreName, i); |
| 558 | } |
| 559 | |
| 560 | pub(super) fn parse_params(&mut self) -> (Vec<String>, u16) { |
| 561 | // No `(`: diagnostic, consume `:` so compile_body starts at Indent correctly. |
no test coverage detected