diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java index 537d52aca79..cf39bc3857c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AsmUtil.java @@ -46,6 +46,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmClassName; import org.jetbrains.kotlin.resolve.jvm.JvmPackage; import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType; import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin; +import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor; import org.jetbrains.kotlin.types.JetType; import org.jetbrains.kotlin.types.TypesPackage; import org.jetbrains.org.objectweb.asm.*; @@ -308,19 +309,38 @@ public class AsmUtil { if (isInterface(containingDeclaration)) { return ACC_PUBLIC; } + Visibility memberVisibility = memberDescriptor.getVisibility(); if (memberVisibility == Visibilities.LOCAL && memberDescriptor instanceof CallableMemberDescriptor) { return ACC_PUBLIC; } + if (isEnumEntry(memberDescriptor)) { return NO_FLAG_PACKAGE_PRIVATE; } + if (memberDescriptor instanceof ConstructorDescriptor && isAnonymousObject(memberDescriptor.getContainingDeclaration())) { return NO_FLAG_PACKAGE_PRIVATE; } + + if (memberDescriptor instanceof SyntheticJavaPropertyDescriptor) { + return getVisibilityAccessFlag(((SyntheticJavaPropertyDescriptor) memberDescriptor).getGetMethod()); + } + if (memberDescriptor instanceof PropertyAccessorDescriptor) { + 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"; + return getVisibilityAccessFlag(method); + } + } + if (!Visibilities.isPrivate(memberVisibility)) { return null; } + // the following code is only for PRIVATE visibility of member if (memberDescriptor instanceof ConstructorDescriptor) { if (isNonCompanionObject(containingDeclaration) || isEnumEntry(containingDeclaration)) { @@ -332,6 +352,7 @@ public class AsmUtil { return ACC_PROTECTED; } } + if (containingDeclaration instanceof PackageFragmentDescriptor) { return ACC_PUBLIC; } diff --git a/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protected.java b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protected.java new file mode 100644 index 00000000000..b0c502c2e5d --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protected.java @@ -0,0 +1,3 @@ +public class _protected { + protected String getOk() { return "OK"; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protected.kt b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protected.kt new file mode 100644 index 00000000000..2b0cece6e0f --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protected.kt @@ -0,0 +1,11 @@ +package p + +import _protected + +fun box(): String { + return KotlinClass().ok() +} + +class KotlinClass : _protected() { + fun ok() = ok +} diff --git a/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protectedSetter.java b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protectedSetter.java new file mode 100644 index 00000000000..3a71175b66e --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protectedSetter.java @@ -0,0 +1,6 @@ +public class _protectedSetter { + private String x = null; + + public String getX() { return "OK"; } + protected void setX(String x) { this.x = x; } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protectedSetter.kt b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protectedSetter.kt new file mode 100644 index 00000000000..58fd8472e9b --- /dev/null +++ b/compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protectedSetter.kt @@ -0,0 +1,15 @@ +package p + +import _protectedSetter + +fun box(): String { + return KotlinClass().ok() +} + +class KotlinClass : _protectedSetter() { + fun ok(): String { + x = "o" + x += "k" + return x + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxAgainstJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxAgainstJavaCodegenTestGenerated.java index 6a7c85ce297..fe52df32d4a 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxAgainstJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxAgainstJavaCodegenTestGenerated.java @@ -894,6 +894,18 @@ public class BlackBoxAgainstJavaCodegenTestGenerated extends AbstractBlackBoxCod String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/syntheticExtensions/setter.kt"); doTestAgainstJava(fileName); } + + @TestMetadata("_protected.kt") + public void test_protected() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protected.kt"); + doTestAgainstJava(fileName); + } + + @TestMetadata("_protectedSetter.kt") + public void test_protectedSetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxAgainstJava/syntheticExtensions/_protectedSetter.kt"); + doTestAgainstJava(fileName); + } } @TestMetadata("compiler/testData/codegen/boxAgainstJava/visibility")