diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java index e1389b9278e..3d6c22506d5 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/context/CodegenContext.java @@ -580,7 +580,8 @@ public abstract class CodegenContext { superCallTarget = (ClassDescriptor) enclosed; } - if (descriptorContext == null && withinInliningContext && superCallTarget != null) { + boolean isSuperCallTarget = superCallTarget != null; + if (descriptorContext == null && withinInliningContext && isSuperCallTarget) { //generate super calls within inline function through synthetic accessors descriptorContext = ExpressionCodegen.getParentContextSubclassOf((ClassDescriptor) enclosed, this); } @@ -606,8 +607,9 @@ public abstract class CodegenContext { PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); int getterAccessFlag = getter == null ? propertyAccessFlag : propertyAccessFlag | getVisibilityAccessFlag(getter); - boolean getterAccessorRequired = isAccessorRequired(getterAccessFlag, unwrappedDescriptor, descriptorContext, - withinInliningContext, superCallTarget != null); + boolean getterAccessorRequired = + canGenerateAccessorInContext(getter == null ? propertyDescriptor : getter, descriptorContext) && + isAccessorRequired(getterAccessFlag, unwrappedDescriptor, descriptorContext, withinInliningContext, isSuperCallTarget); PropertySetterDescriptor setter = propertyDescriptor.getSetter(); @@ -615,8 +617,9 @@ public abstract class CodegenContext { if (setter != null && setter.getVisibility().normalize() != Visibilities.INVISIBLE_FAKE) { setterAccessFlag = propertyAccessFlag | getVisibilityAccessFlag(setter); } - boolean setterAccessorRequired = isAccessorRequired(setterAccessFlag, unwrappedDescriptor, descriptorContext, - withinInliningContext, superCallTarget != null); + boolean setterAccessorRequired = + canGenerateAccessorInContext(setter == null ? propertyDescriptor : setter, descriptorContext) && + isAccessorRequired(setterAccessFlag, unwrappedDescriptor, descriptorContext, withinInliningContext, isSuperCallTarget); if (!getterAccessorRequired && !setterAccessorRequired) { return descriptor; @@ -625,13 +628,20 @@ public abstract class CodegenContext { } else { int flag = getVisibilityAccessFlag(unwrappedDescriptor); - if (!isAccessorRequired(flag, unwrappedDescriptor, descriptorContext, withinInliningContext, superCallTarget != null)) { + if (!isAccessorRequired(flag, unwrappedDescriptor, descriptorContext, withinInliningContext, isSuperCallTarget)) { return descriptor; } return (D) descriptorContext.getAccessor(descriptor, superCallTarget); } } + private static boolean canGenerateAccessorInContext( + @NotNull CallableMemberDescriptor callableDescriptor, + @NotNull CodegenContext hostContext + ) { + return Visibilities.isVisibleWithAnyReceiver(callableDescriptor, hostContext.contextDescriptor); + } + private static boolean isAccessorRequired( int accessFlag, @NotNull CallableMemberDescriptor unwrappedDescriptor, diff --git a/compiler/testData/writeFlags/property/accessors/accessorForProtectedPropertyWithPrivateSetter.kt b/compiler/testData/writeFlags/property/accessors/accessorForProtectedPropertyWithPrivateSetter.kt new file mode 100644 index 00000000000..27bbcd391c5 --- /dev/null +++ b/compiler/testData/writeFlags/property/accessors/accessorForProtectedPropertyWithPrivateSetter.kt @@ -0,0 +1,24 @@ +// FILE: A.kt +package a + +abstract class A { + protected var property: String = "" + private set +} + +// FILE: B.kt +package b + +import a.A + +class B : A() { + init { + invoke { property } + } + + fun invoke(func: () -> String): String = func() +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: b/B, access$setProperty$p +// ABSENT: true \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java index d594273b59c..986fcee45ba 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java @@ -746,6 +746,21 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/writeFlags/property"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); } + @TestMetadata("compiler/testData/writeFlags/property/accessors") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Accessors extends AbstractWriteFlagsTest { + @TestMetadata("accessorForProtectedPropertyWithPrivateSetter.kt") + public void testAccessorForProtectedPropertyWithPrivateSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/writeFlags/property/accessors/accessorForProtectedPropertyWithPrivateSetter.kt"); + doTest(fileName); + } + + public void testAllFilesPresentInAccessors() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/writeFlags/property/accessors"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + } + @TestMetadata("compiler/testData/writeFlags/property/classObject") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)