diff --git a/CHANGELOG.md b/CHANGELOG.md index e60a187b8..6d911f844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,11 @@ [SimplyDanny](https://github.com/SimplyDanny) [#4612](https://github.com/realm/SwiftLint/issues/4612) +* Skip `defer` statements being last in an `#if` block if the `#if` statement is + not itself the last statement in a block. + [SimplyDanny](https://github.com/SimplyDanny) + [#4615](https://github.com/realm/SwiftLint/issues/4615) + * Fix false positives in `empty_enum_arguments` when the called expression is an identifier or an init call. [Steffen Matthischke](https://github.com/heeaad) diff --git a/Source/SwiftLintFramework/Rules/Lint/InertDeferRule.swift b/Source/SwiftLintFramework/Rules/Lint/InertDeferRule.swift index 6287803fb..e3eb00871 100644 --- a/Source/SwiftLintFramework/Rules/Lint/InertDeferRule.swift +++ b/Source/SwiftLintFramework/Rules/Lint/InertDeferRule.swift @@ -25,7 +25,17 @@ struct InertDeferRule: ConfigurationProviderRule, SwiftSyntaxRule { print("other code") } } - """) + """), + Example(""" + func f() { + #if os(macOS) + defer { print(2) } + #else + defer { print(3) } + #endif + print(1) + } + """, excludeFromDocumentation: true) ], triggeringExamples: [ Example(""" @@ -46,7 +56,23 @@ struct InertDeferRule: ConfigurationProviderRule, SwiftSyntaxRule { // comment } } - """) + """), + Example(""" + func f(arg: Int) { + if arg == 1 { + ↓defer { print(2) } + // a comment + } else { + ↓defer { print(3) } + } + print(1) + #if os(macOS) + ↓defer { print(4) } + #else + ↓defer { print(5) } + #endif + } + """, excludeFromDocumentation: true) ] ) @@ -58,9 +84,11 @@ struct InertDeferRule: ConfigurationProviderRule, SwiftSyntaxRule { private extension InertDeferRule { final class Visitor: ViolationsSyntaxVisitor { override func visitPost(_ node: DeferStmtSyntax) { - guard let codeBlockItem = node.parent?.as(CodeBlockItemSyntax.self), - let codeBlockList = codeBlockItem.parent?.as(CodeBlockItemListSyntax.self), - codeBlockList.last == codeBlockItem else { + guard node.isLastStatement else { + return + } + if let ifConfigClause = node.parent?.parent?.parent?.as(IfConfigClauseSyntax.self), + ifConfigClause.parent?.parent?.isLastStatement == false { return } @@ -68,3 +96,13 @@ private extension InertDeferRule { } } } + +private extension SyntaxProtocol { + var isLastStatement: Bool { + if let codeBlockItem = parent?.as(CodeBlockItemSyntax.self), + let codeBlockList = codeBlockItem.parent?.as(CodeBlockItemListSyntax.self) { + return codeBlockList.last == codeBlockItem + } + return false + } +}