Kotlin: Resugar !=

This commit is contained in:
Ian Lynagh
2021-11-19 16:10:50 +00:00
parent b4c3f57bab
commit 5da15ca03b
3 changed files with 96 additions and 80 deletions

View File

@@ -1396,32 +1396,66 @@ open class KotlinFileExtractor(
}
}
fun extractCall(c: IrCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int) {
fun isBuiltin(fName: String): Boolean {
val verbose = false
fun verboseln(s: String) { if(verbose) println(s) }
verboseln("Attempting builtin match for $fName")
val target = c.symbol.owner
if (target.name.asString() != fName) {
verboseln("No match as function name is ${target.name.asString()} not $fName")
return false
}
val extensionReceiverParameter = target.extensionReceiverParameter
// TODO: Are both branches of this `if` possible?:
val targetPkg = if (extensionReceiverParameter == null) target.parent
else (extensionReceiverParameter.type as? IrSimpleType)?.classifier?.owner
if (targetPkg !is IrPackageFragment) {
verboseln("No match as didn't find target package")
return false
}
if (targetPkg.fqName.asString() != "kotlin.internal.ir") {
verboseln("No match as package name is ${targetPkg.fqName.asString()}")
return false
}
verboseln("Match")
return true
fun isBuiltinCall(c: IrCall, fName: String): Boolean {
val verbose = false
fun verboseln(s: String) { if(verbose) println(s) }
verboseln("Attempting builtin match for $fName")
val target = c.symbol.owner
if (target.name.asString() != fName) {
verboseln("No match as function name is ${target.name.asString()} not $fName")
return false
}
val extensionReceiverParameter = target.extensionReceiverParameter
// TODO: Are both branches of this `if` possible?:
val targetPkg = if (extensionReceiverParameter == null) target.parent
else (extensionReceiverParameter.type as? IrSimpleType)?.classifier?.owner
if (targetPkg !is IrPackageFragment) {
verboseln("No match as didn't find target package")
return false
}
if (targetPkg.fqName.asString() != "kotlin.internal.ir") {
verboseln("No match as package name is ${targetPkg.fqName.asString()}")
return false
}
verboseln("Match")
return true
}
fun binop(id: Label<out DbExpr>, c: IrCall, callable: Label<out DbCallable>) {
val locId = tw.getLocation(c)
tw.writeHasLocation(id, locId)
tw.writeCallableEnclosingExpr(id, callable)
val dr = c.dispatchReceiver
if(dr != null) {
logger.warnElement(Severity.ErrorSevere, "Unexpected dispatch receiver found", c)
}
if(c.valueArgumentsCount < 1) {
logger.warnElement(Severity.ErrorSevere, "No arguments found", c)
} else {
val lhs = c.getValueArgument(0)
if(lhs == null) {
logger.warnElement(Severity.ErrorSevere, "LHS null", c)
} else {
extractExpressionExpr(lhs, callable, id, 0)
}
if(c.valueArgumentsCount < 2) {
logger.warnElement(Severity.ErrorSevere, "No RHS found", c)
} else {
val rhs = c.getValueArgument(1)
if(rhs == null) {
logger.warnElement(Severity.ErrorSevere, "RHS null", c)
} else {
extractExpressionExpr(rhs, callable, id, 1)
}
}
if(c.valueArgumentsCount > 2) {
logger.warnElement(Severity.ErrorSevere, "Extra arguments found", c)
}
}
}
fun extractCall(c: IrCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int) {
fun isFunction(pkgName: String, className: String, fName: String): Boolean {
val verbose = false
fun verboseln(s: String) { if(verbose) println(s) }
@@ -1432,6 +1466,7 @@ open class KotlinFileExtractor(
return false
}
val extensionReceiverParameter = target.extensionReceiverParameter
// TODO: Are both branches of this `if` possible?:
val targetClass = if (extensionReceiverParameter == null) target.parent
else (extensionReceiverParameter.type as? IrSimpleType)?.classifier?.owner
if (targetClass !is IrClass) {
@@ -1481,40 +1516,7 @@ open class KotlinFileExtractor(
}
}
fun binop(id: Label<out DbExpr>) {
val locId = tw.getLocation(c)
tw.writeHasLocation(id, locId)
tw.writeCallableEnclosingExpr(id, callable)
val dr = c.dispatchReceiver
if(dr != null) {
logger.warnElement(Severity.ErrorSevere, "Unexpected dispatch receiver found", c)
}
if(c.valueArgumentsCount < 1) {
logger.warnElement(Severity.ErrorSevere, "No arguments found", c)
} else {
val lhs = c.getValueArgument(0)
if(lhs == null) {
logger.warnElement(Severity.ErrorSevere, "LHS null", c)
} else {
extractExpressionExpr(lhs, callable, id, 0)
}
if(c.valueArgumentsCount < 2) {
logger.warnElement(Severity.ErrorSevere, "No RHS found", c)
} else {
val rhs = c.getValueArgument(1)
if(rhs == null) {
logger.warnElement(Severity.ErrorSevere, "RHS null", c)
} else {
extractExpressionExpr(rhs, callable, id, 1)
}
}
if(c.valueArgumentsCount > 2) {
logger.warnElement(Severity.ErrorSevere, "Extra arguments found", c)
}
}
}
val dr = c.dispatchReceiver
when {
c.origin == PLUS &&
(isFunction("kotlin", "Int", "plus") || isFunction("kotlin", "String", "plus")) -> {
@@ -1541,62 +1543,58 @@ open class KotlinFileExtractor(
tw.writeExprs_remexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
binopDisp(id)
}
// != gets desugared into not and ==. Here we resugar it.
c.origin == EXCLEQ && isFunction("kotlin", "Boolean", "not") && c.valueArgumentsCount == 0 && dr != null && dr is IrCall && isBuiltinCall(dr, "EQEQ") -> {
val id = tw.getFreshIdLabel<DbNeexpr>()
val type = useType(c.type)
tw.writeExprs_neexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
binop(id, dr, callable)
}
// compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt
isBuiltin("EQEQ") -> {
isBuiltinCall(c, "EQEQ") -> {
if(c.origin != EQEQ) {
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for EQEQ: ${c.origin}", c)
}
val id = tw.getFreshIdLabel<DbEqexpr>()
val type = useType(c.type)
tw.writeExprs_eqexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
binop(id)
binop(id, c, callable)
}
/*
TODO
c.origin == EXCLEQ -> {
val id = tw.getFreshIdLabel<DbNeexpr>()
val type = useType(c.type)
val locId = tw.getLocation(c)
tw.writeExprs_neexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
tw.writeHasLocation(id, locId)
tw.writeCallableEnclosingExpr(id, callable)
}
*/
isBuiltin("less") -> {
isBuiltinCall(c, "less") -> {
if(c.origin != LT) {
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for LT: ${c.origin}", c)
}
val id = tw.getFreshIdLabel<DbLtexpr>()
val type = useType(c.type)
tw.writeExprs_ltexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
binop(id)
binop(id, c, callable)
}
isBuiltin("lessOrEqual") -> {
isBuiltinCall(c, "lessOrEqual") -> {
if(c.origin != LTEQ) {
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for LTEQ: ${c.origin}", c)
}
val id = tw.getFreshIdLabel<DbLeexpr>()
val type = useType(c.type)
tw.writeExprs_leexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
binop(id)
binop(id, c, callable)
}
isBuiltin("greater") -> {
isBuiltinCall(c, "greater") -> {
if(c.origin != GT) {
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for GT: ${c.origin}", c)
}
val id = tw.getFreshIdLabel<DbGtexpr>()
val type = useType(c.type)
tw.writeExprs_gtexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
binop(id)
binop(id, c, callable)
}
isBuiltin("greaterOrEqual") -> {
isBuiltinCall(c, "greaterOrEqual") -> {
if(c.origin != GTEQ) {
logger.warnElement(Severity.ErrorSevere, "Unexpected origin for GTEQ: ${c.origin}", c)
}
val id = tw.getFreshIdLabel<DbGeexpr>()
val type = useType(c.type)
tw.writeExprs_geexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
binop(id)
binop(id, c, callable)
}
else -> {
val id = tw.getFreshIdLabel<DbMethodaccess>()
@@ -1611,7 +1609,6 @@ TODO
// type arguments at index -2, -3, ...
extractTypeArguments(c, id, callable, -2, true)
val dr = c.dispatchReceiver
if(dr != null) {
extractExpressionExpr(dr, callable, id, -1)
}

View File

@@ -3,6 +3,7 @@
| exprs.kt:8:14:8:18 | ... / ... | exprs.kt:8:14:8:14 | x | exprs.kt:8:18:8:18 | y |
| exprs.kt:9:14:9:18 | ... % ... | exprs.kt:9:14:9:14 | x | exprs.kt:9:18:9:18 | y |
| exprs.kt:20:15:20:20 | ... == ... | exprs.kt:20:15:20:15 | x | exprs.kt:20:20:20:20 | y |
| exprs.kt:21:15:21:20 | ... != ... | exprs.kt:21:15:21:15 | x | exprs.kt:21:20:21:20 | y |
| exprs.kt:22:15:22:19 | ... < ... | exprs.kt:22:15:22:15 | x | exprs.kt:22:19:22:19 | y |
| exprs.kt:23:15:23:20 | ... <= ... | exprs.kt:23:15:23:15 | x | exprs.kt:23:20:23:20 | y |
| exprs.kt:24:15:24:19 | ... > ... | exprs.kt:24:15:24:15 | x | exprs.kt:24:19:24:19 | y |
@@ -10,3 +11,4 @@
| exprs.kt:50:16:50:26 | ... + ... | exprs.kt:50:16:50:19 | str1 | exprs.kt:50:23:50:26 | str2 |
| exprs.kt:53:12:53:23 | ... > ... | exprs.kt:53:12:53:19 | variable | exprs.kt:53:23:53:23 | 0 |
| exprs.kt:57:12:57:20 | ... + ... | exprs.kt:57:12:57:14 | 123 | exprs.kt:57:18:57:20 | 456 |
| exprs.kt:83:8:83:16 | ... != ... | exprs.kt:83:8:83:8 | r | exprs.kt:83:13:83:16 | null |

View File

@@ -20,6 +20,10 @@
| exprs.kt:20:15:20:15 | x | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
| exprs.kt:20:15:20:20 | ... == ... | exprs.kt:4:1:58:1 | topLevelMethod | EQExpr |
| exprs.kt:20:20:20:20 | y | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
| exprs.kt:21:5:21:20 | i14 | exprs.kt:4:1:58:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:21:15:21:15 | x | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
| exprs.kt:21:15:21:20 | ... != ... | exprs.kt:4:1:58:1 | topLevelMethod | NEExpr |
| exprs.kt:21:20:21:20 | y | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
| exprs.kt:22:5:22:19 | i15 | exprs.kt:4:1:58:1 | topLevelMethod | LocalVariableDeclExpr |
| exprs.kt:22:15:22:15 | x | exprs.kt:4:1:58:1 | topLevelMethod | VarAccess |
| exprs.kt:22:15:22:19 | ... < ... | exprs.kt:4:1:58:1 | topLevelMethod | LTExpr |
@@ -137,6 +141,18 @@
| exprs.kt:82:5:82:25 | r | exprs.kt:81:1:88:1 | foo | LocalVariableDeclExpr |
| exprs.kt:82:13:82:13 | p | exprs.kt:81:1:88:1 | foo | VarAccess |
| exprs.kt:82:15:82:25 | getBounds(...) | exprs.kt:81:1:88:1 | foo | MethodAccess |
| exprs.kt:83:5:87:5 | when ... | exprs.kt:81:1:88:1 | foo | WhenExpr |
| exprs.kt:83:8:83:8 | r | exprs.kt:81:1:88:1 | foo | VarAccess |
| exprs.kt:83:8:83:16 | ... != ... | exprs.kt:81:1:88:1 | foo | NEExpr |
| exprs.kt:83:13:83:16 | null | exprs.kt:81:1:88:1 | foo | NullLiteral |
| exprs.kt:84:9:84:29 | r2 | exprs.kt:81:1:88:1 | foo | LocalVariableDeclExpr |
| exprs.kt:84:29:84:29 | (...)... | exprs.kt:81:1:88:1 | foo | CastExpr |
| exprs.kt:84:29:84:29 | Rectangle | exprs.kt:81:1:88:1 | foo | TypeAccess |
| exprs.kt:84:29:84:29 | r | exprs.kt:81:1:88:1 | foo | VarAccess |
| exprs.kt:85:9:85:30 | height | exprs.kt:81:1:88:1 | foo | LocalVariableDeclExpr |
| exprs.kt:85:25:85:30 | height | exprs.kt:81:1:88:1 | foo | VarAccess |
| exprs.kt:86:9:86:17 | ...=... | exprs.kt:81:1:88:1 | foo | AssignExpr |
| exprs.kt:86:21:86:21 | 3 | exprs.kt:81:1:88:1 | foo | IntegerLiteral |
| exprs.kt:90:1:92:1 | <obinit>(...) | exprs.kt:90:6:92:1 | Direction | MethodAccess |
| exprs.kt:90:1:92:1 | new Enum(...) | exprs.kt:90:6:92:1 | Direction | ClassInstanceExpr |
| exprs.kt:94:1:98:1 | <obinit>(...) | exprs.kt:94:6:98:1 | Color | MethodAccess |
@@ -151,6 +167,7 @@
| exprs.kt:102:23:102:27 | GREEN | exprs.kt:100:1:103:1 | enums | VarAccess |
| file://:0:0:0:0 | Color | exprs.kt:94:6:98:1 | Color | TypeAccess |
| file://:0:0:0:0 | Direction | exprs.kt:90:6:92:1 | Direction | TypeAccess |
| file://:0:0:0:0 | height | exprs.kt:81:1:88:1 | foo | VarAccess |
| file://:0:0:0:0 | q | exprs.kt:72:1:79:1 | typeTests | VarAccess |
| file://:0:0:0:0 | q | exprs.kt:72:1:79:1 | typeTests | VarAccess |
| file://:0:0:0:0 | tmp0 | exprs.kt:4:1:58:1 | topLevelMethod | LocalVariableDeclExpr |