Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5da15ca

Browse files
committed
Kotlin: Resugar !=
1 parent b4c3f57 commit 5da15ca

3 files changed

Lines changed: 93 additions & 77 deletions

File tree

java/kotlin-extractor/src/main/kotlin/KotlinExtractorExtension.kt

Lines changed: 74 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,32 +1396,66 @@ open class KotlinFileExtractor(
13961396
}
13971397
}
13981398

1399-
fun extractCall(c: IrCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int) {
1400-
fun isBuiltin(fName: String): Boolean {
1401-
val verbose = false
1402-
fun verboseln(s: String) { if(verbose) println(s) }
1403-
verboseln("Attempting builtin match for $fName")
1404-
val target = c.symbol.owner
1405-
if (target.name.asString() != fName) {
1406-
verboseln("No match as function name is ${target.name.asString()} not $fName")
1407-
return false
1399+
fun isBuiltinCall(c: IrCall, fName: String): Boolean {
1400+
val verbose = false
1401+
fun verboseln(s: String) { if(verbose) println(s) }
1402+
verboseln("Attempting builtin match for $fName")
1403+
val target = c.symbol.owner
1404+
if (target.name.asString() != fName) {
1405+
verboseln("No match as function name is ${target.name.asString()} not $fName")
1406+
return false
1407+
}
1408+
val extensionReceiverParameter = target.extensionReceiverParameter
1409+
// TODO: Are both branches of this `if` possible?:
1410+
val targetPkg = if (extensionReceiverParameter == null) target.parent
1411+
else (extensionReceiverParameter.type as? IrSimpleType)?.classifier?.owner
1412+
if (targetPkg !is IrPackageFragment) {
1413+
verboseln("No match as didn't find target package")
1414+
return false
1415+
}
1416+
if (targetPkg.fqName.asString() != "kotlin.internal.ir") {
1417+
verboseln("No match as package name is ${targetPkg.fqName.asString()}")
1418+
return false
1419+
}
1420+
verboseln("Match")
1421+
return true
1422+
}
1423+
1424+
fun binop(id: Label<out DbExpr>, c: IrCall, callable: Label<out DbCallable>) {
1425+
val locId = tw.getLocation(c)
1426+
tw.writeHasLocation(id, locId)
1427+
tw.writeCallableEnclosingExpr(id, callable)
1428+
1429+
val dr = c.dispatchReceiver
1430+
if(dr != null) {
1431+
logger.warnElement(Severity.ErrorSevere, "Unexpected dispatch receiver found", c)
1432+
}
1433+
if(c.valueArgumentsCount < 1) {
1434+
logger.warnElement(Severity.ErrorSevere, "No arguments found", c)
1435+
} else {
1436+
val lhs = c.getValueArgument(0)
1437+
if(lhs == null) {
1438+
logger.warnElement(Severity.ErrorSevere, "LHS null", c)
1439+
} else {
1440+
extractExpressionExpr(lhs, callable, id, 0)
14081441
}
1409-
val extensionReceiverParameter = target.extensionReceiverParameter
1410-
// TODO: Are both branches of this `if` possible?:
1411-
val targetPkg = if (extensionReceiverParameter == null) target.parent
1412-
else (extensionReceiverParameter.type as? IrSimpleType)?.classifier?.owner
1413-
if (targetPkg !is IrPackageFragment) {
1414-
verboseln("No match as didn't find target package")
1415-
return false
1442+
if(c.valueArgumentsCount < 2) {
1443+
logger.warnElement(Severity.ErrorSevere, "No RHS found", c)
1444+
} else {
1445+
val rhs = c.getValueArgument(1)
1446+
if(rhs == null) {
1447+
logger.warnElement(Severity.ErrorSevere, "RHS null", c)
1448+
} else {
1449+
extractExpressionExpr(rhs, callable, id, 1)
1450+
}
14161451
}
1417-
if (targetPkg.fqName.asString() != "kotlin.internal.ir") {
1418-
verboseln("No match as package name is ${targetPkg.fqName.asString()}")
1419-
return false
1452+
if(c.valueArgumentsCount > 2) {
1453+
logger.warnElement(Severity.ErrorSevere, "Extra arguments found", c)
14201454
}
1421-
verboseln("Match")
1422-
return true
14231455
}
1456+
}
14241457

1458+
fun extractCall(c: IrCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int) {
14251459
fun isFunction(pkgName: String, className: String, fName: String): Boolean {
14261460
val verbose = false
14271461
fun verboseln(s: String) { if(verbose) println(s) }
@@ -1432,6 +1466,7 @@ open class KotlinFileExtractor(
14321466
return false
14331467
}
14341468
val extensionReceiverParameter = target.extensionReceiverParameter
1469+
// TODO: Are both branches of this `if` possible?:
14351470
val targetClass = if (extensionReceiverParameter == null) target.parent
14361471
else (extensionReceiverParameter.type as? IrSimpleType)?.classifier?.owner
14371472
if (targetClass !is IrClass) {
@@ -1481,40 +1516,7 @@ open class KotlinFileExtractor(
14811516
}
14821517
}
14831518

1484-
fun binop(id: Label<out DbExpr>) {
1485-
val locId = tw.getLocation(c)
1486-
tw.writeHasLocation(id, locId)
1487-
tw.writeCallableEnclosingExpr(id, callable)
1488-
1489-
val dr = c.dispatchReceiver
1490-
if(dr != null) {
1491-
logger.warnElement(Severity.ErrorSevere, "Unexpected dispatch receiver found", c)
1492-
}
1493-
if(c.valueArgumentsCount < 1) {
1494-
logger.warnElement(Severity.ErrorSevere, "No arguments found", c)
1495-
} else {
1496-
val lhs = c.getValueArgument(0)
1497-
if(lhs == null) {
1498-
logger.warnElement(Severity.ErrorSevere, "LHS null", c)
1499-
} else {
1500-
extractExpressionExpr(lhs, callable, id, 0)
1501-
}
1502-
if(c.valueArgumentsCount < 2) {
1503-
logger.warnElement(Severity.ErrorSevere, "No RHS found", c)
1504-
} else {
1505-
val rhs = c.getValueArgument(1)
1506-
if(rhs == null) {
1507-
logger.warnElement(Severity.ErrorSevere, "RHS null", c)
1508-
} else {
1509-
extractExpressionExpr(rhs, callable, id, 1)
1510-
}
1511-
}
1512-
if(c.valueArgumentsCount > 2) {
1513-
logger.warnElement(Severity.ErrorSevere, "Extra arguments found", c)
1514-
}
1515-
}
1516-
}
1517-
1519+
val dr = c.dispatchReceiver
15181520
when {
15191521
c.origin == PLUS &&
15201522
(isFunction("kotlin", "Int", "plus") || isFunction("kotlin", "String", "plus")) -> {
@@ -1541,62 +1543,58 @@ open class KotlinFileExtractor(
15411543
tw.writeExprs_remexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
15421544
binopDisp(id)
15431545
}
1546+
// != gets desugared into not and ==. Here we resugar it.
1547+
c.origin == EXCLEQ && isFunction("kotlin", "Boolean", "not") && c.valueArgumentsCount == 0 && dr != null && dr is IrCall && isBuiltinCall(dr, "EQEQ") -> {
1548+
val id = tw.getFreshIdLabel<DbNeexpr>()
1549+
val type = useType(c.type)
1550+
tw.writeExprs_neexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
1551+
binop(id, dr, callable)
1552+
}
15441553
// compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt
1545-
isBuiltin("EQEQ") -> {
1554+
isBuiltinCall(c, "EQEQ") -> {
15461555
if(c.origin != EQEQ) {
15471556
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for EQEQ: ${c.origin}", c)
15481557
}
15491558
val id = tw.getFreshIdLabel<DbEqexpr>()
15501559
val type = useType(c.type)
15511560
tw.writeExprs_eqexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
1552-
binop(id)
1561+
binop(id, c, callable)
15531562
}
1554-
/*
1555-
TODO
1556-
c.origin == EXCLEQ -> {
1557-
val id = tw.getFreshIdLabel<DbNeexpr>()
1558-
val type = useType(c.type)
1559-
val locId = tw.getLocation(c)
1560-
tw.writeExprs_neexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
1561-
tw.writeHasLocation(id, locId)
1562-
tw.writeCallableEnclosingExpr(id, callable)
1563-
}
1564-
*/
1565-
isBuiltin("less") -> {
1563+
isBuiltinCall(c, "less") -> {
15661564
if(c.origin != LT) {
15671565
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for LT: ${c.origin}", c)
15681566
}
15691567
val id = tw.getFreshIdLabel<DbLtexpr>()
15701568
val type = useType(c.type)
15711569
tw.writeExprs_ltexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
1572-
binop(id)
1570+
binop(id, c, callable)
15731571
}
1574-
isBuiltin("lessOrEqual") -> {
1572+
isBuiltinCall(c, "lessOrEqual") -> {
15751573
if(c.origin != LTEQ) {
15761574
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for LTEQ: ${c.origin}", c)
15771575
}
15781576
val id = tw.getFreshIdLabel<DbLeexpr>()
15791577
val type = useType(c.type)
15801578
tw.writeExprs_leexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
1581-
binop(id)
1579+
binop(id, c, callable)
15821580
}
1583-
isBuiltin("greater") -> {
1581+
isBuiltinCall(c, "greater") -> {
15841582
if(c.origin != GT) {
15851583
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for GT: ${c.origin}", c)
15861584
}
15871585
val id = tw.getFreshIdLabel<DbGtexpr>()
15881586
val type = useType(c.type)
15891587
tw.writeExprs_gtexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
1590-
binop(id)
1588+
binop(id, c, callable)
15911589
}
1592-
isBuiltin("greaterOrEqual") -> {
1590+
isBuiltinCall(c, "greaterOrEqual") -> {
15931591
if(c.origin != GTEQ) {
15941592
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for GTEQ: ${c.origin}", c)
15951593
}
15961594
val id = tw.getFreshIdLabel<DbGeexpr>()
15971595
val type = useType(c.type)
15981596
tw.writeExprs_geexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
1599-
binop(id)
1597+
binop(id, c, callable)
16001598
}
16011599
else -> {
16021600
val id = tw.getFreshIdLabel<DbMethodaccess>()
@@ -1611,7 +1609,6 @@ TODO
16111609
// type arguments at index -2, -3, ...
16121610
extractTypeArguments(c, id, callable, -2, true)
16131611

1614-
val dr = c.dispatchReceiver
16151612
if(dr != null) {
16161613
extractExpressionExpr(dr, callable, id, -1)
16171614
}

java/ql/test/kotlin/library-tests/exprs/binop.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
| exprs.kt:8:14:8:18 | ... / ... | exprs.kt:8:14:8:14 | x | exprs.kt:8:18:8:18 | y |
44
| exprs.kt:9:14:9:18 | ... % ... | exprs.kt:9:14:9:14 | x | exprs.kt:9:18:9:18 | y |
55
| exprs.kt:20:15:20:20 | ... == ... | exprs.kt:20:15:20:15 | x | exprs.kt:20:20:20:20 | y |
6+
| exprs.kt:21:15:21:20 | ... != ... | exprs.kt:21:15:21:15 | x | exprs.kt:21:20:21:20 | y |
67
| exprs.kt:22:15:22:19 | ... < ... | exprs.kt:22:15:22:15 | x | exprs.kt:22:19:22:19 | y |
78
| exprs.kt:23:15:23:20 | ... <= ... | exprs.kt:23:15:23:15 | x | exprs.kt:23:20:23:20 | y |
89
| exprs.kt:24:15:24:19 | ... > ... | exprs.kt:24:15:24:15 | x | exprs.kt:24:19:24:19 | y |
910
| exprs.kt:25:15:25:20 | ... >= ... | exprs.kt:25:15:25:15 | x | exprs.kt:25:20:25:20 | y |
1011
| exprs.kt:50:16:50:26 | ... + ... | exprs.kt:50:16:50:19 | str1 | exprs.kt:50:23:50:26 | str2 |
1112
| exprs.kt:53:12:53:23 | ... > ... | exprs.kt:53:12:53:19 | variable | exprs.kt:53:23:53:23 | 0 |
1213
| exprs.kt:57:12:57:20 | ... + ... | exprs.kt:57:12:57:14 | 123 | exprs.kt:57:18:57:20 | 456 |
14+
| exprs.kt:83:8:83:16 | ... != ... | exprs.kt:83:8:83:8 | r | exprs.kt:83:13:83:16 | null |

java/ql/test/kotlin/library-tests/exprs/exprs.expected

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
| exprs.kt:20:15:20:15 | x | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
2121
| exprs.kt:20:15:20:20 | ... == ... | exprs.kt:4:1:58:1 | topLevelMethod | EQExpr |
2222
| exprs.kt:20:20:20:20 | y | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
23+
| exprs.kt:21:5:21:20 | i14 | exprs.kt:4:1:58:1 | topLevelMethod | LocalVariableDeclExpr |
24+
| exprs.kt:21:15:21:15 | x | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
25+
| exprs.kt:21:15:21:20 | ... != ... | exprs.kt:4:1:58:1 | topLevelMethod | NEExpr |
26+
| exprs.kt:21:20:21:20 | y | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
2327
| exprs.kt:22:5:22:19 | i15 | exprs.kt:4:1:58:1 | topLevelMethod | LocalVariableDeclExpr |
2428
| exprs.kt:22:15:22:15 | x | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
2529
| exprs.kt:22:15:22:19 | ... < ... | exprs.kt:4:1:58:1 | topLevelMethod | LTExpr |
@@ -137,6 +141,18 @@
137141
| exprs.kt:82:5:82:25 | r | exprs.kt:81:1:88:1 | foo | LocalVariableDeclExpr |
138142
| exprs.kt:82:13:82:13 | p | exprs.kt:81:1:88:1 | foo | VarAccess |
139143
| exprs.kt:82:15:82:25 | getBounds(...) | exprs.kt:81:1:88:1 | foo | MethodAccess |
144+
| exprs.kt:83:5:87:5 | when ... | exprs.kt:81:1:88:1 | foo | WhenExpr |
145+
| exprs.kt:83:8:83:8 | r | exprs.kt:81:1:88:1 | foo | VarAccess |
146+
| exprs.kt:83:8:83:16 | ... != ... | exprs.kt:81:1:88:1 | foo | NEExpr |
147+
| exprs.kt:83:13:83:16 | null | exprs.kt:81:1:88:1 | foo | NullLiteral |
148+
| exprs.kt:84:9:84:29 | r2 | exprs.kt:81:1:88:1 | foo | LocalVariableDeclExpr |
149+
| exprs.kt:84:29:84:29 | (...)... | exprs.kt:81:1:88:1 | foo | CastExpr |
150+
| exprs.kt:84:29:84:29 | Rectangle | exprs.kt:81:1:88:1 | foo | TypeAccess |
151+
| exprs.kt:84:29:84:29 | r | exprs.kt:81:1:88:1 | foo | VarAccess |
152+
| exprs.kt:85:9:85:30 | height | exprs.kt:81:1:88:1 | foo | LocalVariableDeclExpr |
153+
| exprs.kt:85:25:85:30 | height | exprs.kt:81:1:88:1 | foo | VarAccess |
154+
| exprs.kt:86:9:86:17 | ...=... | exprs.kt:81:1:88:1 | foo | AssignExpr |
155+
| exprs.kt:86:21:86:21 | 3 | exprs.kt:81:1:88:1 | foo | IntegerLiteral |
140156
| exprs.kt:90:1:92:1 | <obinit>(...) | exprs.kt:90:6:92:1 | Direction | MethodAccess |
141157
| exprs.kt:90:1:92:1 | new Enum(...) | exprs.kt:90:6:92:1 | Direction | ClassInstanceExpr |
142158
| exprs.kt:94:1:98:1 | <obinit>(...) | exprs.kt:94:6:98:1 | Color | MethodAccess |
@@ -151,6 +167,7 @@
151167
| exprs.kt:102:23:102:27 | GREEN | exprs.kt:100:1:103:1 | enums | VarAccess |
152168
| file://:0:0:0:0 | Color | exprs.kt:94:6:98:1 | Color | TypeAccess |
153169
| file://:0:0:0:0 | Direction | exprs.kt:90:6:92:1 | Direction | TypeAccess |
170+
| file://:0:0:0:0 | height | exprs.kt:81:1:88:1 | foo | VarAccess |
154171
| file://:0:0:0:0 | q | exprs.kt:72:1:79:1 | typeTests | VarAccess |
155172
| file://:0:0:0:0 | q | exprs.kt:72:1:79:1 | typeTests | VarAccess |
156173
| file://:0:0:0:0 | tmp0 | exprs.kt:4:1:58:1 | topLevelMethod | LocalVariableDeclExpr |

0 commit comments

Comments
 (0)