(
&mut self,
tstring: &ast::TString,
strings: &mut Vec<Wtf8Buf>,
current_string: &mut Wtf8Buf,
interp_count: &mut u32,
)
| 10326 | } |
| 10327 | |
| 10328 | fn compile_tstring_into( |
| 10329 | &mut self, |
| 10330 | tstring: &ast::TString, |
| 10331 | strings: &mut Vec<Wtf8Buf>, |
| 10332 | current_string: &mut Wtf8Buf, |
| 10333 | interp_count: &mut u32, |
| 10334 | ) -> CompileResult<()> { |
| 10335 | for element in &tstring.elements { |
| 10336 | match element { |
| 10337 | ast::InterpolatedStringElement::Literal(lit) => { |
| 10338 | // Accumulate literal parts into current_string |
| 10339 | current_string.push_str(&lit.value); |
| 10340 | } |
| 10341 | ast::InterpolatedStringElement::Interpolation(interp) => { |
| 10342 | // Finish current string segment |
| 10343 | strings.push(core::mem::take(current_string)); |
| 10344 | |
| 10345 | // Compile the interpolation value |
| 10346 | self.compile_expression(&interp.expression)?; |
| 10347 | |
| 10348 | // Load the expression source string, including any |
| 10349 | // whitespace between '{' and the expression start |
| 10350 | let expr_range = interp.expression.range(); |
| 10351 | let expr_source = if interp.range.start() < expr_range.start() |
| 10352 | && interp.range.end() >= expr_range.end() |
| 10353 | { |
| 10354 | let after_brace = interp.range.start() + TextSize::new(1); |
| 10355 | self.source_file |
| 10356 | .slice(TextRange::new(after_brace, expr_range.end())) |
| 10357 | } else { |
| 10358 | // Fallback for programmatically constructed ASTs with dummy ranges |
| 10359 | self.source_file.slice(expr_range) |
| 10360 | }; |
| 10361 | self.emit_load_const(ConstantData::Str { |
| 10362 | value: expr_source.to_string().into(), |
| 10363 | }); |
| 10364 | |
| 10365 | // Determine conversion code |
| 10366 | let conversion: u32 = match interp.conversion { |
| 10367 | ast::ConversionFlag::None => 0, |
| 10368 | ast::ConversionFlag::Str => 1, |
| 10369 | ast::ConversionFlag::Repr => 2, |
| 10370 | ast::ConversionFlag::Ascii => 3, |
| 10371 | }; |
| 10372 | |
| 10373 | // Handle format_spec |
| 10374 | let has_format_spec = interp.format_spec.is_some(); |
| 10375 | if let Some(format_spec) = &interp.format_spec { |
| 10376 | // Compile format_spec as a string using fstring element compilation |
| 10377 | // Use default ast::FStringFlags since format_spec syntax is independent of t-string flags |
| 10378 | self.compile_fstring_elements( |
| 10379 | ast::FStringFlags::empty(), |
| 10380 | &format_spec.elements, |
| 10381 | )?; |
| 10382 | } |
| 10383 | |
| 10384 | // Emit BUILD_INTERPOLATION |
| 10385 | // oparg encoding: (conversion << 2) | has_format_spec |
no test coverage detected