62 lines
2.5 KiB
Swift
62 lines
2.5 KiB
Swift
import SwiftSyntax
|
|
|
|
struct VerticalParameterAlignmentRule: SwiftSyntaxRule, ConfigurationProviderRule {
|
|
var configuration = SeverityConfiguration<Self>(.warning)
|
|
|
|
static let description = RuleDescription(
|
|
identifier: "vertical_parameter_alignment",
|
|
name: "Vertical Parameter Alignment",
|
|
description: "Function parameters should be aligned vertically if they're in multiple lines in a declaration",
|
|
kind: .style,
|
|
nonTriggeringExamples: VerticalParameterAlignmentRuleExamples.nonTriggeringExamples,
|
|
triggeringExamples: VerticalParameterAlignmentRuleExamples.triggeringExamples
|
|
)
|
|
|
|
func makeVisitor(file: SwiftLintFile) -> ViolationsSyntaxVisitor {
|
|
Visitor(locationConverter: file.locationConverter)
|
|
}
|
|
}
|
|
|
|
private extension VerticalParameterAlignmentRule {
|
|
final class Visitor: ViolationsSyntaxVisitor {
|
|
private let locationConverter: SourceLocationConverter
|
|
|
|
init(locationConverter: SourceLocationConverter) {
|
|
self.locationConverter = locationConverter
|
|
super.init(viewMode: .sourceAccurate)
|
|
}
|
|
|
|
override func visitPost(_ node: FunctionDeclSyntax) {
|
|
violations.append(contentsOf: violations(for: node.signature.input.parameterList))
|
|
}
|
|
|
|
override func visitPost(_ node: InitializerDeclSyntax) {
|
|
violations.append(contentsOf: violations(for: node.signature.input.parameterList))
|
|
}
|
|
|
|
private func violations(for params: FunctionParameterListSyntax) -> [AbsolutePosition] {
|
|
guard params.count > 1 else {
|
|
return []
|
|
}
|
|
|
|
let paramLocations = params.compactMap { param -> (position: AbsolutePosition, line: Int, column: Int)? in
|
|
let position = param.positionAfterSkippingLeadingTrivia
|
|
let location = locationConverter.location(for: position)
|
|
return (position, location.line, location.column)
|
|
}
|
|
|
|
guard let firstParamLoc = paramLocations.first else { return [] }
|
|
|
|
var violations: [AbsolutePosition] = []
|
|
for (index, paramLoc) in paramLocations.enumerated() where index > 0 && paramLoc.line > firstParamLoc.line {
|
|
let previousParamLoc = paramLocations[index - 1]
|
|
if previousParamLoc.line < paramLoc.line && firstParamLoc.column != paramLoc.column {
|
|
violations.append(paramLoc.position)
|
|
}
|
|
}
|
|
|
|
return violations
|
|
}
|
|
}
|
|
}
|