From 45718c53b907d303c9d37f3a6d55232e387db7d0 Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Sun, 2 Feb 2025 23:20:17 +0100 Subject: [PATCH] Migrate WebViewJavaScriptSupportCheck to kotlin-analysis-api Co-authored-by: Marharyta Nedzelska Co-authored-by: Evgeny Mandrikov --- .../kotlin/api/checks/ApiExtensions.kt | 1 + .../checks/WebViewJavaScriptSupportCheck.kt | 20 +++++++++---------- 2 files changed, 11 insertions(+), 10 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 f356a4b2f..a7304ff60 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 @@ -780,6 +780,7 @@ fun KtExpression?.isLocalVariable(): Boolean = withKaSession { return mainReference.resolveToSymbol() is KaLocalVariableSymbol } +@Deprecated("use kotlin-analysis-api instead") fun KtExpression?.setterMatches(bindingContext: BindingContext, propertyName: String, matcher: FunMatcherImpl): Boolean = when (this) { is KtNameReferenceExpression -> (getReferencedName() == propertyName) && (matcher.matches((bindingContext[BindingContext.REFERENCE_TARGET, this] as? PropertyDescriptor)?.unwrappedSetMethod)) diff --git a/sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/WebViewJavaScriptSupportCheck.kt b/sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/WebViewJavaScriptSupportCheck.kt index a8b1ffca8..d1011bbf6 100644 --- a/sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/WebViewJavaScriptSupportCheck.kt +++ b/sonar-kotlin-checks/src/main/java/org/sonarsource/kotlin/checks/WebViewJavaScriptSupportCheck.kt @@ -16,44 +16,44 @@ */ package org.sonarsource.kotlin.checks +import org.jetbrains.kotlin.analysis.api.resolution.KaCallableMemberCall +import org.jetbrains.kotlin.analysis.api.resolution.KaFunctionCall +import org.jetbrains.kotlin.analysis.api.resolution.singleCallOrNull import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtExpression -import org.jetbrains.kotlin.psi.KtPsiUtil.deparenthesize -import org.jetbrains.kotlin.resolve.calls.util.getFirstArgumentExpression -import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.sonar.check.Rule import org.sonarsource.kotlin.api.checks.CallAbstractCheck import org.sonarsource.kotlin.api.checks.FunMatcher +import org.sonarsource.kotlin.api.checks.getFirstArgumentExpression import org.sonarsource.kotlin.api.checks.predictRuntimeBooleanValue -import org.sonarsource.kotlin.api.checks.setterMatches import org.sonarsource.kotlin.api.frontend.KotlinFileContext +import org.sonarsource.kotlin.api.visiting.withKaSession private const val MESSAGE = "Make sure that enabling JavaScript support is safe here." private val ANDROID_SET_JAVASCRIPT_ENABLED = FunMatcher(definingSupertype = "android.webkit.WebSettings", name = "setJavaScriptEnabled") { withArguments("kotlin.Boolean") } -@org.sonarsource.kotlin.api.frontend.K1only @Rule(key = "S6362") class WebViewJavaScriptSupportCheck : CallAbstractCheck() { override val functionsToVisit = listOf(ANDROID_SET_JAVASCRIPT_ENABLED) - override fun visitFunctionCall(callExpression: KtCallExpression, resolvedCall: ResolvedCall<*>, kotlinFileContext: KotlinFileContext) { + override fun visitFunctionCall(callExpression: KtCallExpression, resolvedCall: KaFunctionCall<*>, kotlinFileContext: KotlinFileContext) { checkJavaScriptEnabledArgument(kotlinFileContext, resolvedCall.getFirstArgumentExpression()) } - override fun visitBinaryExpression(expression: KtBinaryExpression, ctx: KotlinFileContext) { + override fun visitBinaryExpression(expression: KtBinaryExpression, ctx: KotlinFileContext) = withKaSession { if (expression.operationToken == KtTokens.EQ && - deparenthesize(expression.left).setterMatches(ctx.bindingContext, "javaScriptEnabled", ANDROID_SET_JAVASCRIPT_ENABLED) + ANDROID_SET_JAVASCRIPT_ENABLED.matches(expression.resolveToCall()?.singleCallOrNull>()) ) { checkJavaScriptEnabledArgument(ctx, expression.right) } } - private fun checkJavaScriptEnabledArgument(ctx: KotlinFileContext, argument: KtExpression?) { - if (argument?.predictRuntimeBooleanValue(ctx.bindingContext) == true) { + private fun checkJavaScriptEnabledArgument(ctx: KotlinFileContext, argument: KtExpression?) = withKaSession { + if (argument?.predictRuntimeBooleanValue() == true) { ctx.reportIssue(argument, MESSAGE) } }