mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 04:55:09 +00:00
Accept any Into<AnyNodeRef>
as Comments
arguments (#5205)
This commit is contained in:
parent
6f7d3cc798
commit
b369288833
9 changed files with 73 additions and 41 deletions
|
@ -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<T>(&self, node: T) -> bool
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
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<T>(&self, node: T) -> bool
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
!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<T>(&self, node: T) -> &[SourceComment]
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
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<T>(&self, node: T) -> bool
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
!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<T>(&self, node: T) -> &[SourceComment]
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
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<T>(&self, node: T) -> &[SourceComment]
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
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<T>(&self, node: T) -> bool
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
!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<T>(&self, node: T) -> bool
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
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<T>(
|
||||
&self,
|
||||
node: AnyNodeRef<'a>,
|
||||
) -> impl Iterator<Item = &SourceComment> {
|
||||
node: T,
|
||||
) -> impl Iterator<Item = &SourceComment>
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
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<T>(
|
||||
&self,
|
||||
node: AnyNodeRef<'a>,
|
||||
) -> impl Iterator<Item = &SourceComment> {
|
||||
node: T,
|
||||
) -> impl Iterator<Item = &SourceComment>
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
self.data
|
||||
.comments
|
||||
.parts(&NodeRefEqualityKey::from_ref(node))
|
||||
.parts(&NodeRefEqualityKey::from_ref(node.into()))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
|
@ -91,7 +91,7 @@ impl FormatNodeRule<ExprBinOp> 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()])?;
|
||||
|
|
|
@ -35,7 +35,7 @@ impl Format<PyFormatContext<'_>> 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,
|
||||
[
|
||||
|
|
|
@ -19,7 +19,7 @@ impl FormatNodeRule<ExprList> 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:
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -37,7 +37,7 @@ impl FormatRule<AnyFunctionDefinition<'_>, 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());
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ impl FormatNodeRule<StmtIf> 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<StmtIf> 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,
|
||||
|
|
|
@ -96,9 +96,8 @@ impl FormatRule<Suite, PyFormatContext<'_>> 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()
|
||||
{
|
||||
let start =
|
||||
if let Some(first_leading) = comments.leading_comments(statement).first() {
|
||||
first_leading.slice().start()
|
||||
} else {
|
||||
statement.start()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue