Compile break or continue statement with proper fblock cleanup. compiler_break, compiler_continue This handles unwinding through With blocks and exception handlers.
(
&mut self,
range: ruff_text_size::TextRange,
is_break: bool,
)
| 9650 | /// compiler_break, compiler_continue |
| 9651 | /// This handles unwinding through With blocks and exception handlers. |
| 9652 | fn compile_break_continue( |
| 9653 | &mut self, |
| 9654 | range: ruff_text_size::TextRange, |
| 9655 | is_break: bool, |
| 9656 | ) -> CompileResult<()> { |
| 9657 | if self.do_not_emit_bytecode > 0 { |
| 9658 | // Still validate that we're inside a loop even in dead code |
| 9659 | let code = self.current_code_info(); |
| 9660 | let mut found_loop = false; |
| 9661 | for i in (0..code.fblock.len()).rev() { |
| 9662 | match code.fblock[i].fb_type { |
| 9663 | FBlockType::WhileLoop | FBlockType::ForLoop => { |
| 9664 | found_loop = true; |
| 9665 | break; |
| 9666 | } |
| 9667 | FBlockType::ExceptionGroupHandler => { |
| 9668 | return Err(self.error_ranged( |
| 9669 | CodegenErrorType::BreakContinueReturnInExceptStar, |
| 9670 | range, |
| 9671 | )); |
| 9672 | } |
| 9673 | _ => {} |
| 9674 | } |
| 9675 | } |
| 9676 | if !found_loop { |
| 9677 | if is_break { |
| 9678 | return Err(self.error_ranged(CodegenErrorType::InvalidBreak, range)); |
| 9679 | } else { |
| 9680 | return Err(self.error_ranged(CodegenErrorType::InvalidContinue, range)); |
| 9681 | } |
| 9682 | } |
| 9683 | return Ok(()); |
| 9684 | } |
| 9685 | |
| 9686 | // unwind_fblock_stack |
| 9687 | // We need to unwind fblocks and compile cleanup code. For FinallyTry blocks, |
| 9688 | // we need to compile the finally body inline, but we must temporarily pop |
| 9689 | // the fblock so that nested break/continue in the finally body don't see it. |
| 9690 | |
| 9691 | // First, find the loop |
| 9692 | let code = self.current_code_info(); |
| 9693 | let mut loop_idx = None; |
| 9694 | let mut is_for_loop = false; |
| 9695 | |
| 9696 | for i in (0..code.fblock.len()).rev() { |
| 9697 | match code.fblock[i].fb_type { |
| 9698 | FBlockType::WhileLoop => { |
| 9699 | loop_idx = Some(i); |
| 9700 | is_for_loop = false; |
| 9701 | break; |
| 9702 | } |
| 9703 | FBlockType::ForLoop => { |
| 9704 | loop_idx = Some(i); |
| 9705 | is_for_loop = true; |
| 9706 | break; |
| 9707 | } |
| 9708 | FBlockType::ExceptionGroupHandler => { |
| 9709 | return Err( |
no test coverage detected