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]
|
#[inline]
|
||||||
pub(crate) fn has_comments(&self, node: AnyNodeRef) -> bool {
|
pub(crate) fn has_comments<T>(&self, node: T) -> bool
|
||||||
self.data.comments.has(&NodeRefEqualityKey::from_ref(node))
|
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).
|
/// Returns `true` if the given `node` has any [leading comments](self#leading-comments).
|
||||||
#[inline]
|
#[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()
|
!self.leading_comments(node).is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the `node`'s [leading comments](self#leading-comments).
|
/// Returns the `node`'s [leading comments](self#leading-comments).
|
||||||
#[inline]
|
#[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
|
self.data
|
||||||
.comments
|
.comments
|
||||||
.leading(&NodeRefEqualityKey::from_ref(node))
|
.leading(&NodeRefEqualityKey::from_ref(node.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if node has any [dangling comments](self#dangling-comments).
|
/// 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()
|
!self.dangling_comments(node).is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the [dangling comments](self#dangling-comments) of `node`
|
/// 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
|
self.data
|
||||||
.comments
|
.comments
|
||||||
.dangling(&NodeRefEqualityKey::from_ref(node))
|
.dangling(&NodeRefEqualityKey::from_ref(node.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the `node`'s [trailing comments](self#trailing-comments).
|
/// Returns the `node`'s [trailing comments](self#trailing-comments).
|
||||||
#[inline]
|
#[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
|
self.data
|
||||||
.comments
|
.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).
|
/// Returns `true` if the given `node` has any [trailing comments](self#trailing-comments).
|
||||||
#[inline]
|
#[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()
|
!self.trailing_comments(node).is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the given `node` has any [trailing own line comments](self#trailing-comments).
|
/// Returns `true` if the given `node` has any [trailing own line comments](self#trailing-comments).
|
||||||
#[inline]
|
#[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)
|
self.trailing_comments(node)
|
||||||
.iter()
|
.iter()
|
||||||
.any(|comment| comment.position().is_own_line())
|
.any(|comment| comment.position().is_own_line())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over the [leading](self#leading-comments) and [trailing comments](self#trailing-comments) of `node`.
|
/// 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,
|
&self,
|
||||||
node: AnyNodeRef<'a>,
|
node: T,
|
||||||
) -> impl Iterator<Item = &SourceComment> {
|
) -> impl Iterator<Item = &SourceComment>
|
||||||
|
where
|
||||||
|
T: Into<AnyNodeRef<'a>>,
|
||||||
|
{
|
||||||
|
let node = node.into();
|
||||||
self.leading_comments(node)
|
self.leading_comments(node)
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.trailing_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`.
|
/// 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,
|
&self,
|
||||||
node: AnyNodeRef<'a>,
|
node: T,
|
||||||
) -> impl Iterator<Item = &SourceComment> {
|
) -> impl Iterator<Item = &SourceComment>
|
||||||
|
where
|
||||||
|
T: Into<AnyNodeRef<'a>>,
|
||||||
|
{
|
||||||
self.data
|
self.data
|
||||||
.comments
|
.comments
|
||||||
.parts(&NodeRefEqualityKey::from_ref(node))
|
.parts(&NodeRefEqualityKey::from_ref(node.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[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.
|
// 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()])?;
|
write!(f, [hard_line_break()])?;
|
||||||
} else if needs_space {
|
} else if needs_space {
|
||||||
write!(f, [space()])?;
|
write!(f, [space()])?;
|
||||||
|
|
|
@ -35,7 +35,7 @@ impl Format<PyFormatContext<'_>> for KeyValuePair<'_> {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let comments = f.context().comments().clone();
|
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!(
|
write!(
|
||||||
f,
|
f,
|
||||||
[
|
[
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl FormatNodeRule<ExprList> for FormatExprList {
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
let comments = f.context().comments().clone();
|
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
|
// The empty list is special because there can be dangling comments, and they can be in two
|
||||||
// positions:
|
// 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 anyhow::{anyhow, Context, Result};
|
||||||
use ruff_formatter::prelude::*;
|
use ruff_formatter::prelude::*;
|
||||||
use ruff_formatter::{format, write};
|
use ruff_formatter::{format, write};
|
||||||
|
@ -10,11 +14,6 @@ use rustpython_parser::lexer::lex;
|
||||||
use rustpython_parser::{parse_tokens, Mode};
|
use rustpython_parser::{parse_tokens, Mode};
|
||||||
use std::borrow::Cow;
|
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(crate) mod builders;
|
||||||
pub mod cli;
|
pub mod cli;
|
||||||
mod comments;
|
mod comments;
|
||||||
|
@ -437,9 +436,10 @@ def with_leading_comment(): ...
|
||||||
// Uncomment the `dbg` to print the IR.
|
// Uncomment the `dbg` to print the IR.
|
||||||
// Use `dbg_write!(f, []) instead of `write!(f, [])` in your formatting code to print some IR
|
// Use `dbg_write!(f, []) instead of `write!(f, [])` in your formatting code to print some IR
|
||||||
// inside of a `Format` implementation
|
// inside of a `Format` implementation
|
||||||
// dbg!(formatted
|
// use ruff_formatter::FormatContext;
|
||||||
|
// formatted
|
||||||
// .document()
|
// .document()
|
||||||
// .display(formatted.context().source_code()));
|
// .display(formatted.context().source_code());
|
||||||
|
|
||||||
// dbg!(formatted
|
// dbg!(formatted
|
||||||
// .context()
|
// .context()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub(crate) use crate::{
|
pub(crate) use crate::{
|
||||||
builders::PyFormatterExtensions, AsFormat, FormattedIterExt as _, IntoFormat, PyFormatContext,
|
builders::PyFormatterExtensions, AsFormat, FormatNodeRule, FormattedIterExt as _, IntoFormat,
|
||||||
PyFormatter,
|
PyFormatContext, PyFormatter,
|
||||||
};
|
};
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub(crate) use ruff_formatter::prelude::*;
|
pub(crate) use ruff_formatter::prelude::*;
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl FormatRule<AnyFunctionDefinition<'_>, PyFormatContext<'_>> for FormatAnyFun
|
||||||
) -> FormatResult<()> {
|
) -> FormatResult<()> {
|
||||||
let comments = f.context().comments().clone();
|
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 =
|
let trailing_definition_comments_start =
|
||||||
dangling_comments.partition_point(|comment| comment.position().is_own_line());
|
dangling_comments.partition_point(|comment| comment.position().is_own_line());
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ impl FormatNodeRule<StmtIf> for FormatStmtIf {
|
||||||
} = current_statement;
|
} = current_statement;
|
||||||
|
|
||||||
let first_statement = body.first().ok_or(FormatError::SyntaxError)?;
|
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
|
let trailing_if_comments_end = trailing
|
||||||
.partition_point(|comment| comment.slice().start() < first_statement.start());
|
.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);
|
trailing.split_at(trailing_if_comments_end);
|
||||||
|
|
||||||
if current.is_elif() {
|
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`
|
// Manually format the leading comments because the formatting bypasses `NodeRule::fmt`
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
|
|
@ -96,13 +96,12 @@ impl FormatRule<Suite, PyFormatContext<'_>> for FormatSuite {
|
||||||
// the leading comment. This is why the suite handling counts the lines before the
|
// 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.
|
// start of the next statement or before the first leading comments for compound statements.
|
||||||
let separator = format_with(|f| {
|
let separator = format_with(|f| {
|
||||||
let start = if let Some(first_leading) =
|
let start =
|
||||||
comments.leading_comments(statement.into()).first()
|
if let Some(first_leading) = comments.leading_comments(statement).first() {
|
||||||
{
|
first_leading.slice().start()
|
||||||
first_leading.slice().start()
|
} else {
|
||||||
} else {
|
statement.start()
|
||||||
statement.start()
|
};
|
||||||
};
|
|
||||||
|
|
||||||
match lines_before(start, source) {
|
match lines_before(start, source) {
|
||||||
0 | 1 => hard_line_break().fmt(f),
|
0 | 1 => hard_line_break().fmt(f),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue