Fix DB inconsistencies with KFunction and KFunction::invoke call extraction

This commit is contained in:
Tamas Vajk
2022-03-21 12:17:57 +01:00
committed by Ian Lynagh
parent 0b4cf6ec82
commit 1317d2d578
6 changed files with 103 additions and 8 deletions

View File

@@ -1131,11 +1131,13 @@ open class KotlinFileExtractor(
extractTypeArguments(typeArguments, locId, id, enclosingCallable, enclosingStmt, -2, true)
val drType = dispatchReceiver?.type
val isBigArityFunctionInvoke = drType != null
val isFunctionInvoke = drType != null
&& drType is IrSimpleType
&& drType.isFunctionOrKFunction()
&& callTarget.name.asString() == OperatorNameConventions.INVOKE.asString()
&& drType.arguments.size > BuiltInFunctionArity.BIG_ARITY
val isBigArityFunctionInvoke = isFunctionInvoke
&& (drType as IrSimpleType).arguments.size > BuiltInFunctionArity.BIG_ARITY
if (callTarget.isLocalFunction()) {
val ids = getLocallyVisibleFunctionLabels(callTarget)
@@ -1147,12 +1149,19 @@ open class KotlinFileExtractor(
} else {
val methodId =
if (drType != null && extractClassTypeArguments && drType is IrSimpleType && !isUnspecialised(drType)) {
if (isBigArityFunctionInvoke) {
val interfaceType = getFunctionalInterfaceTypeWithTypeArgs(drType.arguments)
val invokeMethod = findFunction(interfaceType.classOrNull!!.owner, OperatorNameConventions.INVOKE.asString())!!
useFunction<DbCallable>(invokeMethod, listOf(drType.arguments.last()))
val extractionMethod = if (isFunctionInvoke) {
val interfaceType = getFunctionalInterfaceTypeWithTypeArgs(drType.arguments).classOrNull!!.owner
val substituted = getJavaEquivalentClass(interfaceType) ?: interfaceType
findFunction(substituted, OperatorNameConventions.INVOKE.asString())!!
} else {
useFunction<DbCallable>(callTarget, getDeclaringTypeArguments(callTarget, drType))
callTarget
}
if (isBigArityFunctionInvoke) {
useFunction<DbCallable>(extractionMethod, listOf(drType.arguments.last()))
} else {
useFunction<DbCallable>(extractionMethod, getDeclaringTypeArguments(callTarget, drType))
}
}
else

View File

@@ -195,7 +195,14 @@ open class KotlinUsesExtractor(
val extractClass = substituteClass ?: c
val classTypeResult = addClassLabel(extractClass, typeArgs, inReceiverContext)
// `KFunction1<T1,T2>` is substituted by `KFunction<T>`. The last type argument is the return type.
val extractedTypeArgs = if (c.symbol.isKFunction() && typeArgs != null && typeArgs.isNotEmpty()) {
listOf(typeArgs.last())
} else {
typeArgs
}
val classTypeResult = addClassLabel(extractClass, extractedTypeArgs, inReceiverContext)
// Extract both the Kotlin and equivalent Java classes, so that we have database entries
// for both even if all internal references to the Kotlin type are substituted.