mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 22:31:47 +00:00
ruff server
now supports source.fixAll
source action (#10597)
## Summary
`ruff server` now has source action `source.fixAll` as an available code
action.
This also fixes https://github.com/astral-sh/ruff/issues/10593 in the
process of revising the code for quick fix code actions.
## Test Plan
f4c07425
-e68a-445f-a4ed-949c9197a6be
This commit is contained in:
parent
d467aa78c2
commit
257964a8bc
15 changed files with 564 additions and 191 deletions
98
crates/ruff_server/src/edit/replacement.rs
Normal file
98
crates/ruff_server/src/edit/replacement.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||
|
||||
pub(crate) struct Replacement {
|
||||
pub(crate) source_range: TextRange,
|
||||
pub(crate) modified_range: TextRange,
|
||||
}
|
||||
|
||||
impl Replacement {
|
||||
/// Creates a [`Replacement`] that describes the `source_range` of `source` to replace
|
||||
/// with `modified` sliced by `modified_range`.
|
||||
pub(crate) fn between(
|
||||
source: &str,
|
||||
source_line_starts: &[TextSize],
|
||||
modified: &str,
|
||||
modified_line_starts: &[TextSize],
|
||||
) -> Self {
|
||||
let mut source_start = TextSize::default();
|
||||
let mut replaced_start = TextSize::default();
|
||||
let mut source_end = source.text_len();
|
||||
let mut replaced_end = modified.text_len();
|
||||
let mut line_iter = source_line_starts
|
||||
.iter()
|
||||
.copied()
|
||||
.zip(modified_line_starts.iter().copied());
|
||||
for (source_line_start, modified_line_start) in line_iter.by_ref() {
|
||||
if source_line_start != modified_line_start
|
||||
|| source[TextRange::new(source_start, source_line_start)]
|
||||
!= modified[TextRange::new(replaced_start, modified_line_start)]
|
||||
{
|
||||
break;
|
||||
}
|
||||
source_start = source_line_start;
|
||||
replaced_start = modified_line_start;
|
||||
}
|
||||
|
||||
let mut line_iter = line_iter.rev();
|
||||
|
||||
for (old_line_start, new_line_start) in line_iter.by_ref() {
|
||||
if old_line_start <= source_start
|
||||
|| new_line_start <= replaced_start
|
||||
|| source[TextRange::new(old_line_start, source_end)]
|
||||
!= modified[TextRange::new(new_line_start, replaced_end)]
|
||||
{
|
||||
break;
|
||||
}
|
||||
source_end = old_line_start;
|
||||
replaced_end = new_line_start;
|
||||
}
|
||||
|
||||
Replacement {
|
||||
source_range: TextRange::new(source_start, source_end),
|
||||
modified_range: TextRange::new(replaced_start, replaced_end),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ruff_source_file::LineIndex;
|
||||
|
||||
use super::Replacement;
|
||||
|
||||
#[test]
|
||||
fn find_replacement_range_works() {
|
||||
let original = r#"
|
||||
aaaa
|
||||
bbbb
|
||||
cccc
|
||||
dddd
|
||||
eeee
|
||||
"#;
|
||||
let original_index = LineIndex::from_source_text(original);
|
||||
let new = r#"
|
||||
bb
|
||||
cccc
|
||||
dd
|
||||
"#;
|
||||
let new_index = LineIndex::from_source_text(new);
|
||||
let expected = r#"
|
||||
bb
|
||||
cccc
|
||||
dd
|
||||
"#;
|
||||
let replacement = Replacement::between(
|
||||
original,
|
||||
original_index.line_starts(),
|
||||
new,
|
||||
new_index.line_starts(),
|
||||
);
|
||||
let mut test = original.to_string();
|
||||
test.replace_range(
|
||||
replacement.source_range.start().to_usize()..replacement.source_range.end().to_usize(),
|
||||
&new[replacement.modified_range],
|
||||
);
|
||||
|
||||
assert_eq!(expected, &test);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue