mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-04 02:38:25 +00:00
Track formatted comments (#4979)
This commit is contained in:
parent
646ab64850
commit
68d52da43b
6 changed files with 60 additions and 85 deletions
|
@ -206,32 +206,26 @@ break;
|
|||
|
||||
comments_map.push_leading(
|
||||
continue_statement.as_ref().into(),
|
||||
SourceComment {
|
||||
slice: source_code.slice(TextRange::at(TextSize::new(0), TextSize::new(17))),
|
||||
#[cfg(debug_assertions)]
|
||||
formatted: std::cell::Cell::new(false),
|
||||
position: CommentTextPosition::OwnLine,
|
||||
},
|
||||
SourceComment::new(
|
||||
source_code.slice(TextRange::at(TextSize::new(0), TextSize::new(17))),
|
||||
CommentTextPosition::OwnLine,
|
||||
),
|
||||
);
|
||||
|
||||
comments_map.push_trailing(
|
||||
continue_statement.as_ref().into(),
|
||||
SourceComment {
|
||||
slice: source_code.slice(TextRange::at(TextSize::new(28), TextSize::new(10))),
|
||||
#[cfg(debug_assertions)]
|
||||
formatted: std::cell::Cell::new(false),
|
||||
position: CommentTextPosition::EndOfLine,
|
||||
},
|
||||
SourceComment::new(
|
||||
source_code.slice(TextRange::at(TextSize::new(28), TextSize::new(10))),
|
||||
CommentTextPosition::EndOfLine,
|
||||
),
|
||||
);
|
||||
|
||||
comments_map.push_leading(
|
||||
break_statement.as_ref().into(),
|
||||
SourceComment {
|
||||
slice: source_code.slice(TextRange::at(TextSize::new(39), TextSize::new(15))),
|
||||
#[cfg(debug_assertions)]
|
||||
formatted: std::cell::Cell::new(false),
|
||||
position: CommentTextPosition::OwnLine,
|
||||
},
|
||||
SourceComment::new(
|
||||
source_code.slice(TextRange::at(TextSize::new(39), TextSize::new(15))),
|
||||
CommentTextPosition::OwnLine,
|
||||
),
|
||||
);
|
||||
|
||||
let comments = Comments::new(comments_map);
|
||||
|
|
|
@ -36,7 +36,10 @@ impl Format<PyFormatContext<'_>> for FormatLeadingComments<'_> {
|
|||
FormatLeadingComments::Comments(comments) => comments,
|
||||
};
|
||||
|
||||
for comment in leading_comments {
|
||||
for comment in leading_comments
|
||||
.iter()
|
||||
.filter(|comment| comment.is_unformatted())
|
||||
{
|
||||
let slice = comment.slice();
|
||||
|
||||
let lines_after_comment = lines_after(slice.end(), f.context().contents());
|
||||
|
@ -127,7 +130,10 @@ impl Format<PyFormatContext<'_>> for FormatTrailingComments<'_> {
|
|||
|
||||
let mut has_trailing_own_line_comment = false;
|
||||
|
||||
for trailing in trailing_comments {
|
||||
for trailing in trailing_comments
|
||||
.iter()
|
||||
.filter(|comment| comment.is_unformatted())
|
||||
{
|
||||
let slice = trailing.slice();
|
||||
|
||||
has_trailing_own_line_comment |= trailing.position().is_own_line();
|
||||
|
@ -198,7 +204,10 @@ impl Format<PyFormatContext<'_>> for FormatDanglingComments<'_> {
|
|||
};
|
||||
|
||||
let mut first = true;
|
||||
for comment in dangling_comments {
|
||||
for comment in dangling_comments
|
||||
.iter()
|
||||
.filter(|comment| comment.is_unformatted())
|
||||
{
|
||||
if first && comment.position().is_end_of_line() {
|
||||
write!(f, [space(), space()])?;
|
||||
}
|
||||
|
|
|
@ -87,17 +87,6 @@
|
|||
//!
|
||||
//! It is possible to add an additional optional label to [`SourceComment`] If ever the need arises to distinguish two *dangling comments* in the formatting logic,
|
||||
|
||||
use rustpython_parser::ast::Mod;
|
||||
use std::fmt::Debug;
|
||||
use std::rc::Rc;
|
||||
|
||||
mod debug;
|
||||
mod format;
|
||||
mod map;
|
||||
mod node_key;
|
||||
mod placement;
|
||||
mod visitor;
|
||||
|
||||
use crate::comments::debug::{DebugComment, DebugComments};
|
||||
use crate::comments::map::MultiMap;
|
||||
use crate::comments::node_key::NodeRefEqualityKey;
|
||||
|
@ -109,40 +98,60 @@ pub(crate) use format::{
|
|||
use ruff_formatter::{SourceCode, SourceCodeSlice};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use ruff_python_ast::source_code::CommentRanges;
|
||||
use rustpython_parser::ast::Mod;
|
||||
use std::cell::Cell;
|
||||
use std::fmt::Debug;
|
||||
use std::rc::Rc;
|
||||
|
||||
mod debug;
|
||||
mod format;
|
||||
mod map;
|
||||
mod node_key;
|
||||
mod placement;
|
||||
mod visitor;
|
||||
|
||||
/// A comment in the source document.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct SourceComment {
|
||||
/// The location of the comment in the source document.
|
||||
slice: SourceCodeSlice,
|
||||
|
||||
/// Whether the comment has been formatted or not.
|
||||
#[cfg(debug_assertions)]
|
||||
formatted: std::cell::Cell<bool>,
|
||||
|
||||
formatted: Cell<bool>,
|
||||
position: CommentTextPosition,
|
||||
}
|
||||
|
||||
impl SourceComment {
|
||||
fn new(slice: SourceCodeSlice, position: CommentTextPosition) -> Self {
|
||||
Self {
|
||||
slice,
|
||||
position,
|
||||
formatted: Cell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the location of the comment in the original source code.
|
||||
/// Allows retrieving the text of the comment.
|
||||
pub(crate) fn slice(&self) -> &SourceCodeSlice {
|
||||
pub(crate) const fn slice(&self) -> &SourceCodeSlice {
|
||||
&self.slice
|
||||
}
|
||||
|
||||
pub(crate) fn position(&self) -> CommentTextPosition {
|
||||
pub(crate) const fn position(&self) -> CommentTextPosition {
|
||||
self.position
|
||||
}
|
||||
|
||||
#[cfg(not(debug_assertions))]
|
||||
#[inline(always)]
|
||||
pub(crate) fn mark_formatted(&self) {}
|
||||
|
||||
/// Marks the comment as formatted
|
||||
#[cfg(debug_assertions)]
|
||||
pub(crate) fn mark_formatted(&self) {
|
||||
self.formatted.set(true);
|
||||
}
|
||||
|
||||
/// If the comment has already been formatted
|
||||
pub(crate) fn is_formatted(&self) -> bool {
|
||||
self.formatted.get()
|
||||
}
|
||||
|
||||
pub(crate) fn is_unformatted(&self) -> bool {
|
||||
!self.is_formatted()
|
||||
}
|
||||
}
|
||||
|
||||
impl SourceComment {
|
||||
|
|
|
@ -420,12 +420,7 @@ impl<'a> DecoratedComment<'a> {
|
|||
|
||||
impl From<DecoratedComment<'_>> for SourceComment {
|
||||
fn from(decorated: DecoratedComment) -> Self {
|
||||
Self {
|
||||
slice: decorated.slice,
|
||||
position: decorated.text_position,
|
||||
#[cfg(debug_assertions)]
|
||||
formatted: std::cell::Cell::new(false),
|
||||
}
|
||||
Self::new(decorated.slice, decorated.text_position)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,11 @@
|
|||
use crate::comments::leading_node_comments;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{write, FormatRuleWithOptions};
|
||||
use ruff_formatter::write;
|
||||
use ruff_text_size::{TextLen, TextRange};
|
||||
use rustpython_parser::ast::Arg;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatArg {
|
||||
kind: ArgumentKind,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub enum ArgumentKind {
|
||||
/// Positional only, regular argument, or a keyword only argument.
|
||||
#[default]
|
||||
Normal,
|
||||
/// A `*args` arguments
|
||||
Varg,
|
||||
/// A `**kwargs` argument
|
||||
Kwarg,
|
||||
}
|
||||
pub struct FormatArg;
|
||||
|
||||
impl FormatNodeRule<Arg> for FormatArg {
|
||||
fn fmt_fields(&self, item: &Arg, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
|
@ -46,21 +32,4 @@ impl FormatNodeRule<Arg> for FormatArg {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn fmt_leading_comments(&self, node: &Arg, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
match self.kind {
|
||||
ArgumentKind::Normal => leading_node_comments(node).fmt(f),
|
||||
// Formatted as part of the `Arguments` to avoid emitting leading comments between the `*` and the argument.
|
||||
ArgumentKind::Kwarg | ArgumentKind::Varg => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FormatRuleWithOptions<Arg, PyFormatContext<'_>> for FormatArg {
|
||||
type Options = ArgumentKind;
|
||||
|
||||
fn with_options(mut self, options: Self::Options) -> Self {
|
||||
self.kind = options;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use crate::comments::{dangling_node_comments, leading_node_comments};
|
||||
use crate::context::NodeLevel;
|
||||
use crate::other::arg::ArgumentKind;
|
||||
use crate::prelude::*;
|
||||
use crate::trivia::{first_non_trivia_token, SimpleTokenizer, Token, TokenKind};
|
||||
use crate::FormatNodeRule;
|
||||
|
@ -63,7 +62,7 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
joiner.entry(&format_args![
|
||||
leading_node_comments(vararg.as_ref()),
|
||||
text("*"),
|
||||
vararg.format().with_options(ArgumentKind::Varg)
|
||||
vararg.format()
|
||||
]);
|
||||
last_node = Some(vararg.as_any_node_ref());
|
||||
}
|
||||
|
@ -90,7 +89,7 @@ impl FormatNodeRule<Arguments> for FormatArguments {
|
|||
joiner.entry(&format_args![
|
||||
leading_node_comments(kwarg.as_ref()),
|
||||
text("**"),
|
||||
kwarg.format().with_options(ArgumentKind::Kwarg)
|
||||
kwarg.format()
|
||||
]);
|
||||
last_node = Some(kwarg.as_any_node_ref());
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue