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.
80 lines
3.0 KiB
Swift
80 lines
3.0 KiB
Swift
import SwiftSyntax
|
|
|
|
struct NSLocalizedStringKeyRule: SwiftSyntaxRule, OptInRule, ConfigurationProviderRule {
|
|
var configuration = SeverityConfiguration<Self>(.warning)
|
|
|
|
static let description = RuleDescription(
|
|
identifier: "nslocalizedstring_key",
|
|
name: "NSLocalizedString Key",
|
|
description: "Static strings should be used as key/comment" +
|
|
" in NSLocalizedString in order for genstrings to work",
|
|
kind: .lint,
|
|
nonTriggeringExamples: [
|
|
Example("NSLocalizedString(\"key\", comment: \"\")"),
|
|
Example("NSLocalizedString(\"key\" + \"2\", comment: \"\")"),
|
|
Example("NSLocalizedString(\"key\", comment: \"comment\")"),
|
|
Example("""
|
|
NSLocalizedString("This is a multi-" +
|
|
"line string", comment: "")
|
|
"""),
|
|
Example("""
|
|
let format = NSLocalizedString("%@, %@.", comment: "Accessibility label for a post in the post list." +
|
|
" The parameters are the title, and date respectively." +
|
|
" For example, \"Let it Go, 1 hour ago.\"")
|
|
""")
|
|
],
|
|
triggeringExamples: [
|
|
Example("NSLocalizedString(↓method(), comment: \"\")"),
|
|
Example("NSLocalizedString(↓\"key_\\(param)\", comment: \"\")"),
|
|
Example("NSLocalizedString(\"key\", comment: ↓\"comment with \\(param)\")"),
|
|
Example("NSLocalizedString(↓\"key_\\(param)\", comment: ↓method())")
|
|
]
|
|
)
|
|
|
|
func makeVisitor(file: SwiftLintFile) -> ViolationsSyntaxVisitor {
|
|
Visitor(viewMode: .sourceAccurate)
|
|
}
|
|
}
|
|
|
|
private extension NSLocalizedStringKeyRule {
|
|
final class Visitor: ViolationsSyntaxVisitor {
|
|
override func visitPost(_ node: FunctionCallExprSyntax) {
|
|
guard node.calledExpression.as(IdentifierExprSyntax.self)?.identifier.text == "NSLocalizedString" else {
|
|
return
|
|
}
|
|
|
|
if let keyArgument = node.argumentList.first(where: { $0.label == nil })?.expression,
|
|
keyArgument.hasViolation {
|
|
violations.append(keyArgument.positionAfterSkippingLeadingTrivia)
|
|
}
|
|
|
|
if let commentArgument = node.argumentList.first(where: { $0.label?.text == "comment" })?.expression,
|
|
commentArgument.hasViolation {
|
|
violations.append(commentArgument.positionAfterSkippingLeadingTrivia)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension ExprSyntax {
|
|
var hasViolation: Bool {
|
|
if let strExpr = self.as(StringLiteralExprSyntax.self) {
|
|
return strExpr.segments.contains { segment in
|
|
!segment.is(StringSegmentSyntax.self)
|
|
}
|
|
}
|
|
|
|
if let sequenceExpr = self.as(SequenceExprSyntax.self) {
|
|
return sequenceExpr.elements.contains { expr in
|
|
if expr.is(BinaryOperatorExprSyntax.self) {
|
|
return false
|
|
}
|
|
|
|
return expr.hasViolation
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
}
|