mirror of
https://github.com/realm/SwiftLint.git
synced 2026-06-06 20:18:40 +00:00
With the binding of configurations to their associated rule types "unknown configuration" errors can be made more specific mentioning also the rule's identifier in the printed message.
50 lines
1.9 KiB
Swift
50 lines
1.9 KiB
Swift
import SwiftSyntax
|
|
|
|
// this rule exists due to a compiler bug: https://github.com/apple/swift/issues/51036
|
|
struct NSNumberInitAsFunctionReferenceRule: SwiftSyntaxRule, ConfigurationProviderRule {
|
|
var configuration = SeverityConfiguration<Self>(.warning)
|
|
|
|
static let description = RuleDescription(
|
|
identifier: "ns_number_init_as_function_reference",
|
|
name: "NSNumber Init as Function Reference",
|
|
description: "Passing `NSNumber.init` or `NSDecimalNumber.init` as a function reference is dangerous " +
|
|
"as it can cause the wrong initializer to be used, causing crashes; use `.init(value:)` instead",
|
|
kind: .lint,
|
|
nonTriggeringExamples: [
|
|
Example("[0, 0.2].map(NSNumber.init(value:))"),
|
|
Example("[0, 0.2].map { NSNumber(value: $0) }"),
|
|
Example("[0, 0.2].map(NSDecimalNumber.init(value:))"),
|
|
Example("[0, 0.2].map { NSDecimalNumber(value: $0) }")
|
|
],
|
|
triggeringExamples: [
|
|
Example("[0, 0.2].map(↓NSNumber.init)"),
|
|
Example("[0, 0.2].map(↓NSDecimalNumber.init)")
|
|
]
|
|
)
|
|
|
|
func makeVisitor(file: SwiftLintFile) -> ViolationsSyntaxVisitor {
|
|
Visitor(viewMode: .sourceAccurate)
|
|
}
|
|
}
|
|
|
|
private extension NSNumberInitAsFunctionReferenceRule {
|
|
final class Visitor: ViolationsSyntaxVisitor {
|
|
override func visitPost(_ node: MemberAccessExprSyntax) {
|
|
guard node.declNameArguments.isEmptyOrNil,
|
|
node.name.text == "init",
|
|
let baseText = node.base?.as(IdentifierExprSyntax.self)?.identifier.text,
|
|
baseText == "NSNumber" || baseText == "NSDecimalNumber" else {
|
|
return
|
|
}
|
|
|
|
violations.append(node.positionAfterSkippingLeadingTrivia)
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension DeclNameArgumentsSyntax? {
|
|
var isEmptyOrNil: Bool {
|
|
self?.arguments.isEmpty ?? true
|
|
}
|
|
}
|