Merge pull request #10169 from tamasvajk/kotlin-array-iterator

Kotlin: fix array iterator extraction
This commit is contained in:
Tamás Vajk
2022-08-26 08:33:52 +02:00
committed by GitHub
5 changed files with 55 additions and 5 deletions

View File

@@ -1600,11 +1600,13 @@ open class KotlinFileExtractor(
return result
}
private fun findTopLevelFunctionOrWarn(functionFilter: String, type: String, warnAgainstElement: IrElement): IrFunction? {
private fun findTopLevelFunctionOrWarn(functionFilter: String, type: String, parameterTypes: Array<String>, warnAgainstElement: IrElement): IrFunction? {
val fn = pluginContext.referenceFunctions(FqName(functionFilter))
.firstOrNull { it.owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type }
?.owner
.firstOrNull { fnSymbol ->
fnSymbol.owner.parentClassOrNull?.fqNameWhenAvailable?.asString() == type &&
fnSymbol.owner.valueParameters.map { it.type.classFqName?.asString() }.toTypedArray() contentEquals parameterTypes
}?.owner
if (fn != null) {
if (fn.parentClassOrNull != null) {
@@ -1754,6 +1756,12 @@ open class KotlinFileExtractor(
else -> false
}
private fun isGenericArrayType(typeName: String) =
when(typeName) {
"Array" -> true
else -> false
}
private fun extractCall(c: IrCall, callable: Label<out DbCallable>, stmtExprParent: StmtExprParent) {
with("call", c) {
val target = tryReplaceSyntheticFunction(c.symbol.owner)
@@ -2175,8 +2183,20 @@ open class KotlinFileExtractor(
extractRawMethodAccess(getter, c, callable, parent, idx, enclosingStmt, listOf(), null, ext, typeArguments)
}
}
isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "iterator") && c.origin == IrStatementOrigin.FOR_LOOP_ITERATOR -> {
findTopLevelFunctionOrWarn("kotlin.jvm.internal.iterator", "kotlin.jvm.internal.ArrayIteratorKt", c)?.let { iteratorFn ->
isFunction(target, "kotlin", "(some array type)", { isArrayType(it) }, "iterator") -> {
val parentClass = target.parent
if (parentClass !is IrClass) {
logger.errorElement("Iterator parent is not a class", c)
return
}
var typeFilter = if (isGenericArrayType(parentClass.name.asString())) {
"kotlin.jvm.internal.ArrayIteratorKt"
} else {
"kotlin.jvm.internal.ArrayIteratorsKt"
}
findTopLevelFunctionOrWarn("kotlin.jvm.internal.iterator", typeFilter, arrayOf(parentClass.kotlinFqName.asString()), c)?.let { iteratorFn ->
val dispatchReceiver = c.dispatchReceiver
if (dispatchReceiver == null) {
logger.errorElement("No dispatch receiver found for array iterator call", c)