Add include_variables option to non_optional_string_data_conversion rule (#6172)

Co-authored-by: Danny Mösch <danny.moesch@icloud.com>
This commit is contained in:
Copilot
2025-08-02 17:49:58 -04:00
committed by GitHub
parent 7395ead738
commit 8bb69b064a
4 changed files with 43 additions and 6 deletions
+6
View File
@@ -22,6 +22,12 @@
### Enhancements
* Add `include_variables` configuration option to `non_optional_string_data_conversion` rule.
When enabled, the rule will trigger on variables, properties, and function calls in addition
to string literals. Defaults to `false` for backward compatibility.
[SimplyDanny](https://github.com/SimplyDanny)
[#6094](https://github.com/realm/SwiftLint/issues/6094)
* Add Sendable conformance to Rule.Type for building with Swift 6.
[erikkerber](https://github.com/erikkerber)
[#issue_number](https://github.com/realm/SwiftLint/issues/issue_number)
@@ -1,18 +1,35 @@
import SwiftLintCore
import SwiftSyntax
@SwiftSyntaxRule
struct NonOptionalStringDataConversionRule: Rule {
var configuration = SeverityConfiguration<Self>(.warning)
var configuration = NonOptionalStringDataConversionConfiguration()
private static let variablesIncluded = ["include_variables": true]
static let description = RuleDescription(
identifier: "non_optional_string_data_conversion",
name: "Non-optional String -> Data Conversion",
description: "Prefer non-optional `Data(_:)` initializer when converting `String` to `Data`",
kind: .lint,
nonTriggeringExamples: [
Example("Data(\"foo\".utf8)")
Example("Data(\"foo\".utf8)"),
Example("Data(string.utf8)"),
Example("\"foo\".data(using: .ascii)"),
Example("string.data(using: .unicode)"),
Example("Data(\"foo\".utf8)", configuration: variablesIncluded),
Example("Data(string.utf8)", configuration: variablesIncluded),
Example("\"foo\".data(using: .ascii)", configuration: variablesIncluded),
Example("string.data(using: .unicode)", configuration: variablesIncluded),
],
triggeringExamples: [
Example("\"foo\".data(using: .utf8)")
Example("\"foo\".data(using: .utf8)"),
Example("\"foo\".data(using: .utf8)", configuration: variablesIncluded),
Example("↓string.data(using: .utf8)", configuration: variablesIncluded),
Example("↓property.data(using: .utf8)", configuration: variablesIncluded),
Example("↓obj.property.data(using: .utf8)", configuration: variablesIncluded),
Example("↓getString().data(using: .utf8)", configuration: variablesIncluded),
Example("↓getValue()?.data(using: .utf8)", configuration: variablesIncluded),
]
)
}
@@ -20,12 +37,13 @@ struct NonOptionalStringDataConversionRule: Rule {
private extension NonOptionalStringDataConversionRule {
final class Visitor: ViolationsSyntaxVisitor<ConfigurationType> {
override func visitPost(_ node: MemberAccessExprSyntax) {
if node.base?.is(StringLiteralExprSyntax.self) == true,
node.declName.baseName.text == "data",
if node.declName.baseName.text == "data",
let parent = node.parent?.as(FunctionCallExprSyntax.self),
let argument = parent.arguments.onlyElement,
argument.label?.text == "using",
argument.expression.as(MemberAccessExprSyntax.self)?.isUTF8 == true {
argument.expression.as(MemberAccessExprSyntax.self)?.isUTF8 == true,
let base = node.base,
base.is(StringLiteralExprSyntax.self) || configuration.includeVariables {
violations.append(node.positionAfterSkippingLeadingTrivia)
}
}
@@ -0,0 +1,12 @@
import SwiftLintCore
@AutoConfigParser
struct NonOptionalStringDataConversionConfiguration: SeverityBasedRuleConfiguration {
// swiftlint:disable:previous type_name
typealias Parent = NonOptionalStringDataConversionRule
@ConfigurationElement(key: "severity")
private(set) var severityConfiguration = SeverityConfiguration<Parent>(.warning)
@ConfigurationElement(key: "include_variables")
private(set) var includeVariables = false
}
@@ -737,6 +737,7 @@ no_space_in_method_call:
correctable: true
non_optional_string_data_conversion:
severity: warning
include_variables: false
meta:
opt-in: false
correctable: false