Extract ordinary array get and set operations as ArrayAccesses, not calls

This commit is contained in:
Chris Smowton
2022-02-18 13:07:59 +00:00
committed by Ian Lynagh
parent 387e8db161
commit 2fb54de269
7 changed files with 125 additions and 14 deletions

View File

@@ -1151,10 +1151,10 @@ open class KotlinFileExtractor(
fun extractCall(c: IrCall, callable: Label<out DbCallable>, parent: Label<out DbExprparent>, idx: Int, enclosingStmt: Label<out DbStmt>) {
with("call", c) {
fun isFunction(pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false): Boolean {
fun isFunction(pkgName: String, classNameLogged: String, classNamePredicate: (String) -> Boolean, fName: String, hasQuestionMark: Boolean? = false): Boolean {
val verbose = false
fun verboseln(s: String) { if(verbose) println(s) }
verboseln("Attempting match for $pkgName $className $fName")
verboseln("Attempting match for $pkgName $classNameLogged $fName")
val target = c.symbol.owner
if (target.name.asString() != fName) {
verboseln("No match as function name is ${target.name.asString()} not $fName")
@@ -1179,8 +1179,8 @@ open class KotlinFileExtractor(
verboseln("No match as didn't find target class")
return false
}
if (targetClass.name.asString() != className) {
verboseln("No match as class name is ${targetClass.name.asString()} not $className")
if (!classNamePredicate(targetClass.name.asString())) {
verboseln("No match as class name is ${targetClass.name.asString()} not $classNameLogged")
return false
}
val targetPkg = targetClass.parent
@@ -1195,7 +1195,10 @@ open class KotlinFileExtractor(
verboseln("Match")
return true
}
fun isFunction(pkgName: String, className: String, fName: String, hasQuestionMark: Boolean? = false) =
isFunction(pkgName, className, { it == className }, fName, hasQuestionMark)
fun isNumericFunction(fName: String): Boolean {
return isFunction("kotlin", "Int", fName) ||
isFunction("kotlin", "Byte", fName) ||
@@ -1205,6 +1208,20 @@ open class KotlinFileExtractor(
isFunction("kotlin", "Double", fName)
}
fun isArrayType(typeName: String) =
when(typeName) {
"Array" -> true
"IntArray" -> true
"ByteArray" -> true
"ShortArray" -> true
"LongArray" -> true
"FloatArray" -> true
"DoubleArray" -> true
"CharArray" -> true
"BooleanArray" -> true
else -> false
}
fun extractMethodAccess(syntacticCallTarget: IrFunction, extractMethodTypeArguments: Boolean = true, extractClassTypeArguments: Boolean = false) {
val typeArgs =
if (extractMethodTypeArguments)
@@ -1561,6 +1578,46 @@ open class KotlinFileExtractor(
}
}
}
isFunction("kotlin", "(some array type)", { isArrayType(it) }, "get") && c.origin == IrStatementOrigin.GET_ARRAY_ELEMENT -> {
val id = tw.getFreshIdLabel<DbArrayaccess>()
val type = useType(c.type)
tw.writeExprs_arrayaccess(id, type.javaResult.id, parent, idx)
tw.writeExprsKotlinType(id, type.kotlinResult.id)
binopDisp(id)
}
isFunction("kotlin", "(some array type)", { isArrayType(it) }, "set") && c.origin == IrStatementOrigin.EQ -> {
val array = c.dispatchReceiver
val arrayIdx = c.getValueArgument(0)
val assignedValue = c.getValueArgument(1)
if (array != null && arrayIdx != null && assignedValue != null) {
val assignId = tw.getFreshIdLabel<DbAssignexpr>()
val type = useType(c.type)
val locId = tw.getLocation(c)
tw.writeExprs_assignexpr(assignId, type.javaResult.id, parent, idx)
tw.writeExprsKotlinType(assignId, type.kotlinResult.id)
tw.writeHasLocation(assignId, locId)
tw.writeCallableEnclosingExpr(assignId, callable)
tw.writeStatementEnclosingExpr(assignId, enclosingStmt)
val arrayAccessId = tw.getFreshIdLabel<DbArrayaccess>()
val arrayType = useType(array.type)
tw.writeExprs_arrayaccess(arrayAccessId, arrayType.javaResult.id, assignId, 0)
tw.writeExprsKotlinType(arrayAccessId, arrayType.kotlinResult.id)
tw.writeHasLocation(arrayAccessId, locId)
tw.writeCallableEnclosingExpr(arrayAccessId, callable)
tw.writeStatementEnclosingExpr(arrayAccessId, enclosingStmt)
extractExpressionExpr(array, callable, arrayAccessId, 0, enclosingStmt)
extractExpressionExpr(arrayIdx, callable, arrayAccessId, 1, enclosingStmt)
extractExpressionExpr(assignedValue, callable, assignId, 1, enclosingStmt)
} else {
logger.errorElement("Unexpected Array.set function signature", c)
}
}
isBuiltinCall(c, "<unsafe-coerce>", "kotlin.jvm.internal") -> {
if (c.valueArgumentsCount != 1) {

View File

@@ -0,0 +1,18 @@
| arrayGetsSets.kt:12:3:12:7 | ...[...] | arrayGetsSets.kt:12:3:12:7 | ...=... |
| arrayGetsSets.kt:12:11:12:15 | ...[...] | arrayGetsSets.kt:12:3:12:7 | ...=... |
| arrayGetsSets.kt:13:3:13:7 | ...[...] | arrayGetsSets.kt:13:3:13:7 | ...=... |
| arrayGetsSets.kt:13:11:13:15 | ...[...] | arrayGetsSets.kt:13:3:13:7 | ...=... |
| arrayGetsSets.kt:14:3:14:7 | ...[...] | arrayGetsSets.kt:14:3:14:7 | ...=... |
| arrayGetsSets.kt:14:11:14:15 | ...[...] | arrayGetsSets.kt:14:3:14:7 | ...=... |
| arrayGetsSets.kt:15:3:15:7 | ...[...] | arrayGetsSets.kt:15:3:15:7 | ...=... |
| arrayGetsSets.kt:15:11:15:15 | ...[...] | arrayGetsSets.kt:15:3:15:7 | ...=... |
| arrayGetsSets.kt:16:3:16:7 | ...[...] | arrayGetsSets.kt:16:3:16:7 | ...=... |
| arrayGetsSets.kt:16:11:16:15 | ...[...] | arrayGetsSets.kt:16:3:16:7 | ...=... |
| arrayGetsSets.kt:17:3:17:7 | ...[...] | arrayGetsSets.kt:17:3:17:7 | ...=... |
| arrayGetsSets.kt:17:11:17:15 | ...[...] | arrayGetsSets.kt:17:3:17:7 | ...=... |
| arrayGetsSets.kt:18:3:18:7 | ...[...] | arrayGetsSets.kt:18:3:18:7 | ...=... |
| arrayGetsSets.kt:18:11:18:15 | ...[...] | arrayGetsSets.kt:18:3:18:7 | ...=... |
| arrayGetsSets.kt:19:3:19:7 | ...[...] | arrayGetsSets.kt:19:3:19:7 | ...=... |
| arrayGetsSets.kt:19:11:19:15 | ...[...] | arrayGetsSets.kt:19:3:19:7 | ...=... |
| arrayGetsSets.kt:20:3:20:7 | ...[...] | arrayGetsSets.kt:20:3:20:7 | ...=... |
| arrayGetsSets.kt:20:11:20:15 | ...[...] | arrayGetsSets.kt:20:3:20:7 | ...=... |

View File

@@ -0,0 +1,4 @@
import java
from ArrayAccess aa
select aa, aa.getParent()

View File

@@ -0,0 +1,22 @@
fun arrayGetSet(
a1: IntArray,
a2: ShortArray,
a3: ByteArray,
a4: LongArray,
a5: FloatArray,
a6: DoubleArray,
a7: BooleanArray,
a8: CharArray,
a9: Array<Any>) {
a1[0] = a1[0]
a2[0] = a2[0]
a3[0] = a3[0]
a4[0] = a4[0]
a5[0] = a5[0]
a6[0] = a6[0]
a7[0] = a7[0]
a8[0] = a8[0]
a9[0] = a9[0]
}

View File

@@ -17,6 +17,7 @@ sourceSignatures
| arrayCreations.kt:26:27:26:36 | invoke | invoke(int) |
| arrayCreations.kt:27:24:27:38 | | |
| arrayCreations.kt:27:24:27:38 | invoke | invoke(int) |
| arrayGetsSets.kt:1:1:22:1 | arrayGetSet | arrayGetSet(int[],short[],byte[],long[],float[],double[],boolean[],char[],java.lang.Object[]) |
| primitiveArrays.kt:3:1:7:1 | <obinit> | <obinit>() |
| primitiveArrays.kt:3:1:7:1 | Test | Test() |
| primitiveArrays.kt:5:3:5:123 | test | test(java.lang.Integer[],java.lang.Integer[],int[],java.lang.Integer[][],java.lang.Integer[][],int[][]) |

View File

@@ -26,15 +26,9 @@ implicitVarargsArguments
| intList.kt:3:14:3:31 | listOf(...) | 0 | intList.kt:3:21:3:22 | 10 |
| intList.kt:3:14:3:31 | listOf(...) | 1 | intList.kt:3:25:3:26 | 11 |
| intList.kt:3:14:3:31 | listOf(...) | 2 | intList.kt:3:29:3:30 | 12 |
| test.kt:7:5:7:19 | sink(...) | 0 | test.kt:7:10:7:18 | get(...) |
| test.kt:7:10:7:18 | get(...) | 0 | test.kt:7:13:7:17 | get(...) |
| test.kt:7:13:7:17 | get(...) | 0 | test.kt:7:16:7:16 | 0 |
| test.kt:11:5:11:19 | sink(...) | 0 | test.kt:11:10:11:18 | get(...) |
| test.kt:11:10:11:18 | get(...) | 0 | test.kt:11:13:11:17 | get(...) |
| test.kt:11:13:11:17 | get(...) | 0 | test.kt:11:16:11:16 | 0 |
| test.kt:15:5:15:19 | sink(...) | 0 | test.kt:15:10:15:18 | get(...) |
| test.kt:15:10:15:18 | get(...) | 0 | test.kt:15:13:15:17 | get(...) |
| test.kt:15:13:15:17 | get(...) | 0 | test.kt:15:16:15:16 | 0 |
| test.kt:7:5:7:19 | sink(...) | 0 | test.kt:7:10:7:18 | ...[...] |
| test.kt:11:5:11:19 | sink(...) | 0 | test.kt:11:10:11:18 | ...[...] |
| test.kt:15:5:15:19 | sink(...) | 0 | test.kt:15:10:15:18 | ...[...] |
| test.kt:19:14:19:31 | listOf(...) | 0 | test.kt:19:21:19:22 | 10 |
| test.kt:19:14:19:31 | listOf(...) | 1 | test.kt:19:25:19:26 | 11 |
| test.kt:19:14:19:31 | listOf(...) | 2 | test.kt:19:29:19:30 | 12 |

View File

@@ -0,0 +1,15 @@
| test.kt:20:28:20:30 | 100 | test.kt:7:10:7:18 | ...[...] |
| test.kt:20:28:20:30 | 100 | test.kt:11:10:11:18 | ...[...] |
| test.kt:20:28:20:30 | 100 | test.kt:15:10:15:18 | ...[...] |
| test.kt:20:33:20:35 | 101 | test.kt:7:10:7:18 | ...[...] |
| test.kt:20:33:20:35 | 101 | test.kt:11:10:11:18 | ...[...] |
| test.kt:20:33:20:35 | 101 | test.kt:15:10:15:18 | ...[...] |
| test.kt:20:38:20:40 | 102 | test.kt:7:10:7:18 | ...[...] |
| test.kt:20:38:20:40 | 102 | test.kt:11:10:11:18 | ...[...] |
| test.kt:20:38:20:40 | 102 | test.kt:15:10:15:18 | ...[...] |
| test.kt:21:24:21:25 | 20 | test.kt:7:10:7:18 | ...[...] |
| test.kt:21:28:21:29 | 21 | test.kt:7:10:7:18 | ...[...] |
| test.kt:21:32:21:33 | 22 | test.kt:7:10:7:18 | ...[...] |
| test.kt:22:40:22:41 | 30 | test.kt:11:10:11:18 | ...[...] |
| test.kt:22:44:22:45 | 31 | test.kt:11:10:11:18 | ...[...] |
| test.kt:22:48:22:49 | 32 | test.kt:11:10:11:18 | ...[...] |