(mut self)
| 444 | } |
| 445 | |
| 446 | fn parse_string(mut self) -> Result<StringType, LexicalError> { |
| 447 | if self.flags.is_raw_string() { |
| 448 | // For raw strings, no escaping is necessary. |
| 449 | return Ok(StringType::Str(ast::StringLiteral { |
| 450 | value: self.source.into(), |
| 451 | range: self.range, |
| 452 | flags: self.flags.into(), |
| 453 | node_index: AtomicNodeIndex::NONE, |
| 454 | })); |
| 455 | } |
| 456 | |
| 457 | let Some(mut escape) = memchr::memchr(b'\\', self.source.as_bytes()) else { |
| 458 | // If the string doesn't contain any escape sequences, return the owned string. |
| 459 | return Ok(StringType::Str(ast::StringLiteral { |
| 460 | value: self.source.into(), |
| 461 | range: self.range, |
| 462 | flags: self.flags.into(), |
| 463 | node_index: AtomicNodeIndex::NONE, |
| 464 | })); |
| 465 | }; |
| 466 | |
| 467 | // If the string contains escape sequences, we need to parse them. |
| 468 | let mut value = String::with_capacity(self.source.len()); |
| 469 | |
| 470 | loop { |
| 471 | // Add the characters before the escape sequence to the string. |
| 472 | let before_with_slash = self.skip_bytes(escape + 1); |
| 473 | let before = &before_with_slash[..before_with_slash.len() - 1]; |
| 474 | value.push_str(before); |
| 475 | |
| 476 | // Add the escaped character to the string. |
| 477 | match self.parse_escaped_char()? { |
| 478 | None => {} |
| 479 | Some(EscapedChar::Literal(c)) => value.push(c), |
| 480 | Some(EscapedChar::Escape(c)) => { |
| 481 | value.push('\\'); |
| 482 | value.push(c); |
| 483 | } |
| 484 | } |
| 485 | |
| 486 | let Some(next_escape) = self.source[self.cursor..].find('\\') else { |
| 487 | // Add the rest of the string to the value. |
| 488 | let rest = &self.source[self.cursor..]; |
| 489 | value.push_str(rest); |
| 490 | break; |
| 491 | }; |
| 492 | |
| 493 | // Update the position of the next escape sequence. |
| 494 | escape = next_escape; |
| 495 | } |
| 496 | |
| 497 | Ok(StringType::Str(ast::StringLiteral { |
| 498 | value: value.into_boxed_str(), |
| 499 | range: self.range, |
| 500 | flags: self.flags.into(), |
| 501 | node_index: AtomicNodeIndex::NONE, |
| 502 | })) |
| 503 | } |
no test coverage detected