Generate static accessors fro protected functions in different packages

#KT-4617 Fixed
This commit is contained in:
Natalia Ukhorskaya
2014-03-31 15:28:50 +04:00
parent 5b5ecca12a
commit 4a79bfa16d
7 changed files with 78 additions and 3 deletions
@@ -39,6 +39,7 @@ import java.util.HashMap;
import java.util.Map;
import static org.jetbrains.asm4.Opcodes.ACC_PRIVATE;
import static org.jetbrains.asm4.Opcodes.ACC_PROTECTED;
import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD;
import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityAccessFlag;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
@@ -405,8 +406,9 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
@NotNull
private MemberDescriptor accessibleDescriptorIfNeeded(CallableMemberDescriptor descriptor, boolean fromOutsideContext) {
int flag = getAccessFlags(descriptor);
if ((flag & ACC_PRIVATE) == 0) {
CallableMemberDescriptor unwrappedDescriptor = DescriptorUtils.unwrapFakeOverride(descriptor);
int flag = getAccessFlags(unwrappedDescriptor);
if ((flag & ACC_PRIVATE) == 0 && (flag & ACC_PROTECTED) == 0) {
return descriptor;
}
@@ -438,7 +440,24 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
}
}
return (MemberDescriptor) (descriptorContext != null ? descriptorContext.getAccessor(descriptor) : descriptor);
if (descriptorContext == null) {
return descriptor;
}
if ((flag & ACC_PROTECTED) != 0) {
PackageFragmentDescriptor unwrappedDescriptorPackage =
DescriptorUtils.getParentOfType(unwrappedDescriptor, PackageFragmentDescriptor.class, false);
PackageFragmentDescriptor contextDescriptorPackage =
DescriptorUtils.getParentOfType(descriptorContext.getContextDescriptor(), PackageFragmentDescriptor.class, false);
boolean inSamePackage = contextDescriptorPackage != null && unwrappedDescriptorPackage != null &&
unwrappedDescriptorPackage.getFqName().equals(contextDescriptorPackage.getFqName());
if (inSamePackage) {
return descriptor;
}
}
return (MemberDescriptor) descriptorContext.getAccessor(descriptor);
}
private void addChild(@NotNull CodegenContext child) {
@@ -0,0 +1,4 @@
import b.B
import a.BSamePackage
fun box() = if (B().test() == BSamePackage().test()) "OK" else "fail"
@@ -0,0 +1,14 @@
package a
open class A {
protected fun protectedFun(): String = "OK"
}
class BSamePackage: A() {
fun test(): String {
val a = {
protectedFun()
}
return a()
}
}
@@ -0,0 +1,12 @@
package b
import a.A
class B: A() {
fun test(): String {
val a = {
protectedFun()
}
return a()
}
}
@@ -0,0 +1,16 @@
package a
open class A {
protected fun protectedFun(): String = "OK"
}
class BSamePackage: A() {
fun test(): String {
val a = {
protectedFun()
}
return a()
}
}
// 0 INVOKESTATIC a/BSamePackage.protectedFun
@@ -33,6 +33,11 @@ import org.jetbrains.jet.codegen.AbstractBytecodeTextTest;
@TestMetadata("compiler/testData/codegen/bytecodeText")
@InnerTestClasses({BytecodeTextTestGenerated.Constants.class, BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Statements.class})
public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
@TestMetadata("accessorForProtected.kt")
public void testAccessorForProtected() throws Exception {
doTest("compiler/testData/codegen/bytecodeText/accessorForProtected.kt");
}
public void testAllFilesPresentInBytecodeText() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/bytecodeText"), Pattern.compile("^(.+)\\.kt$"), true);
}
@@ -32,6 +32,11 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest;
@SuppressWarnings("all")
@TestMetadata("compiler/testData/codegen/boxMultiFile")
public class BlackBoxMultiFileCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
@TestMetadata("accessorForProtected")
public void testAccessorForProtected() throws Exception {
doTestMultiFile("compiler/testData/codegen/boxMultiFile/accessorForProtected");
}
public void testAllFilesPresentInBoxMultiFile() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/codegen/boxMultiFile"), Pattern.compile("^([^\\.]+)$"), false);
}