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) {
|
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);
|
descriptorContext = ExpressionCodegen.getParentContextSubclassOf((ClassDescriptor) enclosed, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptorContext == null) {
|
if (descriptorContext == null) {
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
boolean isSuperCallInsideInline = withinInliningContext && superCallTarget != null;
|
|
||||||
if (descriptor instanceof PropertyDescriptor) {
|
if (descriptor instanceof PropertyDescriptor) {
|
||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||||
int propertyAccessFlag = getVisibilityAccessFlag(descriptor);
|
int propertyAccessFlag = getVisibilityAccessFlag(descriptor);
|
||||||
@@ -572,13 +571,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
int getterAccessFlag = getter == null ? propertyAccessFlag
|
int getterAccessFlag = getter == null ? propertyAccessFlag
|
||||||
: propertyAccessFlag | getVisibilityAccessFlag(getter);
|
: propertyAccessFlag | getVisibilityAccessFlag(getter);
|
||||||
boolean getterAccessorRequired = isAccessorRequired(getterAccessFlag, unwrappedDescriptor, descriptorContext,
|
boolean getterAccessorRequired = isAccessorRequired(getterAccessFlag, unwrappedDescriptor, descriptorContext,
|
||||||
isSuperCallInsideInline);
|
withinInliningContext, superCallTarget != null);
|
||||||
|
|
||||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||||
int setterAccessFlag = setter == null ? propertyAccessFlag
|
int setterAccessFlag = setter == null ? propertyAccessFlag
|
||||||
: propertyAccessFlag | getVisibilityAccessFlag(setter);
|
: propertyAccessFlag | getVisibilityAccessFlag(setter);
|
||||||
boolean setterAccessorRequired = isAccessorRequired(setterAccessFlag, unwrappedDescriptor, descriptorContext,
|
boolean setterAccessorRequired = isAccessorRequired(setterAccessFlag, unwrappedDescriptor, descriptorContext,
|
||||||
isSuperCallInsideInline);
|
withinInliningContext, superCallTarget != null);
|
||||||
|
|
||||||
if (!getterAccessorRequired && !setterAccessorRequired) {
|
if (!getterAccessorRequired && !setterAccessorRequired) {
|
||||||
return descriptor;
|
return descriptor;
|
||||||
@@ -587,7 +586,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int flag = getVisibilityAccessFlag(unwrappedDescriptor);
|
int flag = getVisibilityAccessFlag(unwrappedDescriptor);
|
||||||
if (!isAccessorRequired(flag, unwrappedDescriptor, descriptorContext, isSuperCallInsideInline)) {
|
if (!isAccessorRequired(flag, unwrappedDescriptor, descriptorContext, withinInliningContext, superCallTarget != null)) {
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
return (D) descriptorContext.getAccessor(descriptor, superCallTarget);
|
return (D) descriptorContext.getAccessor(descriptor, superCallTarget);
|
||||||
@@ -598,10 +597,13 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
|||||||
int accessFlag,
|
int accessFlag,
|
||||||
@NotNull CallableMemberDescriptor unwrappedDescriptor,
|
@NotNull CallableMemberDescriptor unwrappedDescriptor,
|
||||||
@NotNull CodegenContext descriptorContext,
|
@NotNull CodegenContext descriptorContext,
|
||||||
boolean isSuperCallInsideInline
|
boolean withinInline,
|
||||||
|
boolean isSuperCall
|
||||||
) {
|
) {
|
||||||
return isSuperCallInsideInline || (accessFlag & ACC_PRIVATE) != 0 ||
|
return isSuperCall && withinInline ||
|
||||||
((accessFlag & ACC_PROTECTED) != 0 && !isInSamePackage(unwrappedDescriptor, descriptorContext.getContextDescriptor()));
|
(accessFlag & ACC_PRIVATE) != 0 ||
|
||||||
|
((accessFlag & ACC_PROTECTED) != 0 &&
|
||||||
|
(withinInline || !isInSamePackage(unwrappedDescriptor, descriptorContext.getContextDescriptor())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isInSamePackage(DeclarationDescriptor descriptor1, DeclarationDescriptor descriptor2) {
|
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);
|
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")
|
@TestMetadata("superCall.1.kt")
|
||||||
public void testSuperCall() throws Exception {
|
public void testSuperCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/superCall.1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/superCall.1.kt");
|
||||||
|
|||||||
+12
@@ -1381,6 +1381,18 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
|
|||||||
doBoxTestWithInlineCheck(fileName);
|
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")
|
@TestMetadata("superCall.1.kt")
|
||||||
public void testSuperCall() throws Exception {
|
public void testSuperCall() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/superCall.1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxInline/syntheticAccessors/superCall.1.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user