mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
With the binding of configurations to their associated rule types "unknown configuration" errors can be made more specific mentioning also the rule's identifier in the printed message.
65 lines
2.6 KiB
Swift
65 lines
2.6 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)
|
|
guard let line = location.line, let column = location.column else {
|
|
return nil
|
|
}
|
|
return (position, line, 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
|
|
}
|
|
}
|
|
}
|