Skip to content

Commit 7ca393f

Browse files
LaurenWhiteallevato
authored andcommitted
Implement never use force try (swiftlang#56)
1 parent c5c0695 commit 7ca393f

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

Sources/Rules/NeverUseForceTry.swift

+19-5
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,30 @@ import SwiftSyntax
44

55
/// Force-try (`try!`) is forbidden.
66
///
7-
/// This rule does not apply to test code, defined as code which matches one or more of:
8-
/// * Parent directory named "Tests"
7+
/// This rule does not apply to test code, defined as code which:
98
/// * Contains the line `import XCTest`
109
///
1110
/// Lint: Using `try!` results in a lint error.
1211
///
13-
/// Format: The use of `try!` is replaced with a `try`...`catch` block where the `catch` block
14-
/// contains `fatalError("TODO(<username>): document before submitting")`
12+
/// TODO: Create exception for NSRegularExpression
1513
///
1614
/// - SeeAlso: https://google.github.io/swift#error-types
17-
public final class NeverUseForceTry: SyntaxFormatRule {
15+
public final class NeverUseForceTry: SyntaxLintRule {
1816

17+
public override func visit(_ node: SourceFileSyntax) {
18+
setImportsXCTest(context: context, sourceFile: node)
19+
super.visit(node)
20+
}
21+
22+
public override func visit(_ node: TryExprSyntax) {
23+
guard !context.importsXCTest else { return }
24+
guard let mark = node.questionOrExclamationMark else { return }
25+
if mark.tokenKind == .exclamationMark {
26+
diagnose(.doNotForceTry, on: node.tryKeyword)
27+
}
28+
}
29+
}
30+
31+
extension Diagnostic.Message {
32+
static let doNotForceTry = Diagnostic.Message(.warning, "do not use force try")
1933
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Foundation
2+
import XCTest
3+
import SwiftSyntax
4+
5+
@testable import Rules
6+
7+
public class NeverUseForceTryTests: DiagnosingTestCase {
8+
public func testInvalidTryExpression() {
9+
let input =
10+
"""
11+
let document = try! Document(path: "important.data")
12+
let document = try Document(path: "important.data")
13+
let x = try! someThrowingFunction()
14+
if let data = try? fetchDataFromDisk() { return data }
15+
"""
16+
performLint(NeverUseForceTry.self, input: input)
17+
XCTAssertDiagnosed(.doNotForceTry)
18+
XCTAssertDiagnosed(.doNotForceTry)
19+
XCTAssertNotDiagnosed(.doNotForceTry)
20+
}
21+
22+
public func testAllowForceTryInTestCode() {
23+
let input =
24+
"""
25+
import XCTest
26+
27+
let document = try! Document(path: "important.data")
28+
"""
29+
performLint(NeverUseForceTry.self, input: input)
30+
XCTAssertNotDiagnosed(.doNotForceTry)
31+
}
32+
}

0 commit comments

Comments
 (0)