JVM_IR: fix inner class attributes for private class in interface

This commit is contained in:
Dmitry Petrov
2020-07-23 15:46:43 +03:00
parent 0741781462
commit e2a4ca10d6
5 changed files with 48 additions and 25 deletions
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.lower.allOverridden
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.lower.MultifileFacadeFileEntry
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.codegen.*
@@ -33,7 +32,7 @@ import org.jetbrains.kotlin.load.java.JavaVisibilities
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.inline.*
import org.jetbrains.kotlin.resolve.inline.INLINE_ONLY_ANNOTATION_FQ_NAME
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -73,8 +72,7 @@ val IrClass.isJvmInterface get() = isAnnotationClass || isInterface
val IrDeclaration.fileParent: IrFile
get() {
val myParent = parent
return when (myParent) {
return when (val myParent = parent) {
is IrFile -> myParent
else -> (myParent as IrDeclaration).fileParent
}
@@ -103,7 +101,7 @@ fun JvmBackendContext.getSourceMapper(declaration: IrClass): SourceMapper {
}
val IrType.isExtensionFunctionType: Boolean
get() = isFunctionTypeOrSubtype() && hasAnnotation(KotlinBuiltIns.FQ_NAMES.extensionFunctionType)
get() = isFunctionTypeOrSubtype() && hasAnnotation(FQ_NAMES.extensionFunctionType)
/* Borrowed with modifications from MemberCodegen.java */
@@ -121,23 +119,13 @@ fun writeInnerClass(innerClass: IrClass, typeMapper: IrTypeMapper, context: JvmB
private val NO_FLAG_LOCAL = 0
private val visibilityToAccessFlag = mapOf(
Visibilities.PRIVATE to Opcodes.ACC_PRIVATE,
Visibilities.PRIVATE_TO_THIS to Opcodes.ACC_PRIVATE,
Visibilities.PROTECTED to Opcodes.ACC_PROTECTED,
JavaVisibilities.PROTECTED_STATIC_VISIBILITY to Opcodes.ACC_PROTECTED,
JavaVisibilities.PROTECTED_AND_PACKAGE to Opcodes.ACC_PROTECTED,
Visibilities.PUBLIC to Opcodes.ACC_PUBLIC,
Visibilities.INTERNAL to Opcodes.ACC_PUBLIC,
Visibilities.LOCAL to NO_FLAG_LOCAL,
JavaVisibilities.PACKAGE_VISIBILITY to AsmUtil.NO_FLAG_PACKAGE_PRIVATE
)
private fun IrDeclaration.getVisibilityAccessFlagForAnonymous(): Int =
if (isInlineOrContainedInInline(parent as? IrDeclaration)) Opcodes.ACC_PUBLIC else AsmUtil.NO_FLAG_PACKAGE_PRIVATE
fun IrClass.calculateInnerClassAccessFlags(context: JvmBackendContext): Int {
val isLambda = superTypes.any { it.safeAs<IrSimpleType>()?.classifier === context.ir.symbols.lambdaClass }
val isLambda = superTypes.any {
it.safeAs<IrSimpleType>()?.classifier === context.ir.symbols.lambdaClass
}
val visibility = when {
isLambda -> getVisibilityAccessFlagForAnonymous()
visibility === Visibilities.LOCAL -> Opcodes.ACC_PUBLIC
@@ -165,18 +153,30 @@ private fun IrClass.innerAccessFlagsForModalityAndKind(): Int {
return 0
}
fun IrDeclarationWithVisibility.getVisibilityAccessFlag(kind: OwnerKind? = null): Int =
specialCaseVisibility(kind)
?: visibilityToAccessFlag[visibility]
?: throw IllegalStateException("$visibility is not a valid visibility in backend for ${ir2string(this)}")
fun IrDeclarationWithVisibility.getVisibilityAccessFlag(kind: OwnerKind? = null): Int {
specialCaseVisibility(kind)?.let {
return it
}
return when (visibility) {
Visibilities.PRIVATE -> Opcodes.ACC_PRIVATE
Visibilities.PRIVATE_TO_THIS -> Opcodes.ACC_PRIVATE
Visibilities.PROTECTED -> Opcodes.ACC_PROTECTED
JavaVisibilities.PROTECTED_STATIC_VISIBILITY -> Opcodes.ACC_PROTECTED
JavaVisibilities.PROTECTED_AND_PACKAGE -> Opcodes.ACC_PROTECTED
Visibilities.PUBLIC -> Opcodes.ACC_PUBLIC
Visibilities.INTERNAL -> Opcodes.ACC_PUBLIC
Visibilities.LOCAL -> NO_FLAG_LOCAL
JavaVisibilities.PACKAGE_VISIBILITY -> AsmUtil.NO_FLAG_PACKAGE_PRIVATE
else -> throw IllegalStateException("$visibility is not a valid visibility in backend for ${ir2string(this)}")
}
}
private fun IrDeclarationWithVisibility.specialCaseVisibility(kind: OwnerKind?): Int? {
// if (JvmCodegenUtil.isNonIntrinsicPrivateCompanionObjectInInterface(memberDescriptor)) {
// return ACC_PUBLIC
// }
if (this is IrClass && Visibilities.isPrivate(visibility) &&
hasInterfaceParent()
) { // TODO: non-intrinsic
if (this is IrClass && Visibilities.isPrivate(visibility) && isCompanion && hasInterfaceParent()) {
// TODO: non-intrinsic
return Opcodes.ACC_PUBLIC
}
@@ -0,0 +1,3 @@
interface IFoo {
private class Nested
}
@@ -0,0 +1,10 @@
@kotlin.Metadata
final class IFoo$Nested {
public method <init>(): void
private final inner class IFoo$Nested
}
@kotlin.Metadata
public interface IFoo {
private final inner class IFoo$Nested
}
@@ -144,6 +144,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultSetter.kt");
}
@TestMetadata("privateNestedClassInInterface.kt")
public void testPrivateNestedClassInInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/privateNestedClassInInterface.kt");
}
@TestMetadata("samAdapterAndInlinedOne.kt")
public void testSamAdapterAndInlinedOne() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");
@@ -144,6 +144,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
runTest("compiler/testData/codegen/bytecodeListing/privateDefaultSetter.kt");
}
@TestMetadata("privateNestedClassInInterface.kt")
public void testPrivateNestedClassInInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/privateNestedClassInInterface.kt");
}
@TestMetadata("samAdapterAndInlinedOne.kt")
public void testSamAdapterAndInlinedOne() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/samAdapterAndInlinedOne.kt");