Fix for KT-10881 Declaring constant in a mutlifile class causes an IllegalAccessError on its usage.

Generate fields for 'const' properties in facade class.

NB reading annotations for 'const' vals in multifile class doesn't work, KT-10892.
This commit is contained in:
Dmitry Petrov
2016-02-02 12:06:43 +03:00
parent 970d6f6834
commit bad8320038
8 changed files with 85 additions and 2 deletions
@@ -114,7 +114,7 @@ public class PropertyCodegen {
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
if (CodegenContextUtil.isImplClassOwner(context)) {
if (isBackingFieldOwner(descriptor)) {
assert declaration != null : "Declaration is null for different context: " + context;
genBackingFieldAndAnnotations(declaration, descriptor, false);
@@ -128,6 +128,13 @@ public class PropertyCodegen {
}
}
private boolean isBackingFieldOwner(@NotNull PropertyDescriptor descriptor) {
if (descriptor.isConst()) {
return !(context instanceof MultifileClassPartContext);
}
return CodegenContextUtil.isImplClassOwner(context);
}
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
boolean hasBackingField = hasBackingField(declaration, descriptor);
boolean hasDelegate = declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate();
@@ -159,7 +159,7 @@ public class JetTypeMapper {
if (file != null) {
Visibility visibility = descriptor.getVisibility();
if (!publicFacade ||
descriptor instanceof PropertyDescriptor ||
isNonConstProperty(descriptor) ||
Visibilities.isPrivate(visibility) ||
isAccessor/*Cause of KT-9603*/
) {
@@ -181,6 +181,12 @@ public class JetTypeMapper {
" in package fragment " + descriptor.getContainingDeclaration());
}
private static boolean isNonConstProperty(@NotNull CallableMemberDescriptor descriptor) {
if (!(descriptor instanceof PropertyDescriptor)) return false;
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
return !propertyDescriptor.isConst();
}
public static class ContainingClassesInfo {
private final ClassId facadeClassId;
private final ClassId implClassId;
@@ -0,0 +1,3 @@
import a.OK
fun box(): String = OK
@@ -0,0 +1,4 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
const val OK: String = "OK"
@@ -0,0 +1,14 @@
import a.OK
fun box(): String {
val okRef = ::OK
// TODO
// val annotations = okRef.annotations
// val numAnnotations = annotations.size
// if (numAnnotations != 1) {
// return "Failed, annotations: $annotations"
// }
return okRef.get()
}
@@ -0,0 +1,7 @@
@file:[JvmName("MultifileClass") JvmMultifileClass]
package a
annotation class A
@A
const val OK: String = "OK"
@@ -49,6 +49,12 @@ public class BlackBoxMultifileClassKotlinTestGenerated extends AbstractBlackBoxM
doTestMultifileClassAgainstSources(fileName);
}
@TestMetadata("constFromOtherPackage.1.kt")
public void testConstFromOtherPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/calls/constFromOtherPackage.1.kt");
doTestMultifileClassAgainstSources(fileName);
}
@TestMetadata("valFromOtherPackage.1.kt")
public void testValFromOtherPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/calls/valFromOtherPackage.1.kt");
@@ -61,4 +67,19 @@ public class BlackBoxMultifileClassKotlinTestGenerated extends AbstractBlackBoxM
doTestMultifileClassAgainstSources(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxMultifileClasses/reflection")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Reflection extends AbstractBlackBoxMultifileClassCodegenTest {
public void testAllFilesPresentInReflection() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxMultifileClasses/reflection"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("constFromMultifileClass.1.kt")
public void testConstFromMultifileClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/reflection/constFromMultifileClass.1.kt");
doTestMultifileClassAgainstSources(fileName);
}
}
}
@@ -49,6 +49,12 @@ public class CompileKotlinAgainstMultifileKotlinTestGenerated extends AbstractCo
doBoxTest(fileName);
}
@TestMetadata("constFromOtherPackage.1.kt")
public void testConstFromOtherPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/calls/constFromOtherPackage.1.kt");
doBoxTest(fileName);
}
@TestMetadata("valFromOtherPackage.1.kt")
public void testValFromOtherPackage() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/calls/valFromOtherPackage.1.kt");
@@ -61,4 +67,19 @@ public class CompileKotlinAgainstMultifileKotlinTestGenerated extends AbstractCo
doBoxTest(fileName);
}
}
@TestMetadata("compiler/testData/codegen/boxMultifileClasses/reflection")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Reflection extends AbstractCompileKotlinAgainstMultifileKotlinTest {
public void testAllFilesPresentInReflection() throws Exception {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxMultifileClasses/reflection"), Pattern.compile("^(.+)\\.1.kt$"), true);
}
@TestMetadata("constFromMultifileClass.1.kt")
public void testConstFromMultifileClass() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/reflection/constFromMultifileClass.1.kt");
doBoxTest(fileName);
}
}
}