Skip to content

Add NoEmptyLinesOpeningClosingBraces rule #797

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

Conversation

mateusrodriguesxyz
Copy link
Contributor

This rule removes empty lines after opening braces and before closing braces:

// original

struct P {
            
    let x: Int
  
    let y: Int
          
}

// formatted

struct P {  
    let x: Int
  
    let y: Int   
}

That's similar to vertical_whitespace_opening_braces and vertical_whitespace_closing_braces.

It's a style used in official swift projects such as swift-syntax and sourcekit-lsp.

@ahoppen ahoppen requested a review from allevato August 20, 2024 14:16
Copy link
Member

@allevato allevato left a comment

Choose a reason for hiding this comment

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

My initial reaction to this was that I would like to keep rules involving whitespace inside the pretty printer (at least that was my plan when I got around to implementing this rule one day, which I've wanted to do for a while, so thanks for saving me the trouble!). But, that might end up being more complex looking at the logic there, so maybe this is fine the way it is—it removes the blank lines before the pretty printer ever sees them, which does the job.

import SwiftSyntax

@_spi(Rules)
public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
Copy link
Member

Choose a reason for hiding this comment

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

It's too bad we don't have a convenient way to just visit anything that conforms to BracedSyntax here.

Can you add PrecedenceGroupDeclSyntax and SwitchExprSyntax, which look like the only two other BracedSyntax node types that are missing here?

Copy link
Member

Choose a reason for hiding this comment

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

To visit anything conforming to BracedSyntax you can do the following

public override func visitAny(_ node: Syntax) -> Syntax? {
  if let braced = node.as(BracedSyntax.self) {
    // do things
  } else {
    super.visitAny(node)
  }
}

Copy link
Member

Choose a reason for hiding this comment

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

In general that would work for a regular visitor, but generate-swift-format scans the rules to figure out which concrete nodes they visit so that it can generate the pipeline visitor.

It might not be difficult to add visitAny support to the pipeline, but it would be better to do it separately from this PR.

Copy link
Member

Choose a reason for hiding this comment

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

👍🏽 Just wanted to put this pattern out there because it’s not terribly obvious.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've wished more than once that override func f(value: some T) in a class would override any concrete method that matches.

@@ -33,6 +33,7 @@
"NoAssignmentInExpressions": true,
"NoBlockComments": true,
"NoCasesWithOnlyFallthrough": true,
"NoEmptyLinesOpeningClosingBraces": true,
Copy link
Member

Choose a reason for hiding this comment

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

This will change the behavior of the default configuration (and also any existing configuration that doesn't explicitly reference the new rule). Is that something you intend to do with this PR?

Adding public override class var isOptIn: Bool { return true } would be safer for now. Then, we should probably come up with a policy for how we want to handle changes to the default configuration in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, It wasn’t my intention.

}

extension Trivia {
func trimmingSuperfluousNewlines() -> Trivia {
Copy link
Member

Choose a reason for hiding this comment

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

It looks like this function is never used, only the one with the underscore below is. Delete this and remove the underscore from the other one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I forget this 😅

import SwiftSyntax

@_spi(Rules)
public final class NoEmptyLinesOpeningClosingBraces: SyntaxFormatRule {
Copy link
Member

Choose a reason for hiding this comment

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

Can you please add a doc comment for this rule using a similar format to the other rules? RuleDocumentation.md should be generated from that when you run generate-swift-format; you don't need to update it manually.

//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Update the ending copyright date to 2024 here.

@mateusrodriguesxyz mateusrodriguesxyz force-pushed the no-empty-lines-opening-closing-braces branch from 736aed3 to bfcff5a Compare August 20, 2024 19:43
@mateusrodriguesxyz
Copy link
Contributor Author

@allevato I've updated the PR addressing your comments.

@allevato
Copy link
Member

Windows CI is failing because of the new source file. Can you please add Rules/NoEmptyLinesOpeningClosingBraces.swift to Sources/SwiftFormat/CMakeLists.txt?

@mateusrodriguesxyz
Copy link
Contributor Author

Done!

Copy link
Member

@allevato allevato left a comment

Choose a reason for hiding this comment

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

Thanks!

@allevato allevato merged commit 0c71671 into swiftlang:main Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants