@@ -256,13 +256,14 @@ private fun KaFunctionSymbol.hasName(
256
256
)
257
257
}
258
258
259
- private fun KaFunctionSymbol.isNumericWithName (functionName : String ): Boolean {
260
- return this .hasName(" kotlin" , " Int" , functionName) ||
261
- this .hasName(" kotlin" , " Byte" , functionName) ||
262
- this .hasName(" kotlin" , " Short" , functionName) ||
263
- this .hasName(" kotlin" , " Long" , functionName) ||
264
- this .hasName(" kotlin" , " Float" , functionName) ||
265
- this .hasName(" kotlin" , " Double" , functionName)
259
+ private fun KaFunctionSymbol?.isNumericWithName (functionName : String ): Boolean {
260
+ return this != null &&
261
+ (this .hasName(" kotlin" , " Int" , functionName) ||
262
+ this .hasName(" kotlin" , " Byte" , functionName) ||
263
+ this .hasName(" kotlin" , " Short" , functionName) ||
264
+ this .hasName(" kotlin" , " Long" , functionName) ||
265
+ this .hasName(" kotlin" , " Float" , functionName) ||
266
+ this .hasName(" kotlin" , " Double" , functionName))
266
267
}
267
268
268
269
context(KaSession )
@@ -297,37 +298,84 @@ private fun KotlinFileExtractor.extractBinaryExpression(
297
298
val op = expression.operationToken
298
299
val target = expression.resolveCallTarget()?.symbol
299
300
300
- when (op) {
301
- KtTokens .PLUS -> {
302
- if (target == null ) {
303
- TODO ()
304
- }
305
-
306
- if (target.isNumericWithName(" plus" ) ||
307
- target.hasName(" kotlin" , " String" , " plus" ) ||
308
- target.hasMatchingNames(
309
- CallableId (FqName (" kotlin" ), null , Name .identifier(" plus" )),
310
- ClassId (FqName (" kotlin" ), Name .identifier(" String" )),
311
- nullability = KaTypeNullability .NULLABLE ,
312
- )
313
- ) {
314
- val id = tw.getFreshIdLabel<DbAddexpr >()
315
- val type = useType(expression.expressionType)
316
- val exprParent = parent.expr(expression, callable)
317
- tw.writeExprs_addexpr(id, type.javaResult.id, exprParent.parent, exprParent.idx)
318
- tw.writeExprsKotlinType(id, type.kotlinResult.id)
319
-
320
- extractExprContext(id, tw.getLocation(expression), callable, exprParent.enclosingStmt)
321
- extractExpressionExpr(expression.left!! , callable, id, 0 , exprParent.enclosingStmt)
322
- extractExpressionExpr(expression.right!! , callable, id, 1 , exprParent.enclosingStmt)
323
- } else {
324
- TODO (" Extract as method call" )
301
+ if (op == KtTokens .PLUS && target.isBinaryPlus()) {
302
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_addexpr)
303
+ } else if (op == KtTokens .MINUS && target.isNumericWithName(" minus" )) {
304
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_subexpr)
305
+ } else if (op == KtTokens .MUL && target.isNumericWithName(" times" )) {
306
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_mulexpr)
307
+ } else if (op == KtTokens .DIV && target.isNumericWithName(" div" )) {
308
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_divexpr)
309
+ } else if (op == KtTokens .PERC && target.isNumericWithName(" rem" )) {
310
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_remexpr)
311
+ } else if (op == KtTokens .IDENTIFIER && target.isNumericWithName(" and" )) {
312
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_andbitexpr)
313
+ } else if (op == KtTokens .IDENTIFIER && target.isNumericWithName(" or" )) {
314
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_orbitexpr)
315
+ } else if (op == KtTokens .IDENTIFIER && target.isNumericWithName(" xor" )) {
316
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_xorbitexpr)
317
+ } else if (op == KtTokens .IDENTIFIER && target.isNumericWithName(" shl" )) {
318
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_lshiftexpr)
319
+ } else if (op == KtTokens .IDENTIFIER && target.isNumericWithName(" shr" )) {
320
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_rshiftexpr)
321
+ } else if (op == KtTokens .IDENTIFIER && target.isNumericWithName(" ushr" )) {
322
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_urshiftexpr)
323
+ } else if (op == KtTokens .EQEQEQ && target == null ) {
324
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_eqexpr)
325
+ } else if (op == KtTokens .EXCLEQEQEQ && target == null ) {
326
+ extractBinaryExpression(expression, callable, parent, tw::writeExprs_neexpr)
327
+ } else if (op in listOf (KtTokens .LT , KtTokens .GT , KtTokens .LTEQ , KtTokens .GTEQ )) {
328
+ if (target.isNumericWithName(" compareTo" )) {
329
+ when (op) {
330
+ KtTokens .LT -> extractBinaryExpression(expression, callable, parent, tw::writeExprs_ltexpr)
331
+ KtTokens .GT -> extractBinaryExpression(expression, callable, parent, tw::writeExprs_gtexpr)
332
+ KtTokens .LTEQ -> extractBinaryExpression(expression, callable, parent, tw::writeExprs_leexpr)
333
+ KtTokens .GTEQ -> extractBinaryExpression(expression, callable, parent, tw::writeExprs_geexpr)
334
+ else -> TODO (" error" )
325
335
}
336
+ } else {
337
+ TODO (" Extract lowered equivalent call, such as `a.compareTo(b) < 0`" )
326
338
}
327
339
328
- else -> TODO ()
340
+ } else {
341
+ // todo: other operators, such as .., ..<, in, !in, =, +=, -=, *=, /=, %=, ==, !=,
342
+ TODO (" Extract as method call" )
329
343
}
344
+ }
345
+
346
+ private fun KaFunctionSymbol?.isBinaryPlus (): Boolean {
347
+ return this != null && (
348
+ this .isNumericWithName(" plus" ) ||
349
+ this .hasName(" kotlin" , " String" , " plus" ) ||
350
+ /* The target for `(null as String?) + null` is `public operator fun String?.plus(other: Any?): String` */
351
+ this .hasMatchingNames(
352
+ CallableId (FqName (" kotlin" ), null , Name .identifier(" plus" )),
353
+ ClassId (FqName (" kotlin" ), Name .identifier(" String" )),
354
+ nullability = KaTypeNullability .NULLABLE ,
355
+ ))
356
+ }
330
357
358
+ context(KaSession )
359
+ private fun <T : DbBinaryexpr > KotlinFileExtractor.extractBinaryExpression (
360
+ expression : KtBinaryExpression ,
361
+ callable : Label <out DbCallable >,
362
+ parent : StmtExprParent ,
363
+ extractExpression : (
364
+ id: Label <out T >,
365
+ typeid: Label <out DbType >,
366
+ parent: Label <out DbExprparent >,
367
+ idx: Int
368
+ ) -> Unit
369
+ ) {
370
+ val id = tw.getFreshIdLabel<T >()
371
+ val type = useType(expression.expressionType)
372
+ val exprParent = parent.expr(expression, callable)
373
+ extractExpression(id, type.javaResult.id, exprParent.parent, exprParent.idx)
374
+ tw.writeExprsKotlinType(id, type.kotlinResult.id)
375
+
376
+ extractExprContext(id, tw.getLocation(expression), callable, exprParent.enclosingStmt)
377
+ extractExpressionExpr(expression.left!! , callable, id, 0 , exprParent.enclosingStmt)
378
+ extractExpressionExpr(expression.right!! , callable, id, 1 , exprParent.enclosingStmt)
331
379
}
332
380
333
381
context(KaSession )
0 commit comments