Extract missing functions directly in kotlin package

This commit is contained in:
Tamas Vajk
2021-11-25 12:33:09 +01:00
committed by Ian Lynagh
parent 3a2f7bec1c
commit ea4e919af5
5 changed files with 129 additions and 25 deletions

View File

@@ -620,7 +620,7 @@ open class KotlinFileExtractor(
}
fun extractCall(c: IrCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
fun isFunction(pkgName: String, className: String, fName: String): Boolean {
fun isFunction(pkgName: String, className: String, fName: String, hasQuestionMark: Boolean = false): Boolean {
val verbose = false
fun verboseln(s: String) { if(verbose) println(s) }
verboseln("Attempting match for $pkgName $className $fName")
@@ -632,7 +632,14 @@ open class KotlinFileExtractor(
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
else {
val st = extensionReceiverParameter.type as? IrSimpleType
if (st?.hasQuestionMark != hasQuestionMark) {
verboseln("Nullablility of type didn't match")
return false
}
st?.classifier?.owner
}
if (targetClass !is IrClass) {
verboseln("No match as didn't find target class")
return false
@@ -663,6 +670,49 @@ open class KotlinFileExtractor(
isFunction("kotlin", "Double", fName)
}
fun extractMethodAccess(callTarget: IrFunction, extractTypeArguments: Boolean = true){
val id = tw.getFreshIdLabel<DbMethodaccess>()
val type = useType(c.type)
val locId = tw.getLocation(c)
val methodId = useFunction<DbMethod>(callTarget)
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
tw.writeHasLocation(id, locId)
tw.writeCallableEnclosingExpr(id, callable)
tw.writeCallableBinding(id, methodId)
tw.writeStatementEnclosingExpr(id, enclosingStmt)
if (extractTypeArguments) {
// type arguments at index -2, -3, ...
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
}
val dr = c.dispatchReceiver
if(dr != null) {
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
}
for(i in 0 until c.valueArgumentsCount) {
val arg = c.getValueArgument(i)
if(arg != null) {
extractExpressionExpr(arg, callable, id, i, enclosingStmt)
}
}
}
fun extractSpecialEnumFunction(fnName: String){
if (c.typeArgumentsCount != 1) {
logger.warnElement(Severity.ErrorSevere, "Expected to find exactly one type argument", c)
return
}
val func = ((c.getTypeArgument(0) as? IrSimpleType)?.classifier?.owner as? IrClass)?.declarations?.find { it is IrFunction && it.name.asString() == fnName }
if (func == null) {
logger.warnElement(Severity.ErrorSevere, "Couldn't find function $fnName on enum type", c)
return
}
extractMethodAccess(func as IrFunction, false)
}
fun binopDisp(id: Label<out DbExpr>) {
val locId = tw.getLocation(c)
tw.writeHasLocation(id, locId)
@@ -693,12 +743,24 @@ open class KotlinFileExtractor(
val dr = c.dispatchReceiver
when {
c.origin == IrStatementOrigin.PLUS &&
(isNumericFunction("plus") || isFunction("kotlin", "String", "plus")) -> {
(isNumericFunction("plus")
|| isFunction("kotlin", "String", "plus")
|| isFunction("kotlin", "String", "plus", true) // TODO: this is not correct. `a + b` becomes `(a?:"\"null\"") + (b?:"\"null\"")`.
) -> {
val id = tw.getFreshIdLabel<DbAddexpr>()
val type = useType(c.type)
tw.writeExprs_addexpr(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
binopDisp(id)
}
isFunction("kotlin", "String", "plus", true) -> {
// TODO: this is not correct. `a + b` becomes `(a?:"\"null\"") + (b?:"\"null\"")`.
val func = pluginContext.irBuiltIns.stringType.classOrNull?.owner?.declarations?.find { it is IrFunction && it.name.asString() == "plus" }
if (func == null) {
logger.warnElement(Severity.ErrorSevere, "Couldn't find plus function on string type", c)
return
}
extractMethodAccess(func as IrFunction)
}
c.origin == IrStatementOrigin.MINUS && isNumericFunction("minus") -> {
val id = tw.getFreshIdLabel<DbSubexpr>()
val type = useType(c.type)
@@ -840,6 +902,21 @@ open class KotlinFileExtractor(
// TODO
logger.warnElement(Severity.ErrorSevere, "Unhandled builtin", c)
}
isFunction("kotlin", "Any", "toString", true) -> {
// TODO: this is not correct. `a.toString()` becomes `(a?:"\"null\"").toString()`
val func = pluginContext.irBuiltIns.anyType.classOrNull?.owner?.declarations?.find { it is IrFunction && it.name.asString() == "toString" }
if (func == null) {
logger.warnElement(Severity.ErrorSevere, "Couldn't find toString function", c)
return
}
extractMethodAccess(func as IrFunction)
}
isBuiltinCallKotlin(c, "enumValues") -> {
extractSpecialEnumFunction("values")
}
isBuiltinCallKotlin(c, "enumValueOf") -> {
extractSpecialEnumFunction("valueOf")
}
isBuiltinCallKotlin(c, "arrayOfNulls") -> {
val id = tw.getFreshIdLabel<DbArraycreationexpr>()
val type = useType(c.type)
@@ -922,28 +999,7 @@ open class KotlinFileExtractor(
}
}
else -> {
val id = tw.getFreshIdLabel<DbMethodaccess>()
val type = useType(c.type)
val locId = tw.getLocation(c)
val methodId = useFunction<DbMethod>(c.symbol.owner)
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, parent, idx)
tw.writeHasLocation(id, locId)
tw.writeCallableEnclosingExpr(id, callable)
tw.writeCallableBinding(id, methodId)
tw.writeStatementEnclosingExpr(id, enclosingStmt)
// type arguments at index -2, -3, ...
extractTypeArguments(c, id, callable, enclosingStmt, -2, true)
if(dr != null) {
extractExpressionExpr(dr, callable, id, -1, enclosingStmt)
}
for(i in 0 until c.valueArgumentsCount) {
val arg = c.getValueArgument(i)
if(arg != null) {
extractExpressionExpr(arg, callable, id, i, enclosingStmt)
}
}
extractMethodAccess(c.symbol.owner)
}
}
}

View File

@@ -75,3 +75,5 @@
| exprs.kt:138:12:138:20 | ... + ... | exprs.kt:138:12:138:14 | 123 | exprs.kt:138:18:138:20 | 456 |
| exprs.kt:164:8:164:16 | ... != ... | exprs.kt:164:8:164:8 | r | exprs.kt:164:13:164:16 | null |
| exprs.kt:193:31:193:37 | ... + ... | exprs.kt:193:31:193:32 | <get-a1>(...) | exprs.kt:193:36:193:37 | a2 |
| exprs.kt:207:19:207:23 | ... + ... | file://:0:0:0:0 | <none> | exprs.kt:207:23:207:23 | 5 |
| exprs.kt:209:19:209:25 | ... + ... | exprs.kt:209:20:209:21 | ...!! | exprs.kt:209:25:209:25 | 5 |

View File

@@ -537,6 +537,35 @@
| exprs.kt:199:5:199:20 | y | exprs.kt:198:1:200:1 | notNullAssertion | LocalVariableDeclExpr |
| exprs.kt:199:18:199:18 | x | exprs.kt:198:1:200:1 | notNullAssertion | VarAccess |
| exprs.kt:199:19:199:20 | ...!! | exprs.kt:198:1:200:1 | notNullAssertion | NotNullExpr |
| exprs.kt:202:1:215:1 | <obinit>(...) | exprs.kt:202:1:215:1 | Class2 | MethodAccess |
| exprs.kt:205:9:205:29 | a | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:205:20:205:29 | toString(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
| exprs.kt:206:9:206:27 | b0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:206:21:206:27 | plus(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
| exprs.kt:206:26:206:26 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
| exprs.kt:207:9:207:23 | b1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:207:19:207:23 | ... + ... | exprs.kt:203:5:214:5 | x | AddExpr |
| exprs.kt:207:23:207:23 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
| exprs.kt:208:9:208:29 | b2 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:208:19:208:19 | s | exprs.kt:203:5:214:5 | x | VarAccess |
| exprs.kt:208:20:208:21 | ...!! | exprs.kt:203:5:214:5 | x | NotNullExpr |
| exprs.kt:208:23:208:29 | plus(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
| exprs.kt:208:28:208:28 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
| exprs.kt:209:9:209:25 | b3 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:209:19:209:19 | s | exprs.kt:203:5:214:5 | x | VarAccess |
| exprs.kt:209:19:209:25 | ... + ... | exprs.kt:203:5:214:5 | x | AddExpr |
| exprs.kt:209:20:209:21 | ...!! | exprs.kt:203:5:214:5 | x | NotNullExpr |
| exprs.kt:209:25:209:25 | 5 | exprs.kt:203:5:214:5 | x | IntegerLiteral |
| exprs.kt:210:9:210:36 | c0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:210:18:210:36 | values(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
| exprs.kt:211:9:211:31 | c1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:211:24:211:31 | values(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
| exprs.kt:212:9:212:44 | d0 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:212:18:212:44 | valueOf(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
| exprs.kt:212:38:212:42 | GREEN | exprs.kt:203:5:214:5 | x | StringLiteral |
| exprs.kt:213:9:213:39 | d1 | exprs.kt:203:5:214:5 | x | LocalVariableDeclExpr |
| exprs.kt:213:24:213:39 | valueOf(...) | exprs.kt:203:5:214:5 | x | MethodAccess |
| exprs.kt:213:33:213:37 | GREEN | exprs.kt:203:5:214:5 | x | StringLiteral |
| file://:0:0:0:0 | C | exprs.kt:146:5:146:33 | foo | TypeAccess |
| file://:0:0:0:0 | Color | exprs.kt:175:6:179:1 | Color | TypeAccess |
| file://:0:0:0:0 | Direction | exprs.kt:171:6:173:1 | Direction | TypeAccess |

View File

@@ -198,3 +198,18 @@ class Class1 {
fun notNullAssertion(x: Any?) {
val y: Any = x!!
}
class Class2 {
fun x(aa: Any?, s: String?) {
val a = aa.toString()
val b0 = s.plus(5)
val b1 = s + 5
val b2 = s!!.plus(5)
val b3 = s!! + 5
val c0 = enumValues<Color>()
val c1 = Color.values()
val d0 = enumValueOf<Color>("GREEN")
val d1 = Color.valueOf("GREEN")
}
}

View File

@@ -1 +1,3 @@
| exprs.kt:199:19:199:20 | ...!! | exprs.kt:199:18:199:18 | x |
| exprs.kt:208:20:208:21 | ...!! | exprs.kt:208:19:208:19 | s |
| exprs.kt:209:20:209:21 | ...!! | exprs.kt:209:19:209:19 | s |