diff --git a/CHANGELOG.md b/CHANGELOG.md index 612e577b77..e4cdcc7ce8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -68,6 +68,12 @@ [SimplyDanny](https://github.com/SimplyDanny) [#6466](https://github.com/realm/SwiftLint/issues/6466) +* Measure alignment columns in `vertical_parameter_alignment_on_call` using + character positions instead of raw UTF-8 columns, avoiding false positives + when a preceding line contains multi-byte characters. + [theamodhshetty](https://github.com/theamodhshetty) + [#6467](https://github.com/realm/SwiftLint/issues/6467) + ## 0.63.2: High-Speed Extraction ### Breaking diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/VerticalParameterAlignmentOnCallRule.swift b/Source/SwiftLintBuiltInRules/Rules/Style/VerticalParameterAlignmentOnCallRule.swift index 589bb32ac1..5f97f2ab51 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/VerticalParameterAlignmentOnCallRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/VerticalParameterAlignmentOnCallRule.swift @@ -83,6 +83,15 @@ struct VerticalParameterAlignmentOnCallRule: Rule { // completion } """), + Example(""" + func test() { + СreateAdUpdateShopHelper.updateShopModels(categoryModels: &categoryModels, + contactModels: &contactModels, + country: response.country!, + contact: response.contact, + shop: response.shop) + } + """), ], triggeringExamples: [ Example(""" @@ -132,7 +141,7 @@ private extension VerticalParameterAlignmentOnCallRule { return } - var firstArgumentLocation = locationConverter.location(for: firstArg.positionAfterSkippingLeadingTrivia) + var firstArgumentLocation = characterLocation(for: firstArg.positionAfterSkippingLeadingTrivia) var visitedLines = Set() var previousArgumentWasMultiline = false @@ -144,7 +153,7 @@ private extension VerticalParameterAlignmentOnCallRule { } let position = argument.positionAfterSkippingLeadingTrivia - let location = locationConverter.location(for: position) + let location = characterLocation(for: position) guard location.line > firstArgumentLocation.line else { return nil } @@ -174,5 +183,26 @@ private extension VerticalParameterAlignmentOnCallRule { return endPosition.line > startPosition.line } + + private func characterLocation(for position: AbsolutePosition) -> SourceLocation { + let location = locationConverter.location(for: position) + + let characterColumn: Int + let graphemeClusters = String( + locationConverter.sourceLines[location.line - 1].utf8.prefix(location.column - 1) + ) + if let graphemeClusters { + characterColumn = graphemeClusters.count + 1 + } else { + characterColumn = location.column + } + + return SourceLocation( + line: location.line, + column: characterColumn, + offset: location.offset, + file: location.file + ) + } } }