This commit is contained in:
Dylan 2025-12-12 12:36:36 +01:00 committed by GitHub
commit bbe88d949f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
24 changed files with 130 additions and 178 deletions

View File

@ -511,6 +511,54 @@ pub(crate) fn has_skip_comment(trailing_comments: &[SourceComment], source: &str
}) })
} }
pub(crate) struct SuppressedNodeRanges(Vec<TextRange>);
impl<'a> SuppressedNodeRanges {
pub(crate) fn from_comments(comments: &Comments<'a>, source: &'a str) -> Self {
let map = &comments.clone().data.comments;
let mut ranges = map
.keys()
.copied()
.filter_map(|key| suppressed_range(key.node(), map.trailing(&key), source))
.collect::<Vec<_>>();
ranges.sort_by_key(ruff_text_size::Ranged::start);
Self(ranges)
}
pub(crate) fn contains(&self, node: AnyNodeRef<'_>) -> bool {
let target = node.range();
self.0
.binary_search_by(|range| {
if range.eq(&target) {
std::cmp::Ordering::Equal
} else if range.start() < target.start() {
std::cmp::Ordering::Less
} else {
std::cmp::Ordering::Greater
}
})
.is_ok()
}
}
fn suppressed_range<'a>(
node: AnyNodeRef<'a>,
trailing_comments: &[SourceComment],
source: &'a str,
) -> Option<TextRange> {
if has_skip_comment(trailing_comments, source) {
let end = node.end();
let start = node.start();
Some(TextRange::new(start, end))
} else {
None
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use insta::assert_debug_snapshot; use insta::assert_debug_snapshot;

View File

@ -2,17 +2,19 @@ use std::fmt::{Debug, Formatter};
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use ruff_formatter::{Buffer, FormatContext, GroupId, IndentWidth, SourceCode}; use ruff_formatter::{Buffer, FormatContext, GroupId, IndentWidth, SourceCode};
use ruff_python_ast::AnyNodeRef;
use ruff_python_ast::str::Quote; use ruff_python_ast::str::Quote;
use ruff_python_ast::token::Tokens; use ruff_python_ast::token::Tokens;
use crate::PyFormatOptions; use crate::PyFormatOptions;
use crate::comments::Comments; use crate::comments::{Comments, SuppressedNodeRanges};
use crate::other::interpolated_string::InterpolatedStringContext; use crate::other::interpolated_string::InterpolatedStringContext;
pub struct PyFormatContext<'a> { pub struct PyFormatContext<'a> {
options: PyFormatOptions, options: PyFormatOptions,
contents: &'a str, contents: &'a str,
comments: Comments<'a>, comments: Comments<'a>,
suppressed_nodes: SuppressedNodeRanges,
tokens: &'a Tokens, tokens: &'a Tokens,
node_level: NodeLevel, node_level: NodeLevel,
indent_level: IndentLevel, indent_level: IndentLevel,
@ -34,12 +36,14 @@ impl<'a> PyFormatContext<'a> {
options: PyFormatOptions, options: PyFormatOptions,
contents: &'a str, contents: &'a str,
comments: Comments<'a>, comments: Comments<'a>,
suppressed_nodes: SuppressedNodeRanges,
tokens: &'a Tokens, tokens: &'a Tokens,
) -> Self { ) -> Self {
Self { Self {
options, options,
contents, contents,
comments, comments,
suppressed_nodes,
tokens, tokens,
node_level: NodeLevel::TopLevel(TopLevelStatementPosition::Other), node_level: NodeLevel::TopLevel(TopLevelStatementPosition::Other),
indent_level: IndentLevel::new(0), indent_level: IndentLevel::new(0),
@ -112,6 +116,11 @@ impl<'a> PyFormatContext<'a> {
pub(crate) const fn is_preview(&self) -> bool { pub(crate) const fn is_preview(&self) -> bool {
self.options.preview().is_enabled() self.options.preview().is_enabled()
} }
/// Returns `true` if node is suppressed via skip comment.
pub(crate) fn is_suppressed(&self, node: AnyNodeRef<'_>) -> bool {
self.suppressed_nodes.contains(node)
}
} }
impl FormatContext for PyFormatContext<'_> { impl FormatContext for PyFormatContext<'_> {

View File

@ -14,7 +14,8 @@ use ruff_python_trivia::CommentRanges;
use ruff_text_size::{Ranged, TextRange}; use ruff_text_size::{Ranged, TextRange};
use crate::comments::{ use crate::comments::{
Comments, SourceComment, has_skip_comment, leading_comments, trailing_comments, Comments, SourceComment, SuppressedNodeRanges, has_skip_comment, leading_comments,
trailing_comments,
}; };
pub use crate::context::PyFormatContext; pub use crate::context::PyFormatContext;
pub use crate::db::Db; pub use crate::db::Db;
@ -61,7 +62,7 @@ where
let node_ref = AnyNodeRef::from(node); let node_ref = AnyNodeRef::from(node);
let node_comments = comments.leading_dangling_trailing(node_ref); let node_comments = comments.leading_dangling_trailing(node_ref);
if self.is_suppressed(node_comments.trailing, f.context()) { if self.is_suppressed(node, f.context()) {
suppressed_node(node_ref).fmt(f) suppressed_node(node_ref).fmt(f)
} else { } else {
leading_comments(node_comments.leading).fmt(f)?; leading_comments(node_comments.leading).fmt(f)?;
@ -99,11 +100,7 @@ where
/// Formats the node's fields. /// Formats the node's fields.
fn fmt_fields(&self, item: &N, f: &mut PyFormatter) -> FormatResult<()>; fn fmt_fields(&self, item: &N, f: &mut PyFormatter) -> FormatResult<()>;
fn is_suppressed( fn is_suppressed(&self, _node: &N, _context: &PyFormatContext) -> bool {
&self,
_trailing_comments: &[SourceComment],
_context: &PyFormatContext,
) -> bool {
false false
} }
} }
@ -178,9 +175,10 @@ where
{ {
let source_code = SourceCode::new(source); let source_code = SourceCode::new(source);
let comments = Comments::from_ast(parsed.syntax(), source_code, comment_ranges); let comments = Comments::from_ast(parsed.syntax(), source_code, comment_ranges);
let suppressed_nodes = SuppressedNodeRanges::from_comments(&comments, source);
let formatted = format!( let formatted = format!(
PyFormatContext::new(options, source, comments, parsed.tokens()), PyFormatContext::new(options, source, comments, suppressed_nodes, parsed.tokens()),
[parsed.syntax().format()] [parsed.syntax().format()]
)?; )?;
formatted formatted

View File

@ -1,10 +1,9 @@
use ruff_formatter::write; use ruff_formatter::write;
use ruff_python_ast::Decorator; use ruff_python_ast::Decorator;
use crate::comments::SourceComment;
use crate::expression::maybe_parenthesize_expression; use crate::expression::maybe_parenthesize_expression;
use crate::expression::parentheses::Parenthesize; use crate::expression::parentheses::Parenthesize;
use crate::{has_skip_comment, prelude::*}; use crate::prelude::*;
#[derive(Default)] #[derive(Default)]
pub struct FormatDecorator; pub struct FormatDecorator;
@ -25,12 +24,7 @@ impl FormatNodeRule<Decorator> for FormatDecorator {
] ]
) )
} }
fn is_suppressed(&self, node: &Decorator, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -12,7 +12,7 @@ use ruff_python_trivia::{
}; };
use ruff_text_size::{Ranged, TextLen, TextRange, TextSize}; use ruff_text_size::{Ranged, TextLen, TextRange, TextSize};
use crate::comments::Comments; use crate::comments::{Comments, SuppressedNodeRanges};
use crate::context::{IndentLevel, NodeLevel}; use crate::context::{IndentLevel, NodeLevel};
use crate::prelude::*; use crate::prelude::*;
use crate::statement::suite::DocstringStmt; use crate::statement::suite::DocstringStmt;
@ -78,11 +78,13 @@ pub fn format_range(
let source_code = SourceCode::new(source); let source_code = SourceCode::new(source);
let comment_ranges = CommentRanges::from(parsed.tokens()); let comment_ranges = CommentRanges::from(parsed.tokens());
let comments = Comments::from_ast(parsed.syntax(), source_code, &comment_ranges); let comments = Comments::from_ast(parsed.syntax(), source_code, &comment_ranges);
let suppressed_nodes = SuppressedNodeRanges::from_comments(&comments, source);
let mut context = PyFormatContext::new( let mut context = PyFormatContext::new(
options.with_source_map_generation(SourceMapGeneration::Enabled), options.with_source_map_generation(SourceMapGeneration::Enabled),
source, source,
comments, comments,
suppressed_nodes,
parsed.tokens(), parsed.tokens(),
); );

View File

@ -1,14 +1,13 @@
use ruff_formatter::write; use ruff_formatter::write;
use ruff_python_ast::StmtAnnAssign; use ruff_python_ast::StmtAnnAssign;
use crate::comments::SourceComment;
use crate::expression::is_splittable_expression; use crate::expression::is_splittable_expression;
use crate::expression::parentheses::Parentheses; use crate::expression::parentheses::Parentheses;
use crate::prelude::*;
use crate::statement::stmt_assign::{ use crate::statement::stmt_assign::{
AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression, AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression,
}; };
use crate::statement::trailing_semicolon; use crate::statement::trailing_semicolon;
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtAnnAssign; pub struct FormatStmtAnnAssign;
@ -84,12 +83,7 @@ impl FormatNodeRule<StmtAnnAssign> for FormatStmtAnnAssign {
Ok(()) Ok(())
} }
fn is_suppressed(&self, node: &StmtAnnAssign, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -2,10 +2,9 @@ use ruff_formatter::prelude::{space, token};
use ruff_formatter::write; use ruff_formatter::write;
use ruff_python_ast::StmtAssert; use ruff_python_ast::StmtAssert;
use crate::comments::SourceComment;
use crate::expression::maybe_parenthesize_expression; use crate::expression::maybe_parenthesize_expression;
use crate::expression::parentheses::Parenthesize; use crate::expression::parentheses::Parenthesize;
use crate::{has_skip_comment, prelude::*}; use crate::prelude::*;
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtAssert; pub struct FormatStmtAssert;
@ -41,12 +40,7 @@ impl FormatNodeRule<StmtAssert> for FormatStmtAssert {
Ok(()) Ok(())
} }
fn is_suppressed(&self, node: &StmtAssert, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -18,13 +18,13 @@ use crate::expression::{
maybe_parenthesize_expression, maybe_parenthesize_expression,
}; };
use crate::other::interpolated_string::InterpolatedStringLayout; use crate::other::interpolated_string::InterpolatedStringLayout;
use crate::prelude::*;
use crate::statement::trailing_semicolon; use crate::statement::trailing_semicolon;
use crate::string::StringLikeExtensions; use crate::string::StringLikeExtensions;
use crate::string::implicit::{ use crate::string::implicit::{
FormatImplicitConcatenatedStringExpanded, FormatImplicitConcatenatedStringFlat, FormatImplicitConcatenatedStringExpanded, FormatImplicitConcatenatedStringFlat,
ImplicitConcatenatedLayout, ImplicitConcatenatedLayout,
}; };
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtAssign; pub struct FormatStmtAssign;
@ -102,13 +102,8 @@ impl FormatNodeRule<StmtAssign> for FormatStmtAssign {
Ok(()) Ok(())
} }
fn is_suppressed(&self, node: &StmtAssign, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,15 +1,14 @@
use ruff_formatter::write; use ruff_formatter::write;
use ruff_python_ast::StmtAugAssign; use ruff_python_ast::StmtAugAssign;
use crate::comments::SourceComment;
use crate::expression::parentheses::is_expression_parenthesized; use crate::expression::parentheses::is_expression_parenthesized;
use crate::prelude::*;
use crate::statement::stmt_assign::{ use crate::statement::stmt_assign::{
AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression, AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression,
has_target_own_parentheses, has_target_own_parentheses,
}; };
use crate::statement::trailing_semicolon; use crate::statement::trailing_semicolon;
use crate::{AsFormat, FormatNodeRule}; use crate::{AsFormat, FormatNodeRule};
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtAugAssign; pub struct FormatStmtAugAssign;
@ -62,12 +61,7 @@ impl FormatNodeRule<StmtAugAssign> for FormatStmtAugAssign {
Ok(()) Ok(())
} }
fn is_suppressed(&self, node: &StmtAugAssign, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,7 +1,6 @@
use ruff_python_ast::StmtBreak; use ruff_python_ast::StmtBreak;
use crate::comments::SourceComment; use crate::prelude::*;
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtBreak; pub struct FormatStmtBreak;
@ -10,12 +9,7 @@ impl FormatNodeRule<StmtBreak> for FormatStmtBreak {
fn fmt_fields(&self, _item: &StmtBreak, f: &mut PyFormatter) -> FormatResult<()> { fn fmt_fields(&self, _item: &StmtBreak, f: &mut PyFormatter) -> FormatResult<()> {
token("break").fmt(f) token("break").fmt(f)
} }
fn is_suppressed(&self, node: &StmtBreak, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,7 +1,6 @@
use ruff_python_ast::StmtContinue; use ruff_python_ast::StmtContinue;
use crate::comments::SourceComment; use crate::prelude::*;
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtContinue; pub struct FormatStmtContinue;
@ -10,12 +9,7 @@ impl FormatNodeRule<StmtContinue> for FormatStmtContinue {
fn fmt_fields(&self, _item: &StmtContinue, f: &mut PyFormatter) -> FormatResult<()> { fn fmt_fields(&self, _item: &StmtContinue, f: &mut PyFormatter) -> FormatResult<()> {
token("continue").fmt(f) token("continue").fmt(f)
} }
fn is_suppressed(&self, node: &StmtContinue, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -3,10 +3,10 @@ use ruff_python_ast::StmtDelete;
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::builders::{PyFormatterExtensions, parenthesize_if_expands}; use crate::builders::{PyFormatterExtensions, parenthesize_if_expands};
use crate::comments::{SourceComment, dangling_node_comments}; use crate::comments::dangling_node_comments;
use crate::expression::maybe_parenthesize_expression; use crate::expression::maybe_parenthesize_expression;
use crate::expression::parentheses::Parenthesize; use crate::expression::parentheses::Parenthesize;
use crate::{has_skip_comment, prelude::*}; use crate::prelude::*;
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtDelete; pub struct FormatStmtDelete;
@ -57,12 +57,7 @@ impl FormatNodeRule<StmtDelete> for FormatStmtDelete {
} }
} }
} }
fn is_suppressed(&self, node: &StmtDelete, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,12 +1,10 @@
use ruff_python_ast as ast; use ruff_python_ast as ast;
use ruff_python_ast::{Expr, Operator, StmtExpr}; use ruff_python_ast::{Expr, Operator, StmtExpr};
use crate::comments::SourceComment;
use crate::expression::maybe_parenthesize_expression; use crate::expression::maybe_parenthesize_expression;
use crate::expression::parentheses::Parenthesize; use crate::expression::parentheses::Parenthesize;
use crate::prelude::*;
use crate::statement::trailing_semicolon; use crate::statement::trailing_semicolon;
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtExpr; pub struct FormatStmtExpr;
@ -30,13 +28,8 @@ impl FormatNodeRule<StmtExpr> for FormatStmtExpr {
Ok(()) Ok(())
} }
fn is_suppressed(&self, node: &StmtExpr, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,8 +1,6 @@
use ruff_formatter::{format_args, write}; use ruff_formatter::{format_args, write};
use ruff_python_ast::StmtGlobal; use ruff_python_ast::StmtGlobal;
use crate::comments::SourceComment;
use crate::has_skip_comment;
use crate::prelude::*; use crate::prelude::*;
#[derive(Default)] #[derive(Default)]
@ -47,12 +45,7 @@ impl FormatNodeRule<StmtGlobal> for FormatStmtGlobal {
) )
} }
} }
fn is_suppressed(&self, node: &StmtGlobal, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,8 +1,7 @@
use ruff_formatter::{format_args, write}; use ruff_formatter::{format_args, write};
use ruff_python_ast::StmtImport; use ruff_python_ast::StmtImport;
use crate::comments::SourceComment; use crate::prelude::*;
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtImport; pub struct FormatStmtImport;
@ -21,12 +20,7 @@ impl FormatNodeRule<StmtImport> for FormatStmtImport {
}); });
write!(f, [token("import"), space(), names]) write!(f, [token("import"), space(), names])
} }
fn is_suppressed(&self, node: &StmtImport, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -3,9 +3,7 @@ use ruff_python_ast::StmtImportFrom;
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::builders::{PyFormatterExtensions, TrailingComma, parenthesize_if_expands}; use crate::builders::{PyFormatterExtensions, TrailingComma, parenthesize_if_expands};
use crate::comments::SourceComment;
use crate::expression::parentheses::parenthesized; use crate::expression::parentheses::parenthesized;
use crate::has_skip_comment;
use crate::other::identifier::DotDelimitedIdentifier; use crate::other::identifier::DotDelimitedIdentifier;
use crate::prelude::*; use crate::prelude::*;
@ -72,12 +70,7 @@ impl FormatNodeRule<StmtImportFrom> for FormatStmtImportFrom {
.fmt(f) .fmt(f)
} }
} }
fn is_suppressed(&self, node: &StmtImportFrom, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,8 +1,7 @@
use ruff_python_ast::StmtIpyEscapeCommand; use ruff_python_ast::StmtIpyEscapeCommand;
use ruff_text_size::Ranged; use ruff_text_size::Ranged;
use crate::comments::SourceComment; use crate::prelude::*;
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtIpyEscapeCommand; pub struct FormatStmtIpyEscapeCommand;
@ -11,12 +10,7 @@ impl FormatNodeRule<StmtIpyEscapeCommand> for FormatStmtIpyEscapeCommand {
fn fmt_fields(&self, item: &StmtIpyEscapeCommand, f: &mut PyFormatter) -> FormatResult<()> { fn fmt_fields(&self, item: &StmtIpyEscapeCommand, f: &mut PyFormatter) -> FormatResult<()> {
source_text_slice(item.range()).fmt(f) source_text_slice(item.range()).fmt(f)
} }
fn is_suppressed(&self, node: &StmtIpyEscapeCommand, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,8 +1,6 @@
use ruff_formatter::{format_args, write}; use ruff_formatter::{format_args, write};
use ruff_python_ast::StmtNonlocal; use ruff_python_ast::StmtNonlocal;
use crate::comments::SourceComment;
use crate::has_skip_comment;
use crate::prelude::*; use crate::prelude::*;
#[derive(Default)] #[derive(Default)]
@ -47,12 +45,7 @@ impl FormatNodeRule<StmtNonlocal> for FormatStmtNonlocal {
) )
} }
} }
fn is_suppressed(&self, node: &StmtNonlocal, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,7 +1,6 @@
use ruff_python_ast::StmtPass; use ruff_python_ast::StmtPass;
use crate::comments::SourceComment; use crate::prelude::*;
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtPass; pub struct FormatStmtPass;
@ -10,12 +9,7 @@ impl FormatNodeRule<StmtPass> for FormatStmtPass {
fn fmt_fields(&self, _item: &StmtPass, f: &mut PyFormatter) -> FormatResult<()> { fn fmt_fields(&self, _item: &StmtPass, f: &mut PyFormatter) -> FormatResult<()> {
token("pass").fmt(f) token("pass").fmt(f)
} }
fn is_suppressed(&self, node: &StmtPass, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,10 +1,9 @@
use ruff_formatter::write; use ruff_formatter::write;
use ruff_python_ast::StmtRaise; use ruff_python_ast::StmtRaise;
use crate::comments::SourceComment;
use crate::expression::maybe_parenthesize_expression; use crate::expression::maybe_parenthesize_expression;
use crate::expression::parentheses::Parenthesize; use crate::expression::parentheses::Parenthesize;
use crate::{has_skip_comment, prelude::*}; use crate::prelude::*;
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtRaise; pub struct FormatStmtRaise;
@ -43,12 +42,7 @@ impl FormatNodeRule<StmtRaise> for FormatStmtRaise {
} }
Ok(()) Ok(())
} }
fn is_suppressed(&self, node: &StmtRaise, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,10 +1,9 @@
use ruff_formatter::write; use ruff_formatter::write;
use ruff_python_ast::{Expr, StmtReturn}; use ruff_python_ast::{Expr, StmtReturn};
use crate::comments::SourceComment;
use crate::expression::expr_tuple::TupleParentheses; use crate::expression::expr_tuple::TupleParentheses;
use crate::prelude::*;
use crate::statement::stmt_assign::FormatStatementsLastExpression; use crate::statement::stmt_assign::FormatStatementsLastExpression;
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtReturn; pub struct FormatStmtReturn;
@ -43,12 +42,7 @@ impl FormatNodeRule<StmtReturn> for FormatStmtReturn {
None => Ok(()), None => Ok(()),
} }
} }
fn is_suppressed(&self, node: &StmtReturn, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -1,11 +1,10 @@
use ruff_formatter::write; use ruff_formatter::write;
use ruff_python_ast::StmtTypeAlias; use ruff_python_ast::StmtTypeAlias;
use crate::comments::SourceComment; use crate::prelude::*;
use crate::statement::stmt_assign::{ use crate::statement::stmt_assign::{
AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression, AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression,
}; };
use crate::{has_skip_comment, prelude::*};
#[derive(Default)] #[derive(Default)]
pub struct FormatStmtTypeAlias; pub struct FormatStmtTypeAlias;
@ -42,12 +41,7 @@ impl FormatNodeRule<StmtTypeAlias> for FormatStmtTypeAlias {
] ]
) )
} }
fn is_suppressed(&self, node: &StmtTypeAlias, context: &PyFormatContext) -> bool {
fn is_suppressed( context.is_suppressed(node.into())
&self,
trailing_comments: &[SourceComment],
context: &PyFormatContext,
) -> bool {
has_skip_comment(trailing_comments, context.source())
} }
} }

View File

@ -8,7 +8,8 @@ use ruff_python_trivia::{lines_after, lines_after_ignoring_end_of_line_trivia, l
use ruff_text_size::{Ranged, TextRange}; use ruff_text_size::{Ranged, TextRange};
use crate::comments::{ use crate::comments::{
Comments, LeadingDanglingTrailingComments, leading_comments, trailing_comments, Comments, LeadingDanglingTrailingComments, has_skip_comment, leading_comments,
trailing_comments,
}; };
use crate::context::{NodeLevel, TopLevelStatementPosition, WithIndentLevel, WithNodeLevel}; use crate::context::{NodeLevel, TopLevelStatementPosition, WithIndentLevel, WithNodeLevel};
use crate::other::string_literal::StringLiteralKind; use crate::other::string_literal::StringLiteralKind;
@ -16,7 +17,6 @@ use crate::prelude::*;
use crate::preview::{ use crate::preview::{
is_allow_newline_after_block_open_enabled, is_blank_line_before_decorated_class_in_stub_enabled, is_allow_newline_after_block_open_enabled, is_blank_line_before_decorated_class_in_stub_enabled,
}; };
use crate::statement::stmt_expr::FormatStmtExpr;
use crate::verbatim::{ use crate::verbatim::{
suppressed_node, write_suppressed_statements_starting_with_leading_comment, suppressed_node, write_suppressed_statements_starting_with_leading_comment,
write_suppressed_statements_starting_with_trailing_comment, write_suppressed_statements_starting_with_trailing_comment,
@ -840,7 +840,7 @@ impl Format<PyFormatContext<'_>> for DocstringStmt<'_> {
let comments = f.context().comments().clone(); let comments = f.context().comments().clone();
let node_comments = comments.leading_dangling_trailing(self.docstring); let node_comments = comments.leading_dangling_trailing(self.docstring);
if FormatStmtExpr.is_suppressed(node_comments.trailing, f.context()) { if has_skip_comment(node_comments.trailing, f.context().source()) {
suppressed_node(self.docstring).fmt(f) suppressed_node(self.docstring).fmt(f)
} else { } else {
// SAFETY: Safe because `DocStringStmt` guarantees that it only ever wraps a `ExprStmt` containing a `ExprStringLiteral`. // SAFETY: Safe because `DocStringStmt` guarantees that it only ever wraps a `ExprStmt` containing a `ExprStringLiteral`.
@ -945,7 +945,7 @@ mod tests {
use ruff_python_trivia::CommentRanges; use ruff_python_trivia::CommentRanges;
use crate::PyFormatOptions; use crate::PyFormatOptions;
use crate::comments::Comments; use crate::comments::{Comments, SuppressedNodeRanges};
use crate::prelude::*; use crate::prelude::*;
use crate::statement::suite::SuiteKind; use crate::statement::suite::SuiteKind;
@ -973,11 +973,14 @@ def trailing_func():
let parsed = parse_module(source).unwrap(); let parsed = parse_module(source).unwrap();
let comment_ranges = CommentRanges::from(parsed.tokens()); let comment_ranges = CommentRanges::from(parsed.tokens());
let comments = Comments::from_ranges(&comment_ranges);
let suppressed_nodes = SuppressedNodeRanges::from_comments(&comments, source);
let context = PyFormatContext::new( let context = PyFormatContext::new(
PyFormatOptions::default(), PyFormatOptions::default(),
source, source,
Comments::from_ranges(&comment_ranges), comments,
suppressed_nodes,
parsed.tokens(), parsed.tokens(),
); );

View File

@ -20,6 +20,7 @@ use {
}; };
use super::NormalizedString; use super::NormalizedString;
use crate::comments::SuppressedNodeRanges;
use crate::preview::is_no_chaperone_for_escaped_quote_in_triple_quoted_docstring_enabled; use crate::preview::is_no_chaperone_for_escaped_quote_in_triple_quoted_docstring_enabled;
use crate::string::StringQuotes; use crate::string::StringQuotes;
use crate::{DocstringCodeLineWidth, FormatModuleError, prelude::*}; use crate::{DocstringCodeLineWidth, FormatModuleError, prelude::*};
@ -1585,8 +1586,9 @@ fn docstring_format_source(
let comment_ranges = CommentRanges::from(parsed.tokens()); let comment_ranges = CommentRanges::from(parsed.tokens());
let source_code = ruff_formatter::SourceCode::new(source); let source_code = ruff_formatter::SourceCode::new(source);
let comments = crate::Comments::from_ast(parsed.syntax(), source_code, &comment_ranges); let comments = crate::Comments::from_ast(parsed.syntax(), source_code, &comment_ranges);
let suppressed_nodes = SuppressedNodeRanges::from_comments(&comments, source_code.as_str());
let ctx = PyFormatContext::new(options, source, comments, parsed.tokens()) let ctx = PyFormatContext::new(options, source, comments, suppressed_nodes, parsed.tokens())
.in_docstring(docstring_quote_style); .in_docstring(docstring_quote_style);
let formatted = crate::format!(ctx, [parsed.syntax().format()])?; let formatted = crate::format!(ctx, [parsed.syntax().format()])?;
formatted formatted