-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Inserting Comments #2311
Inserting Comments #2311
Conversation
…stream, rename: construct_comment_map to comment_map_from_src
I solved the whitespace changes in the formatted output. I can handle regular whitespace correctly but with the assumption that the offsetting between the comment and the item associated with the comment (assigned by the formatter) is separated by |
Would you mind merging in or rebasing onto |
Thanks for the nice comments @JoshuaBatty @mitchmindtree 🙏 . I applied the changes requested and wanted to comment about the current approach. As @mitchmindtree touched in the review above this comment, although this works this can be done more efficiently. But we need some ninja level refactoring to reach there and this PR is already big and I think we need the formatter v2 to replace the current one as soon as possible. So as @mitchmindtree suggested in the review, I am creating a separate issue for improving the efficiency and handle that later on with a clean look. |
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.
🚢
About this PR
closes #2122.
Comments are stripped in the parsing step which causes them to disappear in the formatted output because the formatter reconstructs the code from the parsed source code. With this PR
sway-fmt-v2
will be able to conserve the comments as they were inserted by the user. To accomplish that, the following concepts are introduced:Span
->Comment
Comment
s yet)Mapping between
Span
->Comment
This is used for fast retrieval of comments with a given range of spans. This is essential since to insert comments we should first find them with respect to items that are also present in the formatted output. To do that we will be searching for comments in possible spots
Visitor that can visit and collect possible positions inside a parsed code piece.
To be able to accomplish this goal of ours we would either need to implement searching logic for all possible spanned pieces in the code like the following:
or we should have a generic logic for searching & insertion of comments with given possible spans. This requires us to be able to visit each possible parsed code piece and collect possible spans from that code piece. Then a generic search & insert would be able to insert all the comments for all possible places that a comment can be seen. Since this seemed a cleaner and shorter way, I followed this path and introduced a
CommentVisitor
trait. IfCommentVisitor
is implemented for a type we can get all of the possibleSpan
s by simply callingcollect_spans()
.A little side note here: Since for BTreeMap to keep an ordering of
Span
->Comment
, I neededSpan
to implementOrd
. SinceSpan
is heavily used in the other parts of the code as well and for comment insertion, I do only require thestart
andend
fields of it, I created a stripped version that also implementsOrd
(CommentSpan
).Collecting some context while finding comments from unformatted code
Since we are finding the comment by simply searching in the mapping for the given range of spans, we are only getting the comment itself. Inserting just the comment itself deletes the user's original alignment whitespaces. We are collecting some extra information (context) while searching for comments to conserve the user's alignment.
General structure of
Comment
insertionmodule
.module
.span
range from unformatted code to aspan
range in formatted code. This is required since we do not have another way of finding the correct spot for the comment in the formatted code because when the code is formatted places ofitem
s etc can heavily change in various scenarios. For example, input with a large number of new lines between items can be considered. When such input is formatted, the number of newlines betweenitem
s will reduce dramatically. Although we will be able to find thecomment
s easily in the unformatted code placing them in the correct places w.t.r to the item they were originally commenting on would be an open problem if we didn't traverse both formatted and unformatted code together.).CommentSpan
and the current one. If we can find some we are inserting them with their collected context to the corresponding place in the formatted output.Current status of
Comment
sThis is a little tricky to write about since while working on comment stuff I had a couple of "a-ha moments" about
comment
insertion. I think this can be enough to reach MVP formatter but this part of the code will require a little bit more love. Some points to keep in mind aroundComment
stuff:/*...*/
from//...
or we can prevent single-line formatting while we have comments.)A final note about the current status: until
expr
formatting lands we will have duplicate comments insideexpr
's since the formatter also adds them (because it is directly pushing rawstr
until it is implemented. @eureka-cpu brewing some cool stuff for that over #2338)Initial explanation of this PR (written while it was still a draft leaving this here for visibility purposes)