mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-09 22:25:20 +00:00
Skip LibCST parsing for standard dedent adjustments (#9769)
## Summary Often, when fixing, we need to dedent a block of code (e.g., if we remove an `if` and dedent its body). Today, we use LibCST to parse and adjust the indentation, which is really expensive -- but this is only really necessary if the block contains a multiline string, since naively adjusting the indentation for such a string can change the whitespace _within_ the string. This PR uses a simple dedent implementation for cases in which the block doesn't intersect with a multi-line string (or an f-string, since we don't support tracking multi-line strings for f-strings right now). We could improve this even further by using the ranges to guide the dedent function, such that we don't apply the dedent if the line starts within a multiline string. But that would also need to take f-strings into account, which is a little tricky. ## Test Plan `cargo test`
This commit is contained in:
parent
4f7fb566f0
commit
c3ca34543f
12 changed files with 193 additions and 19 deletions
|
@ -14,6 +14,14 @@ pub struct FStringRanges {
|
|||
}
|
||||
|
||||
impl FStringRanges {
|
||||
/// Returns `true` if the given range intersects with any f-string range.
|
||||
pub fn intersects(&self, target: TextRange) -> bool {
|
||||
self.raw
|
||||
.values()
|
||||
.take_while(|range| range.start() < target.end())
|
||||
.any(|range| target.intersect(*range).is_some())
|
||||
}
|
||||
|
||||
/// Return the [`TextRange`] of the innermost f-string at the given offset.
|
||||
pub fn innermost(&self, offset: TextSize) -> Option<TextRange> {
|
||||
self.raw
|
||||
|
|
|
@ -9,7 +9,7 @@ pub struct MultilineRanges {
|
|||
|
||||
impl MultilineRanges {
|
||||
/// Returns `true` if the given range is inside a multiline string.
|
||||
pub fn intersects(&self, target: TextRange) -> bool {
|
||||
pub fn contains_range(&self, target: TextRange) -> bool {
|
||||
self.ranges
|
||||
.binary_search_by(|range| {
|
||||
if range.contains_range(target) {
|
||||
|
@ -22,6 +22,21 @@ impl MultilineRanges {
|
|||
})
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
/// Returns `true` if the given range intersects with any multiline string.
|
||||
pub fn intersects(&self, target: TextRange) -> bool {
|
||||
self.ranges
|
||||
.binary_search_by(|range| {
|
||||
if target.intersect(*range).is_some() {
|
||||
std::cmp::Ordering::Equal
|
||||
} else if range.end() < target.start() {
|
||||
std::cmp::Ordering::Less
|
||||
} else {
|
||||
std::cmp::Ordering::Greater
|
||||
}
|
||||
})
|
||||
.is_ok()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue