SwiftLint/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift

67 lines
2.5 KiB
Swift

import SwiftSyntax
struct MultilineParametersRule: SwiftSyntaxRule, OptInRule, ConfigurationProviderRule {
var configuration = MultilineParametersConfiguration()
static let description = RuleDescription(
identifier: "multiline_parameters",
name: "Multiline Parameters",
description: "Functions and methods parameters should be either on the same line, or one per line",
kind: .style,
nonTriggeringExamples: MultilineParametersRuleExamples.nonTriggeringExamples,
triggeringExamples: MultilineParametersRuleExamples.triggeringExamples
)
func makeVisitor(file: SwiftLintFile) -> ViolationsSyntaxVisitor {
Visitor(allowsSingleLine: configuration.allowsSingleLine, locationConverter: file.locationConverter)
}
}
private extension MultilineParametersRule {
final class Visitor: ViolationsSyntaxVisitor {
private let allowsSingleLine: Bool
private let locationConverter: SourceLocationConverter
init(allowsSingleLine: Bool, locationConverter: SourceLocationConverter) {
self.allowsSingleLine = allowsSingleLine
self.locationConverter = locationConverter
super.init(viewMode: .sourceAccurate)
}
override func visitPost(_ node: FunctionDeclSyntax) {
if containsViolation(for: node.signature) {
violations.append(node.identifier.positionAfterSkippingLeadingTrivia)
}
}
override func visitPost(_ node: InitializerDeclSyntax) {
if containsViolation(for: node.signature) {
violations.append(node.initKeyword.positionAfterSkippingLeadingTrivia)
}
}
private func containsViolation(for signature: FunctionSignatureSyntax) -> Bool {
let parameterPositions = signature.input.parameterList.map(\.positionAfterSkippingLeadingTrivia)
guard parameterPositions.isNotEmpty else {
return false
}
var numberOfParameters = 0
var linesWithParameters = Set<Int>()
for position in parameterPositions {
let line = locationConverter.location(for: position).line
linesWithParameters.insert(line)
numberOfParameters += 1
}
guard linesWithParameters.count > (allowsSingleLine ? 1 : 0),
numberOfParameters != linesWithParameters.count else {
return false
}
return true
}
}
}