Skip to content
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

Add means of comment formatting to sway-fmt-v2 #2229

Merged
merged 13 commits into from
Jul 13, 2022
Merged

Conversation

kayagokalp
Copy link
Member

@kayagokalp kayagokalp commented Jul 5, 2022

Opening up for visibility. This is highly WIP.

If we decide to have the actual formatting in a separate PR, this is ready to review.

Related to #2224 and #2122.

To Do

  • Handle comments inside a code block
  • Improve tests

@kayagokalp kayagokalp added enhancement New feature or request formatter labels Jul 5, 2022
@kayagokalp kayagokalp added this to the `swayfmt-v2` milestone Jul 5, 2022
@kayagokalp kayagokalp self-assigned this Jul 5, 2022

impl Ord for CommentSpan {
fn cmp(&self, other: &Self) -> Ordering {
self.start.cmp(&other.start)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it comes to ordering spans, I think the correct approach might be to reflect not just the order in which the start occurs, but also the order in which the spans would be visited during traversal (e.g. larger enclosing spans preceding inner spans.)

E.g. when comparing the spans 2..6 and 2..4, the 2..6 span should come first as it encloses the 2..4 span. I think this would look something like:

match self.start.cmp(&other.start) {
    Ordering::Equal => other.end.cmp(&self.end),
    ord => ord,
}

Anyway, this is more relevant to the ordering of AST spans generally, and shouldn't be relevant to our case as I suppose comments cannot overlap 😂

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was actually thinking about this while writing that part but later on couldn't think of an example where comments would be overlapping as you pointed out 😄. But I will fix the ordering like this. Although it seems like overlapping won't be happening, if somehow it happens I feel like this will be really hard to debug.

@kayagokalp
Copy link
Member Author

kayagokalp commented Jul 6, 2022

This needs couple more touches but at the current status it can format the following code piece:

contract;

// This is a comment.
struct Foo {
    barasdd: u64,
    baz: bool,
}









        // This is the second comment.
struct Foo2 {
    barasdd: u64,
    baz: bool,
}

to

contract;

// This is a comment.
struct Foo {
    barasdd: u64,
    baz: bool,
}
// This is the second comment.
struct Foo2 {
    barasdd: u64,
    baz: bool,
}

Currently, it cannot handle comments that are inside a code block correctly (although they are correctly placed in the comment map). I should have that shortly and after some final clean-ups, this will be ready to go.

// If the starting position is the same encapsulatig span (i.e, wider one) should come
// first
match self.start.cmp(&other.start) {
Ordering::Equal => self.end.cmp(&other.end),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Ordering::Equal => self.end.cmp(&other.end),
Ordering::Equal => other.end.cmp(&self.end),

^ I think it should be this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm while sorting 2..4 and 2..6, should 2..6 come first? I think if we do it as you are suggesting 2..4 is coming first. I added a test for ensuring the ordering is working as we intended but I might have misunderstood the order we should have for the spans (I understand as the encapsulating span should be coming first, i.e 2..6).

@mitchmindtree
Copy link
Contributor

mitchmindtree commented Jul 7, 2022

For now, we might want to preserve the whitespace "gap" between comments and their preceding/following items too. We might be better off thinking about how to format comments and the whitespace gaps between comments and surrounding items in future PRs, as there is probably a lot to consider when trying to re-arrange or format them.

People do all kinds of stuff in comments like diagrams, post-fix on the same line, prefix to the line above, etc.

Could be good to keep some gross examples in mind, or even some as tests to check that we don't accidentally remove them or break them. I'm imagining stuff like:

// The following items are all related to the foo bar baz. Blah blah blah.

// This is a Foobar.
struct Foobar {
    a: A, // A is a A.
    b: B, // TODO: We should change this to a C.
    /// D is important and pub.
    /// blah blah.
    /// -----
    /// | D |
    /// -----
    pub d: D,
}

// This is a foo function.
fn foo(
    bar: Bar, // this is a bar
    baz: Baz, // this is a baz
    // Qux is a little more complicated.
    // So I'm writing multiline on top to describe why.
    // Blah blah blah
    qux: Qux,
) -> /* TODO: Result<Foobar> */ Result<Barfoo> {
}

@kayagokalp
Copy link
Member Author

kayagokalp commented Jul 7, 2022

As I started to explore how I can insert the comments to relevant places without formatting them, I realized that it is going to be somewhat tricky. I am thinking to have a separate PR for the actual comment insert operation and keep this one for only providing the means of comment formatting which will complete these 2 todos in #2122:

  • Implement Ord for Span as mentioned above. If unsuitable for sway-types due to paths, use our own Span type with conversions implemented. Edit: after taking another look at Span I think we don't want to use it directly. Instead we should use our own span (i.e. a simple byte range) and handle one file at a time.
  • Use CommentedTokenStream to collect a map of spans -> comments in sway-fmt-v2.

Would that make sense @mitchmindtree or should I keep going on this one until we have the complete comment stuff implemented?

Also once you are available another brainstorming session about actually inserting the comments would be great for me because as I started to dive deeper into actually inserting them, I started to have some concerns regarding the comments inside a code block. (I feel like I need some sort of mapping between the spans of items before formatting to after formatting, I can do that by re-parsing the formatted code and adding comments in a separate pass after while traversing the AST (that contains formatted code spans) but I feel like there could be a better approach for this)

@kayagokalp kayagokalp changed the title [WIP] Add means of comment formatting to sway-fmt-v2 Add means of comment formatting to sway-fmt-v2 Jul 7, 2022
@kayagokalp kayagokalp marked this pull request as ready for review July 7, 2022 16:12
@kayagokalp kayagokalp enabled auto-merge (squash) July 7, 2022 16:13
Copy link
Contributor

@mitchmindtree mitchmindtree left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea, I agree it makes sense to land the CommentMap and CommentSpan stuff first.

It's looking really good! I've just added a couple small suggestions.

Also, more than happy to have a chat again early next wk about how to go forward from here ☺️

sway-fmt-v2/src/utils/comments.rs Outdated Show resolved Hide resolved
sway-fmt-v2/src/utils/comments.rs Outdated Show resolved Hide resolved
sway-fmt-v2/src/utils/comments.rs Outdated Show resolved Hide resolved
@kayagokalp kayagokalp requested review from mitchmindtree and a team July 8, 2022 10:51
mitchmindtree
mitchmindtree previously approved these changes Jul 11, 2022
Copy link
Contributor

@mitchmindtree mitchmindtree left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, one step closer!

@mitchmindtree mitchmindtree requested a review from a team July 11, 2022 12:53
eureka-cpu
eureka-cpu previously approved these changes Jul 11, 2022
Copy link
Contributor

@eureka-cpu eureka-cpu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one!

#[test]
fn test_comment_span_ordering() {
let first_span = CommentSpan { start: 2, end: 4 };
let second_span = CommentSpan { start: 2, end: 6 };
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I just saw your response to my Ordering suggestion. It looks like this test is incorrect - I think the start: 2, end: 6 span should occur before the start: 2, end: 4 span, as I think we want the "visit" order where the enclosing spans precede the enclosed spans. Does that make sense?

@mitchmindtree mitchmindtree requested a review from a team July 13, 2022 01:44
@kayagokalp kayagokalp merged commit 84fec00 into master Jul 13, 2022
@kayagokalp kayagokalp deleted the kayagokalp/2224 branch July 13, 2022 03:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request formatter
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

Collect positional data to comment map for sway-fmt-v2: comment formatting Handle comments in sway-fmt-v2
4 participants