1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
import SwiftSyntax
/// Force-try (`try!`) is forbidden.
///
/// This rule does not apply to test code, defined as code which:
/// * Contains the line `import XCTest`
///
/// Lint: Using `try!` results in a lint error.
///
/// TODO: Create exception for NSRegularExpression
@_spi(Rules)
public final class NeverUseForceTry: SyntaxLintRule {
/// Identifies this rule as being opt-in. While force try is an unsafe pattern (i.e. it can
/// crash), there are valid contexts for force try where it won't crash. This rule can't
/// evaluate the context around the force try to make that determination.
public override class var isOptIn: Bool { return true }
public override func visit(_ node: SourceFileSyntax) -> SyntaxVisitorContinueKind {
setImportsXCTest(context: context, sourceFile: node)
return .visitChildren
}
public override func visit(_ node: TryExprSyntax) -> SyntaxVisitorContinueKind {
guard context.importsXCTest == .doesNotImportXCTest else { return .skipChildren }
guard let mark = node.questionOrExclamationMark else { return .visitChildren }
if mark.tokenKind == .exclamationMark {
diagnose(.doNotForceTry, on: node.tryKeyword)
}
return .visitChildren
}
}
extension Finding.Message {
fileprivate static let doNotForceTry: Finding.Message = "do not use force try"
}
|