mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-15 16:10:17 +00:00
Range formatting: Fix invalid syntax after parenthesizing expression (#9751)
This commit is contained in:
parent
50bfbcf568
commit
4f7fb566f0
24 changed files with 351 additions and 212 deletions
|
@ -3,7 +3,7 @@ use tracing::Level;
|
|||
|
||||
pub use range::format_range;
|
||||
use ruff_formatter::prelude::*;
|
||||
use ruff_formatter::{format, FormatError, Formatted, PrintError, Printed, SourceCode};
|
||||
use ruff_formatter::{format, write, FormatError, Formatted, PrintError, Printed, SourceCode};
|
||||
use ruff_python_ast::AstNode;
|
||||
use ruff_python_ast::Mod;
|
||||
use ruff_python_index::tokens_and_ranges;
|
||||
|
@ -19,6 +19,7 @@ pub use crate::options::{
|
|||
DocstringCode, DocstringCodeLineWidth, MagicTrailingComma, PreviewMode, PyFormatOptions,
|
||||
PythonVersion, QuoteStyle,
|
||||
};
|
||||
use crate::range::is_logical_line;
|
||||
pub use crate::shared_traits::{AsFormat, FormattedIter, FormattedIterExt, IntoFormat};
|
||||
use crate::verbatim::suppressed_node;
|
||||
|
||||
|
@ -59,19 +60,27 @@ where
|
|||
} else {
|
||||
leading_comments(node_comments.leading).fmt(f)?;
|
||||
|
||||
let is_source_map_enabled = f.options().source_map_generation().is_enabled();
|
||||
let node_ref = node.as_any_node_ref();
|
||||
|
||||
if is_source_map_enabled {
|
||||
source_position(node.start()).fmt(f)?;
|
||||
}
|
||||
// Emit source map information for nodes that are valid "narrowing" targets
|
||||
// in range formatting. Never emit source map information if they're disabled
|
||||
// for performance reasons.
|
||||
let emit_source_position = (is_logical_line(node_ref) || node_ref.is_mod_module())
|
||||
&& f.options().source_map_generation().is_enabled();
|
||||
|
||||
emit_source_position
|
||||
.then_some(source_position(node.start()))
|
||||
.fmt(f)?;
|
||||
|
||||
self.fmt_fields(node, f)?;
|
||||
|
||||
if is_source_map_enabled {
|
||||
source_position(node.end()).fmt(f)?;
|
||||
}
|
||||
|
||||
trailing_comments(node_comments.trailing).fmt(f)
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
emit_source_position.then_some(source_position(node.end())),
|
||||
trailing_comments(node_comments.trailing)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,15 +258,36 @@ def main() -> None:
|
|||
#[ignore]
|
||||
#[test]
|
||||
fn range_formatting_quick_test() {
|
||||
let source = r#"def test2( a): print("body" )
|
||||
"#;
|
||||
let source = r#"def convert_str(value: str) -> str: # Trailing comment
|
||||
"""Return a string as-is."""
|
||||
|
||||
let start = TextSize::new(20);
|
||||
let end = TextSize::new(35);
|
||||
<RANGE_START>
|
||||
|
||||
return value # Trailing comment
|
||||
<RANGE_END>"#;
|
||||
|
||||
let mut source = source.to_string();
|
||||
|
||||
let start = TextSize::try_from(
|
||||
source
|
||||
.find("<RANGE_START>")
|
||||
.expect("Start marker not found"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
source.replace_range(
|
||||
start.to_usize()..start.to_usize() + "<RANGE_START>".len(),
|
||||
"",
|
||||
);
|
||||
|
||||
let end =
|
||||
TextSize::try_from(source.find("<RANGE_END>").expect("End marker not found")).unwrap();
|
||||
|
||||
source.replace_range(end.to_usize()..end.to_usize() + "<RANGE_END>".len(), "");
|
||||
|
||||
let source_type = PySourceType::Python;
|
||||
let options = PyFormatOptions::from_source_type(source_type);
|
||||
let printed = format_range(source, TextRange::new(start, end), options).unwrap();
|
||||
let printed = format_range(&source, TextRange::new(start, end), options).unwrap();
|
||||
|
||||
let mut formatted = source.to_string();
|
||||
formatted.replace_range(
|
||||
|
@ -267,9 +297,11 @@ def main() -> None:
|
|||
|
||||
assert_eq!(
|
||||
formatted,
|
||||
r#"def test2(a):
|
||||
print("body")
|
||||
"#
|
||||
r#"print ( "format me" )
|
||||
print("format me")
|
||||
print("format me")
|
||||
print ( "format me" )
|
||||
print ( "format me" )"#
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -300,7 +332,7 @@ def main() -> None:
|
|||
while let Some(word) = words.next() {
|
||||
let is_last = words.peek().is_none();
|
||||
let format_word = format_with(|f| {
|
||||
write!(f, [text(word, None)])?;
|
||||
write!(f, [text(word)])?;
|
||||
|
||||
if is_last {
|
||||
write!(f, [token("\"")])?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue