mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-22 12:35:08 +00:00
Support fmt: skip
for simple-statements and decorators (#6561)
This commit is contained in:
parent
e3ecbe660e
commit
4dc32a00d0
40 changed files with 545 additions and 316 deletions
|
@ -215,6 +215,18 @@ pub(crate) enum SuppressionKind {
|
|||
Skip,
|
||||
}
|
||||
|
||||
impl SuppressionKind {
|
||||
pub(crate) fn has_skip_comment(trailing_comments: &[SourceComment], source: &str) -> bool {
|
||||
trailing_comments.iter().any(|comment| {
|
||||
comment.line_position().is_end_of_line()
|
||||
&& matches!(
|
||||
comment.suppression_kind(source),
|
||||
Some(SuppressionKind::Skip | SuppressionKind::Off)
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Ranged for SourceComment {
|
||||
#[inline]
|
||||
fn range(&self) -> TextRange {
|
||||
|
|
|
@ -905,7 +905,7 @@ fn handle_leading_class_with_decorators_comment<'a>(
|
|||
comment: DecoratedComment<'a>,
|
||||
class_def: &'a ast::StmtClassDef,
|
||||
) -> CommentPlacement<'a> {
|
||||
if comment.start() < class_def.name.start() {
|
||||
if comment.line_position().is_own_line() && comment.start() < class_def.name.start() {
|
||||
if let Some(decorator) = class_def.decorator_list.last() {
|
||||
if decorator.end() < comment.start() {
|
||||
return CommentPlacement::dangling(class_def, comment);
|
||||
|
|
|
@ -94,7 +94,7 @@ impl FormatRule<Expr, PyFormatContext<'_>> for FormatExpr {
|
|||
Expr::List(expr) => expr.format().fmt(f),
|
||||
Expr::Tuple(expr) => expr.format().fmt(f),
|
||||
Expr::Slice(expr) => expr.format().fmt(f),
|
||||
Expr::IpyEscapeCommand(_) => todo!(),
|
||||
Expr::IpyEscapeCommand(expr) => expr.format().fmt(f),
|
||||
});
|
||||
|
||||
let parenthesize = match parentheses {
|
||||
|
|
|
@ -19,6 +19,7 @@ use crate::comments::{
|
|||
};
|
||||
use crate::context::PyFormatContext;
|
||||
pub use crate::options::{MagicTrailingComma, PyFormatOptions, QuoteStyle};
|
||||
use crate::verbatim::suppressed_node;
|
||||
|
||||
pub(crate) mod builders;
|
||||
pub mod cli;
|
||||
|
@ -50,24 +51,21 @@ where
|
|||
|
||||
let node_comments = comments.leading_dangling_trailing_comments(node.as_any_node_ref());
|
||||
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
leading_comments(node_comments.leading),
|
||||
source_position(node.start())
|
||||
]
|
||||
)?;
|
||||
if self.is_suppressed(node_comments.trailing, f.context()) {
|
||||
suppressed_node(node.as_any_node_ref()).fmt(f)
|
||||
} else {
|
||||
leading_comments(node_comments.leading).fmt(f)?;
|
||||
self.fmt_fields(node, f)?;
|
||||
self.fmt_dangling_comments(node_comments.dangling, f)?;
|
||||
|
||||
self.fmt_fields(node, f)?;
|
||||
self.fmt_dangling_comments(node_comments.dangling, f)?;
|
||||
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
source_position(node.end()),
|
||||
trailing_comments(node_comments.trailing)
|
||||
]
|
||||
)
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
source_position(node.end()),
|
||||
trailing_comments(node_comments.trailing)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Formats the node's fields.
|
||||
|
@ -87,6 +85,14 @@ where
|
|||
) -> FormatResult<()> {
|
||||
dangling_comments(dangling_node_comments).fmt(f)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
_trailing_comments: &[SourceComment],
|
||||
_context: &PyFormatContext,
|
||||
) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
|
@ -236,16 +242,12 @@ if True:
|
|||
#[ignore]
|
||||
#[test]
|
||||
fn quick_test() {
|
||||
let src = r#"def test():
|
||||
# fmt: off
|
||||
let src = r#"
|
||||
@MyDecorator(list = a) # fmt: skip
|
||||
# trailing comment
|
||||
class Test:
|
||||
pass
|
||||
|
||||
a + b
|
||||
|
||||
|
||||
|
||||
# suppressed comments
|
||||
|
||||
a + b # formatted
|
||||
|
||||
"#;
|
||||
// Tokenize once
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
|
@ -23,4 +24,12 @@ impl FormatNodeRule<Decorator> for FormatDecorator {
|
|||
]
|
||||
)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::prelude::*;
|
||||
use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule};
|
||||
use ruff_python_ast::Stmt;
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) mod stmt_ann_assign;
|
||||
pub(crate) mod stmt_assert;
|
||||
pub(crate) mod stmt_assign;
|
||||
|
@ -59,7 +60,7 @@ impl FormatRule<Stmt, PyFormatContext<'_>> for FormatStmt {
|
|||
Stmt::Break(x) => x.format().fmt(f),
|
||||
Stmt::Continue(x) => x.format().fmt(f),
|
||||
Stmt::TypeAlias(x) => x.format().fmt(f),
|
||||
Stmt::IpyEscapeCommand(_) => todo!(),
|
||||
Stmt::IpyEscapeCommand(x) => x.format().fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
|
@ -42,4 +43,12 @@ impl FormatNodeRule<StmtAnnAssign> for FormatStmtAnnAssign {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::context::PyFormatContext;
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
|
@ -38,4 +40,12 @@ impl FormatNodeRule<StmtAssert> for FormatStmtAssert {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use ruff_formatter::{format_args, write, FormatError};
|
||||
use ruff_python_ast::{Expr, StmtAssign};
|
||||
|
||||
|
@ -42,6 +43,14 @@ impl FormatNodeRule<StmtAssign> for FormatStmtAssign {
|
|||
)]
|
||||
)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use ruff_formatter::write;
|
||||
use ruff_python_ast::StmtAugAssign;
|
||||
|
||||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::StmtAugAssign;
|
||||
use crate::prelude::*;
|
||||
use crate::{AsFormat, FormatNodeRule};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtAugAssign;
|
||||
|
@ -28,4 +30,12 @@ impl FormatNodeRule<StmtAugAssign> for FormatStmtAugAssign {
|
|||
]
|
||||
)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::text;
|
||||
use ruff_formatter::{Format, FormatResult};
|
||||
use ruff_python_ast::StmtBreak;
|
||||
|
||||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtBreak;
|
||||
|
||||
|
@ -10,4 +11,12 @@ impl FormatNodeRule<StmtBreak> for FormatStmtBreak {
|
|||
fn fmt_fields(&self, _item: &StmtBreak, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
text("break").fmt(f)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use ruff_formatter::{write, Buffer};
|
||||
use ruff_python_ast::{Ranged, StmtClassDef};
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::{Decorator, Ranged, StmtClassDef};
|
||||
use ruff_python_trivia::lines_after_ignoring_trivia;
|
||||
|
||||
use crate::comments::{leading_comments, trailing_comments, SourceComment};
|
||||
|
@ -30,31 +30,11 @@ impl FormatNodeRule<StmtClassDef> for FormatStmtClassDef {
|
|||
let (leading_definition_comments, trailing_definition_comments) =
|
||||
dangling_comments.split_at(trailing_definition_comments_start);
|
||||
|
||||
if let Some(last_decorator) = decorator_list.last() {
|
||||
f.join_with(hard_line_break())
|
||||
.entries(decorator_list.iter().formatted())
|
||||
.finish()?;
|
||||
|
||||
if leading_definition_comments.is_empty() {
|
||||
write!(f, [hard_line_break()])?;
|
||||
} else {
|
||||
// Write any leading definition comments (between last decorator and the header)
|
||||
// while maintaining the right amount of empty lines between the comment
|
||||
// and the last decorator.
|
||||
let leading_line =
|
||||
if lines_after_ignoring_trivia(last_decorator.end(), f.context().source()) <= 1
|
||||
{
|
||||
hard_line_break()
|
||||
} else {
|
||||
empty_line()
|
||||
};
|
||||
|
||||
write!(
|
||||
f,
|
||||
[leading_line, leading_comments(leading_definition_comments)]
|
||||
)?;
|
||||
}
|
||||
FormatDecorators {
|
||||
decorators: decorator_list,
|
||||
leading_definition_comments,
|
||||
}
|
||||
.fmt(f)?;
|
||||
|
||||
write!(f, [text("class"), space(), name.format()])?;
|
||||
|
||||
|
@ -136,3 +116,43 @@ impl FormatNodeRule<StmtClassDef> for FormatStmtClassDef {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) struct FormatDecorators<'a> {
|
||||
pub(super) decorators: &'a [Decorator],
|
||||
pub(super) leading_definition_comments: &'a [SourceComment],
|
||||
}
|
||||
|
||||
impl Format<PyFormatContext<'_>> for FormatDecorators<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
||||
if let Some(last_decorator) = self.decorators.last() {
|
||||
f.join_with(hard_line_break())
|
||||
.entries(self.decorators.iter().formatted())
|
||||
.finish()?;
|
||||
|
||||
if self.leading_definition_comments.is_empty() {
|
||||
write!(f, [hard_line_break()])?;
|
||||
} else {
|
||||
// Write any leading definition comments (between last decorator and the header)
|
||||
// while maintaining the right amount of empty lines between the comment
|
||||
// and the last decorator.
|
||||
let leading_line =
|
||||
if lines_after_ignoring_trivia(last_decorator.end(), f.context().source()) <= 1
|
||||
{
|
||||
hard_line_break()
|
||||
} else {
|
||||
empty_line()
|
||||
};
|
||||
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
leading_line,
|
||||
leading_comments(self.leading_definition_comments)
|
||||
]
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::text;
|
||||
use ruff_formatter::{Format, FormatResult};
|
||||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use ruff_python_ast::StmtContinue;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtContinue;
|
||||
|
||||
|
@ -10,4 +11,12 @@ impl FormatNodeRule<StmtContinue> for FormatStmtContinue {
|
|||
fn fmt_fields(&self, _item: &StmtContinue, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
text("continue").fmt(f)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use ruff_formatter::write;
|
||||
use ruff_python_ast::{Ranged, StmtDelete};
|
||||
|
||||
use crate::builders::{parenthesize_if_expands, PyFormatterExtensions};
|
||||
use crate::comments::{dangling_node_comments, SourceComment};
|
||||
use crate::comments::{dangling_node_comments, SourceComment, SuppressionKind};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{block_indent, format_with, space, text};
|
||||
use ruff_formatter::{write, Buffer, Format, FormatResult};
|
||||
use ruff_python_ast::{Ranged, StmtDelete};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtDelete;
|
||||
|
@ -61,4 +62,12 @@ impl FormatNodeRule<StmtDelete> for FormatStmtDelete {
|
|||
// Handled in `fmt_fields`
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use ruff_python_ast as ast;
|
||||
use ruff_python_ast::{Expr, Operator, StmtExpr};
|
||||
|
||||
|
@ -19,6 +20,14 @@ impl FormatNodeRule<StmtExpr> for FormatStmtExpr {
|
|||
value.format().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
||||
const fn is_arithmetic_like(expression: &Expr) -> bool {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_formatter::{format_args, write, Buffer, FormatResult};
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::{Expr, Ranged, Stmt, StmtFor};
|
||||
|
||||
use crate::comments::{leading_alternate_branch_comments, trailing_comments, SourceComment};
|
||||
|
@ -6,7 +6,7 @@ use crate::expression::expr_tuple::TupleParentheses;
|
|||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ExprTupleWithoutParentheses<'a>(&'a Expr);
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use ruff_formatter::write;
|
||||
use ruff_python_ast::{Parameters, Ranged, StmtFunctionDef};
|
||||
use ruff_python_trivia::{lines_after_ignoring_trivia, SimpleTokenKind, SimpleTokenizer};
|
||||
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
|
||||
|
||||
use crate::comments::{leading_comments, trailing_comments, SourceComment};
|
||||
use crate::comments::{trailing_comments, SourceComment};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::{Parentheses, Parenthesize};
|
||||
use crate::prelude::*;
|
||||
use crate::statement::stmt_class_def::FormatDecorators;
|
||||
use crate::statement::suite::SuiteKind;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
|
@ -14,6 +15,17 @@ pub struct FormatStmtFunctionDef;
|
|||
|
||||
impl FormatNodeRule<StmtFunctionDef> for FormatStmtFunctionDef {
|
||||
fn fmt_fields(&self, item: &StmtFunctionDef, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
let StmtFunctionDef {
|
||||
range: _,
|
||||
is_async,
|
||||
decorator_list,
|
||||
name,
|
||||
type_params,
|
||||
parameters,
|
||||
returns,
|
||||
body,
|
||||
} = item;
|
||||
|
||||
let comments = f.context().comments().clone();
|
||||
|
||||
let dangling_comments = comments.dangling_comments(item);
|
||||
|
@ -23,46 +35,26 @@ impl FormatNodeRule<StmtFunctionDef> for FormatStmtFunctionDef {
|
|||
let (leading_definition_comments, trailing_definition_comments) =
|
||||
dangling_comments.split_at(trailing_definition_comments_start);
|
||||
|
||||
if let Some(last_decorator) = item.decorator_list.last() {
|
||||
f.join_with(hard_line_break())
|
||||
.entries(item.decorator_list.iter().formatted())
|
||||
.finish()?;
|
||||
|
||||
if leading_definition_comments.is_empty() {
|
||||
write!(f, [hard_line_break()])?;
|
||||
} else {
|
||||
// Write any leading definition comments (between last decorator and the header)
|
||||
// while maintaining the right amount of empty lines between the comment
|
||||
// and the last decorator.
|
||||
let leading_line =
|
||||
if lines_after_ignoring_trivia(last_decorator.end(), f.context().source()) <= 1
|
||||
{
|
||||
hard_line_break()
|
||||
} else {
|
||||
empty_line()
|
||||
};
|
||||
|
||||
write!(
|
||||
f,
|
||||
[leading_line, leading_comments(leading_definition_comments)]
|
||||
)?;
|
||||
}
|
||||
FormatDecorators {
|
||||
decorators: decorator_list,
|
||||
leading_definition_comments,
|
||||
}
|
||||
.fmt(f)?;
|
||||
|
||||
if item.is_async {
|
||||
if *is_async {
|
||||
write!(f, [text("async"), space()])?;
|
||||
}
|
||||
|
||||
write!(f, [text("def"), space(), item.name.format()])?;
|
||||
write!(f, [text("def"), space(), name.format()])?;
|
||||
|
||||
if let Some(type_params) = item.type_params.as_ref() {
|
||||
if let Some(type_params) = type_params.as_ref() {
|
||||
write!(f, [type_params.format()])?;
|
||||
}
|
||||
|
||||
let format_inner = format_with(|f: &mut PyFormatter| {
|
||||
write!(f, [item.parameters.format()])?;
|
||||
write!(f, [parameters.format()])?;
|
||||
|
||||
if let Some(return_annotation) = item.returns.as_ref() {
|
||||
if let Some(return_annotation) = returns.as_ref() {
|
||||
write!(f, [space(), text("->"), space()])?;
|
||||
|
||||
if return_annotation.is_tuple_expr() {
|
||||
|
@ -110,7 +102,7 @@ impl FormatNodeRule<StmtFunctionDef> for FormatStmtFunctionDef {
|
|||
[maybe_parenthesize_expression(
|
||||
return_annotation,
|
||||
item,
|
||||
if empty_parameters(&item.parameters, f.context().source()) {
|
||||
if empty_parameters(parameters, f.context().source()) {
|
||||
// If the parameters are empty, add parentheses if the return annotation
|
||||
// breaks at all.
|
||||
Parenthesize::IfBreaksOrIfRequired
|
||||
|
@ -142,7 +134,7 @@ impl FormatNodeRule<StmtFunctionDef> for FormatStmtFunctionDef {
|
|||
[
|
||||
text(":"),
|
||||
trailing_comments(trailing_definition_comments),
|
||||
block_indent(&item.body.format().with_options(SuiteKind::Function))
|
||||
block_indent(&body.format().with_options(SuiteKind::Function))
|
||||
]
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::StmtGlobal;
|
||||
|
@ -50,4 +51,12 @@ impl FormatNodeRule<StmtGlobal> for FormatStmtGlobal {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
use crate::{FormatNodeRule, FormattedIterExt, PyFormatter};
|
||||
use ruff_formatter::prelude::{format_args, format_with, space, text};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use crate::prelude::*;
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::StmtImport;
|
||||
|
||||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtImport;
|
||||
|
||||
|
@ -16,4 +18,12 @@ impl FormatNodeRule<StmtImport> for FormatStmtImport {
|
|||
});
|
||||
write!(f, [text("import"), space(), names])
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
use ruff_formatter::prelude::{dynamic_text, format_with, space, text};
|
||||
use ruff_formatter::{write, Buffer, Format, FormatResult};
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::{Ranged, StmtImportFrom};
|
||||
|
||||
use crate::builders::{parenthesize_if_expands, PyFormatterExtensions, TrailingComma};
|
||||
use crate::comments::SourceComment;
|
||||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::expression::parentheses::parenthesized;
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtImportFrom;
|
||||
|
@ -78,4 +78,12 @@ impl FormatNodeRule<StmtImportFrom> for FormatStmtImportFrom {
|
|||
// Handled in `fmt_fields`
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::prelude::*;
|
||||
use ruff_python_ast::{Ranged, StmtIpyEscapeCommand};
|
||||
|
||||
|
@ -8,4 +9,12 @@ impl FormatNodeRule<StmtIpyEscapeCommand> for FormatStmtIpyEscapeCommand {
|
|||
fn fmt_fields(&self, item: &StmtIpyEscapeCommand, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
source_text_slice(item.range(), ContainsNewlines::No).fmt(f)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use ruff_formatter::{format_args, write, Buffer, FormatResult};
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::StmtMatch;
|
||||
|
||||
use crate::comments::{leading_alternate_branch_comments, trailing_comments, SourceComment};
|
||||
|
@ -6,7 +6,7 @@ use crate::context::{NodeLevel, WithNodeLevel};
|
|||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtMatch;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::StmtNonlocal;
|
||||
|
@ -50,4 +51,12 @@ impl FormatNodeRule<StmtNonlocal> for FormatStmtNonlocal {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::text;
|
||||
use ruff_formatter::{Format, FormatResult};
|
||||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use ruff_python_ast::StmtPass;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtPass;
|
||||
|
||||
|
@ -10,4 +11,12 @@ impl FormatNodeRule<StmtPass> for FormatStmtPass {
|
|||
fn fmt_fields(&self, _item: &StmtPass, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
text("pass").fmt(f)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
use ruff_formatter::{write, Buffer, Format, FormatResult};
|
||||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::StmtRaise;
|
||||
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use ruff_python_ast::StmtRaise;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtRaise;
|
||||
|
@ -42,4 +43,12 @@ impl FormatNodeRule<StmtRaise> for FormatStmtRaise {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
use ruff_formatter::write;
|
||||
use ruff_python_ast::StmtReturn;
|
||||
|
||||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
use ruff_formatter::{write, Buffer, Format, FormatResult};
|
||||
use ruff_python_ast::StmtReturn;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtReturn;
|
||||
|
@ -24,4 +26,12 @@ impl FormatNodeRule<StmtReturn> for FormatStmtReturn {
|
|||
text("return").fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use ruff_formatter::FormatRuleWithOptions;
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_formatter::{write, FormatRuleWithOptions};
|
||||
use ruff_python_ast::{ExceptHandler, Ranged, StmtTry, Suite};
|
||||
|
||||
use crate::comments;
|
||||
use crate::comments::{leading_alternate_branch_comments, trailing_comments, SourceComment};
|
||||
use crate::comments::SourceComment;
|
||||
use crate::comments::{leading_alternate_branch_comments, trailing_comments};
|
||||
use crate::other::except_handler_except_handler::ExceptHandlerKind;
|
||||
use crate::prelude::*;
|
||||
use crate::statement::{FormatRefWithRule, Stmt};
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
use crate::comments::{SourceComment, SuppressionKind};
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::StmtTypeAlias;
|
||||
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::AsFormat;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::StmtTypeAlias;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtTypeAlias;
|
||||
|
@ -34,4 +35,12 @@ impl FormatNodeRule<StmtTypeAlias> for FormatStmtTypeAlias {
|
|||
]
|
||||
)
|
||||
}
|
||||
|
||||
fn is_suppressed(
|
||||
&self,
|
||||
trailing_comments: &[SourceComment],
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
SuppressionKind::has_skip_comment(trailing_comments, context.source())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
use ruff_formatter::write;
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::{Ranged, Stmt, StmtWhile};
|
||||
|
||||
use crate::comments::{leading_alternate_branch_comments, trailing_comments, SourceComment};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::{Ranged, Stmt, StmtWhile};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtWhile;
|
||||
|
|
|
@ -10,8 +10,9 @@ use crate::context::{NodeLevel, WithNodeLevel};
|
|||
use crate::expression::expr_constant::ExprConstantLayout;
|
||||
use crate::expression::string::StringLayout;
|
||||
use crate::prelude::*;
|
||||
use crate::statement::stmt_expr::FormatStmtExpr;
|
||||
use crate::verbatim::{
|
||||
write_suppressed_statements_starting_with_leading_comment,
|
||||
suppressed_node, write_suppressed_statements_starting_with_leading_comment,
|
||||
write_suppressed_statements_starting_with_trailing_comment,
|
||||
};
|
||||
|
||||
|
@ -399,27 +400,33 @@ impl<'a> DocstringStmt<'a> {
|
|||
|
||||
impl Format<PyFormatContext<'_>> for DocstringStmt<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
||||
// SAFETY: Safe because `DocStringStmt` guarantees that it only ever wraps a `ExprStmt` containing a `ConstantExpr`.
|
||||
let constant = self
|
||||
.0
|
||||
.as_expr_stmt()
|
||||
.unwrap()
|
||||
.value
|
||||
.as_constant_expr()
|
||||
.unwrap();
|
||||
let comments = f.context().comments().clone();
|
||||
let node_comments = comments.leading_dangling_trailing_comments(self.0);
|
||||
|
||||
// We format the expression, but the statement carries the comments
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
leading_comments(comments.leading_comments(self.0)),
|
||||
constant
|
||||
.format()
|
||||
.with_options(ExprConstantLayout::String(StringLayout::DocString)),
|
||||
trailing_comments(comments.trailing_comments(self.0)),
|
||||
]
|
||||
)
|
||||
if FormatStmtExpr.is_suppressed(node_comments.trailing, f.context()) {
|
||||
suppressed_node(self.0).fmt(f)
|
||||
} else {
|
||||
// SAFETY: Safe because `DocStringStmt` guarantees that it only ever wraps a `ExprStmt` containing a `ConstantExpr`.
|
||||
let constant = self
|
||||
.0
|
||||
.as_expr_stmt()
|
||||
.unwrap()
|
||||
.value
|
||||
.as_constant_expr()
|
||||
.unwrap();
|
||||
|
||||
// We format the expression, but the statement carries the comments
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
leading_comments(node_comments.leading),
|
||||
constant
|
||||
.format()
|
||||
.with_options(ExprConstantLayout::String(StringLayout::DocString)),
|
||||
trailing_comments(node_comments.trailing),
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -882,3 +882,51 @@ impl Format<PyFormatContext<'_>> for VerbatimText {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Disables formatting for `node` and instead uses the same formatting as the node has in source.
|
||||
///
|
||||
/// The `node` gets indented as any formatted node to avoid syntax errors when the indentation string changes (e.g. from 2 spaces to 4).
|
||||
/// The `node`s leading and trailing comments are formatted as usual, except if they fall into the suppressed node's range.
|
||||
#[cold]
|
||||
pub(crate) fn suppressed_node<'a, N>(node: N) -> FormatSuppressedNode<'a>
|
||||
where
|
||||
N: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
FormatSuppressedNode { node: node.into() }
|
||||
}
|
||||
|
||||
pub(crate) struct FormatSuppressedNode<'a> {
|
||||
node: AnyNodeRef<'a>,
|
||||
}
|
||||
|
||||
impl Format<PyFormatContext<'_>> for FormatSuppressedNode<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
||||
let comments = f.context().comments().clone();
|
||||
let node_comments = comments.leading_dangling_trailing_comments(self.node);
|
||||
|
||||
// Mark all comments as formatted that fall into the node range
|
||||
for comment in node_comments.leading {
|
||||
if comment.start() > self.node.start() {
|
||||
comment.mark_formatted();
|
||||
}
|
||||
}
|
||||
|
||||
for comment in node_comments.trailing {
|
||||
if comment.start() < self.node.end() {
|
||||
comment.mark_formatted();
|
||||
}
|
||||
}
|
||||
|
||||
comments.mark_verbatim_node_comments_formatted(self.node);
|
||||
|
||||
// Write the outer comments and format the node as verbatim
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
leading_comments(node_comments.leading),
|
||||
verbatim_text(self.node, ContainsNewlines::Detect),
|
||||
trailing_comments(node_comments.trailing)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue