Skip to content

Commit

Permalink
Add excludes_trivial_init for `missing_docs (#4152)
Browse files Browse the repository at this point in the history
Fixes #4107
  • Loading branch information
marcelofabri authored Sep 4, 2022
1 parent c26c40d commit c1650e6
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 18 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

#### Enhancements

* None.
* Add new `excludes_trivial_init` configuration for `missing_docs` rule
to exclude initializers without any parameters.
[Marcelo Fabri](https://github.com/marcelofabri)
[#4107](https://github.com/realm/SwiftLint/issues/4107)

#### Bug Fixes

Expand Down
33 changes: 28 additions & 5 deletions Source/SwiftLintFramework/Rules/Lint/MissingDocsRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ private extension SwiftLintFile {
func missingDocOffsets(in dictionary: SourceKittenDictionary,
acls: [AccessControlLevel],
excludesExtensions: Bool,
excludesInheritedTypes: Bool) -> [(ByteCount, AccessControlLevel)] {
excludesInheritedTypes: Bool,
excludesTrivialInit: Bool) -> [(ByteCount, AccessControlLevel)] {
if dictionary.enclosedSwiftAttributes.contains(.override) ||
(dictionary.inheritedTypes.isNotEmpty && excludesInheritedTypes) {
return []
Expand All @@ -14,9 +15,18 @@ private extension SwiftLintFile {
in: $0,
acls: acls,
excludesExtensions: excludesExtensions,
excludesInheritedTypes: excludesInheritedTypes
excludesInheritedTypes: excludesInheritedTypes,
excludesTrivialInit: excludesTrivialInit
)
}

let isTrivialInit = dictionary.declarationKind == .functionMethodInstance &&
dictionary.name == "init()" &&
dictionary.enclosedVarParameters.isEmpty
if isTrivialInit && excludesTrivialInit {
return substructureOffsets
}

guard let kind = dictionary.declarationKind,
(!SwiftDeclarationKind.extensionKinds.contains(kind) || !excludesExtensions),
case let isDeinit = kind == .functionMethodInstance && dictionary.name == "deinit",
Expand Down Expand Up @@ -73,7 +83,13 @@ public struct MissingDocsRule: OptInRule, ConfigurationProviderRule {
"""),
Example("""
public extension A {}
""")
"""),
Example("""
/// docs
public class A {
public init() {}
}
""", configuration: ["excludes_trivial_init": true])
],
triggeringExamples: [
// public, undocumented
Expand All @@ -93,7 +109,13 @@ public struct MissingDocsRule: OptInRule, ConfigurationProviderRule {
public let b: Int
}
""")
"""),
Example("""
/// docs
public class A {
public init(argument: String) {}
}
""", configuration: ["excludes_trivial_init": true])
]
)

Expand All @@ -104,7 +126,8 @@ public struct MissingDocsRule: OptInRule, ConfigurationProviderRule {
in: dict,
acls: acls,
excludesExtensions: configuration.excludesExtensions,
excludesInheritedTypes: configuration.excludesInheritedTypes
excludesInheritedTypes: configuration.excludesInheritedTypes,
excludesTrivialInit: configuration.excludesTrivialInit
).map { offset, acl in
StyleViolation(ruleDescription: Self.description,
severity: configuration.parameters.first { $0.value == acl }?.severity ?? .warning,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public struct MissingDocsRuleConfiguration: RuleConfiguration, Equatable {
]
private(set) var excludesExtensions = true
private(set) var excludesInheritedTypes = true
private(set) var excludesTrivialInit = false

public var consoleDescription: String {
let parametersDescription = parameters.group { $0.severity }.sorted { $0.key.rawValue < $1.key.rawValue }.map {
Expand All @@ -14,14 +15,16 @@ public struct MissingDocsRuleConfiguration: RuleConfiguration, Equatable {
if parametersDescription.isEmpty {
return [
"excludes_extensions: \(excludesExtensions)",
"excludes_inherited_types: \(excludesInheritedTypes)"
"excludes_inherited_types: \(excludesInheritedTypes)",
"excludes_trivial_init: \(excludesTrivialInit)"
]
.joined(separator: ", ")
} else {
return [
parametersDescription,
"excludes_extensions: \(excludesExtensions)",
"excludes_inherited_types: \(excludesInheritedTypes)"
"excludes_inherited_types: \(excludesInheritedTypes)",
"excludes_trivial_init: \(excludesTrivialInit)"
]
.joined(separator: ", ")
}
Expand All @@ -40,6 +43,16 @@ public struct MissingDocsRuleConfiguration: RuleConfiguration, Equatable {
excludesInheritedTypes = shouldExcludeInheritedTypes
}

if let excludesTrivialInit = dict["excludes_trivial_init"] as? Bool {
self.excludesTrivialInit = excludesTrivialInit
}

if let parameters = try parameters(from: dict) {
self.parameters = parameters
}
}

private func parameters(from dict: [String: Any]) throws -> [RuleParameter<AccessControlLevel>]? {
var parameters: [RuleParameter<AccessControlLevel>] = []

for (key, value) in dict {
Expand Down Expand Up @@ -68,8 +81,6 @@ public struct MissingDocsRuleConfiguration: RuleConfiguration, Equatable {
throw ConfigurationError.unknownConfiguration
}

if parameters.isNotEmpty {
self.parameters = parameters
}
return parameters.isNotEmpty ? parameters : nil
}
}
30 changes: 23 additions & 7 deletions Tests/SwiftLintFrameworkTests/MissingDocsRuleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,35 @@ class MissingDocsRuleTests: XCTestCase {
let configuration = MissingDocsRuleConfiguration()
XCTAssertEqual(
configuration.consoleDescription,
"warning: open, public, excludes_extensions: true, excludes_inherited_types: true"
"warning: open, public, excludes_extensions: true, " +
"excludes_inherited_types: true, excludes_trivial_init: false"
)
}

func testDescriptionExcludesFalse() {
let configuration = MissingDocsRuleConfiguration(excludesExtensions: false, excludesInheritedTypes: false)
XCTAssertEqual(
configuration.consoleDescription,
"warning: open, public, excludes_extensions: false, excludes_inherited_types: false"
"warning: open, public, excludes_extensions: false, " +
"excludes_inherited_types: false, excludes_trivial_init: false"
)
}

func testDescriptionExcludesExtensionsFalseExcludesInheritedTypesTrue() {
let configuration = MissingDocsRuleConfiguration(excludesExtensions: false, excludesInheritedTypes: true)
XCTAssertEqual(
configuration.consoleDescription,
"warning: open, public, excludes_extensions: false, excludes_inherited_types: true"
"warning: open, public, excludes_extensions: false, " +
"excludes_inherited_types: true, excludes_trivial_init: false"
)
}

func testDescriptionExcludesExtensionsTrueExcludesInheritedTypesFalse() {
let configuration = MissingDocsRuleConfiguration(excludesExtensions: true, excludesInheritedTypes: false)
XCTAssertEqual(
configuration.consoleDescription,
"warning: open, public, excludes_extensions: true, excludes_inherited_types: false"
"warning: open, public, excludes_extensions: true, " +
"excludes_inherited_types: false, excludes_trivial_init: false"
)
}

Expand All @@ -39,7 +43,8 @@ class MissingDocsRuleTests: XCTestCase {
parameters: [RuleParameter<AccessControlLevel>(severity: .error, value: .open)])
XCTAssertEqual(
configuration.consoleDescription,
"error: open, excludes_extensions: true, excludes_inherited_types: true"
"error: open, excludes_extensions: true, " +
"excludes_inherited_types: true, excludes_trivial_init: false"
)
}

Expand All @@ -49,7 +54,8 @@ class MissingDocsRuleTests: XCTestCase {
RuleParameter<AccessControlLevel>(severity: .warning, value: .public)])
XCTAssertEqual(
configuration.consoleDescription,
"error: open, warning: public, excludes_extensions: true, excludes_inherited_types: true"
"error: open, warning: public, excludes_extensions: true, " +
"excludes_inherited_types: true, excludes_trivial_init: false"
)
}

Expand All @@ -59,7 +65,17 @@ class MissingDocsRuleTests: XCTestCase {
RuleParameter<AccessControlLevel>(severity: .warning, value: .public)])
XCTAssertEqual(
configuration.consoleDescription,
"warning: open, public, excludes_extensions: true, excludes_inherited_types: true"
"warning: open, public, excludes_extensions: true, " +
"excludes_inherited_types: true, excludes_trivial_init: false"
)
}

func testDescriptionExcludesTrivialInitTrue() {
let configuration = MissingDocsRuleConfiguration(excludesTrivialInit: true)
XCTAssertEqual(
configuration.consoleDescription,
"warning: open, public, excludes_extensions: true, " +
"excludes_inherited_types: true, excludes_trivial_init: true"
)
}

Expand Down

0 comments on commit c1650e6

Please sign in to comment.