Merge pull request #10853 from smowton/smowton/fix/specialised-anon-classes

Kotlin: extract called private methods of specialised types, and specialised instances of anonymous types
This commit is contained in:
Chris Smowton
2022-10-19 16:48:28 +01:00
committed by GitHub
12 changed files with 193 additions and 155 deletions

View File

@@ -120,11 +120,7 @@ open class KotlinFileExtractor(
}
private fun shouldExtractDecl(declaration: IrDeclaration, extractPrivateMembers: Boolean) =
extractPrivateMembers ||
when(declaration) {
is IrDeclarationWithVisibility -> declaration.visibility.let { it != DescriptorVisibilities.PRIVATE && it != DescriptorVisibilities.PRIVATE_TO_THIS }
else -> true
}
extractPrivateMembers || !isPrivate(declaration)
fun extractDeclaration(declaration: IrDeclaration, extractPrivateMembers: Boolean, extractFunctionBodies: Boolean) {
with("declaration", declaration) {
@@ -367,23 +363,37 @@ open class KotlinFileExtractor(
}
}
private fun makeTypeParamSubstitution(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?) =
when (argsIncludingOuterClasses) {
null -> { x: IrType, _: TypeContext, _: IrPluginContext -> x.toRawType() }
else -> makeGenericSubstitutionFunction(c, argsIncludingOuterClasses)
}
fun extractDeclarationPrototype(d: IrDeclaration, parentId: Label<out DbReftype>, argsIncludingOuterClasses: List<IrTypeArgument>?, typeParamSubstitutionQ: TypeSubstitution? = null) {
val typeParamSubstitution = typeParamSubstitutionQ ?:
when(val parent = d.parent) {
is IrClass -> makeTypeParamSubstitution(parent, argsIncludingOuterClasses)
else -> {
logger.warnElement("Unable to extract prototype of local declaration", d)
return
}
}
when (d) {
is IrFunction -> extractFunction(d, parentId, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses)
is IrProperty -> extractProperty(d, parentId, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses)
else -> {}
}
}
// `argsIncludingOuterClasses` can be null to describe a raw generic type.
// For non-generic types it will be zero-length list.
private fun extractNonPrivateMemberPrototypes(c: IrClass, argsIncludingOuterClasses: List<IrTypeArgument>?, id: Label<out DbClassorinterface>) {
with("member prototypes", c) {
val typeParamSubstitution =
when (argsIncludingOuterClasses) {
null -> { x: IrType, _: TypeContext, _: IrPluginContext -> x.toRawType() }
else -> makeGenericSubstitutionFunction(c, argsIncludingOuterClasses)
}
val typeParamSubstitution = makeTypeParamSubstitution(c, argsIncludingOuterClasses)
c.declarations.map {
if (shouldExtractDecl(it, false)) {
when(it) {
is IrFunction -> extractFunction(it, id, extractBody = false, extractMethodAndParameterTypeAccesses = false, typeParamSubstitution, argsIncludingOuterClasses)
is IrProperty -> extractProperty(it, id, extractBackingField = false, extractFunctionBodies = false, extractPrivateMembers = false, typeParamSubstitution, argsIncludingOuterClasses)
else -> {}
}
extractDeclarationPrototype(it, id, argsIncludingOuterClasses, typeParamSubstitution)
}
}
}
@@ -583,12 +593,7 @@ open class KotlinFileExtractor(
var parent: IrDeclarationParent? = declarationParent
while (parent != null) {
if (parent is IrClass) {
val parentId =
if (parent.isAnonymousObject) {
useAnonymousClass(parent).javaResult.id.cast<DbClass>()
} else {
useClassInstance(parent, parentClassTypeArguments).typeResult.id
}
val parentId = useClassInstance(parent, parentClassTypeArguments).typeResult.id
tw.writeEnclInReftype(innerId, parentId)
if (innerClass != null && innerClass.isCompanion) {
// If we are a companion then our parent has a
@@ -868,7 +873,7 @@ open class KotlinFileExtractor(
extractTypeAccess(useType(paramType), locId, paramId, -1)
}
}
val paramsSignature = allParamTypeResults.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature }
val paramsSignature = allParamTypeResults.joinToString(separator = ",", prefix = "(", postfix = ")") { signatureOrWarn(it.javaResult, f) }
val shortName = getDefaultsMethodName(f)
if (f.symbol is IrConstructorSymbol) {
@@ -1078,6 +1083,14 @@ open class KotlinFileExtractor(
}
}
private fun signatureOrWarn(t: TypeResult<*>, associatedElement: IrElement?) =
t.signature ?: "<signature unavailable>".also {
if (associatedElement != null)
logger.warnElement("Needed a signature for a type that doesn't have one", associatedElement)
else
logger.warn("Needed a signature for a type that doesn't have one")
}
private fun forceExtractFunction(f: IrFunction, parentId: Label<out DbReftype>, extractBody: Boolean, extractMethodAndParameterTypeAccesses: Boolean, typeSubstitution: TypeSubstitution?, classTypeArgsIncludingOuterClasses: List<IrTypeArgument>?, extractOrigin: Boolean = true, overriddenAttributes: OverriddenFunctionAttributes? = null): Label<out DbCallable> {
with("function", f) {
DeclarationStackAdjuster(f, overriddenAttributes).use {
@@ -1114,7 +1127,7 @@ open class KotlinFileExtractor(
paramTypes
}
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { it.javaResult.signature }
val paramsSignature = allParamTypes.joinToString(separator = ",", prefix = "(", postfix = ")") { signatureOrWarn(it.javaResult, f) }
val adjustedReturnType = addJavaLoweringWildcards(getAdjustedReturnType(f), false, (javaCallable as? JavaMethod)?.returnType)
val substReturnType = typeSubstitution?.let { it(adjustedReturnType, TypeContext.RETURN, pluginContext) } ?: adjustedReturnType
@@ -2952,20 +2965,8 @@ open class KotlinFileExtractor(
logger.errorElement("Constructor call has non-simple type ${eType.javaClass}", e)
return
}
val type = useType(eType)
val isAnonymous = eType.isAnonymous
val type: TypeResults = if (isAnonymous) {
if (e.typeArgumentsCount > 0) {
logger.warnElement("Unexpected type arguments (${e.typeArgumentsCount}) for anonymous class constructor call", e)
}
val c = eType.classifier.owner
if (c !is IrClass) {
logger.errorElement("Anonymous constructor call type not a class (${c.javaClass})", e)
return
}
useAnonymousClass(c)
} else {
useType(eType)
}
val locId = tw.getLocation(e)
val valueArgs = (0 until e.valueArgumentsCount).map { e.getValueArgument(it) }
// For now, don't try to use default methods for enum constructor calls,
@@ -2982,7 +2983,7 @@ open class KotlinFileExtractor(
}
if (isAnonymous) {
tw.writeIsAnonymClass(type.javaResult.id.cast<DbClass>(), id)
tw.writeIsAnonymClass(type.javaResult.id.cast(), id)
}
val dr = e.dispatchReceiver
@@ -4640,7 +4641,7 @@ open class KotlinFileExtractor(
Pair(paramId, paramType)
}
val paramsSignature = parameters.joinToString(separator = ",", prefix = "(", postfix = ")") { it.second.javaResult.signature }
val paramsSignature = parameters.joinToString(separator = ",", prefix = "(", postfix = ")") { signatureOrWarn(it.second.javaResult, declarationStack.tryPeek()?.first) }
val rt = useType(returnType, TypeContext.RETURN)
tw.writeMethods(methodId, name, "$name$paramsSignature", rt.javaResult.id, parentId, methodId)
@@ -5359,6 +5360,8 @@ open class KotlinFileExtractor(
fun peek() = stack.peek()
fun tryPeek() = if (stack.isEmpty()) null else stack.peek()
fun findOverriddenAttributes(f: IrFunction) =
stack.lastOrNull { it.first == f } ?.second