From a081099499ed8104325bb4b62efeefed26e95937 Mon Sep 17 00:00:00 2001 From: Rodion Ivashkov Date: Tue, 2 Sep 2025 18:28:54 +0300 Subject: [PATCH 1/5] multiline_parameters: add optional checks for function call arguments # Conflicts: # Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift --- .../MultilineParametersConfiguration.swift | 21 +++++++++++ .../Rules/Style/MultilineParametersRule.swift | 24 +++++++++++- .../MultilineParametersRuleExamples.swift | 37 ++++++++++++++++++- .../default_rule_configurations.yml | 1 + 4 files changed, 81 insertions(+), 2 deletions(-) diff --git a/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift b/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift index bd9eed941a..cf3dadadc8 100644 --- a/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift +++ b/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift @@ -10,9 +10,20 @@ struct MultilineParametersConfiguration: SeverityBasedRuleConfiguration { private(set) var allowsSingleLine = true @ConfigurationElement(key: "max_number_of_single_line_parameters") private(set) var maxNumberOfSingleLineParameters: Int? + @ConfigurationElement(key: "check_calls") + private(set) var checkCalls = false // swiftlint:disable:next unneeded_throws_rethrows func validate() throws(Issue) { + if checkCalls, maxNumberOfSingleLineParameters == nil { + Issue.inconsistentConfiguration( + ruleID: Parent.identifier, + message: """ + Option '\($checkCalls.key)' has no effect when \ + '\($maxNumberOfSingleLineParameters.key)' is nil. + """ + ).print() + } guard let maxNumberOfSingleLineParameters else { return } @@ -33,5 +44,15 @@ struct MultilineParametersConfiguration: SeverityBasedRuleConfiguration { """ ).print() } + + if checkCalls, !allowsSingleLine { + Issue.inconsistentConfiguration( + ruleID: Parent.identifier, + message: """ + Option '\($checkCalls.key)' has no effect when \ + '\($allowsSingleLine.key)' is false. + """ + ).print() + } } } diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift b/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift index 7ff00199d6..c50a725daf 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift @@ -7,7 +7,9 @@ struct MultilineParametersRule: Rule { 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", + description: """ + Functions, initializers, and function call arguments should be either on the same line, or one per line + """, kind: .style, nonTriggeringExamples: MultilineParametersRuleExamples.nonTriggeringExamples, triggeringExamples: MultilineParametersRuleExamples.triggeringExamples @@ -28,8 +30,28 @@ private extension MultilineParametersRule { } } + override func visitPost(_ node: FunctionCallExprSyntax) { + guard node.arguments.isNotEmpty else { return } + guard configuration.checkCalls else { return } + guard node.trailingClosure == nil else { return } + + if containsViolation(for: node.arguments) { + let anchor = node.calledExpression.positionAfterSkippingLeadingTrivia + violations.append(anchor) + } + } + private func containsViolation(for signature: FunctionSignatureSyntax) -> Bool { let parameterPositions = signature.parameterClause.parameters.map(\.positionAfterSkippingLeadingTrivia) + return containsViolation(parameterPositions: parameterPositions) + } + + private func containsViolation(for arguments: LabeledExprListSyntax) -> Bool { + let argumentPositions = arguments.map(\.positionAfterSkippingLeadingTrivia) + return containsViolation(parameterPositions: argumentPositions) + } + + private func containsViolation(parameterPositions: [AbsolutePosition]) -> Bool { guard parameterPositions.isNotEmpty else { return false } diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRuleExamples.swift index 250713e900..df910b59e0 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRuleExamples.swift @@ -213,6 +213,20 @@ internal struct MultilineParametersRuleExamples { param3: [String] ) { } """, configuration: ["max_number_of_single_line_parameters": 2]), + Example(""" + foo( + param1: "param1", + param2: false, + param3: [] + ) + """, configuration: ["max_number_of_single_line_parameters": 2]), + Example(""" + foo(param1: 1, + param2: false, + param3: []) + """, configuration: ["max_number_of_single_line_parameters": 1]), + Example("foo(param1: 1, param2: false)", + configuration: ["max_number_of_single_line_parameters": 2]), ] static let triggeringExamples: [Example] = [ @@ -360,6 +374,27 @@ internal struct MultilineParametersRuleExamples { """, configuration: ["max_number_of_single_line_parameters": 3]), Example(""" func ↓foo(param1: Int, param2: Bool, param3: [String]) { } - """, configuration: ["max_number_of_single_line_parameters": 2]), + """, configuration: [ + "max_number_of_single_line_parameters": 2, + "check_calls": true, + ]), + Example("↓foo(param1: 1, param2: false, param3: [])", + configuration: [ + "max_number_of_single_line_parameters": 2, + "check_calls": true, + ]), + Example(""" + func ↓foo(param1: Int, + param2: Bool, param3: [String]) { } + """, configuration: [ + "max_number_of_single_line_parameters": 3, + "check_calls": true, + ]), + Example(""" + ↓foo(param1: Int, param2: Bool, param3: [String]) + """, configuration: [ + "max_number_of_single_line_parameters": 2, + "check_calls": true, + ]), ] } diff --git a/Tests/IntegrationTests/default_rule_configurations.yml b/Tests/IntegrationTests/default_rule_configurations.yml index dbed598b07..0279b89494 100644 --- a/Tests/IntegrationTests/default_rule_configurations.yml +++ b/Tests/IntegrationTests/default_rule_configurations.yml @@ -691,6 +691,7 @@ multiline_literal_brackets: multiline_parameters: severity: warning allows_single_line: true + check_calls: false meta: opt-in: true correctable: false From 883f91230353de438e91be65d871bfe2bf598493 Mon Sep 17 00:00:00 2001 From: Rodion Ivashkov Date: Fri, 21 Nov 2025 16:44:22 +0300 Subject: [PATCH 2/5] Create `multiline_call_arguments` rule --- .../Models/BuiltInRules.swift | 1 + .../Lint/MultilineCallArgumentsRule.swift | 150 ++++++++++++++++++ .../MultilineCallArgumentsConfiguration.swift | 35 ++++ Tests/GeneratedTests/GeneratedTests_05.swift | 12 +- Tests/GeneratedTests/GeneratedTests_06.swift | 12 +- Tests/GeneratedTests/GeneratedTests_07.swift | 12 +- Tests/GeneratedTests/GeneratedTests_08.swift | 12 +- Tests/GeneratedTests/GeneratedTests_09.swift | 12 +- Tests/GeneratedTests/GeneratedTests_10.swift | 6 + .../default_rule_configurations.yml | 6 + 10 files changed, 228 insertions(+), 30 deletions(-) create mode 100644 Source/SwiftLintBuiltInRules/Rules/Lint/MultilineCallArgumentsRule.swift create mode 100644 Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineCallArgumentsConfiguration.swift diff --git a/Source/SwiftLintBuiltInRules/Models/BuiltInRules.swift b/Source/SwiftLintBuiltInRules/Models/BuiltInRules.swift index 459bc18f0b..38104f3ec1 100644 --- a/Source/SwiftLintBuiltInRules/Models/BuiltInRules.swift +++ b/Source/SwiftLintBuiltInRules/Models/BuiltInRules.swift @@ -118,6 +118,7 @@ public let builtInRules: [any Rule.Type] = [ ModifierOrderRule.self, MultilineArgumentsBracketsRule.self, MultilineArgumentsRule.self, + MultilineCallArgumentsRule.self, MultilineFunctionChainsRule.self, MultilineLiteralBracketsRule.self, MultilineParametersBracketsRule.self, diff --git a/Source/SwiftLintBuiltInRules/Rules/Lint/MultilineCallArgumentsRule.swift b/Source/SwiftLintBuiltInRules/Rules/Lint/MultilineCallArgumentsRule.swift new file mode 100644 index 0000000000..1fe92dc0a2 --- /dev/null +++ b/Source/SwiftLintBuiltInRules/Rules/Lint/MultilineCallArgumentsRule.swift @@ -0,0 +1,150 @@ +import SwiftLintCore +import SwiftSyntax + +@SwiftSyntaxRule(optIn: true) +struct MultilineCallArgumentsRule: Rule { + var configuration = MultilineCallArgumentsConfiguration() + + static let description = RuleDescription( + identifier: "multiline_call_arguments", + name: "Multiline Call Arguments", + description: """ + Arguments in function and method calls should be either on the same line \ + or one per line when the call spans multiple lines + """, + kind: .style, + nonTriggeringExamples: [ + Example(""" + foo( + param1: "param1", + param2: false, + param3: [] + ) + """, configuration: ["max_number_of_single_line_parameters": 2]), + Example(""" + foo(param1: 1, + param2: false, + param3: []) + """, configuration: ["max_number_of_single_line_parameters": 1]), + Example("foo(param1: 1, param2: false)", + configuration: ["max_number_of_single_line_parameters": 2]), + Example("Enum.foo(param1: 1, param2: false)", + configuration: ["max_number_of_single_line_parameters": 2]), + Example(""" + foo(param1: 1) + """, + configuration: [ + "allows_single_line": false + ]), + Example(""" + Enum.foo(param1: 1) + """, + configuration: [ + "allows_single_line": false + ]), + Example(""" + Enum.foo(param1: 1, param2: 2, param3: 3) + """, + configuration: [ + "allows_single_line": true + ]), + Example(""" + foo( + param1: 1, + param2: 2, + param3: 3 + ) + """, + configuration: [ + "allows_single_line": false + ]), + ], + triggeringExamples: [ + Example("↓foo(param1: 1, param2: false, param3: [])", + configuration: [ + "max_number_of_single_line_parameters": 2 + ]), + Example("↓Enum.foo(param1: 1, param2: false, param3: [])", + configuration: [ + "max_number_of_single_line_parameters": 2 + ]), + Example(""" + ↓foo(param1: 1, param2: false, + param3: []) + """, configuration: [ + "max_number_of_single_line_parameters": 3 + ]), + Example(""" + ↓Enum.foo(param1: 1, param2: false, + param3: []) + """, configuration: [ + "max_number_of_single_line_parameters": 3 + ]), + Example(""" + ↓foo(param1: 1, param2: false) + """, + configuration: [ + "allows_single_line": false + ]), + Example(""" + ↓Enum.foo(param1: 1, param2: false) + """, + configuration: [ + "allows_single_line": false + ]), + ] + ) +} + +private extension MultilineCallArgumentsRule { + final class Visitor: ViolationsSyntaxVisitor { + override func visitPost(_ node: FunctionCallExprSyntax) { + guard node.arguments.isNotEmpty else { return } + guard node.trailingClosure == nil else { return } + + if containsViolation(for: node.arguments) { + let anchor = node.calledExpression.positionAfterSkippingLeadingTrivia + violations.append(anchor) + } + } + + private func containsViolation(for arguments: LabeledExprListSyntax) -> Bool { + let argumentPositions = arguments.map(\.positionAfterSkippingLeadingTrivia) + return containsViolation(parameterPositions: argumentPositions) + } + + private func containsViolation(parameterPositions: [AbsolutePosition]) -> Bool { + guard parameterPositions.isNotEmpty else { + return false + } + + var numberOfParameters = 0 + var linesWithParameters: Set = [] + var hasMultipleParametersOnSameLine = false + + for position in parameterPositions { + let line = locationConverter.location(for: position).line + + if !linesWithParameters.insert(line).inserted { + hasMultipleParametersOnSameLine = true + } + + numberOfParameters += 1 + } + + if linesWithParameters.count == 1 { + guard configuration.allowsSingleLine else { + return numberOfParameters > 1 + } + + if let maxNumberOfSingleLineParameters = configuration.maxNumberOfSingleLineParameters { + return numberOfParameters > maxNumberOfSingleLineParameters + } + + return false + } + + return hasMultipleParametersOnSameLine + } + } +} diff --git a/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineCallArgumentsConfiguration.swift b/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineCallArgumentsConfiguration.swift new file mode 100644 index 0000000000..74952c3a9f --- /dev/null +++ b/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineCallArgumentsConfiguration.swift @@ -0,0 +1,35 @@ +import SwiftLintCore + +@AutoConfigParser +struct MultilineCallArgumentsConfiguration: SeverityBasedRuleConfiguration { + typealias Parent = MultilineCallArgumentsRule + + @ConfigurationElement(key: "severity") + private(set) var severityConfiguration = SeverityConfiguration(.warning) + @ConfigurationElement(key: "allows_single_line") + private(set) var allowsSingleLine = true + @ConfigurationElement(key: "max_number_of_single_line_parameters") + private(set) var maxNumberOfSingleLineParameters: Int? + + func validate() throws(Issue) { + guard let maxNumberOfSingleLineParameters else { + return + } + guard maxNumberOfSingleLineParameters >= 1 else { + throw Issue.inconsistentConfiguration( + ruleID: Parent.identifier, + message: "Option '\($maxNumberOfSingleLineParameters.key)' should be >= 1." + ) + } + + if maxNumberOfSingleLineParameters > 1, !allowsSingleLine { + throw Issue.inconsistentConfiguration( + ruleID: Parent.identifier, + message: """ + Option '\($maxNumberOfSingleLineParameters.key)' has no effect when \ + '\($allowsSingleLine.key)' is false. + """ + ) + } + } +} diff --git a/Tests/GeneratedTests/GeneratedTests_05.swift b/Tests/GeneratedTests/GeneratedTests_05.swift index b99e15e1df..748d2cf3bc 100644 --- a/Tests/GeneratedTests/GeneratedTests_05.swift +++ b/Tests/GeneratedTests/GeneratedTests_05.swift @@ -103,6 +103,12 @@ final class MultilineArgumentsRuleGeneratedTests: SwiftLintTestCase { } } +final class MultilineCallArgumentsRuleGeneratedTests: SwiftLintTestCase { + func testWithDefaultConfiguration() { + verifyRule(MultilineCallArgumentsRule.description) + } +} + final class MultilineFunctionChainsRuleGeneratedTests: SwiftLintTestCase { func testWithDefaultConfiguration() { verifyRule(MultilineFunctionChainsRule.description) @@ -150,9 +156,3 @@ final class NSNumberInitAsFunctionReferenceRuleGeneratedTests: SwiftLintTestCase verifyRule(NSNumberInitAsFunctionReferenceRule.description) } } - -final class NSObjectPreferIsEqualRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { - verifyRule(NSObjectPreferIsEqualRule.description) - } -} diff --git a/Tests/GeneratedTests/GeneratedTests_06.swift b/Tests/GeneratedTests/GeneratedTests_06.swift index fdaf0e0c07..4e16ca2299 100644 --- a/Tests/GeneratedTests/GeneratedTests_06.swift +++ b/Tests/GeneratedTests/GeneratedTests_06.swift @@ -7,6 +7,12 @@ @testable import SwiftLintCore import TestHelpers +final class NSObjectPreferIsEqualRuleGeneratedTests: SwiftLintTestCase { + func testWithDefaultConfiguration() { + verifyRule(NSObjectPreferIsEqualRule.description) + } +} + final class NestingRuleGeneratedTests: SwiftLintTestCase { func testWithDefaultConfiguration() { verifyRule(NestingRule.description) @@ -150,9 +156,3 @@ final class PreferAssetSymbolsRuleGeneratedTests: SwiftLintTestCase { verifyRule(PreferAssetSymbolsRule.description) } } - -final class PreferConditionListRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { - verifyRule(PreferConditionListRule.description) - } -} diff --git a/Tests/GeneratedTests/GeneratedTests_07.swift b/Tests/GeneratedTests/GeneratedTests_07.swift index e8bf2eacc0..257050f83f 100644 --- a/Tests/GeneratedTests/GeneratedTests_07.swift +++ b/Tests/GeneratedTests/GeneratedTests_07.swift @@ -7,6 +7,12 @@ @testable import SwiftLintCore import TestHelpers +final class PreferConditionListRuleGeneratedTests: SwiftLintTestCase { + func testWithDefaultConfiguration() { + verifyRule(PreferConditionListRule.description) + } +} + final class PreferKeyPathRuleGeneratedTests: SwiftLintTestCase { func testWithDefaultConfiguration() { verifyRule(PreferKeyPathRule.description) @@ -150,9 +156,3 @@ final class RedundantNilCoalescingRuleGeneratedTests: SwiftLintTestCase { verifyRule(RedundantNilCoalescingRule.description) } } - -final class RedundantObjcAttributeRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { - verifyRule(RedundantObjcAttributeRule.description) - } -} diff --git a/Tests/GeneratedTests/GeneratedTests_08.swift b/Tests/GeneratedTests/GeneratedTests_08.swift index b3c989ce75..134d69cf33 100644 --- a/Tests/GeneratedTests/GeneratedTests_08.swift +++ b/Tests/GeneratedTests/GeneratedTests_08.swift @@ -7,6 +7,12 @@ @testable import SwiftLintCore import TestHelpers +final class RedundantObjcAttributeRuleGeneratedTests: SwiftLintTestCase { + func testWithDefaultConfiguration() { + verifyRule(RedundantObjcAttributeRule.description) + } +} + final class RedundantSelfInClosureRuleGeneratedTests: SwiftLintTestCase { func testWithDefaultConfiguration() { verifyRule(RedundantSelfInClosureRule.description) @@ -150,9 +156,3 @@ final class StrongIBOutletRuleGeneratedTests: SwiftLintTestCase { verifyRule(StrongIBOutletRule.description) } } - -final class SuperfluousElseRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { - verifyRule(SuperfluousElseRule.description) - } -} diff --git a/Tests/GeneratedTests/GeneratedTests_09.swift b/Tests/GeneratedTests/GeneratedTests_09.swift index 81a64427bd..73827e5186 100644 --- a/Tests/GeneratedTests/GeneratedTests_09.swift +++ b/Tests/GeneratedTests/GeneratedTests_09.swift @@ -7,6 +7,12 @@ @testable import SwiftLintCore import TestHelpers +final class SuperfluousElseRuleGeneratedTests: SwiftLintTestCase { + func testWithDefaultConfiguration() { + verifyRule(SuperfluousElseRule.description) + } +} + final class SwitchCaseAlignmentRuleGeneratedTests: SwiftLintTestCase { func testWithDefaultConfiguration() { verifyRule(SwitchCaseAlignmentRule.description) @@ -150,9 +156,3 @@ final class UnneededThrowsRuleGeneratedTests: SwiftLintTestCase { verifyRule(UnneededThrowsRule.description) } } - -final class UnownedVariableCaptureRuleGeneratedTests: SwiftLintTestCase { - func testWithDefaultConfiguration() { - verifyRule(UnownedVariableCaptureRule.description) - } -} diff --git a/Tests/GeneratedTests/GeneratedTests_10.swift b/Tests/GeneratedTests/GeneratedTests_10.swift index 0f2f1a6434..002ad994e7 100644 --- a/Tests/GeneratedTests/GeneratedTests_10.swift +++ b/Tests/GeneratedTests/GeneratedTests_10.swift @@ -7,6 +7,12 @@ @testable import SwiftLintCore import TestHelpers +final class UnownedVariableCaptureRuleGeneratedTests: SwiftLintTestCase { + func testWithDefaultConfiguration() { + verifyRule(UnownedVariableCaptureRule.description) + } +} + final class UntypedErrorInCatchRuleGeneratedTests: SwiftLintTestCase { func testWithDefaultConfiguration() { verifyRule(UntypedErrorInCatchRule.description) diff --git a/Tests/IntegrationTests/default_rule_configurations.yml b/Tests/IntegrationTests/default_rule_configurations.yml index 0279b89494..78e8b2de7e 100644 --- a/Tests/IntegrationTests/default_rule_configurations.yml +++ b/Tests/IntegrationTests/default_rule_configurations.yml @@ -678,6 +678,12 @@ multiline_arguments_brackets: meta: opt-in: true correctable: false +multiline_call_arguments: + severity: warning + allows_single_line: true + meta: + opt-in: true + correctable: false multiline_function_chains: severity: warning meta: From fb02e20b96f2f90e4eb5e5c35a81675c16bbc4a2 Mon Sep 17 00:00:00 2001 From: Rodion Ivashkov Date: Fri, 21 Nov 2025 16:44:33 +0300 Subject: [PATCH 3/5] Revert "multiline_parameters: add optional checks for function call arguments" This reverts commit 8448a17df887f09155070d4032df4d63469d1505. --- .../MultilineParametersConfiguration.swift | 21 ----------- .../Rules/Style/MultilineParametersRule.swift | 24 +----------- .../MultilineParametersRuleExamples.swift | 37 +------------------ .../default_rule_configurations.yml | 1 - 4 files changed, 2 insertions(+), 81 deletions(-) diff --git a/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift b/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift index cf3dadadc8..bd9eed941a 100644 --- a/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift +++ b/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/MultilineParametersConfiguration.swift @@ -10,20 +10,9 @@ struct MultilineParametersConfiguration: SeverityBasedRuleConfiguration { private(set) var allowsSingleLine = true @ConfigurationElement(key: "max_number_of_single_line_parameters") private(set) var maxNumberOfSingleLineParameters: Int? - @ConfigurationElement(key: "check_calls") - private(set) var checkCalls = false // swiftlint:disable:next unneeded_throws_rethrows func validate() throws(Issue) { - if checkCalls, maxNumberOfSingleLineParameters == nil { - Issue.inconsistentConfiguration( - ruleID: Parent.identifier, - message: """ - Option '\($checkCalls.key)' has no effect when \ - '\($maxNumberOfSingleLineParameters.key)' is nil. - """ - ).print() - } guard let maxNumberOfSingleLineParameters else { return } @@ -44,15 +33,5 @@ struct MultilineParametersConfiguration: SeverityBasedRuleConfiguration { """ ).print() } - - if checkCalls, !allowsSingleLine { - Issue.inconsistentConfiguration( - ruleID: Parent.identifier, - message: """ - Option '\($checkCalls.key)' has no effect when \ - '\($allowsSingleLine.key)' is false. - """ - ).print() - } } } diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift b/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift index c50a725daf..7ff00199d6 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRule.swift @@ -7,9 +7,7 @@ struct MultilineParametersRule: Rule { static let description = RuleDescription( identifier: "multiline_parameters", name: "Multiline Parameters", - description: """ - Functions, initializers, and function call arguments should be either on the same line, or one per line - """, + description: "Functions and methods parameters should be either on the same line, or one per line", kind: .style, nonTriggeringExamples: MultilineParametersRuleExamples.nonTriggeringExamples, triggeringExamples: MultilineParametersRuleExamples.triggeringExamples @@ -30,28 +28,8 @@ private extension MultilineParametersRule { } } - override func visitPost(_ node: FunctionCallExprSyntax) { - guard node.arguments.isNotEmpty else { return } - guard configuration.checkCalls else { return } - guard node.trailingClosure == nil else { return } - - if containsViolation(for: node.arguments) { - let anchor = node.calledExpression.positionAfterSkippingLeadingTrivia - violations.append(anchor) - } - } - private func containsViolation(for signature: FunctionSignatureSyntax) -> Bool { let parameterPositions = signature.parameterClause.parameters.map(\.positionAfterSkippingLeadingTrivia) - return containsViolation(parameterPositions: parameterPositions) - } - - private func containsViolation(for arguments: LabeledExprListSyntax) -> Bool { - let argumentPositions = arguments.map(\.positionAfterSkippingLeadingTrivia) - return containsViolation(parameterPositions: argumentPositions) - } - - private func containsViolation(parameterPositions: [AbsolutePosition]) -> Bool { guard parameterPositions.isNotEmpty else { return false } diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRuleExamples.swift index df910b59e0..250713e900 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/MultilineParametersRuleExamples.swift @@ -213,20 +213,6 @@ internal struct MultilineParametersRuleExamples { param3: [String] ) { } """, configuration: ["max_number_of_single_line_parameters": 2]), - Example(""" - foo( - param1: "param1", - param2: false, - param3: [] - ) - """, configuration: ["max_number_of_single_line_parameters": 2]), - Example(""" - foo(param1: 1, - param2: false, - param3: []) - """, configuration: ["max_number_of_single_line_parameters": 1]), - Example("foo(param1: 1, param2: false)", - configuration: ["max_number_of_single_line_parameters": 2]), ] static let triggeringExamples: [Example] = [ @@ -374,27 +360,6 @@ internal struct MultilineParametersRuleExamples { """, configuration: ["max_number_of_single_line_parameters": 3]), Example(""" func ↓foo(param1: Int, param2: Bool, param3: [String]) { } - """, configuration: [ - "max_number_of_single_line_parameters": 2, - "check_calls": true, - ]), - Example("↓foo(param1: 1, param2: false, param3: [])", - configuration: [ - "max_number_of_single_line_parameters": 2, - "check_calls": true, - ]), - Example(""" - func ↓foo(param1: Int, - param2: Bool, param3: [String]) { } - """, configuration: [ - "max_number_of_single_line_parameters": 3, - "check_calls": true, - ]), - Example(""" - ↓foo(param1: Int, param2: Bool, param3: [String]) - """, configuration: [ - "max_number_of_single_line_parameters": 2, - "check_calls": true, - ]), + """, configuration: ["max_number_of_single_line_parameters": 2]), ] } diff --git a/Tests/IntegrationTests/default_rule_configurations.yml b/Tests/IntegrationTests/default_rule_configurations.yml index 78e8b2de7e..bbd5250208 100644 --- a/Tests/IntegrationTests/default_rule_configurations.yml +++ b/Tests/IntegrationTests/default_rule_configurations.yml @@ -697,7 +697,6 @@ multiline_literal_brackets: multiline_parameters: severity: warning allows_single_line: true - check_calls: false meta: opt-in: true correctable: false From a56414efff3162e7b818efb5927e20e7f65cff5e Mon Sep 17 00:00:00 2001 From: Rodion Ivashkov Date: Sat, 22 Nov 2025 00:32:05 +0300 Subject: [PATCH 4/5] Fix warnings # Conflicts: # Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift --- ...iscouragedOptionalCollectionExamples.swift | 4 +- .../ImplicitlyUnwrappedOptionalRule.swift | 5 +- .../Rules/Idiomatic/TypeNameRule.swift | 42 ++++-- .../Idiomatic/UnneededBreakInSwitchRule.swift | 4 +- .../Rules/Lint/DeploymentTargetRule.swift | 7 +- .../Rules/Lint/PrivateOutletRule.swift | 4 +- .../Lint/ProhibitedInterfaceBuilderRule.swift | 4 +- .../Rules/Lint/StrongIBOutletRule.swift | 4 +- .../Rules/Lint/UnusedDeclarationRule.swift | 8 +- .../Rules/Lint/UnusedImportRuleExamples.swift | 42 ++++-- .../ClosureBodyLengthRuleExamples.swift | 24 +++- .../Rules/Metrics/LineLengthRule.swift | 7 +- .../DeploymentTargetConfiguration.swift | 7 +- .../Rules/Style/AttributesRuleExamples.swift | 4 +- .../Rules/Style/EmptyEnumArgumentsRule.swift | 8 +- .../Style/NumberSeparatorRuleExamples.swift | 4 +- .../Style/RedundantDiscardableLetRule.swift | 8 +- .../Style/SortedImportsRuleExamples.swift | 56 ++++++-- .../Rules/Style/StatementPositionRule.swift | 7 +- .../Rules/Style/SwitchCaseOnNewlineRule.swift | 4 +- .../Rules/Style/TrailingWhitespaceRule.swift | 3 +- .../Style/TypeContentsOrderRuleExamples.swift | 8 +- ...lWhitespaceClosingBracesRuleExamples.swift | 4 +- .../Extensions/String+SwiftLint.swift | 15 +- .../Protocols/CollectingRule.swift | 8 +- .../RegexConfiguration.swift | 8 +- .../Configuration+CommandLine.swift | 15 +- .../Configuration+FileGraph.swift | 6 +- .../Configuration/Configuration+Parsing.swift | 7 +- .../LintOrAnalyzeCommand.swift | 7 +- Source/SwiftLintFramework/Models/Linter.swift | 14 +- .../Models/LinterCache.swift | 6 +- .../Models/YamlParser.swift | 6 +- .../BlanketDisableCommandRuleTests.swift | 8 +- .../CyclomaticComplexityRuleTests.swift | 14 +- .../FileHeaderRuleTests.swift | 49 ++++--- .../FileLengthRuleTests.swift | 14 +- ...ImplicitlyUnwrappedOptionalRuleTests.swift | 7 +- .../LineLengthRuleTests.swift | 36 +++-- Tests/CoreTests/RuleTests.swift | 22 ++- .../ConfigurationTests.swift | 6 +- Tests/FrameworkTests/CommandTests.swift | 133 +++++++++++++----- Tests/FrameworkTests/LinterCacheTests.swift | 9 +- .../ParserDiagnosticsTests.swift | 16 ++- .../RuleConfigurationTests.swift | 19 ++- Tests/FrameworkTests/RulesFilterTests.swift | 21 ++- Tests/FrameworkTests/RulesTests.swift | 13 +- Tests/FrameworkTests/YamlParserTests.swift | 12 +- Tests/TestHelpers/TestHelpers.swift | 80 +++++++---- 49 files changed, 584 insertions(+), 235 deletions(-) diff --git a/Source/SwiftLintBuiltInRules/Rules/Idiomatic/DiscouragedOptionalCollectionExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Idiomatic/DiscouragedOptionalCollectionExamples.swift index b289d34cb6..6df3e16638 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Idiomatic/DiscouragedOptionalCollectionExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Idiomatic/DiscouragedOptionalCollectionExamples.swift @@ -218,5 +218,7 @@ private func wrapExample(_ type: String, \(type) Foo { \(test) } - """, file: file, line: line) + """, + file: file, + line: line) } diff --git a/Source/SwiftLintBuiltInRules/Rules/Idiomatic/ImplicitlyUnwrappedOptionalRule.swift b/Source/SwiftLintBuiltInRules/Rules/Idiomatic/ImplicitlyUnwrappedOptionalRule.swift index feb337f970..22a3aed612 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Idiomatic/ImplicitlyUnwrappedOptionalRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Idiomatic/ImplicitlyUnwrappedOptionalRule.swift @@ -21,7 +21,10 @@ struct ImplicitlyUnwrappedOptionalRule: Rule { @IBOutlet weak var bar: SomeObject! } - """, configuration: ["mode": "all_except_iboutlets"], excludeFromDocumentation: true), + """, + configuration: ["mode": "all_except_iboutlets"], + excludeFromDocumentation: true + ), ], triggeringExamples: [ Example("let label: ↓UILabel!"), diff --git a/Source/SwiftLintBuiltInRules/Rules/Idiomatic/TypeNameRule.swift b/Source/SwiftLintBuiltInRules/Rules/Idiomatic/TypeNameRule.swift index 13f605fda4..fd5ab12e68 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Idiomatic/TypeNameRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Idiomatic/TypeNameRule.swift @@ -22,15 +22,21 @@ struct TypeNameRule: Rule { private extension TypeNameRule { final class Visitor: ViolationsSyntaxVisitor { override func visitPost(_ node: StructDeclSyntax) { - if let violation = violation(identifier: node.name, modifiers: node.modifiers, - inheritedTypes: node.inheritanceClause?.inheritedTypes) { + if let violation = violation( + identifier: node.name, + modifiers: node.modifiers, + inheritedTypes: node.inheritanceClause?.inheritedTypes + ) { violations.append(violation) } } override func visitPost(_ node: ClassDeclSyntax) { - if let violation = violation(identifier: node.name, modifiers: node.modifiers, - inheritedTypes: node.inheritanceClause?.inheritedTypes) { + if let violation = violation( + identifier: node.name, + modifiers: node.modifiers, + inheritedTypes: node.inheritanceClause?.inheritedTypes + ) { violations.append(violation) } } @@ -42,30 +48,42 @@ private extension TypeNameRule { } override func visitPost(_ node: AssociatedTypeDeclSyntax) { - if let violation = violation(identifier: node.name, modifiers: node.modifiers, - inheritedTypes: node.inheritanceClause?.inheritedTypes) { + if let violation = violation( + identifier: node.name, + modifiers: node.modifiers, + inheritedTypes: node.inheritanceClause?.inheritedTypes + ) { violations.append(violation) } } override func visitPost(_ node: EnumDeclSyntax) { - if let violation = violation(identifier: node.name, modifiers: node.modifiers, - inheritedTypes: node.inheritanceClause?.inheritedTypes) { + if let violation = violation( + identifier: node.name, + modifiers: node.modifiers, + inheritedTypes: node.inheritanceClause?.inheritedTypes + ) { violations.append(violation) } } override func visitPost(_ node: ActorDeclSyntax) { - if let violation = violation(identifier: node.name, modifiers: node.modifiers, - inheritedTypes: node.inheritanceClause?.inheritedTypes) { + if let violation = violation( + identifier: node.name, + modifiers: node.modifiers, + inheritedTypes: node.inheritanceClause?.inheritedTypes + ) { violations.append(violation) } } override func visitPost(_ node: ProtocolDeclSyntax) { if configuration.validateProtocols, - let violation = violation(identifier: node.name, modifiers: node.modifiers, - inheritedTypes: node.inheritanceClause?.inheritedTypes) { + let violation = violation( + identifier: node.name, + modifiers: node.modifiers, + inheritedTypes: node.inheritanceClause?.inheritedTypes + ) { violations.append(violation) } } diff --git a/Source/SwiftLintBuiltInRules/Rules/Idiomatic/UnneededBreakInSwitchRule.swift b/Source/SwiftLintBuiltInRules/Rules/Idiomatic/UnneededBreakInSwitchRule.swift index ec84fe2f15..43978b6d7c 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Idiomatic/UnneededBreakInSwitchRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Idiomatic/UnneededBreakInSwitchRule.swift @@ -11,7 +11,9 @@ private func embedInSwitch( \(`case`): \(text) } - """, file: file, line: line) + """, + file: file, + line: line) } @SwiftSyntaxRule(explicitRewriter: true) diff --git a/Source/SwiftLintBuiltInRules/Rules/Lint/DeploymentTargetRule.swift b/Source/SwiftLintBuiltInRules/Rules/Lint/DeploymentTargetRule.swift index c392de8a49..894ae3c602 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Lint/DeploymentTargetRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Lint/DeploymentTargetRule.swift @@ -86,8 +86,11 @@ private extension DeploymentTargetRule { for elem in node.availabilityArguments { guard let restriction = elem.argument.as(PlatformVersionSyntax.self), let versionString = restriction.version?.description, - let reason = reason(platform: restriction.platform, version: versionString, - violationType: violationType) else { + let reason = reason( + platform: restriction.platform, + version: versionString, + violationType: violationType + ) else { continue } diff --git a/Source/SwiftLintBuiltInRules/Rules/Lint/PrivateOutletRule.swift b/Source/SwiftLintBuiltInRules/Rules/Lint/PrivateOutletRule.swift index a6d8b5ff9d..9731d5e569 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Lint/PrivateOutletRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Lint/PrivateOutletRule.swift @@ -73,7 +73,9 @@ struct PrivateOutletRule: Rule { ellipsisButtonDidTouch?(self) } } - """, configuration: ["allow_private_set": false], excludeFromDocumentation: true), + """, + configuration: ["allow_private_set": false], + excludeFromDocumentation: true), ] ) } diff --git a/Source/SwiftLintBuiltInRules/Rules/Lint/ProhibitedInterfaceBuilderRule.swift b/Source/SwiftLintBuiltInRules/Rules/Lint/ProhibitedInterfaceBuilderRule.swift index ebe95096a3..0ba6599a53 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Lint/ProhibitedInterfaceBuilderRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Lint/ProhibitedInterfaceBuilderRule.swift @@ -41,5 +41,7 @@ private func wrapExample(_ text: String, file: StaticString = #filePath, line: U class ViewController: UIViewController { \(text) } - """, file: file, line: line) + """, + file: file, + line: line) } diff --git a/Source/SwiftLintBuiltInRules/Rules/Lint/StrongIBOutletRule.swift b/Source/SwiftLintBuiltInRules/Rules/Lint/StrongIBOutletRule.swift index 5e9d37a92d..22189eb247 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Lint/StrongIBOutletRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Lint/StrongIBOutletRule.swift @@ -72,5 +72,7 @@ private func wrapExample(_ text: String, file: StaticString = #filePath, line: U class ViewController: UIViewController { \(text) } - """, file: file, line: line) + """, + file: file, + line: line) } diff --git a/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedDeclarationRule.swift b/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedDeclarationRule.swift index 93934ed401..aa7bec2e8e 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedDeclarationRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedDeclarationRule.swift @@ -111,8 +111,12 @@ private extension SwiftLintFile { compilerArguments: [String], configuration: UnusedDeclarationConfiguration) -> Set { Set(index.traverseEntitiesDepthFirst { _, indexEntity in - self.declaredUSR(indexEntity: indexEntity, editorOpen: editorOpen, compilerArguments: compilerArguments, - configuration: configuration) + self.declaredUSR( + indexEntity: indexEntity, + editorOpen: editorOpen, + compilerArguments: compilerArguments, + configuration: configuration + ) }) } diff --git a/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift index 91e06e138f..1e4e34b36c 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Lint/UnusedImportRuleExamples.swift @@ -182,15 +182,20 @@ struct UnusedImportRuleExamples { import Foundation typealias Foo = CFArray dispatchMain() - """, configuration: [ - "require_explicit_imports": true, - "allowed_transitive_imports": [ - [ - "module": "Foundation", - "allowed_transitive_imports": ["CoreFoundation", "Dispatch"], + """, + configuration: [ + "require_explicit_imports": true, + "allowed_transitive_imports": [ + [ + "module": "Foundation", + "allowed_transitive_imports": ["CoreFoundation", "Dispatch"], + ] as [String: any Sendable], + ], ] as [String: any Sendable], - ], - ] as [String: any Sendable], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false): + testMultiByteOffsets: false, + testOnLinux: false, + testOnWindows: false + ): Example(""" import Foundation typealias Foo = CFArray @@ -200,9 +205,14 @@ struct UnusedImportRuleExamples { ↓↓↓import Foundation typealias Foo = CFData dispatchMain() - """, configuration: [ - "require_explicit_imports": true - ], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false): + """, + configuration: [ + "require_explicit_imports": true + ], + testMultiByteOffsets: false, + testOnLinux: false, + testOnWindows: false + ): Example(""" import CoreFoundation import Dispatch @@ -234,9 +244,13 @@ struct UnusedImportRuleExamples { typealias Bar = CFData @objc class A {} - """, configuration: [ - "require_explicit_imports": true - ], testMultiByteOffsets: false, testOnLinux: false, testOnWindows: false): + """, + configuration: [ + "require_explicit_imports": true + ], + testMultiByteOffsets: false, + testOnLinux: false, + testOnWindows: false): Example(""" import CoreFoundation import Foundation diff --git a/Source/SwiftLintBuiltInRules/Rules/Metrics/ClosureBodyLengthRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Metrics/ClosureBodyLengthRuleExamples.swift index db248733f9..a23481d660 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Metrics/ClosureBodyLengthRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Metrics/ClosureBodyLengthRuleExamples.swift @@ -45,7 +45,9 @@ private func trailingClosure(_ violationSymbol: String = "", \(repeatElement("\t// toto\n", count: commentLinesCount).joined())\ \(repeatElement("\t\n", count: emptyLinesCount).joined())\ } - """, file: file, line: line) + """, + file: file, + line: line) } private func argumentClosure(_ violationSymbol: String = "", @@ -56,7 +58,9 @@ private func argumentClosure(_ violationSymbol: String = "", foo.bar(\(violationSymbol){ toto in \((0.. Example { @@ -21,7 +23,9 @@ private func wrapInFunc(_ str: String, file: StaticString = #filePath, line: UIn break } } - """, file: file, line: line) + """, + file: file, + line: line) } @SwiftSyntaxRule(explicitRewriter: true) diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/NumberSeparatorRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Style/NumberSeparatorRuleExamples.swift index a63da2377c..b44e3e2c20 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/NumberSeparatorRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/NumberSeparatorRuleExamples.swift @@ -22,7 +22,9 @@ internal struct NumberSeparatorRuleExamples { """, excludeFromDocumentation: true), Example(""" let color = #colorLiteral(red: 0.354_398_250_6, green: 0.318_749_547, blue: 0.636_701_524_3, alpha: 1) - """, configuration: ["minimum_fraction_length": 3], excludeFromDocumentation: true), + """, + configuration: ["minimum_fraction_length": 3], + excludeFromDocumentation: true), ] } }() diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/RedundantDiscardableLetRule.swift b/Source/SwiftLintBuiltInRules/Rules/Style/RedundantDiscardableLetRule.swift index 29e97f384a..ac752cf78c 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/RedundantDiscardableLetRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/RedundantDiscardableLetRule.swift @@ -86,7 +86,9 @@ struct RedundantDiscardableLetRule: Rule { ↓let _ = foo() Text("Hello, World!") } - """, configuration: ["ignore_swiftui_view_bodies": true], excludeFromDocumentation: true), + """, + configuration: ["ignore_swiftui_view_bodies": true], + excludeFromDocumentation: true), Example(""" var body: some NotView { ↓let _ = foo() @@ -95,7 +97,9 @@ struct RedundantDiscardableLetRule: Rule { } Text("Hello, World!") } - """, configuration: ["ignore_swiftui_view_bodies": true], excludeFromDocumentation: true), + """, + configuration: ["ignore_swiftui_view_bodies": true], + excludeFromDocumentation: true), ], corrections: [ Example("↓let _ = foo()"): Example("_ = foo()"), diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/SortedImportsRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Style/SortedImportsRuleExamples.swift index 45aed4cb4a..25d7565682 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/SortedImportsRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/SortedImportsRuleExamples.swift @@ -65,19 +65,27 @@ internal struct SortedImportsRuleExamples { Example(""" @testable import AAA @testable import BBB - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), Example(""" @testable import BBB import AAA - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), Example(""" @_exported import BBB @testable import AAA - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), Example(""" @_exported @testable import BBB import AAA - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), ].skipMultiByteOffsetTests() static let triggeringExamples = [ @@ -117,23 +125,33 @@ internal struct SortedImportsRuleExamples { Example(""" @testable import BBB @testable import ↓AAA - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), Example(""" import AAA @testable import ↓BBB - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), Example(""" import BBB @testable import ↓AAA - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), Example(""" @testable import AAA @_exported import ↓BBB - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), Example(""" import AAA @_exported @testable import ↓BBB - """, configuration: groupByAttributesConfiguration, excludeFromDocumentation: true), + """, + configuration: groupByAttributesConfiguration, + excludeFromDocumentation: true), ] static let corrections = [ @@ -277,35 +295,45 @@ internal struct SortedImportsRuleExamples { Example(""" @testable import BBB @testable import AAA - """, configuration: groupByAttributesConfiguration, testMultiByteOffsets: false): Example(""" + """, + configuration: groupByAttributesConfiguration, + testMultiByteOffsets: false): Example(""" @testable import AAA @testable import BBB """), Example(""" import AAA @testable import BBB - """, configuration: groupByAttributesConfiguration, testMultiByteOffsets: false): Example(""" + """, + configuration: groupByAttributesConfiguration, + testMultiByteOffsets: false): Example(""" @testable import BBB import AAA """), Example(""" import BBB @testable import AAA - """, configuration: groupByAttributesConfiguration, testMultiByteOffsets: false): Example(""" + """, + configuration: groupByAttributesConfiguration, + testMultiByteOffsets: false): Example(""" @testable import AAA import BBB """), Example(""" @testable import AAA @_exported import BBB - """, configuration: groupByAttributesConfiguration, testMultiByteOffsets: false): Example(""" + """, + configuration: groupByAttributesConfiguration, + testMultiByteOffsets: false): Example(""" @_exported import BBB @testable import AAA """), Example(""" import AAA @_exported @testable import BBB - """, configuration: groupByAttributesConfiguration, testMultiByteOffsets: false): Example(""" + """, + configuration: groupByAttributesConfiguration, + testMultiByteOffsets: false): Example(""" @_exported @testable import BBB import AAA """), diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/StatementPositionRule.swift b/Source/SwiftLintBuiltInRules/Rules/Style/StatementPositionRule.swift index 768a018743..c8ac2372fa 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/StatementPositionRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/StatementPositionRule.swift @@ -110,8 +110,11 @@ private extension StatementPositionRule { let regularExpression = regex(Self.defaultPattern) var contents = file.contents for range in matches.reversed() { - contents = regularExpression.stringByReplacingMatches(in: contents, options: [], range: range, - withTemplate: "} $1") + contents = regularExpression.stringByReplacingMatches( + in: contents, + options: [], + range: range, + withTemplate: "} $1") } file.write(contents) return matches.count diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/SwitchCaseOnNewlineRule.swift b/Source/SwiftLintBuiltInRules/Rules/Style/SwitchCaseOnNewlineRule.swift index 8e4f03b265..425c0e2107 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/SwitchCaseOnNewlineRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/SwitchCaseOnNewlineRule.swift @@ -5,7 +5,9 @@ private func wrapInSwitch(_ str: String, file: StaticString = #filePath, line: U switch foo { \(str) } - """, file: file, line: line) + """, + file: file, + line: line) } @SwiftSyntaxRule(optIn: true) diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/TrailingWhitespaceRule.swift b/Source/SwiftLintBuiltInRules/Rules/Style/TrailingWhitespaceRule.swift index 6c4e0dfee2..8131558b5f 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/TrailingWhitespaceRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/TrailingWhitespaceRule.swift @@ -21,7 +21,8 @@ struct TrailingWhitespaceRule: Rule { ], triggeringExamples: [ Example("let name: String↓ \n"), Example("/* */ let name: String↓ \n"), - Example("let codeWithSpace = 123↓ \n", configuration: ["ignores_literals": true], + Example("let codeWithSpace = 123↓ \n", + configuration: ["ignores_literals": true], testWrappingInComment: false), ], corrections: [ diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/TypeContentsOrderRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Style/TypeContentsOrderRuleExamples.swift index 57186efc8b..c1302f8605 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/TypeContentsOrderRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/TypeContentsOrderRuleExamples.swift @@ -269,14 +269,18 @@ internal struct TypeContentsOrderRuleExamples { ↓associatedtype T typealias U = Int } - """, configuration: ["order": [["type_alias"], ["associated_type"]]], excludeFromDocumentation: true), + """, + configuration: ["order": [["type_alias"], ["associated_type"]]], + excludeFromDocumentation: true), Example(""" enum E { @available(*, unavailable) ↓case a func f() {} } - """, configuration: ["order": [["other_method"], ["case"]]], excludeFromDocumentation: true), + """, + configuration: ["order": [["other_method"], ["case"]]], + excludeFromDocumentation: true), Example(""" final class C { ↓var i = 1 diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/VerticalWhitespaceClosingBracesRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Style/VerticalWhitespaceClosingBracesRuleExamples.swift index e482f2a0af..4a90ac9d60 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/VerticalWhitespaceClosingBracesRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/VerticalWhitespaceClosingBracesRuleExamples.swift @@ -28,7 +28,9 @@ internal struct VerticalWhitespaceClosingBracesRuleExamples { // do something // do something } - """, configuration: beforeTrivialLinesConfiguration, excludeFromDocumentation: true), + """, + configuration: beforeTrivialLinesConfiguration, + excludeFromDocumentation: true), ] static let violatingToValidExamples = [ diff --git a/Source/SwiftLintCore/Extensions/String+SwiftLint.swift b/Source/SwiftLintCore/Extensions/String+SwiftLint.swift index 2d6a431a43..66c0393587 100644 --- a/Source/SwiftLintCore/Extensions/String+SwiftLint.swift +++ b/Source/SwiftLintCore/Extensions/String+SwiftLint.swift @@ -49,10 +49,17 @@ public extension String { guard nsrange.location != NSNotFound else { return nil } - let from16 = utf16.index(utf16.startIndex, offsetBy: nsrange.location, - limitedBy: utf16.endIndex) ?? utf16.endIndex - let to16 = utf16.index(from16, offsetBy: nsrange.length, - limitedBy: utf16.endIndex) ?? utf16.endIndex + let from16 = utf16.index( + utf16.startIndex, + offsetBy: nsrange.location, + limitedBy: utf16.endIndex + ) ?? utf16.endIndex + + let to16 = utf16.index( + from16, + offsetBy: nsrange.length, + limitedBy: utf16.endIndex + ) ?? utf16.endIndex guard let fromIndex = Index(from16, within: self), let toIndex = Index(to16, within: self) else { diff --git a/Source/SwiftLintCore/Protocols/CollectingRule.swift b/Source/SwiftLintCore/Protocols/CollectingRule.swift index 0c8567da7a..313c5d13b7 100644 --- a/Source/SwiftLintCore/Protocols/CollectingRule.swift +++ b/Source/SwiftLintCore/Protocols/CollectingRule.swift @@ -47,8 +47,12 @@ public protocol CollectingRule: AnyCollectingRule { public extension CollectingRule { func collectInfo(for file: SwiftLintFile, into storage: RuleStorage, compilerArguments: [String]) { - storage.collect(info: collectInfo(for: file, compilerArguments: compilerArguments), - for: file, in: self) + storage.collect( + info: collectInfo( + for: file, + compilerArguments: compilerArguments), + for: file, + in: self) } func validate(file: SwiftLintFile, using storage: RuleStorage, compilerArguments: [String]) -> [StyleViolation] { guard let info = storage.collectedInfo(for: self) else { diff --git a/Source/SwiftLintCore/RuleConfigurations/RegexConfiguration.swift b/Source/SwiftLintCore/RuleConfigurations/RegexConfiguration.swift index 1c215d2d22..0e83f95024 100644 --- a/Source/SwiftLintCore/RuleConfigurations/RegexConfiguration.swift +++ b/Source/SwiftLintCore/RuleConfigurations/RegexConfiguration.swift @@ -58,8 +58,12 @@ public struct RegexConfiguration: SeverityBasedRuleConfiguration, /// The `RuleDescription` for the custom rule defined here. public var description: RuleDescription { - RuleDescription(identifier: identifier, name: name ?? identifier, - description: "", kind: .style) + RuleDescription( + identifier: identifier, + name: name ?? identifier, + description: "", + kind: .style + ) } /// Create a `RegexConfiguration` with the specified identifier, with other properties to be set later. diff --git a/Source/SwiftLintFramework/Configuration+CommandLine.swift b/Source/SwiftLintFramework/Configuration+CommandLine.swift index b875a0e888..945c112b20 100644 --- a/Source/SwiftLintFramework/Configuration+CommandLine.swift +++ b/Source/SwiftLintFramework/Configuration+CommandLine.swift @@ -91,8 +91,11 @@ extension Configuration { } let collected = await Signposts.record(name: "Configuration.VisitLintableFiles.Collect") { await zip(lintersForFile, duplicateFileNames).asyncMap { linters, duplicateFileNames in - await collect(linters: linters, visitor: visitor, storage: storage, - duplicateFileNames: duplicateFileNames) + await collect( + linters: linters, + visitor: visitor, + storage: storage, + duplicateFileNames: duplicateFileNames) } } let result = await Signposts.record(name: "Configuration.VisitLintableFiles.Visit") { @@ -287,9 +290,11 @@ extension Configuration { cache: LinterCache? = nil, storage: RuleStorage, visitorBlock: @escaping (CollectedLinter) async -> Void) async throws -> [SwiftLintFile] { - let visitor = try LintableFilesVisitor.create(options, cache: cache, - allowZeroLintableFiles: allowZeroLintableFiles, - block: visitorBlock) + let visitor = try LintableFilesVisitor.create( + options, + cache: cache, + allowZeroLintableFiles: allowZeroLintableFiles, + block: visitorBlock) return try await visitLintableFiles(with: visitor, storage: storage) } diff --git a/Source/SwiftLintFramework/Configuration/Configuration+FileGraph.swift b/Source/SwiftLintFramework/Configuration/Configuration+FileGraph.swift index e15d0f5fa6..14036de759 100644 --- a/Source/SwiftLintFramework/Configuration/Configuration+FileGraph.swift +++ b/Source/SwiftLintFramework/Configuration/Configuration+FileGraph.swift @@ -141,8 +141,10 @@ package extension Configuration { : Configuration.Key.parentConfig.rawValue if let reference = vertex.configurationDict[key] as? String { - let referencedVertex = Vertex(string: reference, rootDirectory: vertex.rootDirectory, - isInitialVertex: false) + let referencedVertex = Vertex( + string: reference, + rootDirectory: vertex.rootDirectory, + isInitialVertex: false) // Local vertices are allowed to have local / remote references // Remote vertices are only allowed to have remote references diff --git a/Source/SwiftLintFramework/Configuration/Configuration+Parsing.swift b/Source/SwiftLintFramework/Configuration/Configuration+Parsing.swift index bf327accdb..f71d252b6c 100644 --- a/Source/SwiftLintFramework/Configuration/Configuration+Parsing.swift +++ b/Source/SwiftLintFramework/Configuration/Configuration+Parsing.swift @@ -57,8 +57,11 @@ extension Configuration { Self.warnAboutInvalidKeys(configurationDictionary: dict, ruleList: ruleList) Self.warnAboutDeprecations( - configurationDictionary: dict, disabledRules: disabledRules, - optInRules: optInRules, onlyRules: onlyRules, ruleList: ruleList + configurationDictionary: dict, + disabledRules: disabledRules, + optInRules: optInRules, + onlyRules: onlyRules, + ruleList: ruleList ) Self.warnAboutMisplacedAnalyzerRules(optInRules: optInRules, ruleList: ruleList) diff --git a/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift b/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift index 4c458942dc..3fb59e13d3 100644 --- a/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift +++ b/Source/SwiftLintFramework/LintOrAnalyzeCommand.swift @@ -212,8 +212,11 @@ package struct LintOrAnalyzeCommand { builder.report(violations: builder.violations, realtimeCondition: false) let numberOfSeriousViolations = builder.violations.filter({ $0.severity == .error }).count if !options.quiet { - printStatus(violations: builder.violations, files: files, serious: numberOfSeriousViolations, - verb: options.verb) + printStatus( + violations: builder.violations, + files: files, + serious: numberOfSeriousViolations, + verb: options.verb) } if options.benchmark { builder.fileBenchmark.save() diff --git a/Source/SwiftLintFramework/Models/Linter.swift b/Source/SwiftLintFramework/Models/Linter.swift index 1af72e043d..b522796fdc 100644 --- a/Source/SwiftLintFramework/Models/Linter.swift +++ b/Source/SwiftLintFramework/Models/Linter.swift @@ -347,13 +347,17 @@ public struct CollectedLinter { $0 is SuperfluousDisableCommandRule }) as? SuperfluousDisableCommandRule let validationResults: [LintResult] = rules.parallelMap { - $0.lint(file: file, regions: regions, benchmark: benchmark, - storage: storage, - superfluousDisableCommandRule: superfluousDisableCommandRule, - compilerArguments: compilerArguments) + $0.lint( + file: file, + regions: regions, + benchmark: benchmark, + storage: storage, + superfluousDisableCommandRule: superfluousDisableCommandRule, + compilerArguments: compilerArguments) } let undefinedSuperfluousCommandViolations = self.undefinedSuperfluousCommandViolations( - regions: regions, configuration: configuration, + regions: regions, + configuration: configuration, superfluousDisableCommandRule: superfluousDisableCommandRule) let violations = validationResults.flatMap(\.violations) + undefinedSuperfluousCommandViolations diff --git a/Source/SwiftLintFramework/Models/LinterCache.swift b/Source/SwiftLintFramework/Models/LinterCache.swift index c6c541255a..335290bf5e 100644 --- a/Source/SwiftLintFramework/Models/LinterCache.swift +++ b/Source/SwiftLintFramework/Models/LinterCache.swift @@ -66,8 +66,10 @@ public final class LinterCache { writeCacheLock.lock() var filesCache = writeCache[configurationDescription] ?? .empty - filesCache.entries[file] = FileCacheEntry(violations: violations, lastModification: lastModification, - swiftVersion: swiftVersion) + filesCache.entries[file] = FileCacheEntry( + violations: violations, + lastModification: lastModification, + swiftVersion: swiftVersion) writeCache[configurationDescription] = filesCache writeCacheLock.unlock() } diff --git a/Source/SwiftLintFramework/Models/YamlParser.swift b/Source/SwiftLintFramework/Models/YamlParser.swift index da44759271..c6348c3253 100644 --- a/Source/SwiftLintFramework/Models/YamlParser.swift +++ b/Source/SwiftLintFramework/Models/YamlParser.swift @@ -16,8 +16,10 @@ struct YamlParser { static func parse(_ yaml: String, env: [String: String] = ProcessInfo.processInfo.environment) throws -> [String: Any] { do { - return try Yams.load(yaml: yaml, .default, - .swiftlintConstructor(env: env)) as? [String: Any] ?? [:] + return try Yams.load( + yaml: yaml, + .default, + .swiftlintConstructor(env: env)) as? [String: Any] ?? [:] } catch { throw Issue.yamlParsing("\(error)") } diff --git a/Tests/BuiltInRulesTests/BlanketDisableCommandRuleTests.swift b/Tests/BuiltInRulesTests/BlanketDisableCommandRuleTests.swift index 061f7a637e..affa436a34 100644 --- a/Tests/BuiltInRulesTests/BlanketDisableCommandRuleTests.swift +++ b/Tests/BuiltInRulesTests/BlanketDisableCommandRuleTests.swift @@ -17,9 +17,11 @@ final class BlanketDisableCommandRuleTests: SwiftLintTestCase { Example("// swiftlint:disable:this ↓file_length"), Example("// swiftlint:disable:next ↓file_length"), ] - verifyRule(emptyDescription.with(triggeringExamples: triggeringExamples), - ruleConfiguration: ["always_blanket_disable": ["file_length"]], - skipCommentTests: true, skipDisableCommandTests: true) + verifyRule( + emptyDescription.with(triggeringExamples: triggeringExamples), + ruleConfiguration: ["always_blanket_disable": ["file_length"]], + skipCommentTests: true, + skipDisableCommandTests: true) } func testAlwaysBlanketDisabledAreAllowed() { diff --git a/Tests/BuiltInRulesTests/CyclomaticComplexityRuleTests.swift b/Tests/BuiltInRulesTests/CyclomaticComplexityRuleTests.swift index 4b6e28bb64..f9b5c36023 100644 --- a/Tests/BuiltInRulesTests/CyclomaticComplexityRuleTests.swift +++ b/Tests/BuiltInRulesTests/CyclomaticComplexityRuleTests.swift @@ -53,8 +53,11 @@ final class CyclomaticComplexityRuleTests: SwiftLintTestCase { let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["ignores_case_statements": true], - commentDoesntViolate: true, stringDoesntViolate: true) + verifyRule( + description, + ruleConfiguration: ["ignores_case_statements": true], + commentDoesntViolate: true, + stringDoesntViolate: true) } func testIgnoresCaseStatementsConfigurationDisabled() { @@ -65,7 +68,10 @@ final class CyclomaticComplexityRuleTests: SwiftLintTestCase { let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["ignores_case_statements": false], - commentDoesntViolate: true, stringDoesntViolate: true) + verifyRule( + description, + ruleConfiguration: ["ignores_case_statements": false], + commentDoesntViolate: true, + stringDoesntViolate: true) } } diff --git a/Tests/BuiltInRulesTests/FileHeaderRuleTests.swift b/Tests/BuiltInRulesTests/FileHeaderRuleTests.swift index 9d38e96843..e5cc2cccc2 100644 --- a/Tests/BuiltInRulesTests/FileHeaderRuleTests.swift +++ b/Tests/BuiltInRulesTests/FileHeaderRuleTests.swift @@ -31,10 +31,14 @@ final class FileHeaderRuleTests: SwiftLintTestCase { .with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["required_string": "**Header"], - stringDoesntViolate: false, skipCommentTests: true, - skipDisableCommandTests: true, testMultiByteOffsets: false, - testShebang: false) + verifyRule( + description, + ruleConfiguration: ["required_string": "**Header"], + stringDoesntViolate: false, + skipCommentTests: true, + skipDisableCommandTests: true, + testMultiByteOffsets: false, + testShebang: false) } func testFileHeaderWithRequiredPattern() { @@ -51,9 +55,12 @@ final class FileHeaderRuleTests: SwiftLintTestCase { .with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["required_pattern": "\\d{4} Realm"], - stringDoesntViolate: false, skipCommentTests: true, - testMultiByteOffsets: false) + verifyRule( + description, + ruleConfiguration: ["required_pattern": "\\d{4} Realm"], + stringDoesntViolate: false, + skipCommentTests: true, + testMultiByteOffsets: false) } func testFileHeaderWithRequiredStringAndURLComment() { @@ -68,9 +75,12 @@ final class FileHeaderRuleTests: SwiftLintTestCase { .with(triggeringExamples: triggeringExamples) let config = ["required_string": "/* Check this url: https://github.com/realm/SwiftLint */"] - verifyRule(description, ruleConfiguration: config, - stringDoesntViolate: false, skipCommentTests: true, - testMultiByteOffsets: false) + verifyRule( + description, + ruleConfiguration: config, + stringDoesntViolate: false, + skipCommentTests: true, + testMultiByteOffsets: false) } func testFileHeaderWithForbiddenString() { @@ -89,8 +99,10 @@ final class FileHeaderRuleTests: SwiftLintTestCase { .with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["forbidden_string": "**All rights reserved."], - skipCommentTests: true) + verifyRule( + description, + ruleConfiguration: ["forbidden_string": "**All rights reserved."], + skipCommentTests: true) } func testFileHeaderWithForbiddenPattern() { @@ -109,8 +121,10 @@ final class FileHeaderRuleTests: SwiftLintTestCase { .with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["forbidden_pattern": "\\s\\w+\\.swift"], - skipCommentTests: true) + verifyRule( + description, + ruleConfiguration: ["forbidden_pattern": "\\s\\w+\\.swift"], + skipCommentTests: true) } func testFileHeaderWithForbiddenPatternAndDocComment() { @@ -126,8 +140,11 @@ final class FileHeaderRuleTests: SwiftLintTestCase { .with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["forbidden_pattern": "[tT]ests"], - skipCommentTests: true, testMultiByteOffsets: false) + verifyRule( + description, + ruleConfiguration: ["forbidden_pattern": "[tT]ests"], + skipCommentTests: true, + testMultiByteOffsets: false) } func testFileHeaderWithRequiredStringUsingFilenamePlaceholder() { diff --git a/Tests/BuiltInRulesTests/FileLengthRuleTests.swift b/Tests/BuiltInRulesTests/FileLengthRuleTests.swift index 490377caac..04cb811b47 100644 --- a/Tests/BuiltInRulesTests/FileLengthRuleTests.swift +++ b/Tests/BuiltInRulesTests/FileLengthRuleTests.swift @@ -3,8 +3,11 @@ import TestHelpers final class FileLengthRuleTests: SwiftLintTestCase { func testFileLengthWithDefaultConfiguration() { - verifyRule(FileLengthRule.description, commentDoesntViolate: false, - testMultiByteOffsets: false, testShebang: false) + verifyRule( + FileLengthRule.description, + commentDoesntViolate: false, + testMultiByteOffsets: false, + testShebang: false) } func testFileLengthIgnoringLinesWithOnlyComments() { @@ -21,7 +24,10 @@ final class FileLengthRuleTests: SwiftLintTestCase { .with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["ignore_comment_only_lines": true], - testMultiByteOffsets: false, testShebang: false) + verifyRule( + description, + ruleConfiguration: ["ignore_comment_only_lines": true], + testMultiByteOffsets: false, + testShebang: false) } } diff --git a/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalRuleTests.swift b/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalRuleTests.swift index e840f3da0d..8c6a13d060 100644 --- a/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalRuleTests.swift +++ b/Tests/BuiltInRulesTests/ImplicitlyUnwrappedOptionalRuleTests.swift @@ -21,8 +21,11 @@ final class ImplicitlyUnwrappedOptionalRuleTests: SwiftLintTestCase { let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["mode": "all"], - commentDoesntViolate: true, stringDoesntViolate: true) + verifyRule( + description, + ruleConfiguration: ["mode": "all"], + commentDoesntViolate: true, + stringDoesntViolate: true) } func testImplicitlyUnwrappedOptionalRuleWarnsOnOutletsInWeakMode() { diff --git a/Tests/BuiltInRulesTests/LineLengthRuleTests.swift b/Tests/BuiltInRulesTests/LineLengthRuleTests.swift index b380653783..22269841cb 100644 --- a/Tests/BuiltInRulesTests/LineLengthRuleTests.swift +++ b/Tests/BuiltInRulesTests/LineLengthRuleTests.swift @@ -153,8 +153,12 @@ final class LineLengthRuleTests: SwiftLintTestCase { let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["ignores_comments": true], - commentDoesntViolate: false, stringDoesntViolate: false, skipCommentTests: true) + verifyRule( + description, + ruleConfiguration: ["ignores_comments": true], + commentDoesntViolate: false, + stringDoesntViolate: false, + skipCommentTests: true) } func testLineLengthWithIgnoreURLsEnabled() { @@ -172,8 +176,11 @@ final class LineLengthRuleTests: SwiftLintTestCase { let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["ignores_urls": true], - commentDoesntViolate: false, stringDoesntViolate: false) + verifyRule( + description, + ruleConfiguration: ["ignores_urls": true], + commentDoesntViolate: false, + stringDoesntViolate: false) } func testLineLengthWithIgnoreInterpolatedStringsTrue() { @@ -187,8 +194,11 @@ final class LineLengthRuleTests: SwiftLintTestCase { let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["ignores_interpolated_strings": true], - commentDoesntViolate: false, stringDoesntViolate: false) + verifyRule( + description, + ruleConfiguration: ["ignores_interpolated_strings": true], + commentDoesntViolate: false, + stringDoesntViolate: false) } func testLineLengthWithIgnoreMultilineStringsTrue() { @@ -211,8 +221,11 @@ final class LineLengthRuleTests: SwiftLintTestCase { let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["ignores_multiline_strings": true], - commentDoesntViolate: false, stringDoesntViolate: false) + verifyRule( + description, + ruleConfiguration: ["ignores_multiline_strings": true], + commentDoesntViolate: false, + stringDoesntViolate: false) } func testLineLengthWithIgnoreInterpolatedStringsFalse() { @@ -225,8 +238,11 @@ final class LineLengthRuleTests: SwiftLintTestCase { let description = baseDescription.with(nonTriggeringExamples: nonTriggeringExamples) .with(triggeringExamples: triggeringExamples) - verifyRule(description, ruleConfiguration: ["ignores_interpolated_strings": false], - commentDoesntViolate: false, stringDoesntViolate: false) + verifyRule( + description, + ruleConfiguration: ["ignores_interpolated_strings": false], + commentDoesntViolate: false, + stringDoesntViolate: false) } func testLineLengthWithExcludedLinesPatterns() { diff --git a/Tests/CoreTests/RuleTests.swift b/Tests/CoreTests/RuleTests.swift index 5b07374f06..a7b3dce463 100644 --- a/Tests/CoreTests/RuleTests.swift +++ b/Tests/CoreTests/RuleTests.swift @@ -6,8 +6,11 @@ final class RuleTests: SwiftLintTestCase { fileprivate struct RuleMock1: Rule { var configuration = SeverityConfiguration(.warning) var configurationDescription: some Documentable { RuleConfigurationOption.noOptions } - static let description = RuleDescription(identifier: "RuleMock1", name: "", - description: "", kind: .style) + static let description = RuleDescription( + identifier: "RuleMock1", + name: "", + description: "", + kind: .style) init() { /* conformance for test */ } init(configuration _: Any) { self.init() } @@ -20,8 +23,11 @@ final class RuleTests: SwiftLintTestCase { fileprivate struct RuleMock2: Rule { var configuration = SeverityConfiguration(.warning) var configurationDescription: some Documentable { RuleConfigurationOption.noOptions } - static let description = RuleDescription(identifier: "RuleMock2", name: "", - description: "", kind: .style) + static let description = RuleDescription( + identifier: "RuleMock2", + name: "", + description: "", + kind: .style) init() { /* conformance for test */ } init(configuration _: Any) { self.init() } @@ -34,9 +40,11 @@ final class RuleTests: SwiftLintTestCase { fileprivate struct RuleWithLevelsMock2: Rule { var configuration = SeverityLevelsConfiguration(warning: 2, error: 3) - static let description = RuleDescription(identifier: "violation_level_mock2", - name: "", - description: "", kind: .style) + static let description = RuleDescription( + identifier: "violation_level_mock2", + name: "", + description: "", + kind: .style) init() { /* conformance for test */ } init(configuration: Any) throws { diff --git a/Tests/FileSystemAccessTests/ConfigurationTests.swift b/Tests/FileSystemAccessTests/ConfigurationTests.swift index c17ca5e064..93ed5e70a7 100644 --- a/Tests/FileSystemAccessTests/ConfigurationTests.swift +++ b/Tests/FileSystemAccessTests/ConfigurationTests.swift @@ -233,13 +233,15 @@ final class ConfigurationTests: SwiftLintTestCase { let duplicateConfig2 = try? Configuration(dict: ["opt_in_rules": [optInRules.first!, optInRules.first!]]) XCTAssertEqual( - duplicateConfig2?.rules.filter { type(of: $0).identifier == optInRules.first! }.count, 1, + duplicateConfig2?.rules.filter { type(of: $0).identifier == optInRules.first! }.count, + 1, "duplicate rules should be removed when initializing Configuration" ) let duplicateConfig3 = try? Configuration(dict: ["disabled_rules": ["todo", "todo"]]) XCTAssertEqual( - duplicateConfig3?.rulesWrapper.disabledRuleIdentifiers.count, 1, + duplicateConfig3?.rulesWrapper.disabledRuleIdentifiers.count, + 1, "duplicate rules should be removed when initializing Configuration" ) } diff --git a/Tests/FrameworkTests/CommandTests.swift b/Tests/FrameworkTests/CommandTests.swift index 9e7fc7ae4d..73a41cd383 100644 --- a/Tests/FrameworkTests/CommandTests.swift +++ b/Tests/FrameworkTests/CommandTests.swift @@ -39,8 +39,12 @@ final class CommandTests: SwiftLintTestCase { func testDisablePrevious() { let input = "// swiftlint:disable:previous rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<38, - modifier: .previous) + let expected = Command( + action: .disable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<38, + modifier: .previous) XCTAssertEqual(file.commands(), expected.expand()) XCTAssertEqual(Command(string: input), expected) } @@ -48,8 +52,12 @@ final class CommandTests: SwiftLintTestCase { func testDisableThis() { let input = "// swiftlint:disable:this rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<34, - modifier: .this) + let expected = Command( + action: .disable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<34, + modifier: .this) XCTAssertEqual(file.commands(), expected.expand()) XCTAssertEqual(Command(string: input), expected) } @@ -57,8 +65,12 @@ final class CommandTests: SwiftLintTestCase { func testDisableNext() { let input = "// swiftlint:disable:next rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<34, - modifier: .next) + let expected = Command( + action: .disable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<34, + modifier: .next) XCTAssertEqual(file.commands(), expected.expand()) XCTAssertEqual(Command(string: input), expected) } @@ -74,8 +86,12 @@ final class CommandTests: SwiftLintTestCase { func testEnablePrevious() { let input = "// swiftlint:enable:previous rule_id\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<37, - modifier: .previous) + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<37, + modifier: .previous) XCTAssertEqual(file.commands(), expected.expand()) XCTAssertEqual(Command(string: input), expected) } @@ -99,9 +115,13 @@ final class CommandTests: SwiftLintTestCase { func testTrailingComment() { let input = "// swiftlint:enable:next rule_id - Comment\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<43, - modifier: .next, - trailingComment: "Comment") + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<43, + modifier: .next, + trailingComment: "Comment") XCTAssertEqual(file.commands(), expected.expand()) XCTAssertEqual(Command(string: input), expected) } @@ -109,9 +129,13 @@ final class CommandTests: SwiftLintTestCase { func testTrailingCommentWithUrl() { let input = "// swiftlint:enable:next rule_id - Comment with URL https://github.com/realm/SwiftLint\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<87, - modifier: .next, - trailingComment: "Comment with URL https://github.com/realm/SwiftLint") + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<87, + modifier: .next, + trailingComment: "Comment with URL https://github.com/realm/SwiftLint") XCTAssertEqual(file.commands(), expected.expand()) XCTAssertEqual(Command(string: input), expected) } @@ -119,9 +143,13 @@ final class CommandTests: SwiftLintTestCase { func testTrailingCommentUrlOnly() { let input = "// swiftlint:enable:next rule_id - https://github.com/realm/SwiftLint\n" let file = SwiftLintFile(contents: input) - let expected = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<70, - modifier: .next, - trailingComment: "https://github.com/realm/SwiftLint") + let expected = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<70, + modifier: .next, + trailingComment: "https://github.com/realm/SwiftLint") XCTAssertEqual(file.commands(), expected.expand()) XCTAssertEqual(Command(string: input), expected) } @@ -154,8 +182,12 @@ final class CommandTests: SwiftLintTestCase { func testExpandPreviousCommand() { do { - let command = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<48, - modifier: .previous) + let command = Command( + action: .disable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<48, + modifier: .previous) let expanded = [ Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 0), Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 0, range: completeLine), @@ -163,8 +195,12 @@ final class CommandTests: SwiftLintTestCase { XCTAssertEqual(command.expand(), expanded) } do { - let command = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<48, - modifier: .previous) + let command = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<48, + modifier: .previous) let expanded = [ Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 0), Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 0, range: completeLine), @@ -172,8 +208,12 @@ final class CommandTests: SwiftLintTestCase { XCTAssertEqual(command.expand(), expanded) } do { - let command = Command(action: .enable, ruleIdentifiers: ["1", "2"], line: 1, range: 4..<48, - modifier: .previous) + let command = Command( + action: .enable, + ruleIdentifiers: ["1", "2"], + line: 1, + range: 4..<48, + modifier: .previous) let expanded = [ Command(action: .enable, ruleIdentifiers: ["1", "2"], line: 0), Command(action: .disable, ruleIdentifiers: ["1", "2"], line: 0, range: completeLine), @@ -184,8 +224,12 @@ final class CommandTests: SwiftLintTestCase { func testExpandThisCommand() { do { - let command = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<48, - modifier: .this) + let command = Command( + action: .disable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<48, + modifier: .this) let expanded = [ Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1), Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: completeLine), @@ -193,8 +237,12 @@ final class CommandTests: SwiftLintTestCase { XCTAssertEqual(command.expand(), expanded) } do { - let command = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<48, - modifier: .this) + let command = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<48, + modifier: .this) let expanded = [ Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1), Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: completeLine), @@ -202,8 +250,12 @@ final class CommandTests: SwiftLintTestCase { XCTAssertEqual(command.expand(), expanded) } do { - let command = Command(action: .enable, ruleIdentifiers: ["1", "2"], line: 1, range: 4..<48, - modifier: .this) + let command = Command( + action: .enable, + ruleIdentifiers: ["1", "2"], + line: 1, + range: 4..<48, + modifier: .this) let expanded = [ Command(action: .enable, ruleIdentifiers: ["1", "2"], line: 1), Command(action: .disable, ruleIdentifiers: ["1", "2"], line: 1, range: completeLine), @@ -214,8 +266,12 @@ final class CommandTests: SwiftLintTestCase { func testExpandNextCommand() { do { - let command = Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<48, - modifier: .next) + let command = Command( + action: .disable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<48, + modifier: .next) let expanded = [ Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 2), Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 2, range: completeLine), @@ -223,8 +279,12 @@ final class CommandTests: SwiftLintTestCase { XCTAssertEqual(command.expand(), expanded) } do { - let command = Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 1, range: 4..<48, - modifier: .next) + let command = Command( + action: .enable, + ruleIdentifiers: ["rule_id"], + line: 1, + range: 4..<48, + modifier: .next) let expanded = [ Command(action: .enable, ruleIdentifiers: ["rule_id"], line: 2), Command(action: .disable, ruleIdentifiers: ["rule_id"], line: 2, range: completeLine), @@ -232,8 +292,11 @@ final class CommandTests: SwiftLintTestCase { XCTAssertEqual(command.expand(), expanded) } do { - let command = Command(action: .enable, ruleIdentifiers: ["1", "2"], line: 1, - modifier: .next) + let command = Command( + action: .enable, + ruleIdentifiers: ["1", "2"], + line: 1, + modifier: .next) let expanded = [ Command(action: .enable, ruleIdentifiers: ["1", "2"], line: 2), Command(action: .disable, ruleIdentifiers: ["1", "2"], line: 2, range: completeLine), diff --git a/Tests/FrameworkTests/LinterCacheTests.swift b/Tests/FrameworkTests/LinterCacheTests.swift index 66c2cb6bda..2c794658c8 100644 --- a/Tests/FrameworkTests/LinterCacheTests.swift +++ b/Tests/FrameworkTests/LinterCacheTests.swift @@ -85,8 +85,13 @@ final class LinterCacheTests: SwiftLintTestCase { line: UInt = #line) { cache.cache(violations: violations, forFile: forFile, configuration: configuration) cache = cache.flushed() - XCTAssertEqual(cache.violations(forFile: forFile, configuration: configuration)!, - violations, file: (file), line: line) + XCTAssertEqual( + cache.violations( + forFile: forFile, + configuration: configuration)!, + violations, + file: (file), + line: line) } private func cacheAndValidateNoViolationsTwoFiles(configuration: Configuration, diff --git a/Tests/FrameworkTests/ParserDiagnosticsTests.swift b/Tests/FrameworkTests/ParserDiagnosticsTests.swift index b02523ced0..426548341e 100644 --- a/Tests/FrameworkTests/ParserDiagnosticsTests.swift +++ b/Tests/FrameworkTests/ParserDiagnosticsTests.swift @@ -20,8 +20,12 @@ final class ParserDiagnosticsTests: SwiftLintTestCase { .with(corrections: [Example(contents): Example(contents)]) let config = try XCTUnwrap(makeConfig(nil, ruleDescription.identifier, skipDisableCommandTests: true)) - verifyCorrections(ruleDescription, config: config, disableCommands: [], - testMultiByteOffsets: false, parserDiagnosticsDisabledForTests: false) + verifyCorrections( + ruleDescription, + config: config, + disableCommands: [], + testMultiByteOffsets: false, + parserDiagnosticsDisabledForTests: false) } func testFileWithParserWarningDiagnostics() throws { @@ -42,8 +46,12 @@ final class ParserDiagnosticsTests: SwiftLintTestCase { .with(corrections: [Example(original): Example(corrected)]) let config = try XCTUnwrap(makeConfig(nil, ruleDescription.identifier, skipDisableCommandTests: true)) - verifyCorrections(ruleDescription, config: config, disableCommands: [], - testMultiByteOffsets: false, parserDiagnosticsDisabledForTests: false) + verifyCorrections( + ruleDescription, + config: config, + disableCommands: [], + testMultiByteOffsets: false, + parserDiagnosticsDisabledForTests: false) } func testFileWithoutParserDiagnostics() { diff --git a/Tests/FrameworkTests/RuleConfigurationTests.swift b/Tests/FrameworkTests/RuleConfigurationTests.swift index 3d8212b127..f236a86cdb 100644 --- a/Tests/FrameworkTests/RuleConfigurationTests.swift +++ b/Tests/FrameworkTests/RuleConfigurationTests.swift @@ -125,13 +125,20 @@ final class RuleConfigurationTests: SwiftLintTestCase { func testRegexRuleDescription() { var regexConfig = RegexConfiguration(identifier: "regex") - XCTAssertEqual(regexConfig.description, RuleDescription(identifier: "regex", - name: "regex", - description: "", kind: .style)) + XCTAssertEqual( + regexConfig.description, + RuleDescription( + identifier: "regex", + name: "regex", + description: "", + kind: .style)) regexConfig.name = "name" - XCTAssertEqual(regexConfig.description, RuleDescription(identifier: "regex", - name: "name", - description: "", kind: .style)) + XCTAssertEqual( + regexConfig.description, RuleDescription( + identifier: "regex", + name: "name", + description: "", + kind: .style)) } func testTrailingWhitespaceConfigurationThrowsOnBadConfig() { diff --git a/Tests/FrameworkTests/RulesFilterTests.swift b/Tests/FrameworkTests/RulesFilterTests.swift index d08302c168..432fec76b3 100644 --- a/Tests/FrameworkTests/RulesFilterTests.swift +++ b/Tests/FrameworkTests/RulesFilterTests.swift @@ -133,8 +133,11 @@ private struct RuleMock1: Rule { var configuration = SeverityConfiguration(.warning) var configurationDescription: some Documentable { RuleConfigurationOption.noOptions } - static let description = RuleDescription(identifier: "RuleMock1", name: "", - description: "", kind: .style) + static let description = RuleDescription( + identifier: "RuleMock1", + name: "", + description: "", + kind: .style) init() { /* conformance for test */ } init(configuration _: Any) { self.init() } @@ -148,8 +151,11 @@ private struct RuleMock2: Rule { var configuration = SeverityConfiguration(.warning) var configurationDescription: some Documentable { RuleConfigurationOption.noOptions } - static let description = RuleDescription(identifier: "RuleMock2", name: "", - description: "", kind: .style) + static let description = RuleDescription( + identifier: "RuleMock2", + name: "", + description: "", + kind: .style) init() { /* conformance for test */ } init(configuration _: Any) { self.init() } @@ -163,8 +169,11 @@ private struct CorrectableRuleMock: CorrectableRule { var configuration = SeverityConfiguration(.warning) var configurationDescription: some Documentable { RuleConfigurationOption.noOptions } - static let description = RuleDescription(identifier: "CorrectableRuleMock", name: "", - description: "", kind: .style) + static let description = RuleDescription( + identifier: "CorrectableRuleMock", + name: "", + description: "", + kind: .style) init() { /* conformance for test */ } init(configuration _: Any) { self.init() } diff --git a/Tests/FrameworkTests/RulesTests.swift b/Tests/FrameworkTests/RulesTests.swift index 4a236fa607..3f66e1a639 100644 --- a/Tests/FrameworkTests/RulesTests.swift +++ b/Tests/FrameworkTests/RulesTests.swift @@ -3,8 +3,11 @@ import TestHelpers final class RulesTests: SwiftLintTestCase { func testLeadingWhitespace() { - verifyRule(LeadingWhitespaceRule.description, skipDisableCommandTests: true, - testMultiByteOffsets: false, testShebang: false) + verifyRule( + LeadingWhitespaceRule.description, + skipDisableCommandTests: true, + testMultiByteOffsets: false, + testShebang: false) } func testMark() { @@ -17,8 +20,10 @@ final class RulesTests: SwiftLintTestCase { } func testTrailingNewline() { - verifyRule(TrailingNewlineRule.description, commentDoesntViolate: false, - stringDoesntViolate: false) + verifyRule( + TrailingNewlineRule.description, + commentDoesntViolate: false, + stringDoesntViolate: false) } func testOrphanedDocComment() { diff --git a/Tests/FrameworkTests/YamlParserTests.swift b/Tests/FrameworkTests/YamlParserTests.swift index 0d8145fa75..ce455e19b6 100644 --- a/Tests/FrameworkTests/YamlParserTests.swift +++ b/Tests/FrameworkTests/YamlParserTests.swift @@ -4,13 +4,17 @@ import XCTest final class YamlParserTests: SwiftLintTestCase { func testParseEmptyString() { - XCTAssertEqual((try YamlParser.parse("", env: [:])).count, 0, - "Parsing empty YAML string should succeed") + XCTAssertEqual( + (try YamlParser.parse("", env: [:])).count, + 0, + "Parsing empty YAML string should succeed") } func testParseValidString() { - XCTAssertEqual(try YamlParser.parse("a: 1\nb: 2", env: [:]).count, 2, - "Parsing valid YAML string should succeed") + XCTAssertEqual( + try YamlParser.parse("a: 1\nb: 2", env: [:]).count, + 2, + "Parsing valid YAML string should succeed") } func testParseReplacesEnvVar() throws { diff --git a/Tests/TestHelpers/TestHelpers.swift b/Tests/TestHelpers/TestHelpers.swift index 5c03260836..80c2ad1951 100644 --- a/Tests/TestHelpers/TestHelpers.swift +++ b/Tests/TestHelpers/TestHelpers.swift @@ -150,8 +150,10 @@ public extension Collection where Element: SwiftLintFile { -> [StyleViolation] { let storage = RuleStorage() let violations = map({ file in - Linter(file: file, configuration: config, - compilerArguments: requiresFileOnDisk ? file.makeCompilerArguments() : []) + Linter( + file: file, + configuration: config, + compilerArguments: requiresFileOnDisk ? file.makeCompilerArguments() : []) }).map({ linter in linter.collect(into: storage) }).flatMap({ linter in @@ -181,8 +183,10 @@ public extension Collection where Element: SwiftLintFile { private extension Collection where Element == StyleViolation { func withoutFiles() -> [StyleViolation] { map { violation in - let locationWithoutFile = Location(file: nil, line: violation.location.line, - character: violation.location.character) + let locationWithoutFile = Location( + file: nil, + line: violation.location.line, + character: violation.location.character) return violation.with(location: locationWithoutFile) } } @@ -271,7 +275,8 @@ private extension Configuration { file.contents, expected.code, #function + ".file contents", - file: before.file, line: before.line) + file: before.file, + line: before.line) let path = file.path! do { let corrected = try String(contentsOfFile: path, encoding: .utf8) @@ -279,11 +284,13 @@ private extension Configuration { corrected, expected.code, #function + ".corrected file equals expected", - file: before.file, line: before.line) + file: before.file, + line: before.line) } catch { XCTFail( "couldn't read file at path '\(path)': \(error)", - file: before.file, line: before.line) + file: before.file, + line: before.line) } } } @@ -383,13 +390,23 @@ public extension XCTestCase { disableCommands = ruleDescription.allIdentifiers.map { "// swiftlint:disable \($0)\n" } } - self.verifyLint(ruleDescription, config: config, commentDoesntViolate: commentDoesntViolate, - stringDoesntViolate: stringDoesntViolate, skipCommentTests: skipCommentTests, - skipStringTests: skipStringTests, disableCommands: disableCommands, - testMultiByteOffsets: testMultiByteOffsets, testShebang: testShebang, - file: file, line: line) - self.verifyCorrections(ruleDescription, config: config, disableCommands: disableCommands, - testMultiByteOffsets: testMultiByteOffsets) + self.verifyLint( + ruleDescription, + config: config, + commentDoesntViolate: commentDoesntViolate, + stringDoesntViolate: stringDoesntViolate, + skipCommentTests: skipCommentTests, + skipStringTests: skipStringTests, + disableCommands: disableCommands, + testMultiByteOffsets: testMultiByteOffsets, + testShebang: testShebang, + file: file, + line: line) + self.verifyCorrections( + ruleDescription, + config: config, + disableCommands: disableCommands, + testMultiByteOffsets: testMultiByteOffsets) } // swiftlint:disable:next function_body_length @@ -405,8 +422,11 @@ public extension XCTestCase { file: StaticString = #filePath, line: UInt = #line) { func verify(triggers: [Example], nonTriggers: [Example]) { - verifyExamples(triggers: triggers, nonTriggers: nonTriggers, configuration: config, - requiresFileOnDisk: ruleDescription.requiresFileOnDisk) + verifyExamples( + triggers: triggers, + nonTriggers: nonTriggers, + configuration: config, + requiresFileOnDisk: ruleDescription.requiresFileOnDisk) } func makeViolations(_ example: Example) -> [StyleViolation] { violations(example, config: config, requiresFileOnDisk: ruleDescription.requiresFileOnDisk) @@ -436,7 +456,8 @@ public extension XCTestCase { triggersToCheck.flatMap { makeViolations($0.with(code: "/*\n " + $0.code + "\n */")) }.count, commentDoesntViolate ? 0 : triggersToCheck.count, "Violation(s) still triggered when code was nested inside a comment", - file: (file), line: line + file: (file), + line: line ) } @@ -447,7 +468,8 @@ public extension XCTestCase { triggersToCheck.flatMap({ makeViolations($0.with(code: $0.code.toStringLiteral())) }).count, stringDoesntViolate ? 0 : triggersToCheck.count, "Violation(s) still triggered when code was nested inside a string literal", - file: (file), line: line + file: (file), + line: line ) } @@ -528,8 +550,10 @@ public extension XCTestCase { requiresFileOnDisk: Bool) { // Non-triggering examples don't violate for nonTrigger in nonTriggers { - let unexpectedViolations = violations(nonTrigger, config: config, - requiresFileOnDisk: requiresFileOnDisk) + let unexpectedViolations = violations( + nonTrigger, + config: config, + requiresFileOnDisk: requiresFileOnDisk) if unexpectedViolations.isEmpty { continue } let nonTriggerWithViolations = render(violations: unexpectedViolations, in: nonTrigger.code) XCTFail( @@ -540,8 +564,10 @@ public extension XCTestCase { // Triggering examples violate for trigger in triggers { - let triggerViolations = violations(trigger, config: config, - requiresFileOnDisk: requiresFileOnDisk) + let triggerViolations = violations( + trigger, + config: config, + requiresFileOnDisk: requiresFileOnDisk) // Triggering examples with violation markers violate at the marker's location let (cleanTrigger, markerOffsets) = cleanedContentsAndMarkerOffsets(from: trigger.code) @@ -578,11 +604,15 @@ public extension XCTestCase { line: trigger.line) } - XCTAssertEqual(triggerViolations.count, expectedLocations.count, - file: trigger.file, line: trigger.line) + XCTAssertEqual( + triggerViolations.count, + expectedLocations.count, + file: trigger.file, + line: trigger.line) for (triggerViolation, expectedLocation) in zip(triggerViolations, expectedLocations) { XCTAssertEqual( - triggerViolation.location, expectedLocation, + triggerViolation.location, + expectedLocation, "'\(trigger)' violation didn't match expected location.", file: trigger.file, line: trigger.line) From 938e650d97fbfd5b3689440596edeec5804ae733 Mon Sep 17 00:00:00 2001 From: Rodion Ivashkov Date: Tue, 2 Sep 2025 18:31:41 +0300 Subject: [PATCH 5/5] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c32fba2d31..e972d6551c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,10 @@ * Add new `unneeded_escaping` rule that detects closure parameters marked with `@escaping` that are never stored or captured escapingly. [SimplyDanny](https://github.com/SimplyDanny) + +* Add `multiline_call_arguments` opt-in rule to enforce consistent multiline + formatting for function and method call arguments. + [GandaLF2006](https://github.com/GandaLF2006) ### Bug Fixes