(&mut self, decorators: u16)
| 478 | pub(super) fn class_def(&mut self) { self.class_def_with(0) } |
| 479 | |
| 480 | pub(super) fn class_def_with(&mut self, decorators: u16) { |
| 481 | // Missing name: non-syncing diagnostic + synthetic name so body still parses. |
| 482 | let cname = if matches!(self.peek(), Some(TokenType::Name)) { |
| 483 | self.advance_text() |
| 484 | } else { |
| 485 | self.diag_at_peek("expected class name"); |
| 486 | "<missing>".to_string() |
| 487 | }; |
| 488 | |
| 489 | // Bases are pushed left-to-right; `MakeClass` pops `num_bases` and stores them in the Class. |
| 490 | let mut num_bases: u16 = 0; |
| 491 | if self.eat_if(TokenType::Lpar) { |
| 492 | while !matches!(self.peek(), Some(TokenType::Rpar) | None) { |
| 493 | self.expr(); |
| 494 | num_bases = num_bases.saturating_add(1); |
| 495 | if !self.eat_if(TokenType::Comma) { break; } |
| 496 | } |
| 497 | self.eat(TokenType::Rpar); |
| 498 | } |
| 499 | |
| 500 | self.eat(TokenType::Colon); |
| 501 | |
| 502 | let body = self.with_fresh_chunk(|s| s.compile_block()); |
| 503 | |
| 504 | let ci = self.chunk.classes.len() as u16; |
| 505 | // Operand packs `(num_bases << 8) | class_idx`; each field is one byte to keep the dispatch decode cheap. |
| 506 | if ci > 0xFF { self.error("too many classes in this scope (limit 255)"); return; } |
| 507 | if num_bases > 0xFF { self.error("too many base classes (limit 255)"); return; } |
| 508 | self.chunk.classes.push(body); |
| 509 | self.chunk.emit(OpCode::MakeClass, (num_bases << 8) | ci); |
| 510 | |
| 511 | // Each decorator Calls with the previous result, same as for functions. |
| 512 | for _ in 0..decorators { |
| 513 | let pos = self.last_end as u32; |
| 514 | self.chunk.emit(OpCode::Call, 1); |
| 515 | self.chunk.record_call_pos(pos); |
| 516 | } |
| 517 | |
| 518 | let ver = self.increment_version(&cname); |
| 519 | let i = self.push_ssa_name(&cname, ver); |
| 520 | self.chunk.emit(OpCode::StoreName, i); |
| 521 | } |
| 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) { |
no test coverage detected