Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SONARKT-540 Migrate ReasonableTypeCastsCheck to kotlin-analysis-api #558

Merged
merged 1 commit into from
Feb 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,25 @@ package checks

class ReasonableTypeCastsCheckSample {
fun noncompliant() {
val i: Int = 10
val i1: Int = 10
// Throws ClassCastException
val s1: String = i1 as String // Noncompliant {{Remove this cast that can never succeed.}}

val i2: Int = 10
// Throws ClassCastException
val s1a: String = i as String // Noncompliant {{Remove this cast that can never succeed.}}
val s1b = i as String // Noncompliant
val s2 = i2 as String // Noncompliant {{Remove this cast that can never succeed.}}

val i3: Int = 10
// Will always be null
val s2: String? = i as? String // Noncompliant
val s3: String? = i3 as? String // Noncompliant {{Remove this cast that can never succeed.}}

val list = listOf(1, 2, 3, 4)

// any operation with list elements will produce ClassCastException
val strings1 = list as List<String> // Noncompliant {{Remove this unchecked cast.}}

val list2 = listOf(1)
// any operation with list elements will produce ClassCastException
val strings2 = list as? List<String> // Noncompliant
val strings2 = list2 as? List<String> // Noncompliant {{Remove this unchecked cast.}}
}

fun compliant() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,18 @@ import org.sonar.check.Rule
import org.sonarsource.kotlin.api.checks.AbstractCheck
import org.sonarsource.kotlin.api.frontend.KotlinFileContext

@org.sonarsource.kotlin.api.frontend.K1only
@Rule(key = "S6530")
class ReasonableTypeCastsCheck : AbstractCheck() {
override fun visitKtFile(file: KtFile, context: KotlinFileContext) {
context.diagnostics
context.kaDiagnostics
.mapNotNull { diagnostic ->
when (diagnostic.factory) {
Errors.UNCHECKED_CAST -> "Remove this unchecked cast."
Errors.CAST_NEVER_SUCCEEDS -> "Remove this cast that can never succeed."
when (diagnostic.factoryName) {
Errors.UNCHECKED_CAST.name -> "Remove this unchecked cast."
Errors.CAST_NEVER_SUCCEEDS.name -> "Remove this cast that can never succeed."
else -> null
}?.let { diagnostic to it }
}.forEach { (diagnostic, msg) ->
context.reportIssue(diagnostic.psiElement, msg)
context.reportIssue(diagnostic.psi, msg)
}
}
}