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:
@@ -114,7 +114,7 @@ public class PropertyCodegen {
|
|||||||
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
|
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
|
||||||
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
|
: "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;
|
assert declaration != null : "Declaration is null for different context: " + context;
|
||||||
|
|
||||||
genBackingFieldAndAnnotations(declaration, descriptor, false);
|
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) {
|
private void genBackingFieldAndAnnotations(@NotNull KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor, boolean isParameter) {
|
||||||
boolean hasBackingField = hasBackingField(declaration, descriptor);
|
boolean hasBackingField = hasBackingField(declaration, descriptor);
|
||||||
boolean hasDelegate = declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate();
|
boolean hasDelegate = declaration instanceof KtProperty && ((KtProperty) declaration).hasDelegate();
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ public class JetTypeMapper {
|
|||||||
if (file != null) {
|
if (file != null) {
|
||||||
Visibility visibility = descriptor.getVisibility();
|
Visibility visibility = descriptor.getVisibility();
|
||||||
if (!publicFacade ||
|
if (!publicFacade ||
|
||||||
descriptor instanceof PropertyDescriptor ||
|
isNonConstProperty(descriptor) ||
|
||||||
Visibilities.isPrivate(visibility) ||
|
Visibilities.isPrivate(visibility) ||
|
||||||
isAccessor/*Cause of KT-9603*/
|
isAccessor/*Cause of KT-9603*/
|
||||||
) {
|
) {
|
||||||
@@ -181,6 +181,12 @@ public class JetTypeMapper {
|
|||||||
" in package fragment " + descriptor.getContainingDeclaration());
|
" 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 {
|
public static class ContainingClassesInfo {
|
||||||
private final ClassId facadeClassId;
|
private final ClassId facadeClassId;
|
||||||
private final ClassId implClassId;
|
private final ClassId implClassId;
|
||||||
|
|||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
import a.OK
|
||||||
|
|
||||||
|
fun box(): String = OK
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
@file:[JvmName("MultifileClass") JvmMultifileClass]
|
||||||
|
package a
|
||||||
|
|
||||||
|
const val OK: String = "OK"
|
||||||
+14
@@ -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()
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
@file:[JvmName("MultifileClass") JvmMultifileClass]
|
||||||
|
package a
|
||||||
|
|
||||||
|
annotation class A
|
||||||
|
|
||||||
|
@A
|
||||||
|
const val OK: String = "OK"
|
||||||
+21
@@ -49,6 +49,12 @@ public class BlackBoxMultifileClassKotlinTestGenerated extends AbstractBlackBoxM
|
|||||||
doTestMultifileClassAgainstSources(fileName);
|
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")
|
@TestMetadata("valFromOtherPackage.1.kt")
|
||||||
public void testValFromOtherPackage() throws Exception {
|
public void testValFromOtherPackage() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/calls/valFromOtherPackage.1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/calls/valFromOtherPackage.1.kt");
|
||||||
@@ -61,4 +67,19 @@ public class BlackBoxMultifileClassKotlinTestGenerated extends AbstractBlackBoxM
|
|||||||
doTestMultifileClassAgainstSources(fileName);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -49,6 +49,12 @@ public class CompileKotlinAgainstMultifileKotlinTestGenerated extends AbstractCo
|
|||||||
doBoxTest(fileName);
|
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")
|
@TestMetadata("valFromOtherPackage.1.kt")
|
||||||
public void testValFromOtherPackage() throws Exception {
|
public void testValFromOtherPackage() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/calls/valFromOtherPackage.1.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/boxMultifileClasses/calls/valFromOtherPackage.1.kt");
|
||||||
@@ -61,4 +67,19 @@ public class CompileKotlinAgainstMultifileKotlinTestGenerated extends AbstractCo
|
|||||||
doBoxTest(fileName);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user