diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43990e825..7f3a98e23 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,21 @@
[Cihat Gündüz](https://github.com/Dschee)
[#1517](https://github.com/realm/SwiftLint/issues/1517)
+* Add `multiline_arguments_brackets` opt-in rule to warn against multiline
+ function call arguments with surrounding brackets without newline.
+ [Cihat Gündüz](https://github.com/Dschee)
+ [#2306](https://github.com/realm/SwiftLint/issues/2306)
+
+* Add `multiline_literal_brackets` opt-in rule to warn against multiline
+ literal arrays & dictionaries with surrounding brackets without newline.
+ [Cihat Gündüz](https://github.com/Dschee)
+ [#2306](https://github.com/realm/SwiftLint/issues/2306)
+
+* Add `multiline_parameters_brackets` opt-in rule to warn against multiline
+ function definition parameters with surrounding brackets without newline.
+ [Cihat Gündüz](https://github.com/Dschee)
+ [#2306](https://github.com/realm/SwiftLint/issues/2306)
+
#### Bug Fixes
* Fix false positive in `nimble_operator` rule.
diff --git a/Rules.md b/Rules.md
index 108d78c71..df2d3b70d 100644
--- a/Rules.md
+++ b/Rules.md
@@ -77,8 +77,11 @@
* [Missing Docs](#missing-docs)
* [Modifier Order](#modifier-order)
* [Multiline Arguments](#multiline-arguments)
+* [Multiline Arguments Brackets](#multiline-arguments-brackets)
* [Multiline Function Chains](#multiline-function-chains)
+* [Multiline Literal Brackets](#multiline-literal-brackets)
* [Multiline Parameters](#multiline-parameters)
+* [Multiline Parameters Brackets](#multiline-parameters-brackets)
* [Multiple Closures with Trailing Closure](#multiple-closures-with-trailing-closure)
* [Nesting](#nesting)
* [Nimble Operator](#nimble-operator)
@@ -11091,6 +11094,95 @@ foo(
+## Multiline Arguments Brackets
+
+Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
+--- | --- | --- | --- | --- | ---
+`multiline_arguments_brackets` | Disabled | No | style | No | 3.0.0
+
+Multiline arguments should have their surrounding brackets in a new line.
+
+### Examples
+
+
+Non Triggering Examples
+
+```swift
+foo(param1: "Param1", param2: "Param2", param3: "Param3")
+```
+
+```swift
+foo(
+ param1: "Param1", param2: "Param2", param3: "Param3"
+)
+```
+
+```swift
+func foo(
+ param1: "Param1",
+ param2: "Param2",
+ param3: "Param3"
+)
+```
+
+```swift
+foo { param1, param2 in
+ print("hello world")
+}
+```
+
+```swift
+foo(
+ bar(
+ x: 5,
+ y: 7
+ )
+)
+```
+
+```swift
+AlertViewModel.AlertAction(title: "some title", style: .default) {
+ AlertManager.shared.presentNextDebugAlert()
+}
+```
+
+
+
+Triggering Examples
+
+```swift
+foo(↓param1: "Param1", param2: "Param2",
+ param3: "Param3"
+)
+```
+
+```swift
+foo(
+ param1: "Param1",
+ param2: "Param2",
+ param3: "Param3"↓)
+```
+
+```swift
+foo(↓bar(
+ x: 5,
+ y: 7
+)
+)
+```
+
+```swift
+foo(
+ bar(
+ x: 5,
+ y: 7
+)↓)
+```
+
+
+
+
+
## Multiline Function Chains
Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
@@ -11207,6 +11299,118 @@ a.b {
+## Multiline Literal Brackets
+
+Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
+--- | --- | --- | --- | --- | ---
+`multiline_literal_brackets` | Disabled | No | style | No | 3.0.0
+
+Multiline literals should have their surrounding brackets in a new line.
+
+### Examples
+
+
+Non Triggering Examples
+
+```swift
+let trio = ["harry", "ronald", "hermione"]
+let houseCup = ["gryffinder": 460, "hufflepuff": 370, "ravenclaw": 410, "slytherin": 450]
+```
+
+```swift
+let trio = [
+ "harry",
+ "ronald",
+ "hermione"
+]
+let houseCup = [
+ "gryffinder": 460,
+ "hufflepuff": 370,
+ "ravenclaw": 410,
+ "slytherin": 450
+]
+```
+
+```swift
+let trio = [
+ "harry", "ronald", "hermione"
+]
+let houseCup = [
+ "gryffinder": 460, "hufflepuff": 370,
+ "ravenclaw": 410, "slytherin": 450
+]
+```
+
+```swift
+ _ = [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5, 6,
+ 7, 8, 9
+ ]
+```
+
+
+
+Triggering Examples
+
+```swift
+let trio = [↓"harry",
+ "ronald",
+ "hermione"
+]
+```
+
+```swift
+let houseCup = [↓"gryffinder": 460, "hufflepuff": 370,
+ "ravenclaw": 410, "slytherin": 450
+]
+```
+
+```swift
+let trio = [
+ "harry",
+ "ronald",
+ "hermione"↓]
+```
+
+```swift
+let houseCup = [
+ "gryffinder": 460, "hufflepuff": 370,
+ "ravenclaw": 410, "slytherin": 450↓]
+```
+
+```swift
+class Hogwarts {
+ let houseCup = [
+ "gryffinder": 460, "hufflepuff": 370,
+ "ravenclaw": 410, "slytherin": 450↓]
+}
+```
+
+```swift
+ _ = [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5, 6,
+ 7, 8, 9↓]
+```
+
+```swift
+ _ = [↓1, 2, 3,
+ 4, 5, 6,
+ 7, 8, 9
+ ]
+```
+
+
+
+
+
## Multiline Parameters
Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
@@ -11687,6 +11891,109 @@ class Foo {
+## Multiline Parameters Brackets
+
+Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
+--- | --- | --- | --- | --- | ---
+`multiline_parameters_brackets` | Disabled | No | style | No | 3.0.0
+
+Multiline parameters should have their surrounding brackets in a new line.
+
+### Examples
+
+
+Non Triggering Examples
+
+```swift
+func foo(param1: String, param2: String, param3: String)
+```
+
+```swift
+func foo(
+ param1: String, param2: String, param3: String
+)
+```
+
+```swift
+func foo(
+ param1: String,
+ param2: String,
+ param3: String
+)
+```
+
+```swift
+class SomeType {
+ func foo(param1: String, param2: String, param3: String)
+}
+```
+
+```swift
+class SomeType {
+ func foo(
+ param1: String, param2: String, param3: String
+ )
+}
+```
+
+```swift
+class SomeType {
+ func foo(
+ param1: String,
+ param2: String,
+ param3: String
+ )
+}
+```
+
+```swift
+func foo(param1: T, param2: String, param3: String) -> T { /* some code */ }
+```
+
+
+
+Triggering Examples
+
+```swift
+func foo(↓param1: String, param2: String,
+ param3: String
+)
+```
+
+```swift
+func foo(
+ param1: String,
+ param2: String,
+ param3: String↓)
+```
+
+```swift
+class SomeType {
+ func foo(↓param1: String, param2: String,
+ param3: String
+ )
+}
+```
+
+```swift
+class SomeType {
+ func foo(
+ param1: String,
+ param2: String,
+ param3: String↓)
+}
+```
+
+```swift
+func foo(↓param1: T, param2: String,
+ param3: String
+) -> T
+```
+
+
+
+
+
## Multiple Closures with Trailing Closure
Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
diff --git a/Source/SwiftLintFramework/Models/MasterRuleList.swift b/Source/SwiftLintFramework/Models/MasterRuleList.swift
index f004d0083..2162fcb7a 100644
--- a/Source/SwiftLintFramework/Models/MasterRuleList.swift
+++ b/Source/SwiftLintFramework/Models/MasterRuleList.swift
@@ -77,8 +77,11 @@ public let masterRuleList = RuleList(rules: [
MarkRule.self,
MissingDocsRule.self,
ModifierOrderRule.self,
+ MultilineArgumentsBracketsRule.self,
MultilineArgumentsRule.self,
MultilineFunctionChainsRule.self,
+ MultilineLiteralBracketsRule.self,
+ MultilineParametersBracketsRule.self,
MultilineParametersRule.self,
MultipleClosuresWithTrailingClosureRule.self,
NestingRule.self,
diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsBracketsRule.swift b/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsBracketsRule.swift
new file mode 100644
index 000000000..d04bfe5ef
--- /dev/null
+++ b/Source/SwiftLintFramework/Rules/Style/MultilineArgumentsBracketsRule.swift
@@ -0,0 +1,115 @@
+import Foundation
+import SourceKittenFramework
+
+public struct MultilineArgumentsBracketsRule: ASTRule, OptInRule, ConfigurationProviderRule, AutomaticTestableRule {
+ public var configuration = SeverityConfiguration(.warning)
+
+ public init() {}
+
+ public static let description = RuleDescription(
+ identifier: "multiline_arguments_brackets",
+ name: "Multiline Arguments Brackets",
+ description: "Multiline arguments should have their surrounding brackets in a new line.",
+ kind: .style,
+ nonTriggeringExamples: [
+ """
+ foo(param1: "Param1", param2: "Param2", param3: "Param3")
+ """,
+ """
+ foo(
+ param1: "Param1", param2: "Param2", param3: "Param3"
+ )
+ """,
+ """
+ func foo(
+ param1: "Param1",
+ param2: "Param2",
+ param3: "Param3"
+ )
+ """,
+ """
+ foo { param1, param2 in
+ print("hello world")
+ }
+ """,
+ """
+ foo(
+ bar(
+ x: 5,
+ y: 7
+ )
+ )
+ """,
+ """
+ AlertViewModel.AlertAction(title: "some title", style: .default) {
+ AlertManager.shared.presentNextDebugAlert()
+ }
+ """
+ ],
+ triggeringExamples: [
+ """
+ foo(↓param1: "Param1", param2: "Param2",
+ param3: "Param3"
+ )
+ """,
+ """
+ foo(
+ param1: "Param1",
+ param2: "Param2",
+ param3: "Param3"↓)
+ """,
+ """
+ foo(↓bar(
+ x: 5,
+ y: 7
+ )
+ )
+ """,
+ """
+ foo(
+ bar(
+ x: 5,
+ y: 7
+ )↓)
+ """
+ ]
+ )
+
+ public func validate(file: File,
+ kind: SwiftExpressionKind,
+ dictionary: [String: SourceKitRepresentable]) -> [StyleViolation] {
+ guard
+ kind == .call,
+ let bodyOffset = dictionary.bodyOffset,
+ let bodyLength = dictionary.bodyLength,
+ let range = file.contents.bridge().byteRangeToNSRange(start: bodyOffset, length: bodyLength)
+ else {
+ return []
+ }
+
+ let body = file.contents.substring(from: range.location, length: range.length)
+ let isMultiline = body.contains("\n")
+ guard isMultiline else {
+ return []
+ }
+
+ let expectedBodyBeginRegex = regex("\\A(?:[ \\t]*\\n|[^\\n]*(?:in|\\{)\\n)")
+ let expectedBodyEndRegex = regex("\\n[ \\t]*\\z")
+
+ var violatingByteOffsets = [Int]()
+ if expectedBodyBeginRegex.firstMatch(in: body, options: [], range: body.fullNSRange) == nil {
+ violatingByteOffsets.append(bodyOffset)
+ }
+
+ if expectedBodyEndRegex.firstMatch(in: body, options: [], range: body.fullNSRange) == nil {
+ violatingByteOffsets.append(bodyOffset + bodyLength)
+ }
+
+ return violatingByteOffsets.map { byteOffset in
+ StyleViolation(
+ ruleDescription: type(of: self).description, severity: configuration.severity,
+ location: Location(file: file, byteOffset: byteOffset)
+ )
+ }
+ }
+}
diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineLiteralBracketsRule.swift b/Source/SwiftLintFramework/Rules/Style/MultilineLiteralBracketsRule.swift
new file mode 100644
index 000000000..61141e3f9
--- /dev/null
+++ b/Source/SwiftLintFramework/Rules/Style/MultilineLiteralBracketsRule.swift
@@ -0,0 +1,137 @@
+import Foundation
+import SourceKittenFramework
+
+public struct MultilineLiteralBracketsRule: ASTRule, OptInRule, ConfigurationProviderRule, AutomaticTestableRule {
+ public var configuration = SeverityConfiguration(.warning)
+
+ public init() {}
+
+ public static let description = RuleDescription(
+ identifier: "multiline_literal_brackets",
+ name: "Multiline Literal Brackets",
+ description: "Multiline literals should have their surrounding brackets in a new line.",
+ kind: .style,
+ nonTriggeringExamples: [
+ """
+ let trio = ["harry", "ronald", "hermione"]
+ let houseCup = ["gryffinder": 460, "hufflepuff": 370, "ravenclaw": 410, "slytherin": 450]
+ """,
+ """
+ let trio = [
+ "harry",
+ "ronald",
+ "hermione"
+ ]
+ let houseCup = [
+ "gryffinder": 460,
+ "hufflepuff": 370,
+ "ravenclaw": 410,
+ "slytherin": 450
+ ]
+ """,
+ """
+ let trio = [
+ "harry", "ronald", "hermione"
+ ]
+ let houseCup = [
+ "gryffinder": 460, "hufflepuff": 370,
+ "ravenclaw": 410, "slytherin": 450
+ ]
+ """,
+ """
+ _ = [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5, 6,
+ 7, 8, 9
+ ]
+ """
+ ],
+ triggeringExamples: [
+ """
+ let trio = [↓"harry",
+ "ronald",
+ "hermione"
+ ]
+ """,
+ """
+ let houseCup = [↓"gryffinder": 460, "hufflepuff": 370,
+ "ravenclaw": 410, "slytherin": 450
+ ]
+ """,
+ """
+ let trio = [
+ "harry",
+ "ronald",
+ "hermione"↓]
+ """,
+ """
+ let houseCup = [
+ "gryffinder": 460, "hufflepuff": 370,
+ "ravenclaw": 410, "slytherin": 450↓]
+ """,
+ """
+ class Hogwarts {
+ let houseCup = [
+ "gryffinder": 460, "hufflepuff": 370,
+ "ravenclaw": 410, "slytherin": 450↓]
+ }
+ """,
+ """
+ _ = [
+ 1,
+ 2,
+ 3,
+ 4,
+ 5, 6,
+ 7, 8, 9↓]
+ """,
+ """
+ _ = [↓1, 2, 3,
+ 4, 5, 6,
+ 7, 8, 9
+ ]
+ """
+ ]
+ )
+
+ public func validate(file: File,
+ kind: SwiftExpressionKind,
+ dictionary: [String: SourceKitRepresentable]) -> [StyleViolation] {
+ guard
+ [.array, .dictionary].contains(kind),
+ let bodyOffset = dictionary.bodyOffset,
+ let bodyLength = dictionary.bodyLength,
+ let range = file.contents.bridge().byteRangeToNSRange(start: bodyOffset, length: bodyLength)
+ else {
+ return []
+ }
+
+ let body = file.contents.substring(from: range.location, length: range.length)
+ let isMultiline = body.contains("\n")
+ guard isMultiline else {
+ return []
+ }
+
+ let expectedBodyBeginRegex = regex("\\A[ \\t]*\\n")
+ let expectedBodyEndRegex = regex("\\n[ \\t]*\\z")
+
+ var violatingByteOffsets = [Int]()
+ if expectedBodyBeginRegex.firstMatch(in: body, options: [], range: body.fullNSRange) == nil {
+ violatingByteOffsets.append(bodyOffset)
+ }
+
+ if expectedBodyEndRegex.firstMatch(in: body, options: [], range: body.fullNSRange) == nil {
+ violatingByteOffsets.append(bodyOffset + bodyLength)
+ }
+
+ return violatingByteOffsets.map { byteOffset in
+ StyleViolation(
+ ruleDescription: type(of: self).description, severity: configuration.severity,
+ location: Location(file: file, byteOffset: byteOffset)
+ )
+ }
+ }
+}
diff --git a/Source/SwiftLintFramework/Rules/Style/MultilineParametersBracketsRule.swift b/Source/SwiftLintFramework/Rules/Style/MultilineParametersBracketsRule.swift
new file mode 100644
index 000000000..e545dc80e
--- /dev/null
+++ b/Source/SwiftLintFramework/Rules/Style/MultilineParametersBracketsRule.swift
@@ -0,0 +1,185 @@
+import Foundation
+import SourceKittenFramework
+
+public struct MultilineParametersBracketsRule: OptInRule, ConfigurationProviderRule, AutomaticTestableRule {
+ public var configuration = SeverityConfiguration(.warning)
+
+ public init() {}
+
+ public static let description = RuleDescription(
+ identifier: "multiline_parameters_brackets",
+ name: "Multiline Parameters Brackets",
+ description: "Multiline parameters should have their surrounding brackets in a new line.",
+ kind: .style,
+ nonTriggeringExamples: [
+ """
+ func foo(param1: String, param2: String, param3: String)
+ """,
+ """
+ func foo(
+ param1: String, param2: String, param3: String
+ )
+ """,
+ """
+ func foo(
+ param1: String,
+ param2: String,
+ param3: String
+ )
+ """,
+ """
+ class SomeType {
+ func foo(param1: String, param2: String, param3: String)
+ }
+ """,
+ """
+ class SomeType {
+ func foo(
+ param1: String, param2: String, param3: String
+ )
+ }
+ """,
+ """
+ class SomeType {
+ func foo(
+ param1: String,
+ param2: String,
+ param3: String
+ )
+ }
+ """,
+ """
+ func foo(param1: T, param2: String, param3: String) -> T { /* some code */ }
+ """
+ ],
+ triggeringExamples: [
+ """
+ func foo(↓param1: String, param2: String,
+ param3: String
+ )
+ """,
+ """
+ func foo(
+ param1: String,
+ param2: String,
+ param3: String↓)
+ """,
+ """
+ class SomeType {
+ func foo(↓param1: String, param2: String,
+ param3: String
+ )
+ }
+ """,
+ """
+ class SomeType {
+ func foo(
+ param1: String,
+ param2: String,
+ param3: String↓)
+ }
+ """,
+ """
+ func foo(↓param1: T, param2: String,
+ param3: String
+ ) -> T
+ """
+ ]
+ )
+
+ public func validate(file: File) -> [StyleViolation] {
+ return violations(in: file.structure.dictionary, file: file)
+ }
+
+ private func violations(in substructure: [String: SourceKitRepresentable], file: File) -> [StyleViolation] {
+ var violations = [StyleViolation]()
+
+ // find violations at current level
+ if let kindString = substructure.kind, let kind = SwiftDeclarationKind(rawValue: kindString),
+ SwiftDeclarationKind.functionKinds.contains(kind) {
+
+ guard
+ let nameOffset = substructure.nameOffset,
+ let nameLength = substructure.nameLength,
+ let functionName = file.contents.bridge().substringWithByteRange(start: nameOffset, length: nameLength)
+ else {
+ return []
+ }
+
+ let isMultiline = functionName.contains("\n")
+
+ let parameters = substructure.substructure.filter { $0.kind == SwiftDeclarationKind.varParameter.rawValue }
+ if isMultiline && !parameters.isEmpty {
+ if let openingBracketViolation = openingBracketViolation(parameters: parameters, file: file) {
+ violations.append(openingBracketViolation)
+ }
+
+ if let closingBracketViolation = closingBracketViolation(parameters: parameters, file: file) {
+ violations.append(closingBracketViolation)
+ }
+ }
+ }
+
+ // find violations at deeper levels
+ for substructure in substructure.substructure {
+ violations += self.violations(in: substructure, file: file)
+ }
+
+ return violations
+ }
+
+ private func openingBracketViolation(parameters: [[String: SourceKitRepresentable]],
+ file: File) -> StyleViolation? {
+ guard
+ let firstParamByteOffset = parameters.first?.offset,
+ let firstParamByteLength = parameters.first?.length,
+ let firstParamRange = file.contents.bridge().byteRangeToNSRange(
+ start: firstParamByteOffset,
+ length: firstParamByteLength
+ )
+ else {
+ return nil
+ }
+
+ let prefix = file.contents.bridge().substring(to: firstParamRange.lowerBound)
+ let invalidRegex = regex("\\([ \\t]*\\z")
+
+ guard let invalidMatch = invalidRegex.firstMatch(in: prefix, options: [], range: prefix.fullNSRange) else {
+ return nil
+ }
+
+ return StyleViolation(
+ ruleDescription: type(of: self).description,
+ severity: configuration.severity,
+ location: Location(file: file, characterOffset: invalidMatch.range.location + 1)
+ )
+ }
+
+ private func closingBracketViolation(parameters: [[String: SourceKitRepresentable]],
+ file: File) -> StyleViolation? {
+ guard
+ let lastParamByteOffset = parameters.last?.offset,
+ let lastParamByteLength = parameters.last?.length,
+ let lastParamRange = file.contents.bridge().byteRangeToNSRange(
+ start: lastParamByteOffset,
+ length: lastParamByteLength
+ )
+ else {
+ return nil
+ }
+
+ let suffix = file.contents.bridge().substring(from: lastParamRange.upperBound)
+ let invalidRegex = regex("\\A[ \\t]*\\)")
+
+ guard let invalidMatch = invalidRegex.firstMatch(in: suffix, options: [], range: suffix.fullNSRange) else {
+ return nil
+ }
+
+ let characterOffset = lastParamRange.upperBound + invalidMatch.range.upperBound - 1
+ return StyleViolation(
+ ruleDescription: type(of: self).description,
+ severity: configuration.severity,
+ location: Location(file: file, characterOffset: characterOffset)
+ )
+ }
+}
diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj
index 8b6afcea8..44bf72b8e 100644
--- a/SwiftLint.xcodeproj/project.pbxproj
+++ b/SwiftLint.xcodeproj/project.pbxproj
@@ -139,10 +139,13 @@
7C0C2E7A1D2866CB0076435A /* ExplicitInitRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C0C2E791D2866CB0076435A /* ExplicitInitRule.swift */; };
820F451E21073D7200AA056A /* ConditionalReturnsOnNewlineRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820F451D21073D7200AA056A /* ConditionalReturnsOnNewlineRuleTests.swift */; };
824AB64D2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824AB64C2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift */; };
+ 823EDC6221020D850070B7CD /* MultilineLiteralBracketsRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823EDC6121020D850070B7CD /* MultilineLiteralBracketsRule.swift */; };
82144ACC20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82144ACB20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift */; };
825F19D11EEFF19700969EF1 /* ObjectLiteralRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825F19D01EEFF19700969EF1 /* ObjectLiteralRuleTests.swift */; };
827169B31F488181003FB9AF /* ExplicitEnumRawValueRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827169B21F488181003FB9AF /* ExplicitEnumRawValueRule.swift */; };
827169B51F48D712003FB9AF /* NoGroupingExtensionRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827169B41F48D712003FB9AF /* NoGroupingExtensionRule.swift */; };
+ 82F614F22106014500D23904 /* MultilineParametersBracketsRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F614F12106014500D23904 /* MultilineParametersBracketsRule.swift */; };
+ 82F614F42106015100D23904 /* MultilineArgumentsBracketsRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F614F32106015100D23904 /* MultilineArgumentsBracketsRule.swift */; };
83894F221B0C928A006214E1 /* RulesCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83894F211B0C928A006214E1 /* RulesCommand.swift */; };
83D71E281B131ECE000395DE /* RuleDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D71E261B131EB5000395DE /* RuleDescription.swift */; };
85DA81321D6B471000951BC4 /* MarkRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 856651A61D6B395F005E6B29 /* MarkRule.swift */; };
@@ -561,10 +564,13 @@
7C0C2E791D2866CB0076435A /* ExplicitInitRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExplicitInitRule.swift; sourceTree = ""; };
820F451D21073D7200AA056A /* ConditionalReturnsOnNewlineRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConditionalReturnsOnNewlineRuleTests.swift; sourceTree = ""; };
824AB64C2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConditionalReturnsOnNewlineConfiguration.swift; sourceTree = ""; };
+ 823EDC6121020D850070B7CD /* MultilineLiteralBracketsRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineLiteralBracketsRule.swift; sourceTree = ""; };
82144ACB20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalWhitespaceBetweenCasesRule.swift; sourceTree = ""; };
825F19D01EEFF19700969EF1 /* ObjectLiteralRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectLiteralRuleTests.swift; sourceTree = ""; };
827169B21F488181003FB9AF /* ExplicitEnumRawValueRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExplicitEnumRawValueRule.swift; sourceTree = ""; };
827169B41F48D712003FB9AF /* NoGroupingExtensionRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NoGroupingExtensionRule.swift; sourceTree = ""; };
+ 82F614F12106014500D23904 /* MultilineParametersBracketsRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineParametersBracketsRule.swift; sourceTree = ""; };
+ 82F614F32106015100D23904 /* MultilineArgumentsBracketsRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineArgumentsBracketsRule.swift; sourceTree = ""; };
83894F211B0C928A006214E1 /* RulesCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RulesCommand.swift; sourceTree = ""; };
83D71E261B131EB5000395DE /* RuleDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuleDescription.swift; sourceTree = ""; };
856651A61D6B395F005E6B29 /* MarkRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MarkRule.swift; sourceTree = ""; };
@@ -1050,9 +1056,12 @@
C946FEC91EAE5E20007DD778 /* LetVarWhitespaceRule.swift */,
D4EA77C91F81FACC00C315FB /* LiteralExpressionEndIdentationRule.swift */,
188B3FF1207D61040073C2D6 /* ModifierOrderRule.swift */,
+ 82F614F32106015100D23904 /* MultilineArgumentsBracketsRule.swift */,
B25DCD071F7E9B5F0028A199 /* MultilineArgumentsRule.swift */,
B25DCD091F7E9BB50028A199 /* MultilineArgumentsRuleExamples.swift */,
3ABE19CD20B7CDE0009C2EC2 /* MultilineFunctionChainsRule.swift */,
+ 823EDC6121020D850070B7CD /* MultilineLiteralBracketsRule.swift */,
+ 82F614F12106014500D23904 /* MultilineParametersBracketsRule.swift */,
6238AE411ED4D734006C3601 /* MultilineParametersRule.swift */,
621061BE1ED57E640082D51E /* MultilineParametersRuleExamples.swift */,
BB00B4E71F5216070079869F /* MultipleClosuresWithTrailingClosureRule.swift */,
@@ -1787,6 +1796,7 @@
D44AD2761C0AA5350048F7B0 /* LegacyConstructorRule.swift in Sources */,
D286EC021E02DF6F0003CF72 /* SortedImportsRule.swift in Sources */,
D40E041C1F46E3B30043BC4E /* SuperfluousDisableCommandRule.swift in Sources */,
+ 82F614F42106015100D23904 /* MultilineArgumentsBracketsRule.swift in Sources */,
E86623671F1D377900AAA3A2 /* Configuration+Parsing.swift in Sources */,
3BCC04CD1C4F5694006073C3 /* ConfigurationError.swift in Sources */,
D4C4A34E1DEA877200E0E04C /* FileHeaderRule.swift in Sources */,
@@ -1839,6 +1849,7 @@
D4B022A41E105636007E5297 /* GenericTypeNameRule.swift in Sources */,
E86396CB1BADB519002C9E88 /* CSVReporter.swift in Sources */,
37B3FA8B1DFD45A700AD30D2 /* Dictionary+SwiftLint.swift in Sources */,
+ 823EDC6221020D850070B7CD /* MultilineLiteralBracketsRule.swift in Sources */,
D47EF4801F69E3100012C4CA /* ColonRule+FunctionCall.swift in Sources */,
E88198561BEA94D800333A11 /* FileLengthRule.swift in Sources */,
D47079A91DFDBED000027086 /* ClosureParameterPositionRule.swift in Sources */,
@@ -1904,6 +1915,7 @@
E86396C51BADAC15002C9E88 /* XcodeReporter.swift in Sources */,
E889D8C51F1D11A200058332 /* Configuration+LintableFiles.swift in Sources */,
094385011D5D2894009168CF /* WeakDelegateRule.swift in Sources */,
+ 82F614F22106014500D23904 /* MultilineParametersBracketsRule.swift in Sources */,
3B1DF0121C5148140011BCED /* CustomRules.swift in Sources */,
2E5761AA1C573B83003271AF /* FunctionParameterCountRule.swift in Sources */,
E86396C91BADB2B9002C9E88 /* JSONReporter.swift in Sources */,
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
index 43bbab27f..426e0ace9 100644
--- a/Tests/LinuxMain.swift
+++ b/Tests/LinuxMain.swift
@@ -714,6 +714,12 @@ extension ModifierOrderTests {
]
}
+extension MultilineArgumentsBracketsRuleTests {
+ static var allTests: [(String, (MultilineArgumentsBracketsRuleTests) -> () throws -> Void)] = [
+ ("testWithDefaultConfiguration", testWithDefaultConfiguration)
+ ]
+}
+
extension MultilineArgumentsRuleTests {
static var allTests: [(String, (MultilineArgumentsRuleTests) -> () throws -> Void)] = [
("testMultilineArgumentsWithDefaultConfiguration", testMultilineArgumentsWithDefaultConfiguration),
@@ -729,6 +735,18 @@ extension MultilineFunctionChainsRuleTests {
]
}
+extension MultilineLiteralBracketsRuleTests {
+ static var allTests: [(String, (MultilineLiteralBracketsRuleTests) -> () throws -> Void)] = [
+ ("testWithDefaultConfiguration", testWithDefaultConfiguration)
+ ]
+}
+
+extension MultilineParametersBracketsRuleTests {
+ static var allTests: [(String, (MultilineParametersBracketsRuleTests) -> () throws -> Void)] = [
+ ("testWithDefaultConfiguration", testWithDefaultConfiguration)
+ ]
+}
+
extension MultilineParametersRuleTests {
static var allTests: [(String, (MultilineParametersRuleTests) -> () throws -> Void)] = [
("testWithDefaultConfiguration", testWithDefaultConfiguration)
@@ -1400,8 +1418,11 @@ XCTMain([
testCase(MissingDocsRuleConfigurationTests.allTests),
testCase(MissingDocsRuleTests.allTests),
testCase(ModifierOrderTests.allTests),
+ testCase(MultilineArgumentsBracketsRuleTests.allTests),
testCase(MultilineArgumentsRuleTests.allTests),
testCase(MultilineFunctionChainsRuleTests.allTests),
+ testCase(MultilineLiteralBracketsRuleTests.allTests),
+ testCase(MultilineParametersBracketsRuleTests.allTests),
testCase(MultilineParametersRuleTests.allTests),
testCase(MultipleClosuresWithTrailingClosureRuleTests.allTests),
testCase(NestingRuleTests.allTests),
diff --git a/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift b/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift
index 068108733..1941262c1 100644
--- a/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift
+++ b/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift
@@ -330,12 +330,30 @@ class MissingDocsRuleTests: XCTestCase {
}
}
+class MultilineArgumentsBracketsRuleTests: XCTestCase {
+ func testWithDefaultConfiguration() {
+ verifyRule(MultilineArgumentsBracketsRule.description)
+ }
+}
+
class MultilineFunctionChainsRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(MultilineFunctionChainsRule.description)
}
}
+class MultilineLiteralBracketsRuleTests: XCTestCase {
+ func testWithDefaultConfiguration() {
+ verifyRule(MultilineLiteralBracketsRule.description)
+ }
+}
+
+class MultilineParametersBracketsRuleTests: XCTestCase {
+ func testWithDefaultConfiguration() {
+ verifyRule(MultilineParametersBracketsRule.description)
+ }
+}
+
class MultilineParametersRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(MultilineParametersRule.description)