Skip to content

Commit

Permalink
Merge pull request #421 from realm/rule/force-unwrapping
Browse files Browse the repository at this point in the history
Add opt-in force unwrapping rule
  • Loading branch information
jpsim committed Jan 26, 2016
2 parents c888215 + 614c27a commit 7559cc6
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
[Scott Hoyt](https://github.com/scottrhoyt)
[#123](https://github.com/realm/SwiftLint/issues/123)

* Added opt-in `ForceUnwrappingRule` to issue warnings for all forced
unwrappings.
[Benjamin Otto](https://github.com/Argent)
[#55](https://github.com/realm/SwiftLint/issues/55)

##### Bug Fixes

* Fix several false positives in `ValidDocsRule`.
Expand Down
1 change: 1 addition & 0 deletions Source/SwiftLintFramework/Models/MasterRuleList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public let masterRuleList = RuleList( rules: ClosingBraceRule.self,
FileLengthRule.self,
ForceCastRule.self,
ForceTryRule.self,
ForceUnwrappingRule.self,
FunctionBodyLengthRule.self,
LeadingWhitespaceRule.self,
LegacyConstantRule.self,
Expand Down
40 changes: 40 additions & 0 deletions Source/SwiftLintFramework/Rules/ForceUnwrappingRule.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// ForceUnwrappingRule.swift
// SwiftLint
//
// Created by Benjamin Otto on 14/01/16.
// Copyright (c) 2015 Realm. All rights reserved.
//

import SourceKittenFramework

public struct ForceUnwrappingRule: OptInRule, ConfigProviderRule {

public var config = SeverityConfig(.Warning)

public init() {}

public static let description = RuleDescription(
identifier: "force_unwrapping",
name: "Force Unwrapping",
description: "Force unwrapping should be avoided.",
nonTriggeringExamples: [
"if let url = NSURL(string: query)",
"navigationController?.pushViewController(viewController, animated: true)"
],
triggeringExamples: [
"let url = NSURL(string: query)↓!",
"navigationController↓!.pushViewController(viewController, animated: true)",
"let unwrapped = optional↓!",
"return cell↓!"
]
)

public func validateFile(file: File) -> [StyleViolation] {
return file.matchPattern("[\\w)]+!", withSyntaxKinds: [.Identifier]).map {
StyleViolation(ruleDescription: self.dynamicType.description,
severity: config.severity,
location: Location(file: file, characterOffset: NSMaxRange($0) - 1))
}
}
}
4 changes: 4 additions & 0 deletions Source/SwiftLintFrameworkTests/RulesTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ class RulesTests: XCTestCase {
verifyRule(ForceTryRule.description)
}

func testForceUnwrapping() {
verifyRule(ForceUnwrappingRule.description)
}

func testFunctionBodyLength() {
verifyRule(FunctionBodyLengthRule.description)
}
Expand Down
4 changes: 4 additions & 0 deletions SwiftLint.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
69F88BF71BDA38A6005E7CAE /* OpeningBraceRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 692B1EB11BD7E00F00EAABFF /* OpeningBraceRule.swift */; };
83894F221B0C928A006214E1 /* RulesCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83894F211B0C928A006214E1 /* RulesCommand.swift */; };
83D71E281B131ECE000395DE /* RuleDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 83D71E261B131EB5000395DE /* RuleDescription.swift */; };
B58AEED61C492C7B00E901FD /* ForceUnwrappingRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58AEED51C492C7B00E901FD /* ForceUnwrappingRule.swift */; };
D0AAAB5019FB0960007B24B3 /* SwiftLintFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D0D1216D19E87B05005E4BAA /* SwiftLintFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
D0D1217819E87B05005E4BAA /* SwiftLintFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D1216D19E87B05005E4BAA /* SwiftLintFramework.framework */; };
D0E7B65319E9C6AD00EDBA4D /* SwiftLintFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D1216D19E87B05005E4BAA /* SwiftLintFramework.framework */; };
Expand Down Expand Up @@ -191,6 +192,7 @@
695BE9CE1BDFD92B0071E985 /* CommaRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommaRule.swift; sourceTree = "<group>"; };
83894F211B0C928A006214E1 /* RulesCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RulesCommand.swift; sourceTree = "<group>"; };
83D71E261B131EB5000395DE /* RuleDescription.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RuleDescription.swift; sourceTree = "<group>"; };
B58AEED51C492C7B00E901FD /* ForceUnwrappingRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ForceUnwrappingRule.swift; sourceTree = "<group>"; };
D0D1211B19E87861005E4BAA /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; usesTabs = 0; };
D0D1212419E878CC005E4BAA /* Common.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Common.xcconfig; sourceTree = "<group>"; };
D0D1212619E878CC005E4BAA /* Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
Expand Down Expand Up @@ -545,6 +547,7 @@
E88DEA891B0992B300A66CB0 /* FileLengthRule.swift */,
E88DEA7F1B09903300A66CB0 /* ForceCastRule.swift */,
E816194D1BFBFEAB00946723 /* ForceTryRule.swift */,
B58AEED51C492C7B00E901FD /* ForceUnwrappingRule.swift */,
E88DEA8F1B099A3100A66CB0 /* FunctionBodyLengthRule.swift */,
E88DEA7D1B098F2A00A66CB0 /* LeadingWhitespaceRule.swift */,
006ECFC31C44E99E00EF6364 /* LegacyConstantRule.swift */,
Expand Down Expand Up @@ -851,6 +854,7 @@
E88198421BEA929F00333A11 /* NestingRule.swift in Sources */,
3BB47D851C51D80000AE6A10 /* NSRegularExpression+SwiftLint.swift in Sources */,
E881985B1BEA974E00333A11 /* StatementPositionRule.swift in Sources */,
B58AEED61C492C7B00E901FD /* ForceUnwrappingRule.swift in Sources */,
E88DEA711B09847500A66CB0 /* ViolationSeverity.swift in Sources */,
3BD9CD3D1C37175B009A5D25 /* YamlParser.swift in Sources */,
E88DEA8C1B0999A000A66CB0 /* ASTRule.swift in Sources */,
Expand Down

0 comments on commit 7559cc6

Please sign in to comment.