Skip to content

Fix closure_end_indentation corrupting CRLF files#6830

Open
sjh9714 wants to merge 1 commit into
realm:mainfrom
sjh9714:codex/20260722-6598-closure-end-crlf
Open

Fix closure_end_indentation corrupting CRLF files#6830
sjh9714 wants to merge 1 commit into
realm:mainfrom
sjh9714:codex/20260722-6598-closure-end-crlf

Conversation

@sjh9714

@sjh9714 sjh9714 commented Jul 21, 2026

Copy link
Copy Markdown

Summary

Fixes #6598.

Running swiftlint --fix with closure_end_indentation on a file with CRLF
(\r\n) line endings moved the closing braces of multi-line closures to
column 1, corrupting the file. LF files were unaffected.

The rule computed the expected indentation by indexing SourceKitten's
file.lines with a line number produced by SwiftSyntax's
locationConverter. The two disagree on CRLF: SwiftSyntax counts \r\n as
one newline, while StringView splits it into \n and \r separately,
inserting a phantom empty line after every real line. On CRLF files the
anchor-line lookup therefore hit the wrong (often empty) line, making the
expected indentation column 0.

Changes

  • ClosureEndIndentationRule.Visitor.getFirstNonWhitespaceColumn(onLine:)
    now reads the anchor line from locationConverter.sourceLines, the same
    line-numbering domain that produced the line number. No behavior change for
    LF files.
  • Regression test with CRLF examples: a correctly indented closure no longer
    triggers, and a genuinely misindented closing brace is corrected to the
    right column while CRLF endings are preserved. (testWrappingInString is
    disabled for the triggering example because the test helper's string
    wrapping escapes only \n, leaving bare \r bytes in the literal.)
  • CHANGELOG entry.

Testing

  • swift test --filter ClosureEndIndentationRule — new CRLF test fails
    before the fix (closing braces pulled to column 1) and passes after;
    the generated default-examples suite also passes.
  • swift test — full suite locally (1063 tests), except MacroTests, which
    cannot run in this environment (no XCTest under Command Line Tools). One
    unrelated suite (UnusedDeclarationRuleGeneratedTests) fails identically
    with and without this change in my environment.
  • Manual check of the reproduction from closure_end_indentation rule corrupts files with CRLF line endings #6598: on the corrupted file the fix
    restores the correct indentation; on the correctly indented CRLF file
    swiftlint --fix makes no changes and swiftlint reports 0 violations,
    with CRLF endings preserved throughout.

The rule computed expected indentation by indexing SourceKitten's
file.lines with a line number produced by SwiftSyntax's location
converter. The two disagree on CRLF line endings: SwiftSyntax counts
\r\n as one newline while StringView splits it into two, inserting a
phantom empty line after every real line. On CRLF files the anchor line
lookup then hit the wrong (often empty) line, so swiftlint --fix moved
closing braces to column 1.

Read the anchor line from locationConverter.sourceLines instead, which
uses the same line numbering that produced the line number.
@SwiftLintBot

Copy link
Copy Markdown
19 Messages
📖 Building this branch resulted in the same binary size as when built on main.
📖 Linting Aerial with this PR took 0.64 s vs 0.64 s on main (0% slower).
📖 Linting Alamofire with this PR took 0.9 s vs 0.92 s on main (2% faster).
📖 Linting Brave with this PR took 5.97 s vs 5.97 s on main (0% slower).
📖 Linting DuckDuckGo with this PR took 26.28 s vs 26.2 s on main (0% slower).
📖 Linting Firefox with this PR took 10.49 s vs 10.46 s on main (0% slower).
📖 Linting Kickstarter with this PR took 7.35 s vs 7.25 s on main (1% slower).
📖 Linting Moya with this PR took 0.42 s vs 0.36 s on main (16% slower).
📖 Linting NetNewsWire with this PR took 2.34 s vs 2.35 s on main (0% faster).
📖 Linting Nimble with this PR took 0.57 s vs 0.59 s on main (3% faster).
📖 Linting PocketCasts with this PR took 6.82 s vs 6.89 s on main (1% faster).
📖 Linting Quick with this PR took 0.4 s vs 0.35 s on main (14% slower).
📖 Linting Realm with this PR took 2.84 s vs 2.47 s on main (14% slower).
📖 Linting Sourcery with this PR took 1.64 s vs 1.45 s on main (13% slower).
📖 Linting Swift with this PR took 4.22 s vs 4.22 s on main (0% slower).
📖 Linting SwiftLintPerformanceTests with this PR took 0.16 s vs 0.16 s on main (0% slower).
📖 Linting VLC with this PR took 1.14 s vs 1.12 s on main (1% slower).
📖 Linting Wire with this PR took 15.15 s vs 15.14 s on main (0% slower).
📖 Linting WordPress with this PR took 9.65 s vs 9.69 s on main (0% faster).

Generated by 🚫 Danger

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.

closure_end_indentation rule corrupts files with CRLF line endings

2 participants