Skip to content

Commit

Permalink
Dont trigger for non-optional type casting, or for optional types (#5805
Browse files Browse the repository at this point in the history
)
  • Loading branch information
mildm8nnered authored Oct 11, 2024
1 parent 0a1ee18 commit 9ebd6ae
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 7 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@
[chipp](https://github.com/chipp)
[#5791](https://github.com/realm/SwiftLint/issues/5791)

* The `prefer_type_checking` rule will no longer trigger for non-optional
type casting (`as`), or for comparisons to optional types.
[Martin Redington](https://github.com/mildm8nnered)
[#5802](https://github.com/realm/SwiftLint/issues/5802)

## 0.57.0: Squeaky Clean Cycle

#### Breaking
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ struct PreferTypeCheckingRule: Rule {
foo.run()
}
"""),
Example("bar as Foo != nil"),
Example("nil != bar as Foo"),
Example("bar as Foo? != nil"),
Example("bar as? Foo? != nil"),
],
triggeringExamples: [
Example("bar ↓as? Foo != nil"),
Expand All @@ -33,9 +37,12 @@ struct PreferTypeCheckingRule: Rule {
doSomeThing()
}
"""),
Example("nil != bar ↓as? Foo"),
Example("nil != 2*x ↓as? X"),
],
corrections: [
Example("bar ↓as? Foo != nil"): Example("bar is Foo"),
Example("nil != bar ↓as? Foo"): Example("bar is Foo"),
Example("2*x ↓as? X != nil"): Example("2*x is X"),
Example("""
if foo ↓as? Bar != nil {
Expand All @@ -53,16 +60,15 @@ struct PreferTypeCheckingRule: Rule {
private extension PreferTypeCheckingRule {
final class Visitor: ViolationsSyntaxVisitor<ConfigurationType> {
override func visitPost(_ node: InfixOperatorExprSyntax) {
if node.typeChecksWithAsCasting, let asExpr = node.leftOperand.as(AsExprSyntax.self) {
if let asExpr = node.asExprWithOptionalTypeChecking {
violations.append(asExpr.asKeyword.positionAfterSkippingLeadingTrivia)
}
}
}

final class Rewriter: ViolationsSyntaxRewriter<ConfigurationType> {
override func visit(_ node: InfixOperatorExprSyntax) -> ExprSyntax {
guard node.typeChecksWithAsCasting,
let asExpr = node.leftOperand.as(AsExprSyntax.self) else {
guard let asExpr = node.asExprWithOptionalTypeChecking else {
return super.visit(node)
}

Expand All @@ -79,9 +85,15 @@ private extension PreferTypeCheckingRule {
}

private extension InfixOperatorExprSyntax {
var typeChecksWithAsCasting: Bool {
self.leftOperand.is(AsExprSyntax.self)
&& self.operator.as(BinaryOperatorExprSyntax.self)?.operator.tokenKind == .binaryOperator("!=")
&& self.rightOperand.is(NilLiteralExprSyntax.self)
var asExprWithOptionalTypeChecking: AsExprSyntax? {
if let asExpr = leftOperand.as(AsExprSyntax.self) ?? rightOperand.as(AsExprSyntax.self),
asExpr.questionOrExclamationMark?.tokenKind == .postfixQuestionMark,
!asExpr.type.is(OptionalTypeSyntax.self),
self.operator.as(BinaryOperatorExprSyntax.self)?.operator.tokenKind == .binaryOperator("!="),
rightOperand.is(NilLiteralExprSyntax.self) || leftOperand.is(NilLiteralExprSyntax.self) {
asExpr
} else {
nil
}
}
}

0 comments on commit 9ebd6ae

Please sign in to comment.