@@ -3,6 +3,10 @@ package com.github.codeql
3
3
import com.github.codeql.KotlinFileExtractor.StmtExprParent
4
4
import org.jetbrains.kotlin.KtNodeTypes
5
5
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
6
10
import org.jetbrains.kotlin.analysis.api.types.KaType
7
11
import org.jetbrains.kotlin.lexer.KtTokens
8
12
import org.jetbrains.kotlin.parsing.parseNumericLiteral
@@ -211,6 +215,78 @@ OLD: KE1
211
215
}
212
216
*/
213
217
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
+
214
290
context(KaSession )
215
291
private fun KotlinFileExtractor.extractExpression (
216
292
e : KtExpression ,
@@ -225,6 +301,10 @@ private fun KotlinFileExtractor.extractExpression(
225
301
extractExpression(e.baseExpression!! , callable, parent)
226
302
}
227
303
304
+ is KtBinaryExpression -> {
305
+ extractBinaryExpression(e, callable, parent)
306
+ }
307
+
228
308
is KtIsExpression -> {
229
309
230
310
val locId = tw.getLocation(e)
0 commit comments