diff --git a/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/ImplicitReturnConfiguration.swift b/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/ImplicitReturnConfiguration.swift index edcd8f2c68..354c320e6c 100644 --- a/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/ImplicitReturnConfiguration.swift +++ b/Source/SwiftLintBuiltInRules/Rules/RuleConfigurations/ImplicitReturnConfiguration.swift @@ -11,6 +11,7 @@ struct ImplicitReturnConfiguration: SeverityBasedRuleConfiguration { case getter case `subscript` case initializer + case `switch` static func < (lhs: Self, rhs: Self) -> Bool { lhs.rawValue < rhs.rawValue diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRule.swift b/Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRule.swift index 236280e18a..cbf97b673b 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRule.swift @@ -61,6 +61,36 @@ private extension ImplicitReturnRule { } } + override func visitPost(_ node: SwitchExprSyntax) { + if configuration.isKindIncluded(.switch) { + dump(file.syntaxTree) + var violations: [CodeBlockItemListSyntax] = [] + let switchCases: SwitchCaseListSyntax = node.cases + for switchCase in switchCases { + dump("🏴‍☠️ \(switchCase)") + var childViolations: [CodeBlockItemListSyntax] = [] + if let item = switchCase.as(SwitchCaseSyntax.self) { + if item.statements.count > 1 { + return + } else { + childViolations.append(item.statements) + } + } + for violation in childViolations { + violations.append(violation) + } + } +// if node.statements.syntaxNodeType != NilLiteralExprSyntax.self { +// if item != "return" && item != "return nil" { +// collectViolation(in: node.statements) +// } +// } + for violation in violations { + collectViolation(in: violation) + } + } + } + private func collectViolation(in itemList: CodeBlockItemListSyntax) { guard let returnStmt = itemList.onlyElement?.item.as(ReturnStmtSyntax.self) else { return diff --git a/Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRuleExamples.swift b/Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRuleExamples.swift index df92fb92da..49509bf2f4 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRuleExamples.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRuleExamples.swift @@ -333,6 +333,88 @@ struct ImplicitReturnRuleExamples { ] } + struct SwitchExamples { + static let nonTriggeringExamples = [ + Example(""" + switch someBool { + case true: true + case false: nil + } + """), + Example(""" + switch someBool { + case true: + true + case false: + nil + } + """), + Example(""" + return switch someBool { + case true: + true + case false: + nil + } + """), + Example(""" + switch someBool { + case true: + return true + case false: + let someVar = 0 + return nil + } + """), + ] + + static let triggeringExamples = [ + Example(""" + switch someBool { + case true: ↓return true + case false: ↓return nil + } + """), + Example(""" + switch someBool { + case true: + ↓return true + case false: + ↓return nil + } + """), + ] + + static let corrections = [ + Example(""" + switch someBool { + case true: ↓return true + case false: ↓return nil + } + """): Example(""" + switch someBool { + case true: true + case false: nil + } + """), + Example(""" + switch someBool { + case true: + ↓return true + case false: + ↓return nil + } + """): Example(""" + switch someBool { + case true: + true + case false: + nil + } + """), + ] + } + struct MixedExamples { static let corrections = [ Example(""" @@ -356,14 +438,16 @@ struct ImplicitReturnRuleExamples { FunctionExamples.nonTriggeringExamples + GetterExamples.nonTriggeringExamples + InitializerExamples.nonTriggeringExamples + - SubscriptExamples.nonTriggeringExamples + SubscriptExamples.nonTriggeringExamples + + SwitchExamples.nonTriggeringExamples static let triggeringExamples = ClosureExamples.triggeringExamples + FunctionExamples.triggeringExamples + GetterExamples.triggeringExamples + InitializerExamples.triggeringExamples + - SubscriptExamples.triggeringExamples + SubscriptExamples.triggeringExamples + + SwitchExamples.triggeringExamples static var corrections: [Example: Example] { [ @@ -372,6 +456,7 @@ struct ImplicitReturnRuleExamples { GetterExamples.corrections, InitializerExamples.corrections, SubscriptExamples.corrections, + SwitchExamples.corrections, MixedExamples.corrections, ] .reduce(into: [:]) { result, element in diff --git a/Tests/IntegrationTests/default_rule_configurations.yml b/Tests/IntegrationTests/default_rule_configurations.yml index c87aa691cb..50dc0ce7fa 100644 --- a/Tests/IntegrationTests/default_rule_configurations.yml +++ b/Tests/IntegrationTests/default_rule_configurations.yml @@ -237,7 +237,7 @@ implicit_getter: severity: warning implicit_return: severity: warning - included: [closure, function, getter, initializer, subscript] + included: [closure, function, getter, initializer, subscript, switch] implicitly_unwrapped_optional: severity: warning mode: all_except_iboutlets diff --git a/Tests/SwiftLintFrameworkTests/ImplicitReturnRuleTests.swift b/Tests/SwiftLintFrameworkTests/ImplicitReturnRuleTests.swift index 6aa4036f22..e3aa22cb89 100644 --- a/Tests/SwiftLintFrameworkTests/ImplicitReturnRuleTests.swift +++ b/Tests/SwiftLintFrameworkTests/ImplicitReturnRuleTests.swift @@ -76,6 +76,21 @@ final class ImplicitReturnRuleTests: SwiftLintTestCase { ) } + func testOnlySwitchKindIncluded() { + var nonTriggeringExamples = ImplicitReturnRuleExamples.nonTriggeringExamples + + ImplicitReturnRuleExamples.triggeringExamples + nonTriggeringExamples.removeAll( + where: ImplicitReturnRuleExamples.SwitchExamples.triggeringExamples.contains + ) + + verifySubset( + nonTriggeringExamples: nonTriggeringExamples, + triggeringExamples: ImplicitReturnRuleExamples.SwitchExamples.triggeringExamples, + corrections: ImplicitReturnRuleExamples.SwitchExamples.corrections, + kind: .switch + ) + } + private func verifySubset( nonTriggeringExamples: [Example], triggeringExamples: [Example],