Skip to content

Commit 6f3c9e4

Browse files
committed
Split up extractRawMethodAccess
1 parent a856bc8 commit 6f3c9e4

File tree

1 file changed

+75
-73
lines changed

1 file changed

+75
-73
lines changed

java/kotlin-extractor/src/main/kotlin/KotlinFileExtractor.kt

Lines changed: 75 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,64 @@ open class KotlinFileExtractor(
15571557

15581558
}
15591559

1560+
private fun getFunctionInvokeMethod(typeArgs: List<IrTypeArgument>): IrFunction? {
1561+
// For `kotlin.FunctionX` and `kotlin.reflect.KFunctionX` interfaces, we're making sure that we
1562+
// extract the call to the `invoke` method that does exist, `kotlin.jvm.functions.FunctionX::invoke`.
1563+
val functionalInterface = getFunctionalInterfaceTypeWithTypeArgs(typeArgs)
1564+
if (functionalInterface == null) {
1565+
logger.warn("Cannot find functional interface type for raw method access")
1566+
return null
1567+
}
1568+
val functionalInterfaceClass = functionalInterface.classOrNull
1569+
if (functionalInterfaceClass == null) {
1570+
logger.warn("Cannot find functional interface class for raw method access")
1571+
return null
1572+
}
1573+
val interfaceType = functionalInterfaceClass.owner
1574+
val substituted = getJavaEquivalentClass(interfaceType) ?: interfaceType
1575+
val function = findFunction(substituted, OperatorNameConventions.INVOKE.asString())
1576+
if (function == null) {
1577+
logger.warn("Cannot find invoke function for raw method access")
1578+
return null
1579+
}
1580+
return function
1581+
}
1582+
1583+
private fun isFunctionInvoke(callTarget: IrFunction, drType: IrSimpleType) =
1584+
(drType.isFunctionOrKFunction() || drType.isSuspendFunctionOrKFunction()) &&
1585+
callTarget.name.asString() == OperatorNameConventions.INVOKE.asString()
1586+
1587+
private fun getCalleeMethodId(callTarget: IrFunction, drType: IrType?, allowInstantiatedGenericMethod: Boolean): Label<out DbCallable>? {
1588+
if (callTarget.isLocalFunction())
1589+
return getLocallyVisibleFunctionLabels(callTarget).function
1590+
1591+
if (allowInstantiatedGenericMethod && drType is IrSimpleType && !isUnspecialised(drType, logger)) {
1592+
val calleeIsInvoke = isFunctionInvoke(callTarget, drType)
1593+
1594+
val extractionMethod =
1595+
if (calleeIsInvoke)
1596+
getFunctionInvokeMethod(drType.arguments)
1597+
else
1598+
callTarget
1599+
1600+
return extractionMethod?.let {
1601+
val typeArgs =
1602+
if (calleeIsInvoke && drType.arguments.size > BuiltInFunctionArity.BIG_ARITY) {
1603+
// Big arity `invoke` methods have a special implementation on JVM, they are transformed to a call to
1604+
// `kotlin.jvm.functions.FunctionN<out R>::invoke(vararg args: Any?)`, so we only need to pass the type
1605+
// argument for the return type. Additionally, the arguments are extracted inside an array literal below.
1606+
listOf(drType.arguments.last())
1607+
} else {
1608+
getDeclaringTypeArguments(callTarget, drType)
1609+
}
1610+
useFunction<DbCallable>(extractionMethod, typeArgs)
1611+
}
1612+
}
1613+
else {
1614+
return useFunction<DbCallable>(callTarget)
1615+
}
1616+
}
1617+
15601618

15611619
fun extractRawMethodAccess(
15621620
syntacticCallTarget: IrFunction,
@@ -1588,86 +1646,30 @@ open class KotlinFileExtractor(
15881646
// type arguments at index -2, -3, ...
15891647
extractTypeArguments(typeArguments, locId, id, enclosingCallable, enclosingStmt, -2, true)
15901648

1591-
val (isFunctionInvoke, isBigArityFunctionInvoke) =
1592-
if (drType is IrSimpleType &&
1593-
(drType.isFunctionOrKFunction() || drType.isSuspendFunctionOrKFunction()) &&
1594-
callTarget.name.asString() == OperatorNameConventions.INVOKE.asString()) {
1595-
Pair(true, drType.arguments.size > BuiltInFunctionArity.BIG_ARITY)
1596-
} else {
1597-
Pair(false, false)
1598-
}
1599-
1600-
if (callTarget.isLocalFunction()) {
1601-
val ids = getLocallyVisibleFunctionLabels(callTarget)
1602-
1603-
val methodId = ids.function
1604-
tw.writeCallableBinding(id, methodId)
1649+
val methodId = getCalleeMethodId(callTarget, drType, extractClassTypeArguments)
16051650

1606-
extractNewExprForLocalFunction(ids, id, locId, enclosingCallable, enclosingStmt)
1651+
if (methodId == null) {
1652+
logger.warn("No method to bind call to for raw method access")
16071653
} else {
1608-
val methodId =
1609-
if (extractClassTypeArguments && drType is IrSimpleType && !isUnspecialised(drType, logger)) {
1610-
1611-
val extractionMethod = if (isFunctionInvoke) {
1612-
// For `kotlin.FunctionX` and `kotlin.reflect.KFunctionX` interfaces, we're making sure that we
1613-
// extract the call to the `invoke` method that does exist, `kotlin.jvm.functions.FunctionX::invoke`.
1614-
val functionalInterface = getFunctionalInterfaceTypeWithTypeArgs(drType.arguments)
1615-
if (functionalInterface == null) {
1616-
logger.warn("Cannot find functional interface type for raw method access")
1617-
null
1618-
} else {
1619-
val functionalInterfaceClass = functionalInterface.classOrNull
1620-
if (functionalInterfaceClass == null) {
1621-
logger.warn("Cannot find functional interface class for raw method access")
1622-
null
1623-
} else {
1624-
val interfaceType = functionalInterfaceClass.owner
1625-
val substituted = getJavaEquivalentClass(interfaceType) ?: interfaceType
1626-
val function = findFunction(substituted, OperatorNameConventions.INVOKE.asString())
1627-
if (function == null) {
1628-
logger.warn("Cannot find invoke function for raw method access")
1629-
null
1630-
} else {
1631-
function
1632-
}
1633-
}
1634-
}
1635-
} else {
1636-
callTarget
1637-
}
1638-
1639-
if (extractionMethod == null) {
1640-
null
1641-
} else if (isBigArityFunctionInvoke) {
1642-
// Big arity `invoke` methods have a special implementation on JVM, they are transformed to a call to
1643-
// `kotlin.jvm.functions.FunctionN<out R>::invoke(vararg args: Any?)`, so we only need to pass the type
1644-
// argument for the return type. Additionally, the arguments are extracted inside an array literal below.
1645-
useFunction<DbCallable>(extractionMethod, listOf(drType.arguments.last()))
1646-
} else {
1647-
useFunction<DbCallable>(extractionMethod, getDeclaringTypeArguments(callTarget, drType))
1648-
}
1649-
}
1650-
else {
1651-
useFunction<DbCallable>(callTarget)
1652-
}
1653-
1654-
if (methodId == null) {
1655-
logger.warn("No method to bind call to for raw method access")
1656-
} else {
1657-
tw.writeCallableBinding(id, methodId)
1658-
}
1654+
tw.writeCallableBinding(id, methodId)
1655+
}
16591656

1660-
if (callTarget.shouldExtractAsStatic) {
1661-
extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt)
1662-
} else if (superQualifierSymbol != null) {
1663-
extractSuperAccess(superQualifierSymbol.typeWith(), enclosingCallable, id, -1, enclosingStmt, locId)
1664-
} else if (extractDispatchReceiver != null) {
1665-
extractDispatchReceiver(id)
1666-
}
1657+
if (callTarget.isLocalFunction()) {
1658+
extractNewExprForLocalFunction(getLocallyVisibleFunctionLabels(callTarget), id, locId, enclosingCallable, enclosingStmt)
1659+
} else if (callTarget.shouldExtractAsStatic) {
1660+
extractStaticTypeAccessQualifier(callTarget, id, locId, enclosingCallable, enclosingStmt)
1661+
} else if (superQualifierSymbol != null) {
1662+
extractSuperAccess(superQualifierSymbol.typeWith(), enclosingCallable, id, -1, enclosingStmt, locId)
1663+
} else if (extractDispatchReceiver != null) {
1664+
extractDispatchReceiver(id)
16671665
}
16681666

16691667
val idxOffset = if (extractExtensionReceiver != null) 1 else 0
16701668

1669+
val isBigArityFunctionInvoke = drType is IrSimpleType &&
1670+
isFunctionInvoke(callTarget, drType) &&
1671+
drType.arguments.size > BuiltInFunctionArity.BIG_ARITY
1672+
16711673
val argParent = if (isBigArityFunctionInvoke) {
16721674
extractArrayCreationWithInitializer(id, nValueArguments + idxOffset, locId, enclosingCallable, enclosingStmt)
16731675
} else {

0 commit comments

Comments
 (0)