From c10a0e549aebeb8d09cb7603c86c5fe5c479b05d Mon Sep 17 00:00:00 2001 From: Tamas Vajk Date: Tue, 29 Oct 2024 12:12:16 +0100 Subject: [PATCH] Handle named arguments in method call extraction --- .../src/main/kotlin/entities/Expression.kt | 6 ++-- .../src/main/kotlin/entities/MethodCall.kt | 30 ++++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt b/java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt index 1b2d4febe1b..2b730e00455 100644 --- a/java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt +++ b/java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt @@ -266,10 +266,10 @@ private fun KaFunctionSymbol.isNumericWithName(functionName: String): Boolean { } context(KaSession) -fun KtExpression.resolveCallTarget(): KaFunctionSymbol? { +fun KtExpression.resolveCallTarget(): KaSimpleFunctionCall? { val callInfo = this.resolveToCall() as? KaSuccessCallInfo val functionCall = callInfo?.call as? KaSimpleFunctionCall - return functionCall?.symbol + return functionCall } /** @@ -295,7 +295,7 @@ private fun KotlinFileExtractor.extractBinaryExpression( parent: StmtExprParent ) { val op = expression.operationToken - val target = expression.resolveCallTarget() + val target = expression.resolveCallTarget()?.symbol when (op) { KtTokens.PLUS -> { diff --git a/java/kotlin-extractor2/src/main/kotlin/entities/MethodCall.kt b/java/kotlin-extractor2/src/main/kotlin/entities/MethodCall.kt index ed0e0abe9cd..d276ba586f1 100644 --- a/java/kotlin-extractor2/src/main/kotlin/entities/MethodCall.kt +++ b/java/kotlin-extractor2/src/main/kotlin/entities/MethodCall.kt @@ -2,11 +2,13 @@ package com.github.codeql import com.github.codeql.KotlinFileExtractor.StmtExprParent import org.jetbrains.kotlin.analysis.api.KaSession +import org.jetbrains.kotlin.analysis.api.resolution.symbol import org.jetbrains.kotlin.analysis.api.symbols.KaFunctionSymbol import org.jetbrains.kotlin.analysis.api.types.KaType import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.KtExpression +import org.jetbrains.kotlin.utils.mapToIndex context(KaSession) fun KotlinFileExtractor.extractMethodCall( @@ -14,12 +16,32 @@ fun KotlinFileExtractor.extractMethodCall( enclosingCallable: Label, stmtExprParent: StmtExprParent ) { - val target = call.resolveCallTarget() + val callTarget = call.resolveCallTarget() + val target = callTarget?.symbol + val argMapping = callTarget?.argumentMapping - if (target == null) TODO() + if (target == null || argMapping == null) TODO() - // TODO: we need to make sure that the args are in the correct order. Named arguments can change the order - val args = call.valueArguments.map { it.argumentExpression } + val parameterIndexMap = target.valueParameters.mapToIndex() + + // TODO: we need to handle + // - arguments passed to vararg parameters, in which case there can be multiple (idx, expr) pairs with the same idx. + // - missing arguments due to default parameter values, in which case some indices are missing. + val args = call.valueArguments + .map { arg -> + val expr = arg.argumentExpression + val p = argMapping[expr] + if (p == null) { + TODO("This is unexpected, no parameter was found for the argument") + } + val idx = parameterIndexMap[p.symbol] + if (idx == null) { + TODO("This is unexpected, we couldn't find the parameter that the argument was mapped to") + } + Pair(idx, expr) + } + .sortedBy { p -> p.first } + .map { p -> p.second } // TODO: fix getting te qualifier, we should handle safe qualified expressions too val qualifier: KtExpression? = (call.parent as? KtDotQualifiedExpression)?.receiverExpression