Compare commits
1 Commits
pythonplus
...
collect_de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f2979ed66 |
@@ -8,8 +8,10 @@ use ruff_python_parser::lexer::lex;
|
|||||||
use ruff_python_parser::{parse_tokens, Mode};
|
use ruff_python_parser::{parse_tokens, Mode};
|
||||||
|
|
||||||
use ruff_formatter::SourceCode;
|
use ruff_formatter::SourceCode;
|
||||||
|
use ruff_python_ast::Ranged;
|
||||||
use ruff_python_index::CommentRangesBuilder;
|
use ruff_python_index::CommentRangesBuilder;
|
||||||
|
|
||||||
|
use crate::comments::Comments;
|
||||||
use crate::{format_node, PyFormatOptions};
|
use crate::{format_node, PyFormatOptions};
|
||||||
|
|
||||||
#[derive(ValueEnum, Clone, Debug)]
|
#[derive(ValueEnum, Clone, Debug)]
|
||||||
@@ -68,6 +70,29 @@ pub fn format_and_debug_print(input: &str, cli: &Cli) -> Result<String> {
|
|||||||
println!("{}", formatted.document().display(SourceCode::new(input)));
|
println!("{}", formatted.document().display(SourceCode::new(input)));
|
||||||
}
|
}
|
||||||
if cli.print_comments {
|
if cli.print_comments {
|
||||||
|
// Print preceding, following and enclosing nodes
|
||||||
|
let decorated_comments = Comments::collect_decorated_comments(
|
||||||
|
&python_ast,
|
||||||
|
SourceCode::new(input),
|
||||||
|
&comment_ranges,
|
||||||
|
);
|
||||||
|
for comment in decorated_comments {
|
||||||
|
println!(
|
||||||
|
"{:?} {:?} {:?} {:?} {:?}",
|
||||||
|
comment.slice().range(),
|
||||||
|
comment
|
||||||
|
.preceding_node()
|
||||||
|
.map(|node| (node.kind(), node.range())),
|
||||||
|
comment
|
||||||
|
.following_node()
|
||||||
|
.map(|node| (node.kind(), node.range())),
|
||||||
|
(
|
||||||
|
comment.enclosing_node().kind(),
|
||||||
|
comment.enclosing_node().range()
|
||||||
|
),
|
||||||
|
comment.slice().text(SourceCode::new(input)),
|
||||||
|
);
|
||||||
|
}
|
||||||
println!(
|
println!(
|
||||||
"{:#?}",
|
"{:#?}",
|
||||||
formatted.context().comments().debug(SourceCode::new(input))
|
formatted.context().comments().debug(SourceCode::new(input))
|
||||||
|
|||||||
@@ -105,7 +105,9 @@ use ruff_python_index::CommentRanges;
|
|||||||
use crate::comments::debug::{DebugComment, DebugComments};
|
use crate::comments::debug::{DebugComment, DebugComments};
|
||||||
use crate::comments::map::MultiMap;
|
use crate::comments::map::MultiMap;
|
||||||
use crate::comments::node_key::NodeRefEqualityKey;
|
use crate::comments::node_key::NodeRefEqualityKey;
|
||||||
use crate::comments::visitor::CommentsVisitor;
|
use crate::comments::visitor::{
|
||||||
|
CommentsBuilder, CommentsVisitor, DecoratedComment, DecoratedCommentsCollector,
|
||||||
|
};
|
||||||
|
|
||||||
mod debug;
|
mod debug;
|
||||||
mod format;
|
mod format;
|
||||||
@@ -262,12 +264,25 @@ impl<'a> Comments<'a> {
|
|||||||
let map = if comment_ranges.is_empty() {
|
let map = if comment_ranges.is_empty() {
|
||||||
CommentsMap::new()
|
CommentsMap::new()
|
||||||
} else {
|
} else {
|
||||||
CommentsVisitor::new(source_code, comment_ranges).visit(root)
|
let mut builder = CommentsBuilder::default();
|
||||||
|
CommentsVisitor::new(source_code, comment_ranges, &mut builder).visit(root);
|
||||||
|
builder.finish()
|
||||||
};
|
};
|
||||||
|
|
||||||
Self::new(map)
|
Self::new(map)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extracts the comments from the AST.
|
||||||
|
pub(crate) fn collect_decorated_comments(
|
||||||
|
root: &'a Mod,
|
||||||
|
source_code: SourceCode<'a>,
|
||||||
|
comment_ranges: &'a CommentRanges,
|
||||||
|
) -> Vec<DecoratedComment<'a>> {
|
||||||
|
let mut builder = DecoratedCommentsCollector::default();
|
||||||
|
CommentsVisitor::new(source_code, comment_ranges, &mut builder).visit(root);
|
||||||
|
builder.finish()
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn has_comments<T>(&self, node: T) -> bool
|
pub(crate) fn has_comments<T>(&self, node: T) -> bool
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -22,19 +22,29 @@ use crate::comments::placement::place_comment;
|
|||||||
use crate::comments::{CommentLinePosition, CommentsMap, SourceComment};
|
use crate::comments::{CommentLinePosition, CommentsMap, SourceComment};
|
||||||
|
|
||||||
/// Visitor extracting the comments from an AST.
|
/// Visitor extracting the comments from an AST.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct CommentsVisitor<'a> {
|
pub(super) struct CommentsVisitor<'a, 'b, Collector>
|
||||||
builder: CommentsBuilder<'a>,
|
where
|
||||||
|
Collector: CommentsCollector<'a>,
|
||||||
|
{
|
||||||
|
collector: &'b mut Collector,
|
||||||
source_code: SourceCode<'a>,
|
source_code: SourceCode<'a>,
|
||||||
parents: Vec<AnyNodeRef<'a>>,
|
parents: Vec<AnyNodeRef<'a>>,
|
||||||
preceding_node: Option<AnyNodeRef<'a>>,
|
preceding_node: Option<AnyNodeRef<'a>>,
|
||||||
comment_ranges: Peekable<std::slice::Iter<'a, TextRange>>,
|
comment_ranges: Peekable<std::slice::Iter<'a, TextRange>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CommentsVisitor<'a> {
|
impl<'a, 'b, Collector> CommentsVisitor<'a, 'b, Collector>
|
||||||
pub(crate) fn new(source_code: SourceCode<'a>, comment_ranges: &'a CommentRanges) -> Self {
|
where
|
||||||
|
Collector: CommentsCollector<'a>,
|
||||||
|
{
|
||||||
|
pub(super) fn new(
|
||||||
|
source_code: SourceCode<'a>,
|
||||||
|
comment_ranges: &'a CommentRanges,
|
||||||
|
collector: &'b mut Collector,
|
||||||
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
builder: CommentsBuilder::default(),
|
collector,
|
||||||
source_code,
|
source_code,
|
||||||
parents: Vec::new(),
|
parents: Vec::new(),
|
||||||
preceding_node: None,
|
preceding_node: None,
|
||||||
@@ -42,10 +52,8 @@ impl<'a> CommentsVisitor<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn visit(mut self, root: &'a Mod) -> CommentsMap<'a> {
|
pub(super) fn visit(mut self, root: &'a Mod) {
|
||||||
self.visit_mod(root);
|
self.visit_mod(root);
|
||||||
|
|
||||||
self.finish()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_node<N>(&mut self, node: N) -> TraversalSignal
|
fn start_node<N>(&mut self, node: N) -> TraversalSignal
|
||||||
@@ -78,10 +86,8 @@ impl<'a> CommentsVisitor<'a> {
|
|||||||
slice: self.source_code.slice(*comment_range),
|
slice: self.source_code.slice(*comment_range),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.builder.add_comment(place_comment(
|
self.collector
|
||||||
comment,
|
.add_comment(comment, &Locator::new(self.source_code.as_str()));
|
||||||
&Locator::new(self.source_code.as_str()),
|
|
||||||
));
|
|
||||||
self.comment_ranges.next();
|
self.comment_ranges.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,23 +143,20 @@ impl<'a> CommentsVisitor<'a> {
|
|||||||
slice: self.source_code.slice(*comment_range),
|
slice: self.source_code.slice(*comment_range),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.builder.add_comment(place_comment(
|
self.collector
|
||||||
comment,
|
.add_comment(comment, &Locator::new(self.source_code.as_str()));
|
||||||
&Locator::new(self.source_code.as_str()),
|
|
||||||
));
|
|
||||||
|
|
||||||
self.comment_ranges.next();
|
self.comment_ranges.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
self.preceding_node = Some(node);
|
self.preceding_node = Some(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn finish(self) -> CommentsMap<'a> {
|
|
||||||
self.builder.finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
impl<'ast, 'b, Collector> PreorderVisitor<'ast> for CommentsVisitor<'ast, 'b, Collector>
|
||||||
|
where
|
||||||
|
Collector: CommentsCollector<'ast>,
|
||||||
|
{
|
||||||
fn visit_mod(&mut self, module: &'ast Mod) {
|
fn visit_mod(&mut self, module: &'ast Mod) {
|
||||||
if self.start_node(module).is_traverse() {
|
if self.start_node(module).is_traverse() {
|
||||||
walk_module(self, module);
|
walk_module(self, module);
|
||||||
@@ -336,7 +339,7 @@ fn text_position(comment_range: TextRange, source_code: SourceCode) -> CommentLi
|
|||||||
///
|
///
|
||||||
/// Used by [`CommentStyle::place_comment`] to determine if this should become a [leading](self#leading-comments), [dangling](self#dangling-comments), or [trailing](self#trailing-comments) comment.
|
/// Used by [`CommentStyle::place_comment`] to determine if this should become a [leading](self#leading-comments), [dangling](self#dangling-comments), or [trailing](self#trailing-comments) comment.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(super) struct DecoratedComment<'a> {
|
pub(crate) struct DecoratedComment<'a> {
|
||||||
enclosing: AnyNodeRef<'a>,
|
enclosing: AnyNodeRef<'a>,
|
||||||
preceding: Option<AnyNodeRef<'a>>,
|
preceding: Option<AnyNodeRef<'a>>,
|
||||||
following: Option<AnyNodeRef<'a>>,
|
following: Option<AnyNodeRef<'a>>,
|
||||||
@@ -362,17 +365,17 @@ impl<'a> DecoratedComment<'a> {
|
|||||||
///
|
///
|
||||||
/// The enclosing node is the list expression and not the name `b` because
|
/// The enclosing node is the list expression and not the name `b` because
|
||||||
/// `a` and `b` are children of the list expression and `comment` is between the two nodes.
|
/// `a` and `b` are children of the list expression and `comment` is between the two nodes.
|
||||||
pub(super) fn enclosing_node(&self) -> AnyNodeRef<'a> {
|
pub(crate) fn enclosing_node(&self) -> AnyNodeRef<'a> {
|
||||||
self.enclosing
|
self.enclosing
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the parent of the enclosing node, if any
|
/// Returns the parent of the enclosing node, if any
|
||||||
pub(super) fn enclosing_parent(&self) -> Option<AnyNodeRef<'a>> {
|
pub(crate) fn enclosing_parent(&self) -> Option<AnyNodeRef<'a>> {
|
||||||
self.parent
|
self.parent
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the slice into the source code.
|
/// Returns the slice into the source code.
|
||||||
pub(super) fn slice(&self) -> &SourceCodeSlice {
|
pub(crate) fn slice(&self) -> &SourceCodeSlice {
|
||||||
&self.slice
|
&self.slice
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,7 +419,7 @@ impl<'a> DecoratedComment<'a> {
|
|||||||
///
|
///
|
||||||
/// Returns `Some(a)` because `a` is the preceding node of `comment`. The presence of the `,` token
|
/// Returns `Some(a)` because `a` is the preceding node of `comment`. The presence of the `,` token
|
||||||
/// doesn't change that.
|
/// doesn't change that.
|
||||||
pub(super) fn preceding_node(&self) -> Option<AnyNodeRef<'a>> {
|
pub(crate) fn preceding_node(&self) -> Option<AnyNodeRef<'a>> {
|
||||||
self.preceding
|
self.preceding
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,12 +477,12 @@ impl<'a> DecoratedComment<'a> {
|
|||||||
///
|
///
|
||||||
/// Returns `None` because `comment` is enclosed inside the parenthesized expression and it has no children
|
/// Returns `None` because `comment` is enclosed inside the parenthesized expression and it has no children
|
||||||
/// following `# comment`.
|
/// following `# comment`.
|
||||||
pub(super) fn following_node(&self) -> Option<AnyNodeRef<'a>> {
|
pub(crate) fn following_node(&self) -> Option<AnyNodeRef<'a>> {
|
||||||
self.following
|
self.following
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The position of the comment in the text.
|
/// The position of the comment in the text.
|
||||||
pub(super) fn line_position(&self) -> CommentLinePosition {
|
pub(crate) fn line_position(&self) -> CommentLinePosition {
|
||||||
self.line_position
|
self.line_position
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -683,13 +686,18 @@ impl TraversalSignal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) trait CommentsCollector<'a>: Default {
|
||||||
|
fn add_comment(&mut self, placement: DecoratedComment<'a>, locator: &Locator);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
struct CommentsBuilder<'a> {
|
pub(super) struct CommentsBuilder<'a> {
|
||||||
comments: CommentsMap<'a>,
|
comments: CommentsMap<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CommentsBuilder<'a> {
|
impl<'a> CommentsCollector<'a> for CommentsBuilder<'a> {
|
||||||
fn add_comment(&mut self, placement: CommentPlacement<'a>) {
|
fn add_comment(&mut self, placement: DecoratedComment<'a>, locator: &Locator) {
|
||||||
|
let placement = place_comment(placement, locator);
|
||||||
match placement {
|
match placement {
|
||||||
CommentPlacement::Leading { node, comment } => {
|
CommentPlacement::Leading { node, comment } => {
|
||||||
self.push_leading_comment(node, comment);
|
self.push_leading_comment(node, comment);
|
||||||
@@ -748,11 +756,9 @@ impl<'a> CommentsBuilder<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn finish(self) -> CommentsMap<'a> {
|
impl<'a> CommentsBuilder<'a> {
|
||||||
self.comments
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push_leading_comment(&mut self, node: AnyNodeRef<'a>, comment: impl Into<SourceComment>) {
|
fn push_leading_comment(&mut self, node: AnyNodeRef<'a>, comment: impl Into<SourceComment>) {
|
||||||
self.comments
|
self.comments
|
||||||
.push_leading(NodeRefEqualityKey::from_ref(node), comment.into());
|
.push_leading(NodeRefEqualityKey::from_ref(node), comment.into());
|
||||||
@@ -767,4 +773,26 @@ impl<'a> CommentsBuilder<'a> {
|
|||||||
self.comments
|
self.comments
|
||||||
.push_trailing(NodeRefEqualityKey::from_ref(node), comment.into());
|
.push_trailing(NodeRefEqualityKey::from_ref(node), comment.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn finish(self) -> CommentsMap<'a> {
|
||||||
|
self.comments
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Used for the debug output, collects preceding, following and enclosing
|
||||||
|
#[derive(Default)]
|
||||||
|
pub(super) struct DecoratedCommentsCollector<'a> {
|
||||||
|
comments: Vec<DecoratedComment<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> CommentsCollector<'a> for DecoratedCommentsCollector<'a> {
|
||||||
|
fn add_comment(&mut self, placement: DecoratedComment<'a>, _locator: &Locator) {
|
||||||
|
self.comments.push(placement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> DecoratedCommentsCollector<'a> {
|
||||||
|
pub(super) fn finish(self) -> Vec<DecoratedComment<'a>> {
|
||||||
|
self.comments
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user