-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Untyped error checks in catch statement
- Loading branch information
Daniel Metzing
committed
Feb 19, 2018
1 parent
dddb0f6
commit 1fb429d
Showing
6 changed files
with
181 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
78 changes: 78 additions & 0 deletions
78
Source/SwiftLintFramework/Rules/UntypedErrorInCatchRule.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// | ||
// UntypedErrorInCatchRule.swift | ||
// SwiftLint | ||
// | ||
// Created by Daniel.Metzing on 17/02/18. | ||
// Copyright © 2018 Realm. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import SourceKittenFramework | ||
|
||
public struct UntypedErrorInCatchRule: OptInRule, ConfigurationProviderRule { | ||
|
||
public var configuration = SeverityConfiguration(.warning) | ||
|
||
public init() {} | ||
|
||
private static let regularExpression = regex( | ||
"catch" + // The catch keyword | ||
"(?:" + // Start of the first non-capturing group | ||
"\\s*" + // Zero or multiple whitespace character | ||
"\\(" + // The `(` character | ||
"?" + // Zero or one occurrence of the previous character | ||
"\\s*" + // Zero or multiple whitespace character | ||
"(?:" + // Start of the alternative non-capturing group | ||
"let" + // `let` keyword | ||
"|" + // OR | ||
"var" + // `var` keyword | ||
")" + // End of the alternative non-capturing group | ||
"\\s+" + // At least one any type of whitespace character | ||
"\\w+" + // At least one any type of word character | ||
"\\s*" + // Zero or multiple whitespace character | ||
"\\)" + // The `)` character | ||
"?" + // Zero or one occurrence of the previous character | ||
")" + // End of the first non-capturing group | ||
"(?:" + // Start of the second non-capturing group | ||
"\\s*" + // Zero or unlimited any whitespace character | ||
")" + // End of the second non-capturing group | ||
"\\{" // Start scope character | ||
) | ||
|
||
public static let description = RuleDescription( | ||
identifier: "untyped_error_in_catch", | ||
name: "Untyped error in catch rule", | ||
description: "Catch statements should not declare error variables without type casting.", | ||
kind: .idiomatic, | ||
nonTriggeringExamples: [ | ||
"do {\n try foo() \n} catch {}", | ||
"do {\n try foo() \n} catch Error.invalidOperation {\n} catch {}", | ||
"do {\n try foo() \n} catch let error as MyError {\n} catch {}", | ||
"do {\n try foo() \n} catch var error as MyError {\n} catch {}" | ||
], | ||
triggeringExamples: [ | ||
"do {\n try foo() \n} ↓catch var error {}", | ||
"do {\n try foo() \n} ↓catch let error {}", | ||
"do {\n try foo() \n} ↓catch let someError {}", | ||
"do {\n try foo() \n} ↓catch var someError {}", | ||
"do {\n try foo() \n} ↓catch let e {}", | ||
"do {\n try foo() \n} ↓catch(let error) {}", | ||
"do {\n try foo() \n} ↓catch (let error) {}" | ||
]) | ||
|
||
public func validate(file: File) -> [StyleViolation] { | ||
let matchesAndSyntaxKinds = file.matchesAndSyntaxKinds(matching: type(of: self).regularExpression.pattern) | ||
return matchesAndSyntaxKinds.flatMap { match, syntaxKinds in | ||
guard syntaxKinds.contains(.keyword) else { | ||
return nil | ||
} | ||
|
||
let location = Location(file: file, | ||
characterOffset: match.range.lowerBound) | ||
return StyleViolation(ruleDescription: type(of: self).description, | ||
severity: configuration.severity, | ||
location: location, | ||
reason: configuration.consoleDescription) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters