Support access to protected members within inline functions
This commit is contained in:
@@ -556,14 +556,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
|
||||
if (descriptorContext == null && withinInliningContext && superCallTarget != null) {
|
||||
//generate super callы within inline function through synthetic accessors
|
||||
//generate super calls within inline function through synthetic accessors
|
||||
descriptorContext = ExpressionCodegen.getParentContextSubclassOf((ClassDescriptor) enclosed, this);
|
||||
}
|
||||
|
||||
if (descriptorContext == null) {
|
||||
return descriptor;
|
||||
}
|
||||
boolean isSuperCallInsideInline = withinInliningContext && superCallTarget != null;
|
||||
if (descriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||
int propertyAccessFlag = getVisibilityAccessFlag(descriptor);
|
||||
@@ -572,13 +571,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
int getterAccessFlag = getter == null ? propertyAccessFlag
|
||||
: propertyAccessFlag | getVisibilityAccessFlag(getter);
|
||||
boolean getterAccessorRequired = isAccessorRequired(getterAccessFlag, unwrappedDescriptor, descriptorContext,
|
||||
isSuperCallInsideInline);
|
||||
withinInliningContext, superCallTarget != null);
|
||||
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
int setterAccessFlag = setter == null ? propertyAccessFlag
|
||||
: propertyAccessFlag | getVisibilityAccessFlag(setter);
|
||||
boolean setterAccessorRequired = isAccessorRequired(setterAccessFlag, unwrappedDescriptor, descriptorContext,
|
||||
isSuperCallInsideInline);
|
||||
withinInliningContext, superCallTarget != null);
|
||||
|
||||
if (!getterAccessorRequired && !setterAccessorRequired) {
|
||||
return descriptor;
|
||||
@@ -587,7 +586,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
}
|
||||
else {
|
||||
int flag = getVisibilityAccessFlag(unwrappedDescriptor);
|
||||
if (!isAccessorRequired(flag, unwrappedDescriptor, descriptorContext, isSuperCallInsideInline)) {
|
||||
if (!isAccessorRequired(flag, unwrappedDescriptor, descriptorContext, withinInliningContext, superCallTarget != null)) {
|
||||
return descriptor;
|
||||
}
|
||||
return (D) descriptorContext.getAccessor(descriptor, superCallTarget);
|
||||
@@ -598,10 +597,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
int accessFlag,
|
||||
@NotNull CallableMemberDescriptor unwrappedDescriptor,
|
||||
@NotNull CodegenContext descriptorContext,
|
||||
boolean isSuperCallInsideInline
|
||||
boolean withinInline,
|
||||
boolean isSuperCall
|
||||
) {
|
||||
return isSuperCallInsideInline || (accessFlag & ACC_PRIVATE) != 0 ||
|
||||
((accessFlag & ACC_PROTECTED) != 0 && !isInSamePackage(unwrappedDescriptor, descriptorContext.getContextDescriptor()));
|
||||
return isSuperCall && withinInline ||
|
||||
(accessFlag & ACC_PRIVATE) != 0 ||
|
||||
((accessFlag & ACC_PROTECTED) != 0 &&
|
||||
(withinInline || !isInSamePackage(unwrappedDescriptor, descriptorContext.getContextDescriptor())));
|
||||
}
|
||||
|
||||
private static boolean isInSamePackage(DeclarationDescriptor descriptor1, DeclarationDescriptor descriptor2) {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import test.*
|
||||
|
||||
class A: P() {
|
||||
override val FOO: String
|
||||
get() = "fail"
|
||||
|
||||
override fun test(): String {
|
||||
return "fail"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val p = P()
|
||||
return p.protectedProp() + p.protectedFun()
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package test
|
||||
|
||||
open class P {
|
||||
protected open val FOO = "O"
|
||||
|
||||
protected open fun test() = "K"
|
||||
|
||||
inline fun protectedProp(): String {
|
||||
return FOO
|
||||
}
|
||||
|
||||
inline fun protectedFun(): String {
|
||||
return test()
|
||||
}
|
||||
}
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import test.*
|
||||
|
||||
class A: P() {
|
||||
override val FOO: String
|
||||
get() = "fail"
|
||||
|
||||
override fun test(): String {
|
||||
return "fail"
|
||||
}
|
||||
}
|
||||
|
||||
fun box() : String {
|
||||
val p = P()
|
||||
return p.protectedProp() + p.protectedFun()
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package test
|
||||
|
||||
open class Base {
|
||||
protected open val FOO = "O"
|
||||
|
||||
protected open fun test() = "K"
|
||||
}
|
||||
|
||||
open class P : Base() {
|
||||
|
||||
inline fun protectedProp(): String {
|
||||
return FOO
|
||||
}
|
||||
|
||||
inline fun protectedFun(): String {
|
||||
return test()
|
||||
}
|
||||
}
|
||||
|
||||
+12
@@ -1381,6 +1381,18 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("protectedMembers.1.kt")
|
||||
public void testProtectedMembers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/protectedMembers.1.kt");
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("protectedMembersFromSuper.1.kt")
|
||||
public void testProtectedMembersFromSuper() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/protectedMembersFromSuper.1.kt");
|
||||
doTestMultiFileWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("superCall.1.kt")
|
||||
public void testSuperCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/superCall.1.kt");
|
||||
|
||||
+12
@@ -1381,6 +1381,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("protectedMembers.1.kt")
|
||||
public void testProtectedMembers() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/protectedMembers.1.kt");
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("protectedMembersFromSuper.1.kt")
|
||||
public void testProtectedMembersFromSuper() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/protectedMembersFromSuper.1.kt");
|
||||
doBoxTestWithInlineCheck(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("superCall.1.kt")
|
||||
public void testSuperCall() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/superCall.1.kt");
|
||||
|
||||
Reference in New Issue
Block a user