Skip to content

Commit 9c27966

Browse files
fix(optional_data_string_conversion): match init shorthand
1 parent 63e0372 commit 9c27966

2 files changed

Lines changed: 34 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@
7272
`redundant_self` rule.
7373
[SimplyDanny](https://github.com/SimplyDanny)
7474
[#6553](https://github.com/realm/SwiftLint/issues/6553)
75+
76+
* Catch `String.init(decoding:as:)` and `.init(decoding:as:)` in
77+
`optional_data_string_conversion`, matching the existing
78+
`String(decoding:as:)` check.
79+
[theamodhshetty](https://github.com/theamodhshetty)
80+
[#6359](https://github.com/realm/SwiftLint/issues/6359)
7581

7682
* Respect existing environment variables when setting `BUILD_WORKSPACE_DIRECTORY`
7783
in build tool plugins.

Source/SwiftLintBuiltInRules/Rules/Lint/OptionalDataStringConversionRule.swift

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,42 @@ struct OptionalDataStringConversionRule: Rule {
1717
Example("String(decoding: data, encoding: UTF8.self)"),
1818
],
1919
triggeringExamples: [
20-
Example("String(decoding: data, as: UTF8.self)")
21-
]
20+
Example("String(decoding: data, as: UTF8.self)"),
21+
Example("String.init(decoding: data, as: UTF8.self)"),
22+
Example("let text: String = .init(decoding: data, as: UTF8.self)"),
23+
],
2224
)
2325
}
2426

2527
private extension OptionalDataStringConversionRule {
2628
final class Visitor: ViolationsSyntaxVisitor<ConfigurationType> {
27-
override func visitPost(_ node: DeclReferenceExprSyntax) {
28-
if node.baseName.text == "String",
29-
let parent = node.parent?.as(FunctionCallExprSyntax.self),
30-
parent.arguments.map(\.label?.text) == ["decoding", "as"],
31-
let expr = parent.arguments.last?.expression.as(MemberAccessExprSyntax.self),
29+
override func visitPost(_ node: FunctionCallExprSyntax) {
30+
if node.arguments.map(\.label?.text) == ["decoding", "as"],
31+
let expr = node.arguments.last?.expression.as(MemberAccessExprSyntax.self),
3232
expr.base?.description == "UTF8",
33-
expr.declName.baseName.description == "self" {
33+
expr.declName.baseName.description == "self",
34+
node.calledExpression.isOptionalDataStringInitializer {
3435
violations.append(node.positionAfterSkippingLeadingTrivia)
3536
}
3637
}
3738
}
3839
}
40+
41+
private extension ExprSyntax {
42+
var isOptionalDataStringInitializer: Bool {
43+
if let declReference = `as`(DeclReferenceExprSyntax.self) {
44+
return declReference.baseName.text == "String"
45+
}
46+
47+
guard let memberAccess = `as`(MemberAccessExprSyntax.self),
48+
memberAccess.declName.baseName.text == "init" else {
49+
return false
50+
}
51+
52+
if memberAccess.base == nil {
53+
return true
54+
}
55+
56+
return memberAccess.base?.as(DeclReferenceExprSyntax.self)?.baseName.text == "String"
57+
}
58+
}

0 commit comments

Comments
 (0)