diff --git a/crates/ruff_python_formatter/src/comments/mod.rs b/crates/ruff_python_formatter/src/comments/mod.rs index 171073d5654a7..837ce8266eff4 100644 --- a/crates/ruff_python_formatter/src/comments/mod.rs +++ b/crates/ruff_python_formatter/src/comments/mod.rs @@ -260,76 +260,109 @@ impl<'a> Comments<'a> { } #[inline] - pub(crate) fn has_comments(&self, node: AnyNodeRef) -> bool { - self.data.comments.has(&NodeRefEqualityKey::from_ref(node)) + pub(crate) fn has_comments(&self, node: T) -> bool + where + T: Into>, + { + self.data + .comments + .has(&NodeRefEqualityKey::from_ref(node.into())) } /// Returns `true` if the given `node` has any [leading comments](self#leading-comments). #[inline] - pub(crate) fn has_leading_comments(&self, node: AnyNodeRef) -> bool { + pub(crate) fn has_leading_comments(&self, node: T) -> bool + where + T: Into>, + { !self.leading_comments(node).is_empty() } /// Returns the `node`'s [leading comments](self#leading-comments). #[inline] - pub(crate) fn leading_comments(&self, node: AnyNodeRef<'a>) -> &[SourceComment] { + pub(crate) fn leading_comments(&self, node: T) -> &[SourceComment] + where + T: Into>, + { self.data .comments - .leading(&NodeRefEqualityKey::from_ref(node)) + .leading(&NodeRefEqualityKey::from_ref(node.into())) } /// Returns `true` if node has any [dangling comments](self#dangling-comments). - pub(crate) fn has_dangling_comments(&self, node: AnyNodeRef<'a>) -> bool { + pub(crate) fn has_dangling_comments(&self, node: T) -> bool + where + T: Into>, + { !self.dangling_comments(node).is_empty() } /// Returns the [dangling comments](self#dangling-comments) of `node` - pub(crate) fn dangling_comments(&self, node: AnyNodeRef<'a>) -> &[SourceComment] { + pub(crate) fn dangling_comments(&self, node: T) -> &[SourceComment] + where + T: Into>, + { self.data .comments - .dangling(&NodeRefEqualityKey::from_ref(node)) + .dangling(&NodeRefEqualityKey::from_ref(node.into())) } /// Returns the `node`'s [trailing comments](self#trailing-comments). #[inline] - pub(crate) fn trailing_comments(&self, node: AnyNodeRef<'a>) -> &[SourceComment] { + pub(crate) fn trailing_comments(&self, node: T) -> &[SourceComment] + where + T: Into>, + { self.data .comments - .trailing(&NodeRefEqualityKey::from_ref(node)) + .trailing(&NodeRefEqualityKey::from_ref(node.into())) } /// Returns `true` if the given `node` has any [trailing comments](self#trailing-comments). #[inline] - pub(crate) fn has_trailing_comments(&self, node: AnyNodeRef) -> bool { + pub(crate) fn has_trailing_comments(&self, node: T) -> bool + where + T: Into>, + { !self.trailing_comments(node).is_empty() } /// Returns `true` if the given `node` has any [trailing own line comments](self#trailing-comments). #[inline] - pub(crate) fn has_trailing_own_line_comments(&self, node: AnyNodeRef) -> bool { + pub(crate) fn has_trailing_own_line_comments(&self, node: T) -> bool + where + T: Into>, + { self.trailing_comments(node) .iter() .any(|comment| comment.position().is_own_line()) } /// Returns an iterator over the [leading](self#leading-comments) and [trailing comments](self#trailing-comments) of `node`. - pub(crate) fn leading_trailing_comments( + pub(crate) fn leading_trailing_comments( &self, - node: AnyNodeRef<'a>, - ) -> impl Iterator { + node: T, + ) -> impl Iterator + where + T: Into>, + { + let node = node.into(); self.leading_comments(node) .iter() .chain(self.trailing_comments(node).iter()) } /// Returns an iterator over the [leading](self#leading-comments), [dangling](self#dangling-comments), and [trailing](self#trailing) comments of `node`. - pub(crate) fn leading_dangling_trailing_comments( + pub(crate) fn leading_dangling_trailing_comments( &self, - node: AnyNodeRef<'a>, - ) -> impl Iterator { + node: T, + ) -> impl Iterator + where + T: Into>, + { self.data .comments - .parts(&NodeRefEqualityKey::from_ref(node)) + .parts(&NodeRefEqualityKey::from_ref(node.into())) } #[inline(always)] diff --git a/crates/ruff_python_formatter/src/expression/expr_bin_op.rs b/crates/ruff_python_formatter/src/expression/expr_bin_op.rs index 92461b4dfe26f..f9a87237285cb 100644 --- a/crates/ruff_python_formatter/src/expression/expr_bin_op.rs +++ b/crates/ruff_python_formatter/src/expression/expr_bin_op.rs @@ -91,7 +91,7 @@ impl FormatNodeRule for FormatExprBinOp { )?; // Format the operator on its own line if the right side has any leading comments. - if comments.has_leading_comments(right.as_ref().into()) { + if comments.has_leading_comments(right.as_ref()) { write!(f, [hard_line_break()])?; } else if needs_space { write!(f, [space()])?; diff --git a/crates/ruff_python_formatter/src/expression/expr_dict.rs b/crates/ruff_python_formatter/src/expression/expr_dict.rs index 11d1a3ca85c9e..e40574ee24063 100644 --- a/crates/ruff_python_formatter/src/expression/expr_dict.rs +++ b/crates/ruff_python_formatter/src/expression/expr_dict.rs @@ -35,7 +35,7 @@ impl Format> for KeyValuePair<'_> { ) } else { let comments = f.context().comments().clone(); - let leading_value_comments = comments.leading_comments(self.value.into()); + let leading_value_comments = comments.leading_comments(self.value); write!( f, [ diff --git a/crates/ruff_python_formatter/src/expression/expr_list.rs b/crates/ruff_python_formatter/src/expression/expr_list.rs index a2698535798b4..2e6c055315865 100644 --- a/crates/ruff_python_formatter/src/expression/expr_list.rs +++ b/crates/ruff_python_formatter/src/expression/expr_list.rs @@ -19,7 +19,7 @@ impl FormatNodeRule for FormatExprList { } = item; let comments = f.context().comments().clone(); - let dangling = comments.dangling_comments(item.into()); + let dangling = comments.dangling_comments(item); // The empty list is special because there can be dangling comments, and they can be in two // positions: diff --git a/crates/ruff_python_formatter/src/lib.rs b/crates/ruff_python_formatter/src/lib.rs index 6ad37c5665c5d..3e38b1d4875e8 100644 --- a/crates/ruff_python_formatter/src/lib.rs +++ b/crates/ruff_python_formatter/src/lib.rs @@ -1,3 +1,7 @@ +use crate::comments::{ + dangling_node_comments, leading_node_comments, trailing_node_comments, Comments, +}; +use crate::context::PyFormatContext; use anyhow::{anyhow, Context, Result}; use ruff_formatter::prelude::*; use ruff_formatter::{format, write}; @@ -10,11 +14,6 @@ use rustpython_parser::lexer::lex; use rustpython_parser::{parse_tokens, Mode}; use std::borrow::Cow; -use crate::comments::{ - dangling_node_comments, leading_node_comments, trailing_node_comments, Comments, -}; -use crate::context::PyFormatContext; - pub(crate) mod builders; pub mod cli; mod comments; @@ -437,9 +436,10 @@ def with_leading_comment(): ... // Uncomment the `dbg` to print the IR. // Use `dbg_write!(f, []) instead of `write!(f, [])` in your formatting code to print some IR // inside of a `Format` implementation - // dbg!(formatted + // use ruff_formatter::FormatContext; + // formatted // .document() - // .display(formatted.context().source_code())); + // .display(formatted.context().source_code()); // dbg!(formatted // .context() diff --git a/crates/ruff_python_formatter/src/prelude.rs b/crates/ruff_python_formatter/src/prelude.rs index 7382684dba647..f3f88f6145a8d 100644 --- a/crates/ruff_python_formatter/src/prelude.rs +++ b/crates/ruff_python_formatter/src/prelude.rs @@ -1,7 +1,7 @@ #[allow(unused_imports)] pub(crate) use crate::{ - builders::PyFormatterExtensions, AsFormat, FormattedIterExt as _, IntoFormat, PyFormatContext, - PyFormatter, + builders::PyFormatterExtensions, AsFormat, FormatNodeRule, FormattedIterExt as _, IntoFormat, + PyFormatContext, PyFormatter, }; #[allow(unused_imports)] pub(crate) use ruff_formatter::prelude::*; diff --git a/crates/ruff_python_formatter/src/statement/stmt_function_def.rs b/crates/ruff_python_formatter/src/statement/stmt_function_def.rs index ed48d4820deda..12432c8b1ddb4 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_function_def.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_function_def.rs @@ -37,7 +37,7 @@ impl FormatRule, PyFormatContext<'_>> for FormatAnyFun ) -> FormatResult<()> { let comments = f.context().comments().clone(); - let dangling_comments = comments.dangling_comments(item.into()); + let dangling_comments = comments.dangling_comments(item); let trailing_definition_comments_start = dangling_comments.partition_point(|comment| comment.position().is_own_line()); diff --git a/crates/ruff_python_formatter/src/statement/stmt_if.rs b/crates/ruff_python_formatter/src/statement/stmt_if.rs index 33fad5466fcc6..85a9fabee127b 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_if.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_if.rs @@ -23,7 +23,7 @@ impl FormatNodeRule for FormatStmtIf { } = current_statement; let first_statement = body.first().ok_or(FormatError::SyntaxError)?; - let trailing = comments.dangling_comments(current_statement.into()); + let trailing = comments.dangling_comments(current_statement); let trailing_if_comments_end = trailing .partition_point(|comment| comment.slice().start() < first_statement.start()); @@ -32,7 +32,7 @@ impl FormatNodeRule for FormatStmtIf { trailing.split_at(trailing_if_comments_end); if current.is_elif() { - let elif_leading = comments.leading_comments(current_statement.into()); + let elif_leading = comments.leading_comments(current_statement); // Manually format the leading comments because the formatting bypasses `NodeRule::fmt` write!( f, diff --git a/crates/ruff_python_formatter/src/statement/suite.rs b/crates/ruff_python_formatter/src/statement/suite.rs index 3c075cf862012..0a264a6214a72 100644 --- a/crates/ruff_python_formatter/src/statement/suite.rs +++ b/crates/ruff_python_formatter/src/statement/suite.rs @@ -96,13 +96,12 @@ impl FormatRule> for FormatSuite { // the leading comment. This is why the suite handling counts the lines before the // start of the next statement or before the first leading comments for compound statements. let separator = format_with(|f| { - let start = if let Some(first_leading) = - comments.leading_comments(statement.into()).first() - { - first_leading.slice().start() - } else { - statement.start() - }; + let start = + if let Some(first_leading) = comments.leading_comments(statement).first() { + first_leading.slice().start() + } else { + statement.start() + }; match lines_before(start, source) { 0 | 1 => hard_line_break().fmt(f),