Skip to content

Commit

Permalink
Merge pull request #2428 from biboran/compiler-protocol-init-description
Browse files Browse the repository at this point in the history
#2422 - Specify which literal rule was violated for CompilerProtocolInitRule
  • Loading branch information
marcelofabri authored Oct 2, 2018
2 parents bf85625 + 1b71ae7 commit 5bcaa61
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 16 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
[Marcelo Fabri](https://github.com/marcelofabri)
[#2395](https://github.com/realm/SwiftLint/issues/2395)

* Specify what type of compiler protocol initializer violated the
`compiler_protocol_init` rule.
[Timofey Solonin](https://github.com/biboran)
[#2422](https://github.com/realm/SwiftLint/issues/2422)

#### Bug Fixes

* Fix `comma` rule false positives on object literals (for example, images).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import Foundation
import SourceKittenFramework

public struct CompilerProtocolInitRule: ASTRule, ConfigurationProviderRule, AutomaticTestableRule {
public struct CompilerProtocolInitRule: ASTRule, ConfigurationProviderRule {
public var configuration = SeverityConfiguration(.warning)

public init() {}

public static let description = RuleDescription(
identifier: "compiler_protocol_init",
name: "Compiler Protocol Init",
description: "The initializers declared in compiler protocols such as `ExpressibleByArrayLiteral` " +
"shouldn't be called directly.",
description: CompilerProtocolInitRule.violationReason(
protocolName: "such as `ExpressibleByArrayLiteral`",
isPlural: true
),
kind: .lint,
nonTriggeringExamples: [
"let set: Set<Int> = [1, 2]\n",
Expand All @@ -22,17 +24,26 @@ public struct CompilerProtocolInitRule: ASTRule, ConfigurationProviderRule, Auto
]
)

private static func violationReason(protocolName: String, isPlural: Bool) -> String {
return "The initializers declared in compiler protocol\(isPlural ? "s" : "") \(protocolName) " +
"shouldn't be called directly."
}

public func validate(file: File, kind: SwiftExpressionKind,
dictionary: [String: SourceKitRepresentable]) -> [StyleViolation] {
return violationRanges(in: file, kind: kind, dictionary: dictionary).map {
StyleViolation(ruleDescription: type(of: self).description,
severity: configuration.severity,
location: Location(file: file, characterOffset: $0.location))
let (violation, range) = $0
return StyleViolation(
ruleDescription: type(of: self).description,
severity: configuration.severity,
location: Location(file: file, characterOffset: range.location),
reason: type(of: self).violationReason(protocolName: violation.protocolName, isPlural: false)
)
}
}

private func violationRanges(in file: File, kind: SwiftExpressionKind,
dictionary: [String: SourceKitRepresentable]) -> [NSRange] {
dictionary: [String: SourceKitRepresentable]) -> [(ExpressibleByCompiler, NSRange)] {
guard kind == .call, let name = dictionary.name else {
return []
}
Expand All @@ -47,15 +58,15 @@ public struct CompilerProtocolInitRule: ASTRule, ConfigurationProviderRule, Auto
continue
}

return [range]
return [(compilerProtocol, range)]
}

return []
}
}

private struct ExpressibleByCompiler {
private let protocolName: String
let protocolName: String
let initCallNames: Set<String>
private let arguments: [[String]]

Expand Down
4 changes: 4 additions & 0 deletions SwiftLint.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
B89F3BCE1FD5EE0200931E59 /* RequiredEnumCaseRuleTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89F3BCB1FD5EDA900931E59 /* RequiredEnumCaseRuleTestCase.swift */; };
B89F3BCF1FD5EE1400931E59 /* RequiredEnumCaseRuleConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89F3BC71FD5ED7D00931E59 /* RequiredEnumCaseRuleConfiguration.swift */; };
BB00B4E91F5216090079869F /* MultipleClosuresWithTrailingClosureRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB00B4E71F5216070079869F /* MultipleClosuresWithTrailingClosureRule.swift */; };
BCB68283216213130078E4C3 /* CompilerProtocolInitRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BCB68282216213130078E4C3 /* CompilerProtocolInitRuleTests.swift */; };
BFF028AE1CBCF8A500B38A9D /* TrailingWhitespaceConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF48D2D61CBCCA5F0080BDAE /* TrailingWhitespaceConfiguration.swift */; };
C25EBBDF2107884200E27603 /* PrefixedTopLevelConstantRuleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25EBBDD210787B200E27603 /* PrefixedTopLevelConstantRuleTests.swift */; };
C25EBBE221078D5F00E27603 /* GlobTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C25EBBE021078D5B00E27603 /* GlobTests.swift */; };
Expand Down Expand Up @@ -599,6 +600,7 @@
B89F3BC91FD5ED9000931E59 /* RequiredEnumCaseRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequiredEnumCaseRule.swift; sourceTree = "<group>"; };
B89F3BCB1FD5EDA900931E59 /* RequiredEnumCaseRuleTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequiredEnumCaseRuleTestCase.swift; sourceTree = "<group>"; };
BB00B4E71F5216070079869F /* MultipleClosuresWithTrailingClosureRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MultipleClosuresWithTrailingClosureRule.swift; sourceTree = "<group>"; };
BCB68282216213130078E4C3 /* CompilerProtocolInitRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompilerProtocolInitRuleTests.swift; sourceTree = "<group>"; };
BF48D2D61CBCCA5F0080BDAE /* TrailingWhitespaceConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrailingWhitespaceConfiguration.swift; sourceTree = "<group>"; };
C25EBBDD210787B200E27603 /* PrefixedTopLevelConstantRuleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrefixedTopLevelConstantRuleTests.swift; sourceTree = "<group>"; };
C25EBBE021078D5B00E27603 /* GlobTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GlobTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1338,6 +1340,7 @@
F480DC801F2609AB00099465 /* XCTestCase+BundlePath.swift */,
3B30C4A01C3785B300E04027 /* YamlParserTests.swift */,
3B12C9C21C320A53000B423F /* YamlSwiftLintTests.swift */,
BCB68282216213130078E4C3 /* CompilerProtocolInitRuleTests.swift */,
);
name = SwiftLintFrameworkTests;
path = Tests/SwiftLintFrameworkTests;
Expand Down Expand Up @@ -2050,6 +2053,7 @@
62329C2B1F30B2310035737E /* DiscouragedDirectInitRuleTests.swift in Sources */,
C25EBBE221078D5F00E27603 /* GlobTests.swift in Sources */,
E86396C71BADAFE6002C9E88 /* ReporterTests.swift in Sources */,
BCB68283216213130078E4C3 /* CompilerProtocolInitRuleTests.swift in Sources */,
D43B04661E071ED3004016AF /* ColonRuleTests.swift in Sources */,
D4F5851920E99B5A0085C6D8 /* PrivateOutletRuleTests.swift in Sources */,
3B12C9C71C3361CB000B423F /* RuleTests.swift in Sources */,
Expand Down
3 changes: 2 additions & 1 deletion Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ extension CommandTests {

extension CompilerProtocolInitRuleTests {
static var allTests: [(String, (CompilerProtocolInitRuleTests) -> () throws -> Void)] = [
("testWithDefaultConfiguration", testWithDefaultConfiguration)
("testWithDefaultConfiguration", testWithDefaultConfiguration),
("testViolationMessageForExpressibleByIntegerLiteral", testViolationMessageForExpressibleByIntegerLiteral)
]
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ class CommaRuleTests: XCTestCase {
}
}

class CompilerProtocolInitRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(CompilerProtocolInitRule.description)
}
}

class ContainsOverFirstNotNilRuleTests: XCTestCase {
func testWithDefaultConfiguration() {
verifyRule(ContainsOverFirstNotNilRule.description)
Expand Down
29 changes: 29 additions & 0 deletions Tests/SwiftLintFrameworkTests/CompilerProtocolInitRuleTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@testable import SwiftLintFramework
import XCTest

class CompilerProtocolInitRuleTests: XCTestCase {
private let ruleID = CompilerProtocolInitRule.description.identifier

func testWithDefaultConfiguration() {
verifyRule(CompilerProtocolInitRule.description)
}

func testViolationMessageForExpressibleByIntegerLiteral() {
guard let config = makeConfig(nil, ruleID) else {
XCTFail("Failed to create configuration")
return
}
let allViolations = violations("let a = NSNumber(integerLiteral: 1)", config: config)

let compilerProtocolInitViolation = allViolations.first { $0.ruleDescription.identifier == ruleID }
if let violation = compilerProtocolInitViolation {
XCTAssertEqual(
violation.reason,
"The initializers declared in compiler protocol ExpressibleByIntegerLiteral " +
"shouldn't be called directly."
)
} else {
XCTFail("A compiler protocol init violation should have been triggered!")
}
}
}

0 comments on commit 5bcaa61

Please sign in to comment.