diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 6475f1074ae..1b093825447 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -310,11 +310,11 @@ public class AsmUtil { @Nullable private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor) { DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration(); + Visibility memberVisibility = memberDescriptor.getVisibility(); if (isInterface(containingDeclaration)) { - return ACC_PUBLIC; + return memberVisibility == Visibilities.PRIVATE ? NO_FLAG_PACKAGE_PRIVATE : ACC_PUBLIC; } - Visibility memberVisibility = memberDescriptor.getVisibility(); if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) { return ACC_PUBLIC; } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index 43c4bf67211..a0d3c93835b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -142,6 +142,12 @@ public class FunctionCodegen { @NotNull FunctionGenerationStrategy strategy ) { OwnerKind contextKind = methodContext.getContextKind(); + if (isTrait(functionDescriptor.getContainingDeclaration()) && + functionDescriptor.getVisibility() == Visibilities.PRIVATE && + contextKind != OwnerKind.TRAIT_IMPL) { + return; + } + JvmMethodSignature jvmSignature = typeMapper.mapSignature(functionDescriptor, contextKind); Method asmMethod = jvmSignature.getAsmMethod(); @@ -577,9 +583,7 @@ public class FunctionCodegen { ) { DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration(); - if (kind != OwnerKind.TRAIT_IMPL && - contextClass instanceof ClassDescriptor && - ((ClassDescriptor) contextClass).getKind() == ClassKind.INTERFACE) { + if (kind != OwnerKind.TRAIT_IMPL && isTrait(contextClass)) { return; } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java index f8d8143d226..b7912441561 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java @@ -55,6 +55,7 @@ import java.io.File; import static org.jetbrains.kotlin.descriptors.Modality.ABSTRACT; import static org.jetbrains.kotlin.descriptors.Modality.FINAL; +import static org.jetbrains.kotlin.resolve.DescriptorUtils.isTrait; public class JvmCodegenUtil { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java index bf1c4772a95..6ffd2b6677a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/JetTypeMapper.java @@ -58,11 +58,9 @@ import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature; import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature; import org.jetbrains.kotlin.resolve.scopes.AbstractScopeAdapter; -import org.jetbrains.kotlin.resolve.scopes.ChainedScope; import org.jetbrains.kotlin.resolve.scopes.JetScope; import org.jetbrains.kotlin.serialization.deserialization.DeserializedType; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor; -import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope; import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.expressions.OperatorConventions; import org.jetbrains.org.objectweb.asm.Type; @@ -625,7 +623,7 @@ public class JetTypeMapper { ownerForDefaultParam = mapClass(ownerForDefault); ownerForDefaultImpl = isInterface(ownerForDefault) ? mapTraitImpl(ownerForDefault) : ownerForDefaultParam; - if (isInterface && superCall) { + if (isInterface && (superCall || descriptor.getVisibility() == Visibilities.PRIVATE)) { thisClass = mapClass(currentOwner); if (declarationOwner instanceof JavaClassDescriptor) { invokeOpcode = INVOKESPECIAL; diff --git a/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PrivateInTrait.java b/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PrivateInTrait.java index 2cac91c83cf..d64ea0c1fd6 100644 --- a/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PrivateInTrait.java +++ b/compiler/testData/asJava/lightClasses/nullabilityAnnotations/PrivateInTrait.java @@ -1,12 +1,2 @@ public interface PrivateInTrait { - @org.jetbrains.annotations.NotNull - java.lang.String getNn(); - - void setNn(@org.jetbrains.annotations.NotNull java.lang.String value); - - @org.jetbrains.annotations.Nullable - java.lang.String getN(); - - @org.jetbrains.annotations.Nullable - java.lang.String bar(@org.jetbrains.annotations.NotNull java.lang.String a, @org.jetbrains.annotations.Nullable java.lang.String b); } diff --git a/compiler/testData/codegen/box/traits/traitWithPrivateMember.kt b/compiler/testData/codegen/box/traits/traitWithPrivateMember.kt new file mode 100644 index 00000000000..50debaa1e26 --- /dev/null +++ b/compiler/testData/codegen/box/traits/traitWithPrivateMember.kt @@ -0,0 +1,26 @@ +interface Z { + + fun testFun() : String { + return privateFun() + } + + fun testProperty() : String { + return privateProp + } + + private fun privateFun(): String { + return "O" + } + + private val privateProp: String + get() = "K" +} + +object Z2 : Z { + +} + +fun box() : String { + return Z2.testFun() + Z2.testProperty() +} + diff --git a/compiler/testData/codegen/box/traits/traitWithPrivateMemberAccessFromLambda.kt b/compiler/testData/codegen/box/traits/traitWithPrivateMemberAccessFromLambda.kt new file mode 100644 index 00000000000..0b2a16072d3 --- /dev/null +++ b/compiler/testData/codegen/box/traits/traitWithPrivateMemberAccessFromLambda.kt @@ -0,0 +1,26 @@ +interface Z { + + fun testFun(): String { + return { privateFun() } () + } + + fun testProperty(): String { + return { privateProp } () + } + + private fun privateFun(): String { + return "O" + } + + private val privateProp: String + get() = "K" +} + +object Z2 : Z { + +} + +fun box(): String { + return Z2.testFun() + Z2.testProperty() +} + diff --git a/compiler/testData/codegen/bytecodeText/interfaces/noPrivateMemberInJavaInterface.kt b/compiler/testData/codegen/bytecodeText/interfaces/noPrivateMemberInJavaInterface.kt new file mode 100644 index 00000000000..8f97d153bd9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/interfaces/noPrivateMemberInJavaInterface.kt @@ -0,0 +1,17 @@ +interface A { + + private val prop: String + get() = "1" + + private fun foo() { + + } + + private fun defaultFun(p: String = "OK") { + + } +} + +// 1 foo +// 1 getProp +// 1 defaultFun\$ \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index e06e6b389d4..c7f0cbeadeb 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -544,6 +544,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("noPrivateMemberInJavaInterface.kt") + public void testNoPrivateMemberInJavaInterface() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/interfaces/noPrivateMemberInJavaInterface.kt"); + doTest(fileName); + } + @TestMetadata("traitImplGeneratedOnce.kt") public void testTraitImplGeneratedOnce() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/interfaces/traitImplGeneratedOnce.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index 4ae05fd5130..6f08b16af91 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -7593,6 +7593,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/traitWithPrivateExtension.kt"); doTest(fileName); } + + @TestMetadata("traitWithPrivateMember.kt") + public void testTraitWithPrivateMember() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/traitWithPrivateMember.kt"); + doTest(fileName); + } + + @TestMetadata("traitWithPrivateMemberAccessFromLambda.kt") + public void testTraitWithPrivateMemberAccessFromLambda() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/traitWithPrivateMemberAccessFromLambda.kt"); + doTest(fileName); + } } @TestMetadata("compiler/testData/codegen/box/typeInfo")