diff --git a/CHANGELOG.md b/CHANGELOG.md
index 91f2dd3619..91649e37f7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -43,6 +43,11 @@
[Marcelo Fabri](https://github.com/marcelofabri)
[#2678](https://github.com/realm/SwiftLint/issues/2678)
+* Add `unused_capture_list` rule to ensure that all references in a closure
+ capture list are used.
+ [Dalton Claybrook](https://github.com/daltonclaybrook)
+ [#2715](https://github.com/realm/SwiftLint/issues/2715)
+
#### Bug Fixes
* Fix bug where SwiftLint ignores excluded files list in a nested configuration
diff --git a/Rules.md b/Rules.md
index 55d4429847..80634cddea 100644
--- a/Rules.md
+++ b/Rules.md
@@ -154,6 +154,7 @@
* [Unneeded Break in Switch](#unneeded-break-in-switch)
* [Unneeded Parentheses in Closure Argument](#unneeded-parentheses-in-closure-argument)
* [Untyped Error in Catch](#untyped-error-in-catch)
+* [Unused Capture List](#unused-capture-list)
* [Unused Closure Parameter](#unused-closure-parameter)
* [Unused Control Flow Label](#unused-control-flow-label)
* [Unused Enumerated](#unused-enumerated)
@@ -22910,6 +22911,83 @@ do {
+## Unused Capture List
+
+Identifier | Enabled by default | Supports autocorrection | Kind | Analyzer | Minimum Swift Compiler Version
+--- | --- | --- | --- | --- | ---
+`unused_capture_list` | Enabled | No | lint | No | 4.2.0
+
+Unused reference in a capture list should be removed.
+
+### Examples
+
+
+Non Triggering Examples
+
+```swift
+[1, 2].map { [weak self] num in
+ self?.handle(num)
+}
+```
+
+```swift
+let failure: Failure = { [weak self, unowned delegate = self.delegate!] foo in
+ delegate.handle(foo, self)
+}
+```
+
+```swift
+numbers.forEach({
+ [weak handler] in
+ handler?.handle($0)
+})
+```
+
+```swift
+{ [foo] in foo.bar() }()
+```
+
+```swift
+sizes.max().flatMap { [(offset: offset, size: $0)] } ?? []
+```
+
+
+
+Triggering Examples
+
+```swift
+[1, 2].map { [↓weak self] num in
+ print(num)
+}
+```
+
+```swift
+let failure: Failure = { [weak self, ↓unowned delegate = self.delegate!] foo in
+ self?.handle(foo)
+}
+```
+
+```swift
+let failure: Failure = { [↓weak self, ↓unowned delegate = self.delegate!] foo in
+ print(foo)
+}
+```
+
+```swift
+numbers.forEach({
+ [weak handler] in
+ print($0)
+})
+```
+
+```swift
+{ [↓foo] in _ }()
+```
+
+
+
+
+
## Unused Closure Parameter
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 56d3215890..72f0b15059 100644
--- a/Source/SwiftLintFramework/Models/MasterRuleList.swift
+++ b/Source/SwiftLintFramework/Models/MasterRuleList.swift
@@ -155,6 +155,7 @@ public let masterRuleList = RuleList(rules: [
UnneededBreakInSwitchRule.self,
UnneededParenthesesInClosureArgumentRule.self,
UntypedErrorInCatchRule.self,
+ UnusedCaptureListRule.self,
UnusedClosureParameterRule.self,
UnusedControlFlowLabelRule.self,
UnusedEnumeratedRule.self,
diff --git a/Source/SwiftLintFramework/Rules/Lint/UnusedCaptureListRule.swift b/Source/SwiftLintFramework/Rules/Lint/UnusedCaptureListRule.swift
new file mode 100644
index 0000000000..6292bc996c
--- /dev/null
+++ b/Source/SwiftLintFramework/Rules/Lint/UnusedCaptureListRule.swift
@@ -0,0 +1,142 @@
+import Foundation
+import SourceKittenFramework
+
+public struct UnusedCaptureListRule: ASTRule, ConfigurationProviderRule, AutomaticTestableRule {
+ public var configuration = SeverityConfiguration(.warning)
+
+ public init() {}
+
+ public static var description = RuleDescription(
+ identifier: "unused_capture_list",
+ name: "Unused Capture List",
+ description: "Unused reference in a capture list should be removed.",
+ kind: .lint,
+ minSwiftVersion: .fourDotTwo,
+ nonTriggeringExamples: [
+ """
+ [1, 2].map { [weak self] num in
+ self?.handle(num)
+ }
+ """,
+ """
+ let failure: Failure = { [weak self, unowned delegate = self.delegate!] foo in
+ delegate.handle(foo, self)
+ }
+ """,
+ """
+ numbers.forEach({
+ [weak handler] in
+ handler?.handle($0)
+ })
+ """,
+ "{ [foo] in foo.bar() }()",
+ "sizes.max().flatMap { [(offset: offset, size: $0)] } ?? []"
+ ],
+ triggeringExamples: [
+ """
+ [1, 2].map { [↓weak self] num in
+ print(num)
+ }
+ """,
+ """
+ let failure: Failure = { [weak self, ↓unowned delegate = self.delegate!] foo in
+ self?.handle(foo)
+ }
+ """,
+ """
+ let failure: Failure = { [↓weak self, ↓unowned delegate = self.delegate!] foo in
+ print(foo)
+ }
+ """,
+ """
+ numbers.forEach({
+ [weak handler] in
+ print($0)
+ })
+ """,
+ "{ [↓foo] in _ }()"
+ ]
+ )
+
+ private let captureListRegex = regex("^\\{\\s*\\[([^\\]]+)\\].*\\bin\\b")
+
+ public func validate(file: File, kind: SwiftExpressionKind,
+ dictionary: [String: SourceKitRepresentable]) -> [StyleViolation] {
+ let contents = file.contents.bridge()
+ guard kind == .closure,
+ let offset = dictionary.offset,
+ let length = dictionary.length,
+ let closureRange = contents.byteRangeToNSRange(start: offset, length: length),
+ let match = captureListRegex.firstMatch(in: file.contents, options: [], range: closureRange)
+ else { return [] }
+
+ let captureListRange = match.range(at: 1)
+ guard captureListRange.location != NSNotFound,
+ captureListRange.length > 0 else { return [] }
+
+ let captureList = contents.substring(with: captureListRange)
+ let references = referencesAndLocationsFromCaptureList(captureList)
+
+ let restOfClosureLocation = captureListRange.location + captureListRange.length + 1
+ let restOfClosureLength = closureRange.length - (restOfClosureLocation - closureRange.location)
+ let restOfClosureRange = NSRange(location: restOfClosureLocation, length: restOfClosureLength)
+ guard let restOfClosureByteRange = contents
+ .NSRangeToByteRange(start: restOfClosureRange.location, length: restOfClosureRange.length)
+ else { return [] }
+
+ let identifiers = identifierStrings(in: file, byteRange: restOfClosureByteRange)
+ return violations(in: file, references: references,
+ identifiers: identifiers, captureListRange: captureListRange)
+ }
+
+ // MARK: - Private
+
+ private func referencesAndLocationsFromCaptureList(_ captureList: String) -> [(String, Int)] {
+ var locationOffset = 0
+ return captureList.components(separatedBy: ",")
+ .reduce(into: [(String, Int)]()) { referencesAndLocations, item in
+ let item = item.bridge()
+ let range = item.rangeOfCharacter(from: CharacterSet.whitespacesAndNewlines.inverted)
+ guard range.location != NSNotFound else { return }
+
+ let location = range.location + locationOffset
+ locationOffset += item.length + 1 // 1 for comma
+ let reference = item.components(separatedBy: "=")
+ .first?
+ .trimmingCharacters(in: .whitespacesAndNewlines)
+ .components(separatedBy: .whitespaces)
+ .last
+ if let reference = reference {
+ referencesAndLocations.append((reference, location))
+ }
+ }
+ }
+
+ private func identifierStrings(in file: File, byteRange: NSRange) -> Set {
+ let contents = file.contents.bridge()
+ let identifiers = file.syntaxMap
+ .tokens(inByteRange: byteRange)
+ .compactMap { token -> String? in
+ guard token.type == SyntaxKind.identifier.rawValue || token.type == SyntaxKind.keyword.rawValue,
+ let range = contents.byteRangeToNSRange(start: token.offset, length: token.length)
+ else { return nil }
+ return contents.substring(with: range)
+ }
+ return Set(identifiers)
+ }
+
+ private func violations(in file: File, references: [(String, Int)],
+ identifiers: Set, captureListRange: NSRange) -> [StyleViolation] {
+ return references.compactMap { reference, location -> StyleViolation? in
+ guard !identifiers.contains(reference) else { return nil }
+ let offset = captureListRange.location + location
+ let reason = "Unused reference \(reference) in a capture list should be removed."
+ return StyleViolation(
+ ruleDescription: type(of: self).description,
+ severity: configuration.severity,
+ location: Location(file: file, characterOffset: offset),
+ reason: reason
+ )
+ }
+ }
+}
diff --git a/SwiftLint.xcodeproj/project.pbxproj b/SwiftLint.xcodeproj/project.pbxproj
index 7b923861a0..5655aeeae0 100644
--- a/SwiftLint.xcodeproj/project.pbxproj
+++ b/SwiftLint.xcodeproj/project.pbxproj
@@ -142,33 +142,32 @@
750BBD0B214180AF007EC437 /* CollectionAlignmentRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7578C915214173BE0080FEC9 /* CollectionAlignmentRuleTests.swift */; };
75161FDF213B9D73009DE767 /* CollectionAlignmentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75161FDD213B9D67009DE767 /* CollectionAlignmentConfiguration.swift */; };
7551DF6D21382C9A00AA1F4D /* ToggleBoolRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7551DF6C21382C9A00AA1F4D /* ToggleBoolRule.swift */; };
+ 7565E5F12262BA0900B0597C /* UnusedCaptureListRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7565E5F02262BA0900B0597C /* UnusedCaptureListRule.swift */; };
756B585D2138ECD300D1A4E9 /* CollectionAlignmentRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 756B585C2138ECD300D1A4E9 /* CollectionAlignmentRule.swift */; };
787CDE39208E7D41005F3D2F /* SwitchCaseAlignmentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787CDE38208E7D41005F3D2F /* SwitchCaseAlignmentConfiguration.swift */; };
787CDE3B208F9C34005F3D2F /* SwitchCaseAlignmentRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 787CDE3A208F9C34005F3D2F /* SwitchCaseAlignmentRuleTests.swift */; };
78F032461D7C877E00BE709A /* OverriddenSuperCallRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78F032441D7C877800BE709A /* OverriddenSuperCallRule.swift */; };
78F032481D7D614300BE709A /* OverridenSuperCallConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78F032471D7D614300BE709A /* OverridenSuperCallConfiguration.swift */; };
7C0C2E7A1D2866CB0076435A /* ExplicitInitRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C0C2E791D2866CB0076435A /* ExplicitInitRule.swift */; };
- 820F451E21073D7200AA056A /* ConditionalReturnsOnNewlineRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820F451D21073D7200AA056A /* ConditionalReturnsOnNewlineRuleTests.swift */; };
- 82144ACC20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82144ACB20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift */; };
- 823EDC6221020D850070B7CD /* MultilineLiteralBracketsRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823EDC6121020D850070B7CD /* MultilineLiteralBracketsRule.swift */; };
- 824AB64D2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824AB64C2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift */; };
820F451C2107292500AA056A /* TypeContentsOrderRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820F451B2107292500AA056A /* TypeContentsOrderRuleTests.swift */; };
820F451E21073D7200AA056A /* ConditionalReturnsOnNewlineRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820F451D21073D7200AA056A /* ConditionalReturnsOnNewlineRuleTests.swift */; };
+ 82144ACC20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82144ACB20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift */; };
821F70B7210720C700E2C84F /* FileTypesOrderRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 821F70B6210720C700E2C84F /* FileTypesOrderRuleTests.swift */; };
+ 823EDC6221020D850070B7CD /* MultilineLiteralBracketsRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 823EDC6121020D850070B7CD /* MultilineLiteralBracketsRule.swift */; };
824AB64D2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 824AB64C2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift */; };
825F19D11EEFF19700969EF1 /* ObjectLiteralRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 825F19D01EEFF19700969EF1 /* ObjectLiteralRuleTests.swift */; };
827009FD20FE26B700ECA185 /* FileTypesOrderRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827009FC20FE26B700ECA185 /* FileTypesOrderRule.swift */; };
827009FF20FE26C500ECA185 /* TypeContentsOrderRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 827009FE20FE26C500ECA185 /* TypeContentsOrderRule.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 */; };
- 82FE253F20F604AD00295958 /* VerticalWhitespaceOpeningBracesRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82FE253E20F604AD00295958 /* VerticalWhitespaceOpeningBracesRule.swift */; };
- 82FE254120F604CB00295958 /* VerticalWhitespaceClosingBracesRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82FE254020F604CB00295958 /* VerticalWhitespaceClosingBracesRule.swift */; };
82DB55FE21008F3E001C62FF /* FileTypesOrderConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82DB55FD21008F3E001C62FF /* FileTypesOrderConfiguration.swift */; };
82DB560021008F54001C62FF /* TypeContentsOrderConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82DB55FF21008F54001C62FF /* TypeContentsOrderConfiguration.swift */; };
82EB7885215BAE790042E0FD /* FileTypesOrderRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82EB7883215BAE780042E0FD /* FileTypesOrderRuleExamples.swift */; };
82EB7886215BAE790042E0FD /* TypeContentsOrderRuleExamples.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82EB7884215BAE780042E0FD /* TypeContentsOrderRuleExamples.swift */; };
+ 82F614F22106014500D23904 /* MultilineParametersBracketsRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F614F12106014500D23904 /* MultilineParametersBracketsRule.swift */; };
+ 82F614F42106015100D23904 /* MultilineArgumentsBracketsRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82F614F32106015100D23904 /* MultilineArgumentsBracketsRule.swift */; };
+ 82FE253F20F604AD00295958 /* VerticalWhitespaceOpeningBracesRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82FE253E20F604AD00295958 /* VerticalWhitespaceOpeningBracesRule.swift */; };
+ 82FE254120F604CB00295958 /* VerticalWhitespaceClosingBracesRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82FE254020F604CB00295958 /* VerticalWhitespaceClosingBracesRule.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 */; };
@@ -607,6 +606,7 @@
740DF1AF203F5AFC0081F694 /* EmptyStringRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EmptyStringRule.swift; sourceTree = ""; };
75161FDD213B9D67009DE767 /* CollectionAlignmentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionAlignmentConfiguration.swift; sourceTree = ""; };
7551DF6C21382C9A00AA1F4D /* ToggleBoolRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ToggleBoolRule.swift; sourceTree = ""; };
+ 7565E5F02262BA0900B0597C /* UnusedCaptureListRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnusedCaptureListRule.swift; sourceTree = ""; };
756B585C2138ECD300D1A4E9 /* CollectionAlignmentRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionAlignmentRule.swift; sourceTree = ""; };
7578C915214173BE0080FEC9 /* CollectionAlignmentRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CollectionAlignmentRuleTests.swift; sourceTree = ""; };
787CDE38208E7D41005F3D2F /* SwitchCaseAlignmentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchCaseAlignmentConfiguration.swift; sourceTree = ""; };
@@ -614,27 +614,25 @@
78F032441D7C877800BE709A /* OverriddenSuperCallRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverriddenSuperCallRule.swift; sourceTree = ""; };
78F032471D7D614300BE709A /* OverridenSuperCallConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OverridenSuperCallConfiguration.swift; sourceTree = ""; };
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 = ""; };
- 82144ACB20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalWhitespaceBetweenCasesRule.swift; sourceTree = ""; };
- 823EDC6121020D850070B7CD /* MultilineLiteralBracketsRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineLiteralBracketsRule.swift; sourceTree = ""; };
- 824AB64C2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConditionalReturnsOnNewlineConfiguration.swift; sourceTree = ""; };
820F451B2107292500AA056A /* TypeContentsOrderRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeContentsOrderRuleTests.swift; sourceTree = ""; };
820F451D21073D7200AA056A /* ConditionalReturnsOnNewlineRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConditionalReturnsOnNewlineRuleTests.swift; sourceTree = ""; };
+ 82144ACB20F640F200B06695 /* VerticalWhitespaceBetweenCasesRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalWhitespaceBetweenCasesRule.swift; sourceTree = ""; };
821F70B6210720C700E2C84F /* FileTypesOrderRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileTypesOrderRuleTests.swift; sourceTree = ""; };
+ 823EDC6121020D850070B7CD /* MultilineLiteralBracketsRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultilineLiteralBracketsRule.swift; sourceTree = ""; };
824AB64C2105C39F004B5A8F /* ConditionalReturnsOnNewlineConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConditionalReturnsOnNewlineConfiguration.swift; sourceTree = ""; };
825F19D01EEFF19700969EF1 /* ObjectLiteralRuleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectLiteralRuleTests.swift; sourceTree = ""; };
827009FC20FE26B700ECA185 /* FileTypesOrderRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileTypesOrderRule.swift; sourceTree = ""; };
827009FE20FE26C500ECA185 /* TypeContentsOrderRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeContentsOrderRule.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 = ""; };
- 82FE253E20F604AD00295958 /* VerticalWhitespaceOpeningBracesRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalWhitespaceOpeningBracesRule.swift; sourceTree = ""; };
- 82FE254020F604CB00295958 /* VerticalWhitespaceClosingBracesRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalWhitespaceClosingBracesRule.swift; sourceTree = ""; };
82DB55FD21008F3E001C62FF /* FileTypesOrderConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileTypesOrderConfiguration.swift; sourceTree = ""; };
82DB55FF21008F54001C62FF /* TypeContentsOrderConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TypeContentsOrderConfiguration.swift; sourceTree = ""; };
82EB7883215BAE780042E0FD /* FileTypesOrderRuleExamples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FileTypesOrderRuleExamples.swift; sourceTree = ""; };
82EB7884215BAE780042E0FD /* TypeContentsOrderRuleExamples.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeContentsOrderRuleExamples.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 = ""; };
+ 82FE253E20F604AD00295958 /* VerticalWhitespaceOpeningBracesRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalWhitespaceOpeningBracesRule.swift; sourceTree = ""; };
+ 82FE254020F604CB00295958 /* VerticalWhitespaceClosingBracesRule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalWhitespaceClosingBracesRule.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 = ""; };
@@ -1108,6 +1106,7 @@
D450D1D021EC4A6900E60010 /* StrongIBOutletRule.swift */,
D40E041B1F46E3B30043BC4E /* SuperfluousDisableCommandRule.swift */,
E88DEA811B0990A700A66CB0 /* TodoRule.swift */,
+ 7565E5F02262BA0900B0597C /* UnusedCaptureListRule.swift */,
D40AD0891E032F9700F48C30 /* UnusedClosureParameterRule.swift */,
D4D7320C21E15ED4001C07D9 /* UnusedControlFlowLabelRule.swift */,
8F715B82213B528B00427BD9 /* UnusedImportRule.swift */,
@@ -2037,6 +2036,7 @@
D4DAE8BC1DE14E8F00B0AE7A /* NimbleOperatorRule.swift in Sources */,
6CB514E91C760C6900FA02C4 /* Structure+SwiftLint.swift in Sources */,
D4C0E46F1E3D973600C560F2 /* ForWhereRule.swift in Sources */,
+ 7565E5F12262BA0900B0597C /* UnusedCaptureListRule.swift in Sources */,
D4EA77CA1F81FACC00C315FB /* LiteralExpressionEndIdentationRule.swift in Sources */,
E86396C51BADAC15002C9E88 /* XcodeReporter.swift in Sources */,
E889D8C51F1D11A200058332 /* Configuration+LintableFiles.swift in Sources */,
diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift
index 4c1c094b61..840c5c489c 100644
--- a/Tests/LinuxMain.swift
+++ b/Tests/LinuxMain.swift
@@ -1339,6 +1339,12 @@ extension UntypedErrorInCatchRuleTests {
]
}
+extension UnusedCaptureListRuleTests {
+ static var allTests: [(String, (UnusedCaptureListRuleTests) -> () throws -> Void)] = [
+ ("testWithDefaultConfiguration", testWithDefaultConfiguration)
+ ]
+}
+
extension UnusedClosureParameterRuleTests {
static var allTests: [(String, (UnusedClosureParameterRuleTests) -> () throws -> Void)] = [
("testWithDefaultConfiguration", testWithDefaultConfiguration)
@@ -1669,6 +1675,7 @@ XCTMain([
testCase(UnneededBreakInSwitchRuleTests.allTests),
testCase(UnneededParenthesesInClosureArgumentRuleTests.allTests),
testCase(UntypedErrorInCatchRuleTests.allTests),
+ testCase(UnusedCaptureListRuleTests.allTests),
testCase(UnusedClosureParameterRuleTests.allTests),
testCase(UnusedControlFlowLabelRuleTests.allTests),
testCase(UnusedEnumeratedRuleTests.allTests),
diff --git a/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift b/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift
index c47dcff5bb..ca0dbc1eeb 100644
--- a/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift
+++ b/Tests/SwiftLintFrameworkTests/AutomaticRuleTests.generated.swift
@@ -672,6 +672,12 @@ class UntypedErrorInCatchRuleTests: XCTestCase {
}
}
+class UnusedCaptureListRuleTests: XCTestCase {
+ func testWithDefaultConfiguration() {
+ verifyRule(UnusedCaptureListRule.description)
+ }
+}
+
class UnusedClosureParameterRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(UnusedClosureParameterRule.description)