(mut self)
| 385 | } |
| 386 | |
| 387 | fn parse_string(mut self) -> Result<StringType, LexicalError> { |
| 388 | if self.flags.is_raw_string() { |
| 389 | // For raw strings, no escaping is necessary. |
| 390 | return Ok(StringType::Str(ast::StringLiteral { |
| 391 | value: self.source, |
| 392 | range: self.range, |
| 393 | flags: self.flags.into(), |
| 394 | })); |
| 395 | } |
| 396 | |
| 397 | let Some(mut escape) = memchr::memchr(b'\\', self.source.as_bytes()) else { |
| 398 | // If the string doesn't contain any escape sequences, return the owned string. |
| 399 | return Ok(StringType::Str(ast::StringLiteral { |
| 400 | value: self.source, |
| 401 | range: self.range, |
| 402 | flags: self.flags.into(), |
| 403 | })); |
| 404 | }; |
| 405 | |
| 406 | // If the string contains escape sequences, we need to parse them. |
| 407 | let mut value = String::with_capacity(self.source.len()); |
| 408 | |
| 409 | loop { |
| 410 | // Add the characters before the escape sequence to the string. |
| 411 | let before_with_slash = self.skip_bytes(escape + 1); |
| 412 | let before = &before_with_slash[..before_with_slash.len() - 1]; |
| 413 | value.push_str(before); |
| 414 | |
| 415 | // Add the escaped character to the string. |
| 416 | match self.parse_escaped_char()? { |
| 417 | None => {} |
| 418 | Some(EscapedChar::Literal(c)) => value.push(c), |
| 419 | Some(EscapedChar::Escape(c)) => { |
| 420 | value.push('\\'); |
| 421 | value.push(c); |
| 422 | } |
| 423 | } |
| 424 | |
| 425 | let Some(next_escape) = self.source[self.cursor..].find('\\') else { |
| 426 | // Add the rest of the string to the value. |
| 427 | let rest = &self.source[self.cursor..]; |
| 428 | value.push_str(rest); |
| 429 | break; |
| 430 | }; |
| 431 | |
| 432 | // Update the position of the next escape sequence. |
| 433 | escape = next_escape; |
| 434 | } |
| 435 | |
| 436 | Ok(StringType::Str(ast::StringLiteral { |
| 437 | value: value.into_boxed_str(), |
| 438 | range: self.range, |
| 439 | flags: self.flags.into(), |
| 440 | })) |
| 441 | } |
| 442 | |
| 443 | fn parse(self) -> Result<StringType, LexicalError> { |
| 444 | if self.flags.is_byte_string() { |
no test coverage detected