Kotlin: Handle null parent IDs in getFunctionLabel correctly

This commit is contained in:
Ian Lynagh
2023-08-10 16:55:27 +01:00
parent f377d25c23
commit 58da62e244
2 changed files with 47 additions and 14 deletions

View File

@@ -472,7 +472,7 @@ open class KotlinFileExtractor(
private fun extractObinitFunction(c: IrClass, parentId: Label<out DbClassorinterface>) {
// add method:
val obinitLabel = getObinitLabel(c)
val obinitLabel = getObinitLabel(c, parentId)
val obinitId = tw.getLabelFor<DbMethod>(obinitLabel)
val returnType = useType(pluginContext.irBuiltIns.unitType, TypeContext.RETURN)
tw.writeMethods(obinitId, "<obinit>", "<obinit>()", returnType.javaResult.id, parentId, obinitId)
@@ -1160,6 +1160,10 @@ open class KotlinFileExtractor(
return
val id = getDefaultsMethodLabel(f)
if (id == null) {
logger.errorElement("Cannot get defaults method label for function", f)
return
}
val locId = getLocation(f, null)
val extReceiver = f.extensionReceiverParameter
val dispatchReceiver = if (f.shouldExtractAsStatic) null else f.dispatchReceiverParameter
@@ -1284,6 +1288,10 @@ open class KotlinFileExtractor(
useDeclarationParent(f.parent, false)
else
parentId
if (sourceParentId == null) {
logger.errorElement("Cannot get source parent ID for function", f)
return
}
val sourceDeclId = tw.getLabelFor<DbCallable>(getFunctionLabel(f, sourceParentId, listOf(), overloadParameters))
val overriddenAttributes = OverriddenFunctionAttributes(id = overloadId, sourceDeclarationId = sourceDeclId, valueParameters = overloadParameters)
forceExtractFunction(f, parentId, extractBody = false, extractMethodAndParameterTypeAccesses, extractAnnotations = false, typeSubstitution, classTypeArgsIncludingOuterClasses, overriddenAttributes = overriddenAttributes)
@@ -1301,7 +1309,7 @@ open class KotlinFileExtractor(
val constructorCallId = tw.getFreshIdLabel<DbConstructorinvocationstmt>()
tw.writeStmts_constructorinvocationstmt(constructorCallId, blockId, 0, overloadId)
tw.writeHasLocation(constructorCallId, realFunctionLocId)
tw.writeCallableBinding(constructorCallId, getDefaultsMethodLabel(f))
tw.writeCallableBinding(constructorCallId, getDefaultsMethodLabel(f, parentId))
extractDefaultsCallArguments(constructorCallId, f, overloadId, constructorCallId, regularArgs, null, null)
} else {
@@ -2081,13 +2089,23 @@ open class KotlinFileExtractor(
getFunctionShortName(f).nameInDB + "\$default"
}
private fun getDefaultsMethodLabel(f: IrFunction): Label<out DbCallable> {
private fun getDefaultsMethodLabel(f: IrFunction): Label<out DbCallable>? {
val classTypeArgsIncludingOuterClasses = null
val parentId = useDeclarationParent(f.parent, false, classTypeArgsIncludingOuterClasses, true)
if (parentId == null) {
logger.errorElement("Couldn't get parent ID for defaults method", f)
return null
}
return getDefaultsMethodLabel(f, parentId)
}
private fun getDefaultsMethodLabel(f: IrFunction, parentId: Label<out DbElement>): Label<out DbCallable> {
val defaultsMethodName = if (f is IrConstructor) "<init>" else getDefaultsMethodName(f)
val argTypes = getDefaultsMethodArgTypes(f)
val defaultMethodLabelStr = getFunctionLabel(
f.parent,
maybeParentId = null,
parentId,
defaultsMethodName,
argTypes,
erase(f.returnType),
@@ -3300,9 +3318,9 @@ open class KotlinFileExtractor(
private fun needsObinitFunction(c: IrClass) = c.primaryConstructor == null && c.constructors.count() > 1
private fun getObinitLabel(c: IrClass) = getFunctionLabel(
private fun getObinitLabel(c: IrClass, parentId: Label<out DbElement>): String = getFunctionLabel(
c,
null,
parentId,
"<obinit>",
listOf(),
pluginContext.irBuiltIns.unitType,
@@ -3332,7 +3350,12 @@ open class KotlinFileExtractor(
val valueArgs = (0 until e.valueArgumentsCount).map { e.getValueArgument(it) }
val id = if (e !is IrEnumConstructorCall && callUsesDefaultArguments(e.symbol.owner, valueArgs)) {
extractNewExpr(getDefaultsMethodLabel(e.symbol.owner).cast(), type, locId, parent, idx, callable, enclosingStmt).also {
val defaultsMethodId = getDefaultsMethodLabel(e.symbol.owner)
if (defaultsMethodId == null) {
logger.errorElement("Cannot get defaults method ID", e)
return
}
extractNewExpr(defaultsMethodId.cast(), type, locId, parent, idx, callable, enclosingStmt).also {
extractDefaultsCallArguments(it, e.symbol.owner, callable, enclosingStmt, valueArgs, null, null)
}
} else {
@@ -3817,7 +3840,13 @@ open class KotlinFileExtractor(
val id = tw.getFreshIdLabel<DbMethodaccess>()
val type = useType(pluginContext.irBuiltIns.unitType)
val locId = tw.getLocation(e)
val methodLabel = getObinitLabel(irConstructor.parentAsClass)
val parentClass = irConstructor.parentAsClass
val parentId = useDeclarationParent(parentClass, false, null, true)
if (parentId == null) {
logger.errorElement("Cannot get parent ID for obinit", e)
return
}
val methodLabel = getObinitLabel(parentClass, parentId)
val methodId = tw.getLabelFor<DbMethod>(methodLabel)
tw.writeExprs_methodaccess(id, type.javaResult.id, exprParent.parent, exprParent.idx)
tw.writeExprsKotlinType(id, type.kotlinResult.id)

View File

@@ -1034,8 +1034,13 @@ open class KotlinUsesExtractor(
* enclosing classes to get the instantiation that this function is
* in.
*/
fun getFunctionLabel(f: IrFunction, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?) : String {
return getFunctionLabel(f, null, classTypeArgsIncludingOuterClasses)
fun getFunctionLabel(f: IrFunction, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?): String? {
val parentId = useDeclarationParent(f.parent, false, classTypeArgsIncludingOuterClasses, true)
if (parentId == null) {
logger.error("Couldn't get parent ID for function label")
return null
}
return getFunctionLabel(f, parentId, classTypeArgsIncludingOuterClasses)
}
/*
@@ -1052,10 +1057,10 @@ open class KotlinUsesExtractor(
* that omit one or more parameters that has a default value specified.
*/
@OptIn(ObsoleteDescriptorBasedAPI::class)
fun getFunctionLabel(f: IrFunction, maybeParentId: Label<out DbElement>?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, maybeParameterList: List<IrValueParameter>? = null) =
fun getFunctionLabel(f: IrFunction, parentId: Label<out DbElement>, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, maybeParameterList: List<IrValueParameter>? = null): String =
getFunctionLabel(
f.parent,
maybeParentId,
parentId,
getFunctionShortName(f).nameInDB,
(maybeParameterList ?: f.valueParameters).map { it.type },
getAdjustedReturnType(f),
@@ -1078,7 +1083,7 @@ open class KotlinUsesExtractor(
// The parent of the function; normally f.parent.
parent: IrDeclarationParent,
// The ID of the function's parent, or null if we should work it out ourselves.
maybeParentId: Label<out DbElement>?,
parentId: Label<out DbElement>,
// The name of the function; normally f.name.asString().
name: String,
// The types of the value parameters that the functions takes; normally f.valueParameters.map { it.type }.
@@ -1102,7 +1107,6 @@ open class KotlinUsesExtractor(
// The prefix used in the label. "callable", unless a property label is created, then it's "property".
prefix: String = "callable"
): String {
val parentId = maybeParentId ?: useDeclarationParent(parent, false, classTypeArgsIncludingOuterClasses, true)
val allParamTypes = if (extensionParamType == null) parameterTypes else listOf(extensionParamType) + parameterTypes
val substitutionMap = classTypeArgsIncludingOuterClasses?.let { notNullArgs ->