-
Notifications
You must be signed in to change notification settings - Fork 644
Add breakLineAt End & Start OfScope rule #2029
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
base: main
Are you sure you want to change the base?
Add breakLineAt End & Start OfScope rule #2029
Conversation
SwiftFormat.xcodeproj/xcshareddata/xcschemes/SwiftFormatTests.xcscheme
Outdated
Show resolved
Hide resolved
9e5558a
to
6c28718
Compare
@@ -1047,3 +1046,9 @@ public struct Options { | |||
fileOptions?.shouldSkipFile(inputURL) ?? false | |||
} | |||
} | |||
|
|||
public enum TypeBlankLines: String, CaseIterable { |
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.
Please place this declaration next to the other declaration option types in this file
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.
A doc comment would be nice as well
""" | ||
} | ||
} | ||
|
||
private extension Formatter { |
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 should be internal
// we need to modify the tokens | ||
if linebreakCount != 2 || !hasWhitespaceAfterLastLinebreak { | ||
// Remove existing whitespace and linebreaks | ||
formatter.removeTokens(in: (lastContentIndex + 1) ..< endOfScopeIndex) |
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.
Why remove tokens before adding tokens? One problem is that this will remove any comments that may be present at the end of the type.
I think it would be better to just insert a single line break at the end of the type if necessary.
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.
Perhaps this code could be simplified using the existing numberOfTrailingLinebreaks()
helper defined on Array<Token>
. You could do:
let typeBody = Array(formatter.tokens[startOfScope..<endOfScope])
let numberOfTrailingLinebreaks = typeBody.numberOfTrailingLinebreaks()
if numberOfTrailingLinebreaks != 2 {
// insert linebreak at end of type
}
return | ||
} | ||
// Check if this is a type declaration | ||
let isTypeDeclaration = ["class", "actor", "struct", "enum", "protocol", "extension"].contains( |
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.
Maybe this could use the Formatter.isTypeDeclaration
helper that you factored out in the other file
formatter.removeTokens(in: indexOfFirstLineBreak ..< indexOfLastLineBreak) | ||
} | ||
case .insert, .preserve: | ||
// We don't insert blank lines at start of scope, and preserve means do nothing |
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.
Would you mind adding support for the .insert
case here as well? 🙏🏻
@@ -930,7 +929,7 @@ public struct FormatOptions: CustomStringConvertible { | |||
self.timeZone = timeZone | |||
self.nilInit = nilInit | |||
self.preservedPrivateDeclarations = preservedPrivateDeclarations | |||
// Doesn't really belong here, but hard to put elsewhere |
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.
Please preserve this existing comment
This pull request introduces a new formatting rule,
breakLineAtEndOfTypes
, to enforce a blank line before the closing brace of type declarations (e.g.,class
,struct
,enum
). It includes updates to the core formatting logic, configuration options, and test cases, as well as project file changes to integrate the new rule.New Rule Implementation
breakLineAtEndOfTypes
, to ensure a blank line exists before the closing brace of type declarations. This rule supports types such asclass
,struct
,enum
,protocol
,extension
, andactor
. (Sources/Rules/BreakLineAtEndOfTypes.swift
)Configuration and Options
breakLineAtEndOfTypes
property in theFormatOptions
struct to enable or disable the rule. Default value isfalse
. (Sources/Options.swift
) [1] [2] [3]OptionDescriptor
forbreakLineAtEndOfTypes
to allow configuration through command-line arguments or configuration files. (Sources/OptionDescriptor.swift
)Testing
BreakLineAtEndOfTypesTests.swift
to validate the new rule against various scenarios, including classes, structs, enums, protocols, extensions, and actors. Tests also cover edge cases like preserving existing blank lines and handling disabled options. (Tests/Rules/BreakLineAtEndOfTypesTests.swift
)Project Integration
BreakLineAtEndOfTypes.swift
) and its corresponding test file (BreakLineAtEndOfTypesTests.swift
). (SwiftFormat.xcodeproj/project.pbxproj
) [1] [2] [3] [4] [5] [6] [7] [8] [9]SwiftFormatTests.xcscheme
, to include the new test cases in the test suite. (SwiftFormat.xcodeproj/xcshareddata/xcschemes/SwiftFormatTests.xcscheme
)Minor Adjustments
PerformanceTests
to include the new rule in its configuration options for performance measurement. (PerformanceTests/PerformanceTests.swift
)