Function labels: include <n> suffix (where n is the number of function type parameters)

This matches the Java extractor's behaviour.
This commit is contained in:
Chris Smowton
2022-01-13 09:56:34 +00:00
committed by Ian Lynagh
parent 448b3d38d3
commit 178f128bdc
2 changed files with 35 additions and 22 deletions

View File

@@ -46,7 +46,7 @@ open class KotlinFileExtractor(
is IrFunction -> {
@Suppress("UNCHECKED_CAST")
val parentId = useDeclarationParent(declaration.parent, false) as Label<DbReftype>
extractFunctionIfReal(declaration, parentId)
extractFunctionIfReal(declaration, parentId, true, null, listOf())
}
is IrAnonymousInitializer -> {
// Leaving this intentionally empty. init blocks are extracted during class extraction.
@@ -54,7 +54,7 @@ open class KotlinFileExtractor(
is IrProperty -> {
@Suppress("UNCHECKED_CAST")
val parentId = useDeclarationParent(declaration.parent, false) as Label<DbReftype>
extractProperty(declaration, parentId)
extractProperty(declaration, parentId, true, null, listOf())
}
is IrEnumEntry -> {
@Suppress("UNCHECKED_CAST")
@@ -216,8 +216,8 @@ open class KotlinFileExtractor(
c.declarations.map {
when(it) {
is IrFunction -> extractFunctionIfReal(it, id, false, typeParamSubstitution)
is IrProperty -> extractProperty(it, id, false, typeParamSubstitution)
is IrFunction -> extractFunctionIfReal(it, id, false, typeParamSubstitution, typeArgs)
is IrProperty -> extractProperty(it, id, false, typeParamSubstitution, typeArgs)
else -> {}
}
}
@@ -374,7 +374,7 @@ open class KotlinFileExtractor(
}
// add method:
val obinitLabel = getFunctionLabel(c, "<obinit>", listOf(), pluginContext.irBuiltIns.unitType, extensionReceiverParameter = null)
val obinitLabel = getFunctionLabel(c, "<obinit>", listOf(), pluginContext.irBuiltIns.unitType, extensionReceiverParameter = null, functionTypeParameters = listOf(), classTypeArguments = listOf())
val obinitId = tw.getLabelFor<DbMethod>(obinitLabel)
val returnType = useType(pluginContext.irBuiltIns.unitType)
tw.writeMethods(obinitId, "<obinit>", "<obinit>()", returnType.javaResult.id, returnType.kotlinResult.id, parentId, obinitId)
@@ -442,13 +442,13 @@ open class KotlinFileExtractor(
}
}
fun extractFunctionIfReal(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean = true, typeSubstitution: TypeSubstitution? = null) {
fun extractFunctionIfReal(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgs: List<IrTypeArgument>?) {
if (f.origin == IrDeclarationOrigin.FAKE_OVERRIDE)
return
extractFunction(f, parentId, extractBody, typeSubstitution)
extractFunction(f, parentId, extractBody, typeSubstitution, classTypeArgs)
}
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean = true, typeSubstitution: TypeSubstitution? = null): Label<out DbCallable> {
fun extractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgs: List<IrTypeArgument>?): Label<out DbCallable> {
declarationStack.push(f)
f.typeParameters.map { extractTypeParameter(it) }
@@ -459,7 +459,7 @@ open class KotlinFileExtractor(
if (f.isLocalFunction())
getLocallyVisibleFunctionLabels(f).function
else
useFunction<DbCallable>(f, parentId)
useFunction<DbCallable>(f, parentId, classTypeArgs)
val extReceiver = f.extensionReceiverParameter
val idxOffset = if (extReceiver != null) 1 else 0
@@ -543,7 +543,7 @@ open class KotlinFileExtractor(
return id
}
fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean = true, typeSubstitution: TypeSubstitution? = null) {
fun extractProperty(p: IrProperty, parentId: Label<out DbReftype>, extractBackingField: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgs: List<IrTypeArgument>?) {
val id = useProperty(p, parentId)
val locId = tw.getLocation(p)
tw.writeKtProperties(id, p.name.asString())
@@ -555,7 +555,7 @@ open class KotlinFileExtractor(
if(getter != null) {
@Suppress("UNCHECKED_CAST")
val getterId = extractFunction(getter, parentId, extractBackingField, typeSubstitution) as Label<out DbMethod>
val getterId = extractFunction(getter, parentId, extractBackingField, typeSubstitution, classTypeArgs) as Label<out DbMethod>
tw.writeKtPropertyGetters(id, getterId)
} else {
if (p.modality != Modality.FINAL || !isExternalDeclaration(p)) {
@@ -568,7 +568,7 @@ open class KotlinFileExtractor(
logger.warnElement(Severity.ErrorSevere, "!isVar property with a setter", p)
}
@Suppress("UNCHECKED_CAST")
val setterId = extractFunction(setter, parentId, extractBackingField, typeSubstitution) as Label<out DbMethod>
val setterId = extractFunction(setter, parentId, extractBackingField, typeSubstitution, classTypeArgs) as Label<out DbMethod>
tw.writeKtPropertySetters(id, setterId)
} else {
if (p.isVar && !isExternalDeclaration(p)) {
@@ -1493,7 +1493,7 @@ open class KotlinFileExtractor(
val id = tw.getFreshIdLabel<DbMethodaccess>()
val type = useType(e.type)
val locId = tw.getLocation(e)
val methodLabel = getFunctionLabel(irCallable.parent, "<obinit>", listOf(), e.type, null)
val methodLabel = getFunctionLabel(irCallable.parent, "<obinit>", listOf(), e.type, null, functionTypeParameters = listOf(), classTypeArguments = listOf())
val methodId = tw.getLabelFor<DbMethod>(methodLabel)
tw.writeExprs_methodaccess(id, type.javaResult.id, type.kotlinResult.id, exprParent.parent, exprParent.idx)
tw.writeHasLocation(id, locId)
@@ -2536,7 +2536,7 @@ open class KotlinFileExtractor(
val id = extractGeneratedClass(ids, superTypes, tw.getLocation(localFunction), localFunction)
// Extract local function as a member
extractFunctionIfReal(localFunction, id)
extractFunctionIfReal(localFunction, id, true, null, listOf())
return id
}

View File

@@ -567,8 +567,13 @@ class X {
return f.name.asString()
}
// This excludes class type parameters that show up in (at least) constructors' typeParameters list.
fun getFunctionTypeParameters(f: IrFunction): List<IrTypeParameter> {
return if (f is IrConstructor) f.typeParameters else f.typeParameters.filter { it.parent == f }
}
fun getFunctionLabel(f: IrFunction, classTypeArguments: List<IrTypeArgument>? = null) : String {
return getFunctionLabel(f.parent, getFunctionShortName(f), f.valueParameters, f.returnType, f.extensionReceiverParameter, classTypeArguments)
return getFunctionLabel(f.parent, getFunctionShortName(f), f.valueParameters, f.returnType, f.extensionReceiverParameter, getFunctionTypeParameters(f), classTypeArguments)
}
fun getFunctionLabel(
@@ -577,21 +582,24 @@ class X {
parameters: List<IrValueParameter>,
returnType: IrType,
extensionReceiverParameter: IrValueParameter?,
functionTypeParameters: List<IrTypeParameter>,
classTypeArguments: List<IrTypeArgument>? = null
): String {
val parentId = useDeclarationParent(parent, false, classTypeArguments, true)
return getFunctionLabel(parentId, name, parameters, returnType, extensionReceiverParameter)
return getFunctionLabel(parentId, name, parameters, returnType, extensionReceiverParameter, functionTypeParameters, classTypeArguments)
}
fun getFunctionLabel(f: IrFunction, parentId: Label<out DbElement>) =
getFunctionLabel(parentId, getFunctionShortName(f), f.valueParameters, f.returnType, f.extensionReceiverParameter)
fun getFunctionLabel(f: IrFunction, parentId: Label<out DbElement>, classTypeArguments: List<IrTypeArgument>?) =
getFunctionLabel(parentId, getFunctionShortName(f), f.valueParameters, f.returnType, f.extensionReceiverParameter, getFunctionTypeParameters(f), classTypeArguments)
fun getFunctionLabel(
parentId: Label<out DbElement>,
name: String,
parameters: List<IrValueParameter>,
returnType: IrType,
extensionReceiverParameter: IrValueParameter?
extensionReceiverParameter: IrValueParameter?,
functionTypeParameters: List<IrTypeParameter>,
classTypeArguments: List<IrTypeArgument>?
): String {
val allParams = if (extensionReceiverParameter == null) {
parameters
@@ -603,7 +611,12 @@ class X {
val paramTypeIds = allParams.joinToString { "{${useType(erase(it.type)).javaResult.id}}" }
val labelReturnType = if (name == "<init>") pluginContext.irBuiltIns.unitType else erase(returnType)
val returnTypeId = useType(labelReturnType, TypeContext.RETURN).javaResult.id
return "@\"callable;{$parentId}.$name($paramTypeIds){$returnTypeId}\""
// This suffix is added to generic methods (and constructors) to match the Java extractor's behaviour.
// Comments in that extractor indicates it didn't want the label of the callable to clash with the raw
// method (and presumably that disambiguation is never needed when the method belongs to a parameterized
// instance of a generic class), but as of now I don't know when the raw method would be referred to.
val typeArgSuffix = if (functionTypeParameters.isNotEmpty() && classTypeArguments.isNullOrEmpty()) "<${functionTypeParameters.size}>" else "";
return "@\"callable;{$parentId}.$name($paramTypeIds){$returnTypeId}${typeArgSuffix}\""
}
protected fun IrFunction.isLocalFunction(): Boolean {
@@ -665,8 +678,8 @@ class X {
}
}
fun <T: DbCallable> useFunction(f: IrFunction, parentId: Label<out DbElement>) =
useFunctionCommon<T>(f, getFunctionLabel(f, parentId))
fun <T: DbCallable> useFunction(f: IrFunction, parentId: Label<out DbElement>, classTypeArguments: List<IrTypeArgument>?) =
useFunctionCommon<T>(f, getFunctionLabel(f, parentId, classTypeArguments))
fun getTypeArgumentLabel(
arg: IrTypeArgument