-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Formatter: Show preceding, following and enclosing nodes of comments, Attempt 2 #6813
Conversation
fn add_comment(&mut self, placement: CommentPlacement<'a>) { | ||
impl<'a> CommentsBuilderTrait<'a> for CommentsBuilder<'a> { | ||
fn add_comment(&mut self, comment: DecoratedComment<'a>, locator: &Locator) { | ||
let placement = place_comment(comment, locator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i didn't find a better location for this
pub(crate) struct CommentsVisitor<'a> { | ||
builder: CommentsBuilder<'a>, | ||
struct CommentsVisitor<'a, 'builder> { | ||
builder: &'builder mut (dyn CommentsBuilderTrait<'a> + 'a), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
side effect: the visitor is now private
This comment was marked as outdated.
This comment was marked as outdated.
Can you run some local benchmarks to confirm/deny the performance regression? |
909e1af
to
b153208
Compare
Should we just use |
you mean through tracing? |
CodSpeed Performance ReportMerging #6813 will not alter performanceComparing Summary
|
/// 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>> { | ||
collect_comments(root, source_code, comment_ranges) | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method feels misplaced because it doesn't involve Comments
at all. Why not expose collect_comments
directly?
let mut builder = CommentsBuilder::default(); | ||
CommentsVisitor::new(source_code, comment_ranges, &mut builder).visit(root); | ||
builder.finish() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: I'm leaning towards inlining this function into Comments::from_ast
because get_comments_map
sounds like your getting a value rather than computing it. Maybe rename it to build_comments_map
? IMO, CommentsVisitor
and CommentsBuilder
being visible to the comments module seems reasonable to me.
@@ -512,13 +529,29 @@ impl<'a> CommentPlacement<'a> { | |||
} | |||
} | |||
|
|||
pub(super) trait CommentsBuilderTrait<'a> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's uncommon to include the type-kind in the name, especially because only the CommentsBuilder
is building Comments
.
A rusty name could be AddComment
, or we use Add<DecoratedComment>
and make locator
a field on CommentsBuilder
.
Or another idea is to accept any type that implements Extend
. The downside is that we'll have to pass [comment]
because extend_one
isn't stable. But I think that resembles the idea the closest. You get a comment and can append it to some data structure. Which also removes the need for CommentsCollector
because you can simply pass a &mut Vec
.
I think I'm then leaning to making collect_comments
public and make it accept any &dyn Extend<DecoratedComment<'a>>
and to make CommentsBuilder
pub(super)`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went with PushComment::push_comment
, mirroring Vec
. A possible improvement could be implementing PushComment
directly on CommentsMap<'a>
and Vec<DecoratedComment<'a>>
. I think we do need a dedicated trait though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't mind implementing it directly on Vec<DecoratedComment>
but I think I would keep the builder around since we don't want adding the Locator
to CommentsMap
.
35e6f9a
to
c7e658e
Compare
c7e658e
to
527aa84
Compare
One thing I forgot to mention before. I struggle reading the output of the new comment because it isn't clear to me which node is the enclosing, trailing, or leading node. I think it would help to have labels and/or use Rust's expanded struct display |
**Summary** Show a header in the formatter comment decoration debug output that shows which node is preceding/following/enclosing (#6813 (comment)). I also kept this intentionally condensed to make it easy to use this is a small sidebar without vertical scrolling. ``` # Comment decoration: Range Preceding Following Enclosing Comment 1292..1298 Some((ExprName, 1274..1280)) Some((ExprName, 1307..1310)) (StmtAnnAssign, 1274..1316) "# type" 2507..2555 None Some((StmtIf, 2634..2891)) (StmtClassDef, 2478..3279) "# didn't match the name in the C implementation," 2560..2629 None Some((StmtIf, 2634..2891)) (StmtClassDef, 2478..3279) "# meaning it is only *safe* to pass it as a keyword argument on 3.12+" 3281..3298 Some((StmtClassDef, 2478..3279)) Some((StmtFunctionDef, 3300..3317)) (ModModule, 0..4162) "# Top level rules" 3481..3496 Some((StmtClassDef, 3452..3479)) Some((StmtClassDef, 3498..3876)) (ModModule, 0..4162) "# Nesting rules" { Node { kind: ExprName, range: 1307..1310, source: `int`, }: { ... ``` **Test Plan** It's debug output.
**Summary** The comment visitor used to rebuild the locator for every comment. Instead, we now keep the locator on the builder. Follow-up to #6813. **Test Plan** No formatting changes.
**Summary** Show a header in the formatter comment decoration debug output that shows which node is preceding/following/enclosing (#6813 (comment)). I also kept this intentionally condensed to make it easy to use this is a small sidebar without vertical scrolling. ``` # Comment decoration: Range Preceding Following Enclosing Comment 1292..1298 Some((ExprName, 1274..1280)) Some((ExprName, 1307..1310)) (StmtAnnAssign, 1274..1316) "# type" 2507..2555 None Some((StmtIf, 2634..2891)) (StmtClassDef, 2478..3279) "# didn't match the name in the C implementation," 2560..2629 None Some((StmtIf, 2634..2891)) (StmtClassDef, 2478..3279) "# meaning it is only *safe* to pass it as a keyword argument on 3.12+" 3281..3298 Some((StmtClassDef, 2478..3279)) Some((StmtFunctionDef, 3300..3317)) (ModModule, 0..4162) "# Top level rules" 3481..3496 Some((StmtClassDef, 3452..3479)) Some((StmtClassDef, 3498..3876)) (ModModule, 0..4162) "# Nesting rules" { Node { kind: ExprName, range: 1307..1310, source: `int`, }: { ... ``` **Test Plan** It's debug output.
Show header for formatter comment decoration info **Summary** Show a header in the formatter comment decoration debug output that shows which node is preceding/following/enclosing (#6813 (comment)). I kept this intentionally condensed to make it easy to use this is a small sidebar without vertical scrolling. ```console $ cargo run --bin ruff_python_formatter -- --emit stdout --print-comments scratch.py # Comment decoration: Range, Preceding, Following, Enclosing, Comment 17..20, Some((ParameterWithDefault, 6..10)), None, (Parameters, 5..22), "# a" 44..47, Some((StmtExpr, 28..39)), Some((StmtExpr, 52..60)), (StmtFunctionDef, 0..60), "# b" 77..80, None, None, (ExprList, 71..82), "# c" { Node { kind: ParameterWithDefault, range: 6..10, source: `x=[]`, }: { ... ``` **Test Plan** It's debug output.
This is a new attempt after #6337.
Summary I used to always add
dbg!
for the preceding, following and enclosing node. With this change--print-comments
can do this instead.Additional
--print-comments
Output:Test Plan n/a