mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-16 01:25:11 +00:00
Basic string formatting
<!-- Thank you for contributing to Ruff! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary This PR implements formatting for non-f-string Strings that do not use implicit concatenation. Docstring formatting is out of the scope of this PR. <!-- What's the purpose of the change? What does it do, and why? --> ## Test Plan I added a few tests for simple string literals. ## Performance Ouch. This is hitting performance somewhat hard. This is probably because we now iterate each string a couple of times: 1. To detect if it is an implicit string continuation 2. To detect if the string contains any new lines 3. To detect the preferred quote 4. To normalize the string Edit: I integrated the detection of newlines into the preferred quote detection so that we only iterate the string three time. We can probably do better by merging the implicit string continuation with the quote detection and new line detection by iterating till the end of the string part and returning the offset. We then use our simple tokenizer to skip over any comments or whitespace until we find the first non trivia token. From there we keep continue doing this in a loop until we reach the end o the string. I'll leave this improvement for later.
This commit is contained in:
parent
3e12bdff45
commit
c52aa8f065
46 changed files with 1278 additions and 1086 deletions
|
@ -220,11 +220,15 @@ pub fn is_implicit_concatenation(content: &str) -> bool {
|
|||
let mut rest = &content[leading_quote_str.len()..content.len() - trailing_quote_str.len()];
|
||||
while let Some(index) = rest.find(trailing_quote_str) {
|
||||
let mut chars = rest[..index].chars().rev();
|
||||
|
||||
if let Some('\\') = chars.next() {
|
||||
// If the quote is double-escaped, then it's _not_ escaped, so the string is
|
||||
// implicitly concatenated.
|
||||
if let Some('\\') = chars.next() {
|
||||
return true;
|
||||
if chars.next() == Some('\\') {
|
||||
// Either `\\'` or `\\\'` need to test one more character
|
||||
|
||||
// If the quote is preceded by `//` then it is not escaped, instead the backslash is escaped.
|
||||
if chars.next() != Some('\\') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If the quote is _not_ escaped, then it's implicitly concatenated.
|
||||
|
@ -299,5 +303,6 @@ mod tests {
|
|||
|
||||
// Negative cases with escaped quotes.
|
||||
assert!(!is_implicit_concatenation(r#""abc\"def""#));
|
||||
assert!(!is_implicit_concatenation(r#"'\\\' ""'"#));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue