Skip to content

Commit bc15f40

Browse files
authored
Merge pull request #17729 from tamasvajk/ke2-numeric-plus
KE2: Extract binary plus on numeric types
2 parents 643419a + ea68837 commit bc15f40

File tree

2 files changed

+80
-17
lines changed

2 files changed

+80
-17
lines changed

java/kotlin-extractor2/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3515,18 +3515,6 @@ OLD: KE1
35153515
isNullable: Boolean? = false
35163516
) = isFunction(target, pkgName, className, { it == className }, fName, isNullable)
35173517
3518-
private fun isNumericFunction(target: IrFunction, fName: String): Boolean {
3519-
return isFunction(target, "kotlin", "Int", fName) ||
3520-
isFunction(target, "kotlin", "Byte", fName) ||
3521-
isFunction(target, "kotlin", "Short", fName) ||
3522-
isFunction(target, "kotlin", "Long", fName) ||
3523-
isFunction(target, "kotlin", "Float", fName) ||
3524-
isFunction(target, "kotlin", "Double", fName)
3525-
}
3526-
3527-
private fun isNumericFunction(target: IrFunction, vararg fNames: String) =
3528-
fNames.any { isNumericFunction(target, it) }
3529-
35303518
private fun isArrayType(typeName: String) =
35313519
when (typeName) {
35323520
"Array" -> true
@@ -3747,11 +3735,6 @@ OLD: KE1
37473735
val type = useType(c.type)
37483736
val id: Label<out DbExpr> =
37493737
when (val targetName = target.name.asString()) {
3750-
"plus" -> {
3751-
val id = tw.getFreshIdLabel<DbAddexpr>()
3752-
tw.writeExprs_addexpr(id, type.javaResult.id, parent, idx)
3753-
id
3754-
}
37553738
"minus" -> {
37563739
val id = tw.getFreshIdLabel<DbSubexpr>()
37573740
tw.writeExprs_subexpr(id, type.javaResult.id, parent, idx)

java/kotlin-extractor2/src/main/kotlin/entities/Expression.kt

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ package com.github.codeql
33
import com.github.codeql.KotlinFileExtractor.StmtExprParent
44
import org.jetbrains.kotlin.KtNodeTypes
55
import org.jetbrains.kotlin.analysis.api.KaSession
6+
import org.jetbrains.kotlin.analysis.api.resolution.KaSimpleFunctionCall
7+
import org.jetbrains.kotlin.analysis.api.resolution.KaSuccessCallInfo
8+
import org.jetbrains.kotlin.analysis.api.resolution.symbol
9+
import org.jetbrains.kotlin.analysis.api.symbols.KaFunctionSymbol
610
import org.jetbrains.kotlin.analysis.api.types.KaType
711
import org.jetbrains.kotlin.lexer.KtTokens
812
import org.jetbrains.kotlin.parsing.parseNumericLiteral
@@ -211,6 +215,78 @@ OLD: KE1
211215
}
212216
*/
213217

218+
private fun isFunction(
219+
symbol: KaFunctionSymbol,
220+
packageName: String,
221+
className: String,
222+
functionName: String
223+
): Boolean {
224+
225+
return symbol.callableId?.packageName?.asString() == packageName &&
226+
symbol.callableId?.className?.asString() == className &&
227+
symbol.callableId?.callableName?.asString() == functionName
228+
}
229+
230+
private fun isNumericFunction(target: KaFunctionSymbol, fName: String): Boolean {
231+
return isFunction(target, "kotlin", "Int", fName) ||
232+
isFunction(target, "kotlin", "Byte", fName) ||
233+
isFunction(target, "kotlin", "Short", fName) ||
234+
isFunction(target, "kotlin", "Long", fName) ||
235+
isFunction(target, "kotlin", "Float", fName) ||
236+
isFunction(target, "kotlin", "Double", fName)
237+
}
238+
239+
/**
240+
* Extracts a binary expression as either a binary expression or a function call.
241+
*
242+
* Overloaded operators are extracted as function calls.
243+
*
244+
* ```
245+
* data class Counter(val dayIndex: Int) {
246+
* operator fun plus(increment: Int): Counter {
247+
* return Counter(dayIndex + increment)
248+
* }
249+
* }
250+
* ```
251+
*
252+
* `Counter(1) + 3` is extracted as `Counter(1).plus(3)`.
253+
*
254+
*/
255+
context(KaSession)
256+
private fun KotlinFileExtractor.extractBinaryExpression(
257+
expression: KtBinaryExpression,
258+
callable: Label<out DbCallable>,
259+
parent: StmtExprParent
260+
) {
261+
val op = expression.operationToken
262+
val target = ((expression.resolveToCall() as? KaSuccessCallInfo)?.call as? KaSimpleFunctionCall)?.symbol
263+
264+
when (op) {
265+
KtTokens.PLUS -> {
266+
if (target == null) {
267+
TODO()
268+
}
269+
270+
if (isNumericFunction(target, "plus")) {
271+
val id = tw.getFreshIdLabel<DbAddexpr>()
272+
val type = useType(expression.expressionType)
273+
val exprParent = parent.expr(expression, callable)
274+
tw.writeExprs_addexpr(id, type.javaResult.id, exprParent.parent, exprParent.idx)
275+
tw.writeExprsKotlinType(id, type.kotlinResult.id)
276+
277+
extractExprContext(id, tw.getLocation(expression), callable, exprParent.enclosingStmt)
278+
extractExpressionExpr(expression.left!!, callable, id, 0, exprParent.enclosingStmt)
279+
extractExpressionExpr(expression.right!!, callable, id, 1, exprParent.enclosingStmt)
280+
} else {
281+
TODO()
282+
}
283+
}
284+
285+
else -> TODO()
286+
}
287+
288+
}
289+
214290
context(KaSession)
215291
private fun KotlinFileExtractor.extractExpression(
216292
e: KtExpression,
@@ -225,6 +301,10 @@ private fun KotlinFileExtractor.extractExpression(
225301
extractExpression(e.baseExpression!!, callable, parent)
226302
}
227303

304+
is KtBinaryExpression -> {
305+
extractBinaryExpression(e, callable, parent)
306+
}
307+
228308
is KtIsExpression -> {
229309

230310
val locId = tw.getLocation(e)

0 commit comments

Comments
 (0)