mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 04:45:01 +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
79
crates/ruff_server/src/fix.rs
Normal file
79
crates/ruff_server/src/fix.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
use ruff_linter::{
|
||||
linter::{FixerResult, LinterResult},
|
||||
settings::{flags, types::UnsafeFixes, LinterSettings},
|
||||
source_kind::SourceKind,
|
||||
};
|
||||
use ruff_python_ast::PySourceType;
|
||||
use ruff_source_file::LineIndex;
|
||||
use std::{borrow::Cow, path::Path};
|
||||
|
||||
use crate::{
|
||||
edit::{Replacement, ToRangeExt},
|
||||
PositionEncoding,
|
||||
};
|
||||
|
||||
pub(crate) fn fix_all(
|
||||
document: &crate::edit::Document,
|
||||
linter_settings: &LinterSettings,
|
||||
encoding: PositionEncoding,
|
||||
) -> crate::Result<Vec<lsp_types::TextEdit>> {
|
||||
let source = document.contents();
|
||||
|
||||
let source_type = PySourceType::default();
|
||||
|
||||
// TODO(jane): Support Jupyter Notebooks
|
||||
let source_kind = SourceKind::Python(source.to_string());
|
||||
|
||||
// We need to iteratively apply all safe fixes onto a single file and then
|
||||
// create a diff between the modified file and the original source to use as a single workspace
|
||||
// edit.
|
||||
// If we simply generated the diagnostics with `check_path` and then applied fixes individually,
|
||||
// there's a possibility they could overlap or introduce new problems that need to be fixed,
|
||||
// which is inconsistent with how `ruff check --fix` works.
|
||||
let FixerResult {
|
||||
transformed,
|
||||
result: LinterResult { error, .. },
|
||||
..
|
||||
} = ruff_linter::linter::lint_fix(
|
||||
Path::new("<filename>"),
|
||||
None,
|
||||
flags::Noqa::Enabled,
|
||||
UnsafeFixes::Disabled,
|
||||
linter_settings,
|
||||
&source_kind,
|
||||
source_type,
|
||||
)?;
|
||||
|
||||
if let Some(error) = error {
|
||||
// abort early if a parsing error occurred
|
||||
return Err(anyhow::anyhow!(
|
||||
"A parsing error occurred during `fix_all`: {error}"
|
||||
));
|
||||
}
|
||||
|
||||
// fast path: if `transformed` is still borrowed, no changes were made and we can return early
|
||||
if let Cow::Borrowed(_) = transformed {
|
||||
return Ok(vec![]);
|
||||
}
|
||||
|
||||
let modified = transformed.source_code();
|
||||
|
||||
let modified_index = LineIndex::from_source_text(modified);
|
||||
|
||||
let source_index = document.index();
|
||||
|
||||
let Replacement {
|
||||
source_range,
|
||||
modified_range,
|
||||
} = Replacement::between(
|
||||
source,
|
||||
source_index.line_starts(),
|
||||
modified,
|
||||
modified_index.line_starts(),
|
||||
);
|
||||
|
||||
Ok(vec![lsp_types::TextEdit {
|
||||
range: source_range.to_range(source, source_index, encoding),
|
||||
new_text: modified[modified_range].to_owned(),
|
||||
}])
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue