Support access to protected members within inline functions

This commit is contained in:
Michael Bogdanov
2015-11-11 11:54:15 +03:00
parent 5a8ead0092
commit 3651ec9294
7 changed files with 99 additions and 8 deletions
@@ -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()
}
}
@@ -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,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()
}
}
@@ -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");
@@ -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");