SwiftLint icon indicating copy to clipboard operation
SwiftLint copied to clipboard

Fix: optional_data_string_conversion should detect String.init and leading-dot .init usages

Open nadeemnali opened this issue 1 month ago • 1 comments

Summary

The optional_data_string_conversion SwiftSyntax rule only detected direct calls like:

String(decoding: data, as: UTF8.self)

but it missed two common variants:

  • Type-qualified initializer: String.init(decoding: data, as: UTF8.self)
  • Leading dot initializer used with an explicit type annotation: let text: String = .init(decoding: data, as: UTF8.self)

This change updates the rule to detect both String.init(...) and leading-dot .init(...) when the contextual type is String. It also adds examples to the rule description and a unit test that verifies the rule's description examples.

Changes

  • Update OptionalDataStringConversionRule visitor to:
    • keep existing detection for direct String(...) calls,
    • detect String.init(...) (MemberAccessExpr with base String and member init),
    • detect leading-dot .init(...) when assigned to a variable with an explicit String type annotation.
  • Add a test file which runs the rule's description examples.

Why

This fixes the bug reported where let text: String = .init(decoding: data, as: UTF8.self) did not produce the expected lint violation.

Test plan

  • Unit test included: Tests/SwiftLintBuiltInRulesTests/OptionalDataStringConversionRuleTests.swift
  • The test verifies the rule's nonTriggering and triggering examples contained in the RuleDescription.

nadeemnali avatar Dec 09 '25 21:12 nadeemnali

1 Warning
:warning: This PR may need tests.
19 Messages
:book: Building this branch resulted in a binary size of 26850.93 KiB vs 26850.74 KiB when built on main (0% larger).
:book: Linting Aerial with this PR took 0.18 s vs 0.2 s on main (10% faster).
:book: Linting Alamofire with this PR took 0.21 s vs 0.2 s on main (4% slower).
:book: Linting Brave with this PR took 0.81 s vs 0.83 s on main (2% faster).
:book: Linting DuckDuckGo with this PR took 3.03 s vs 3.02 s on main (0% slower).
:book: Linting Firefox with this PR took 1.47 s vs 1.5 s on main (2% faster).
:book: Linting Kickstarter with this PR took 0.89 s vs 0.89 s on main (0% slower).
:book: Linting Moya with this PR took 0.12 s vs 0.15 s on main (20% faster).
:book: Linting NetNewsWire with this PR took 0.31 s vs 0.32 s on main (3% faster).
:book: Linting Nimble with this PR took 0.16 s vs 0.16 s on main (0% slower).
:book: Linting PocketCasts with this PR took 0.88 s vs 0.87 s on main (1% slower).
:book: Linting Quick with this PR took 0.16 s vs 0.12 s on main (33% slower).
:book: Linting Realm with this PR took 0.46 s vs 0.43 s on main (6% slower).
:book: Linting Sourcery with this PR took 0.29 s vs 0.33 s on main (12% faster).
:book: Linting Swift with this PR took 0.45 s vs 0.48 s on main (6% faster).
:book: Linting SwiftLintPerformanceTests with this PR took 3.81 s vs 3.83 s on main (0% faster).
:book: Linting VLC with this PR took 0.23 s vs 0.26 s on main (11% faster).
:book: Linting Wire with this PR took 2.0 s vs 2.0 s on main (0% slower).
:book: Linting WordPress with this PR took 1.31 s vs 1.31 s on main (0% slower).

Generated by :no_entry_sign: Danger

SwiftLintBot avatar Dec 09 '25 21:12 SwiftLintBot