diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 3e7eb6ae76e..ca602b3fc94 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -32,12 +32,12 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.JetTypeMapper; import org.jetbrains.kotlin.descriptors.*; +import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo; import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.load.java.JavaVisibilities; import org.jetbrains.kotlin.load.java.JvmAbi; import org.jetbrains.kotlin.load.java.JvmAnnotationNames; import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor; -import org.jetbrains.kotlin.jvm.RuntimeAssertionInfo; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage; @@ -330,13 +330,21 @@ public class AsmUtil { PropertyDescriptor property = ((PropertyAccessorDescriptor) memberDescriptor).getCorrespondingProperty(); if (property instanceof SyntheticJavaPropertyDescriptor) { FunctionDescriptor method = memberDescriptor == property.getGetter() - ? ((SyntheticJavaPropertyDescriptor) property).getGetMethod() - : ((SyntheticJavaPropertyDescriptor) property).getSetMethod(); - assert method != null : "No setMethod in SyntheticJavaPropertyDescriptor"; + ? ((SyntheticJavaPropertyDescriptor) property).getGetMethod() + : ((SyntheticJavaPropertyDescriptor) property).getSetMethod(); + assert method != null : "No get/set method in SyntheticJavaPropertyDescriptor: " + property; return getVisibilityAccessFlag(method); } } + if (memberDescriptor instanceof CallableDescriptor && memberVisibility == Visibilities.PROTECTED) { + for (CallableDescriptor overridden : DescriptorUtils.getAllOverriddenDescriptors((CallableDescriptor) memberDescriptor)) { + if (isInterface(overridden.getContainingDeclaration())) { + return ACC_PUBLIC; + } + } + } + if (!Visibilities.isPrivate(memberVisibility)) { return null; } diff --git a/compiler/testData/codegen/box/traits/inheritProtectedInterfaceMembers.kt b/compiler/testData/codegen/box/traits/inheritProtectedInterfaceMembers.kt new file mode 100644 index 00000000000..7c9a21dce3b --- /dev/null +++ b/compiler/testData/codegen/box/traits/inheritProtectedInterfaceMembers.kt @@ -0,0 +1,30 @@ +interface A { + protected fun foo() + + protected fun fooImpl() { } + + protected var bar: Int + + public var baz: String + public get() = "" + protected set(value) {} + + fun test(): String { + foo() + fooImpl() + bar = bar + 1 + baz = baz + "1" + return "OK" + } +} + +class B : A { + protected override fun foo() {} + + protected override var bar: Int = 42 + + override var baz: String = "" + protected set +} + +fun box() = B().test() diff --git a/compiler/testData/codegen/box/traits/protectedClassInInterface.kt b/compiler/testData/codegen/box/traits/protectedClassInInterface.kt new file mode 100644 index 00000000000..9ca4ffb4e68 --- /dev/null +++ b/compiler/testData/codegen/box/traits/protectedClassInInterface.kt @@ -0,0 +1,11 @@ +interface Foo { + protected class Bar { + fun box() = "OK" + } +} + +class Baz : Foo { + fun box() = Foo.Bar().box() +} + +fun box() = Baz().box() diff --git a/compiler/testData/codegen/box/traits/protectedFunDiamond.kt b/compiler/testData/codegen/box/traits/protectedFunDiamond.kt new file mode 100644 index 00000000000..6a75f82fc3d --- /dev/null +++ b/compiler/testData/codegen/box/traits/protectedFunDiamond.kt @@ -0,0 +1,15 @@ +interface A { + protected fun foo(): String + + fun box() = foo() +} + +interface B : A + +interface C : A { + protected override fun foo() = "OK" +} + +class D : B, C + +fun box() = D().box() diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java index 5ea2961c97a..82dd588851d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -7420,6 +7420,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("inheritProtectedInterfaceMembers.kt") + public void testInheritProtectedInterfaceMembers() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/inheritProtectedInterfaceMembers.kt"); + doTest(fileName); + } + @TestMetadata("inheritedFun.kt") public void testInheritedFun() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/inheritedFun.kt"); @@ -7516,6 +7522,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("protectedClassInInterface.kt") + public void testProtectedClassInInterface() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/protectedClassInInterface.kt"); + doTest(fileName); + } + + @TestMetadata("protectedFunDiamond.kt") + public void testProtectedFunDiamond() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/protectedFunDiamond.kt"); + doTest(fileName); + } + @TestMetadata("traitImplDelegationWithCovariantOverride.kt") public void testTraitImplDelegationWithCovariantOverride() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/box/traits/traitImplDelegationWithCovariantOverride.kt");