Skip to content

Commit

Permalink
Fix conflict between sortDeclarations and organizeDeclarations
Browse files Browse the repository at this point in the history
  • Loading branch information
nicklockwood committed Jun 11, 2024
1 parent 7db0538 commit 25fd24d
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
4 changes: 2 additions & 2 deletions Sources/FormattingHelpers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2210,7 +2210,7 @@ extension Formatter {
// If this type has a leading :sort directive, we sort alphabetically
// within the subcategories (where ordering is otherwise undefined)
let sortAlphabeticallyWithinSubcategories = typeDeclaration.open.contains(where: {
$0.isComment && $0.string.contains("swiftformat:sort") && !$0.string.contains(":sort:")
$0.isCommentBody && $0.string.contains("swiftformat:sort") && !$0.string.contains(":sort:")
})

// Sorts the given categoried declarations based on their derived metadata
Expand Down Expand Up @@ -2246,7 +2246,7 @@ extension Formatter {
// The compiler will synthesize a memberwise init for `struct`
// declarations that don't have an `init` declaration.
// We have to take care to not reorder any properties (but reordering functions etc is ok!)
if typeDeclaration.kind == "struct",
if !sortAlphabeticallyWithinSubcategories, typeDeclaration.kind == "struct",
!typeDeclaration.body.contains(where: { $0.keyword == "init" })
{
// Whether or not this declaration is an instance property that can affect
Expand Down
4 changes: 2 additions & 2 deletions Sources/Rules.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6041,7 +6041,7 @@ public struct _FormatRules {
sharedOptions: ["organizetypes"]
) { formatter in
formatter.forEachToken(
where: { $0.isComment && $0.string.contains("swiftformat:sort") }
where: { $0.isCommentBody && $0.string.contains("swiftformat:sort") }
) { commentIndex, commentToken in

let rangeToSort: ClosedRange<Int>
Expand Down Expand Up @@ -6073,7 +6073,7 @@ public struct _FormatRules {
lastTypeBodyToken > typeOpenBrace
else { return }

// Sorting the body of a type conflicts with the `organizeDeclaration`
// Sorting the body of a type conflicts with the `organizeDeclarations`
// keyword if enabled for this type of declaration. In that case,
// defer to the sorting implementation in `organizeDeclarations`.
if formatter.options.enabledRules.contains(FormatRules.organizeDeclarations.name),
Expand Down
9 changes: 9 additions & 0 deletions Sources/Tokenizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,15 @@ public extension Token {
}
}

var isCommentBody: Bool {
switch self {
case .commentBody:
return true
default:
return false
}
}

var isStringBody: Bool {
switch self {
case .stringBody:
Expand Down
40 changes: 40 additions & 0 deletions Tests/RulesTests+Organization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4130,6 +4130,46 @@ class OrganizationTests: RulesTests {
exclude: ["blankLinesAtStartOfScope", "blankLinesAtEndOfScope"])
}

func testSortStructPropertiesWithAttributes() {
let input = """
// swiftformat:sort
struct BookReaderView {
@Namespace private var animation
@State private var animationContent: Bool = false
@State private var offsetY: CGFloat = 0
@Bindable var model: Book
@Query(
filter: #Predicate<TextContent> { $0.progress_ < 1 },
sort: \\.updatedAt_,
order: .reverse
) private var incompleteTextContents: [TextContent]
}
"""
let output = """
// swiftformat:sort
struct BookReaderView {
// MARK: Internal
@Bindable var model: Book
// MARK: Private
@Namespace private var animation
@State private var animationContent: Bool = false
@Query(
filter: #Predicate<TextContent> { $0.progress_ < 1 },
sort: \\.updatedAt_,
order: .reverse
) private var incompleteTextContents: [TextContent]
@State private var offsetY: CGFloat = 0
}
"""
let options = FormatOptions(indent: " ", organizeTypes: ["struct"])
testFormatting(for: input, output, rule: FormatRules.organizeDeclarations,
options: options, exclude: ["blankLinesAtStartOfScope"])
}

// MARK: - sortTypealiases

func testSortSingleLineTypealias() {
Expand Down

0 comments on commit 25fd24d

Please sign in to comment.