From d412f661eb363340da7c682997633a0fddd2729a Mon Sep 17 00:00:00 2001 From: Marharyta Nedzelska Date: Mon, 27 Jan 2025 23:33:29 +0100 Subject: [PATCH] SONARKT-423 Migrate DuplicateBranchCheck to kotlin-analysis-api --- .../kotlin/api/checks/ApiExtensions.kt | 11 +++--- .../kotlin/api/checks/ApiExtensionsKtTest.kt | 35 ------------------- .../kotlin/checks/DuplicateBranchCheck.kt | 11 +++--- 3 files changed, 11 insertions(+), 46 deletions(-) diff --git a/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/checks/ApiExtensions.kt b/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/checks/ApiExtensions.kt index 1ca7bcb4a..f356a4b2f 100644 --- a/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/checks/ApiExtensions.kt +++ b/sonar-kotlin-api/src/main/java/org/sonarsource/kotlin/api/checks/ApiExtensions.kt @@ -877,12 +877,15 @@ fun DeclarationDescriptor?.determineType(): KotlinType? = else -> null } -fun KtQualifiedExpression?.determineSignature(bindingContext: BindingContext): DeclarationDescriptor? = - when (val selectorExpr = this?.selectorExpression) { - is KtCallExpression -> bindingContext[BindingContext.REFERENCE_TARGET, selectorExpr.getCallNameExpression()] - is KtSimpleNameExpression -> bindingContext[BindingContext.REFERENCE_TARGET, selectorExpr] +fun KtQualifiedExpression?.determineSignature(): KaSymbol? = withKaSession { + when (val selectorExpr = this@determineSignature?.selectorExpression) { + is KtCallExpression -> + selectorExpr.getCallNameExpression()?.mainReference?.resolveToSymbol() + is KtSimpleNameExpression -> + selectorExpr.mainReference.resolveToSymbol() else -> null } +} fun KtAnnotationEntry.annotatedElement(): KtAnnotated { var annotated = parent diff --git a/sonar-kotlin-api/src/test/java/org/sonarsource/kotlin/api/checks/ApiExtensionsKtTest.kt b/sonar-kotlin-api/src/test/java/org/sonarsource/kotlin/api/checks/ApiExtensionsKtTest.kt index 0ff17f270..d059d0b9b 100644 --- a/sonar-kotlin-api/src/test/java/org/sonarsource/kotlin/api/checks/ApiExtensionsKtTest.kt +++ b/sonar-kotlin-api/src/test/java/org/sonarsource/kotlin/api/checks/ApiExtensionsKtTest.kt @@ -512,41 +512,6 @@ private class ApiExtensionsKtDetermineTypeTest : AbstractApiExtensionsKtTest() { } } -private class ApiExtensionsKtDetermineSignatureTest : AbstractApiExtensionsKtTest() { - private val bindingContext: BindingContext - private val ktFile: KtFile - - init { - val kotlinTree = parse( - """ - package bar - - class Foo { - val prop: Int = 0 - - fun aFun(param: Float): Long { - this.prop - } - } - """.trimIndent() - ) - bindingContext = kotlinTree.bindingContext - ktFile = kotlinTree.psiFile - } - - @Test - fun `determineSignature of KtQualifiedExpression`() { - val expr = ktFile.findDescendantOfType { it.text == "this.prop" }!! - - assertThat(expr.determineSignature(bindingContext)?.fqNameOrNull()?.asString()).isEqualTo("bar.Foo.prop") - } - - @Test - fun `determineSignature of a null KtQualifiedExpression`() { - assertThat(null.determineSignature(bindingContext)).isNull() - } -} - private class ApiExtensionsScopeFunctionResolutionTest : AbstractApiExtensionsKtTest() { private fun generateAst(funContent: String) = """ package bar diff --git a/sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/DuplicateBranchCheck.kt b/sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/DuplicateBranchCheck.kt index fc0b3a73d..fa172b93b 100644 --- a/sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/DuplicateBranchCheck.kt +++ b/sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/DuplicateBranchCheck.kt @@ -19,14 +19,12 @@ package org.sonarsource.kotlin.checks import org.jetbrains.kotlin.psi.KtBlockExpression import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtQualifiedExpression -import org.jetbrains.kotlin.resolve.BindingContext import org.sonar.check.Rule import org.sonarsource.kotlin.api.checks.determineSignature import org.sonarsource.kotlin.api.reporting.SecondaryLocation import org.sonarsource.kotlin.api.reporting.KotlinTextRanges.textRange import org.sonarsource.kotlin.api.frontend.KotlinFileContext -@org.sonarsource.kotlin.api.frontend.K1only @Rule(key = "S1871") class DuplicateBranchCheck : AbstractBranchDuplication() { @@ -36,7 +34,7 @@ class DuplicateBranchCheck : AbstractBranchDuplication() { group.asSequence() .drop(1) .filter { spansMultipleLines(it, ctx) } - .filter { it !is KtQualifiedExpression || it.hasSameSignature(original as KtQualifiedExpression, ctx.bindingContext) } + .filter { it !is KtQualifiedExpression || it.hasSameSignature(original as KtQualifiedExpression) } .forEach { duplicated -> val originalRange = ctx.textRange(original) ctx.reportIssue( @@ -53,14 +51,13 @@ class DuplicateBranchCheck : AbstractBranchDuplication() { } } -private fun KtQualifiedExpression.hasSameSignature(other: KtQualifiedExpression, bindingContext: BindingContext): Boolean = - this.determineSignature(bindingContext) == other.determineSignature(bindingContext) - +private fun KtQualifiedExpression.hasSameSignature(other: KtQualifiedExpression): Boolean = + this@hasSameSignature.determineSignature() == other.determineSignature() private fun spansMultipleLines(tree: KtElement, ctx: KotlinFileContext): Boolean { if (tree is KtBlockExpression) { val statements = tree.statements - if (statements.isNullOrEmpty()) { + if (statements.isEmpty()) { return false } val firstStatement = statements[0]