Support @JvmField on interface properties
#KT-15807 Fixed
This commit is contained in:
@@ -2005,12 +2005,12 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
|
||||||
|
|
||||||
boolean isBackingFieldInClassCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
boolean isBackingFieldMovedFromCompanion = JvmAbi.isPropertyWithBackingFieldInOuterClass(propertyDescriptor);
|
||||||
AccessorKind fieldAccessorKind;
|
AccessorKind fieldAccessorKind;
|
||||||
if (skipLateinitAssertion) {
|
if (skipLateinitAssertion) {
|
||||||
fieldAccessorKind = AccessorKind.LATEINIT_INTRINSIC;
|
fieldAccessorKind = AccessorKind.LATEINIT_INTRINSIC;
|
||||||
}
|
}
|
||||||
else if (isBackingFieldInClassCompanion &&
|
else if (isBackingFieldMovedFromCompanion &&
|
||||||
(forceField ||
|
(forceField ||
|
||||||
(Visibilities.isPrivate(propertyDescriptor.getVisibility()) &&
|
(Visibilities.isPrivate(propertyDescriptor.getVisibility()) &&
|
||||||
isDefaultAccessor(propertyDescriptor.getGetter()) && isDefaultAccessor(propertyDescriptor.getSetter())))) {
|
isDefaultAccessor(propertyDescriptor.getGetter()) && isDefaultAccessor(propertyDescriptor.getSetter())))) {
|
||||||
@@ -2076,7 +2076,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
skipPropertyAccessors = forceField;
|
skipPropertyAccessors = forceField;
|
||||||
ownerDescriptor = isBackingFieldInClassCompanion ? containingDeclaration : propertyDescriptor;
|
ownerDescriptor = isBackingFieldMovedFromCompanion ? containingDeclaration : propertyDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!skipPropertyAccessors) {
|
if (!skipPropertyAccessors) {
|
||||||
|
|||||||
@@ -929,7 +929,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
boolean isNonCompanionObject = isNonCompanionObject(descriptor);
|
boolean isNonCompanionObject = isNonCompanionObject(descriptor);
|
||||||
boolean isInterfaceCompanion = isCompanionObjectInInterfaceNotIntrinsic(descriptor);
|
boolean isInterfaceCompanion = isCompanionObjectInInterfaceNotIntrinsic(descriptor);
|
||||||
boolean isMappedIntrinsicCompanionObject = isMappedIntrinsicCompanionObject(descriptor);
|
boolean isMappedIntrinsicCompanionObject = isMappedIntrinsicCompanionObject(descriptor);
|
||||||
if (isNonCompanionObject || isInterfaceCompanion || isMappedIntrinsicCompanionObject) {
|
boolean objectWithBackingFieldsInOuter = isCompanionObjectWithBackingFieldsInOuter(descriptor);
|
||||||
|
if (isNonCompanionObject || (isInterfaceCompanion && !objectWithBackingFieldsInOuter) || isMappedIntrinsicCompanionObject) {
|
||||||
ExpressionCodegen clInitCodegen = createOrGetClInitCodegen();
|
ExpressionCodegen clInitCodegen = createOrGetClInitCodegen();
|
||||||
InstructionAdapter v = clInitCodegen.v;
|
InstructionAdapter v = clInitCodegen.v;
|
||||||
markLineNumberForElement(element.getPsiOrParent(), v);
|
markLineNumberForElement(element.getPsiOrParent(), v);
|
||||||
@@ -957,7 +958,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (isCompanionObjectWithBackingFieldsInOuter(descriptor)) {
|
else if (objectWithBackingFieldsInOuter) {
|
||||||
ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
ImplementationBodyCodegen parentCodegen = (ImplementationBodyCodegen) getParentCodegen();
|
||||||
ExpressionCodegen parentClInitCodegen = parentCodegen.createOrGetClInitCodegen();
|
ExpressionCodegen parentClInitCodegen = parentCodegen.createOrGetClInitCodegen();
|
||||||
InstructionAdapter parentVisitor = parentClInitCodegen.v;
|
InstructionAdapter parentVisitor = parentClInitCodegen.v;
|
||||||
|
|||||||
@@ -57,9 +57,9 @@ import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAn
|
|||||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTIES;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTIES;
|
||||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER;
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.DELEGATED_PROPERTY_METADATA_OWNER;
|
||||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.FIELD_FOR_PROPERTY;
|
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||||
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.SYNTHETIC_METHOD_FOR_PROPERTY;
|
|
||||||
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND;
|
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND;
|
||||||
|
import static org.jetbrains.kotlin.load.java.JvmAbi.isInterfaceCompanionWithBackingFieldsInOuter;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
|
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
|
||||||
@@ -420,6 +420,10 @@ public class PropertyCodegen {
|
|||||||
String name = backingFieldContext.getFieldName(propertyDescriptor, isDelegate);
|
String name = backingFieldContext.getFieldName(propertyDescriptor, isDelegate);
|
||||||
|
|
||||||
v.getSerializationBindings().put(FIELD_FOR_PROPERTY, propertyDescriptor, Pair.create(type, name));
|
v.getSerializationBindings().put(FIELD_FOR_PROPERTY, propertyDescriptor, Pair.create(type, name));
|
||||||
|
if (hasJvmFieldAnnotation(propertyDescriptor) &&
|
||||||
|
isInterfaceCompanionWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration())) {
|
||||||
|
v.getSerializationBindings().put(FIELD_MOVED_FROM_INTERFACE_COMPANION, propertyDescriptor, true);
|
||||||
|
}
|
||||||
|
|
||||||
FieldVisitor fv = builder.newField(
|
FieldVisitor fv = builder.newField(
|
||||||
JvmDeclarationOriginKt.OtherOrigin(element, propertyDescriptor), modifiers, name, type.getDescriptor(),
|
JvmDeclarationOriginKt.OtherOrigin(element, propertyDescriptor), modifiers, name, type.getDescriptor(),
|
||||||
|
|||||||
+2
@@ -35,6 +35,8 @@ public final class JvmSerializationBindings {
|
|||||||
SerializationMappingSlice.create();
|
SerializationMappingSlice.create();
|
||||||
public static final SerializationMappingSlice<PropertyDescriptor, Method> SYNTHETIC_METHOD_FOR_PROPERTY =
|
public static final SerializationMappingSlice<PropertyDescriptor, Method> SYNTHETIC_METHOD_FOR_PROPERTY =
|
||||||
SerializationMappingSlice.create();
|
SerializationMappingSlice.create();
|
||||||
|
public static final SerializationMappingSlice<PropertyDescriptor, Boolean> FIELD_MOVED_FROM_INTERFACE_COMPANION =
|
||||||
|
SerializationMappingSlice.create();
|
||||||
|
|
||||||
private static final class SerializationMappingSlice<K, V> extends BasicWritableSlice<K, V> {
|
private static final class SerializationMappingSlice<K, V> extends BasicWritableSlice<K, V> {
|
||||||
public SerializationMappingSlice() {
|
public SerializationMappingSlice() {
|
||||||
|
|||||||
+5
@@ -189,6 +189,11 @@ public class JvmSerializerExtension extends SerializerExtension {
|
|||||||
);
|
);
|
||||||
|
|
||||||
proto.setExtension(JvmProtoBuf.propertySignature, signature);
|
proto.setExtension(JvmProtoBuf.propertySignature, signature);
|
||||||
|
Boolean fieldMovedFromInterfaceCompanion = bindings.get(FIELD_MOVED_FROM_INTERFACE_COMPANION, descriptor);
|
||||||
|
if (fieldMovedFromInterfaceCompanion != null && fieldMovedFromInterfaceCompanion) {
|
||||||
|
proto.setExtension(JvmProtoBuf.isMovedFromInterfaceCompanion, 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
+12
-1
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.jvm.checkers
|
package org.jetbrains.kotlin.resolve.jvm.checkers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
import org.jetbrains.kotlin.fileClasses.isInsideJvmMultifileClassFile
|
import org.jetbrains.kotlin.fileClasses.isInsideJvmMultifileClassFile
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtProperty
|
import org.jetbrains.kotlin.psi.KtProperty
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
@@ -40,6 +42,7 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
|||||||
LATEINIT("JvmField cannot be applied to lateinit property"),
|
LATEINIT("JvmField cannot be applied to lateinit property"),
|
||||||
CONST("JvmField cannot be applied to const property"),
|
CONST("JvmField cannot be applied to const property"),
|
||||||
INSIDE_COMPANION_OF_INTERFACE("JvmField cannot be applied to a property defined in companion object of interface"),
|
INSIDE_COMPANION_OF_INTERFACE("JvmField cannot be applied to a property defined in companion object of interface"),
|
||||||
|
NOT_PUBLIC_VAL_WITH_JVMFIELD("JvmField could be applied only if all interface companion properties are 'public final val' with '@JvmField' annotation"),
|
||||||
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE("JvmField cannot be applied to top level property of a file annotated with ${JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT}"),
|
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE("JvmField cannot be applied to top level property of a file annotated with ${JvmFileClassUtil.JVM_MULTIFILE_CLASS_SHORT}"),
|
||||||
DELEGATE("JvmField cannot be applied to delegated property")
|
DELEGATE("JvmField cannot be applied to delegated property")
|
||||||
}
|
}
|
||||||
@@ -57,7 +60,14 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
|||||||
descriptor.overriddenDescriptors.isNotEmpty() -> OVERRIDES
|
descriptor.overriddenDescriptors.isNotEmpty() -> OVERRIDES
|
||||||
descriptor.isLateInit -> LATEINIT
|
descriptor.isLateInit -> LATEINIT
|
||||||
descriptor.isConst -> CONST
|
descriptor.isConst -> CONST
|
||||||
descriptor.isInsideCompanionObjectOfInterface() -> INSIDE_COMPANION_OF_INTERFACE
|
descriptor.isInsideCompanionObjectOfInterface() ->
|
||||||
|
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.JvmFieldInInterface))
|
||||||
|
INSIDE_COMPANION_OF_INTERFACE
|
||||||
|
else {
|
||||||
|
if (!JvmAbi.isInterfaceCompanionWithBackingFieldsInOuter(descriptor.containingDeclaration)) {
|
||||||
|
NOT_PUBLIC_VAL_WITH_JVMFIELD
|
||||||
|
} else return
|
||||||
|
}
|
||||||
DescriptorUtils.isTopLevelDeclaration(descriptor) && declaration.isInsideJvmMultifileClassFile() ->
|
DescriptorUtils.isTopLevelDeclaration(descriptor) && declaration.isInsideJvmMultifileClassFile() ->
|
||||||
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE
|
TOP_LEVEL_PROPERTY_OF_MULTIFILE_FACADE
|
||||||
else -> return
|
else -> return
|
||||||
@@ -79,4 +89,5 @@ class JvmFieldApplicabilityChecker : DeclarationChecker {
|
|||||||
val outerClassKind = (containingClass.containingDeclaration as? ClassDescriptor)?.kind
|
val outerClassKind = (containingClass.containingDeclaration as? ClassDescriptor)?.kind
|
||||||
return outerClassKind == ClassKind.INTERFACE || outerClassKind == ClassKind.ANNOTATION_CLASS
|
return outerClassKind == ClassKind.INTERFACE || outerClassKind == ClassKind.ANNOTATION_CLASS
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
import kotlin.reflect.full.memberProperties
|
||||||
|
|
||||||
|
class Bar(val value: String)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val z = Bar("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val field = Foo.Companion::z
|
||||||
|
return field.get().value
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface +NestedClassesInAnnotations
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// FILE: Foo.kt
|
||||||
|
|
||||||
|
public class Bar(public val value: String)
|
||||||
|
|
||||||
|
annotation class Foo {
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val FOO = Bar("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: bar.kt
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return Foo.FOO.value
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface +NestedClassesInAnnotations
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// FILE: Test.java
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
public static String publicField() {
|
||||||
|
return Foo.z.getS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: simple.kt
|
||||||
|
|
||||||
|
|
||||||
|
public class Bar(public val s: String)
|
||||||
|
|
||||||
|
annotation class Foo {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val z = Bar("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return Test.publicField()
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@
|
|||||||
package zzz
|
package zzz
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
import kotlin.reflect.KProperty1
|
import kotlin.reflect.KProperty1
|
||||||
|
import kotlin.reflect.KProperty0
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class A(val s1: String, val s2: String) {
|
class A(val s1: String, val s2: String) {
|
||||||
@@ -21,27 +22,28 @@ class A(val s1: String, val s2: String) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
// TODO: uncomment when callable references to object members are supported
|
|
||||||
class AWithCompanion {
|
class AWithCompanion {
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField public val publicField = "1";
|
@JvmField public val publicField = "1";
|
||||||
@JvmField internal val internalField = "2";
|
@JvmField internal val internalField = "2";
|
||||||
|
|
||||||
fun testAccessors() {
|
fun testAccessors() {
|
||||||
checkAccessor(AWithCompanion.Companion::publicField, "1", AWithCompanion.Companion)
|
checkAccessor(AWithCompanion.Companion::publicField, "1")
|
||||||
checkAccessor(AWithCompanion.Companion::internalField, "2", AWithCompanion.Companion)
|
checkAccessor(AWithCompanion.Companion::internalField, "2")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
A("1", "2").testAccessors()
|
A("1", "2").testAccessors()
|
||||||
// AWithCompanion.testAccessors()
|
AWithCompanion.testAccessors()
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun <T, R> checkAccessor(prop: KProperty1<T, R>, value: R, receiver: T) {
|
public fun <T, R> checkAccessor(prop: KProperty1<T, R>, value: R, receiver: T) {
|
||||||
assertEquals(prop.get(receiver), value, "Property ${prop} has wrong value")
|
assertEquals(prop.get(receiver), value, "Property ${prop} has wrong value")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun <R> checkAccessor(prop: KProperty0<R>, value: R) {
|
||||||
|
assertEquals(prop.get(), value, "Property ${prop} has wrong value")
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// FILE: Foo.kt
|
||||||
|
|
||||||
|
public class Bar(public val value: String)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val FOO = Bar("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: bar.kt
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return Foo.FOO.value
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// FILE: Test.java
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
public static String publicField() {
|
||||||
|
return Foo.o.getS() + Foo.k.getS();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: simple.kt
|
||||||
|
|
||||||
|
|
||||||
|
public class Bar(public val s: String)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val o = Bar("O")
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val k = Bar("K")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return Test.publicField()
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
import kotlin.reflect.jvm.*
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val value = "OK"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val field = Foo.Companion::value.javaField!!
|
||||||
|
return field.get(null) as String
|
||||||
|
}
|
||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface +NestedClassesInAnnotations
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
import kotlin.reflect.full.declaredMemberProperties
|
||||||
|
|
||||||
|
annotation class Ann(val value: String)
|
||||||
|
|
||||||
|
public class Bar(public val value: String)
|
||||||
|
|
||||||
|
annotation class Foo {
|
||||||
|
companion object {
|
||||||
|
@JvmField @Ann("O")
|
||||||
|
val FOO = Bar("K")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val field = Foo.Companion::class.declaredMemberProperties.single()
|
||||||
|
return (field.annotations.single() as Ann).value + (field.get(Foo.Companion) as Bar).value
|
||||||
|
}
|
||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_REFLECT
|
||||||
|
import kotlin.reflect.KProperty1
|
||||||
|
import kotlin.reflect.full.memberProperties
|
||||||
|
import kotlin.reflect.full.companionObject
|
||||||
|
|
||||||
|
class Bar(val value: String)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val z = Bar("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val field = Foo::class.companionObject!!.memberProperties.single() as KProperty1<Foo.Companion, Bar>
|
||||||
|
return field.get(Foo.Companion).value
|
||||||
|
}
|
||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
import kotlin.reflect.full.declaredMemberProperties
|
||||||
|
|
||||||
|
annotation class Ann(val value: String)
|
||||||
|
|
||||||
|
public class Bar(public val value: String)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
companion object {
|
||||||
|
@JvmField @Ann("O")
|
||||||
|
val FOO = Bar("K")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val field = Foo.Companion::class.declaredMemberProperties.single()
|
||||||
|
return (field.annotations.single() as Ann).value + (field.get(Foo.Companion) as Bar).value
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface +NestedClassesInAnnotations
|
||||||
|
// TARGER_BACKEND: JVM
|
||||||
|
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// FILE: Foo.kt
|
||||||
|
|
||||||
|
public class Bar(public val value: String)
|
||||||
|
|
||||||
|
annotation class Foo {
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val FOO = Bar("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: bar.kt
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return Foo.FOO.value
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface
|
||||||
|
// TARGER_BACKEND: JVM
|
||||||
|
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// FILE: Foo.kt
|
||||||
|
|
||||||
|
public class Bar(public val value: String)
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val FOO = Bar("OK")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// FILE: bar.kt
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
return Foo.FOO.value
|
||||||
|
}
|
||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
// !LANGUAGE: +JvmFieldInInterface
|
||||||
|
|
||||||
|
interface A {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val c = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface B {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmField
|
||||||
|
val c = 3
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
val a = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface C {
|
||||||
|
companion object {
|
||||||
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
|
val c = 3
|
||||||
|
|
||||||
|
val a = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface D {
|
||||||
|
companion object {
|
||||||
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
|
var c = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface E {
|
||||||
|
companion object {
|
||||||
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
|
private val a = 3
|
||||||
|
|
||||||
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
|
internal val b = 3
|
||||||
|
|
||||||
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
|
protected val c = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface F {
|
||||||
|
companion object {
|
||||||
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
|
<!NON_FINAL_MEMBER_IN_OBJECT!>open<!> val a = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
+75
@@ -0,0 +1,75 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public interface A {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
@kotlin.jvm.JvmField public final val c: kotlin.Int = 3
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface B {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
@kotlin.jvm.JvmField public final val a: kotlin.Int = 3
|
||||||
|
@kotlin.jvm.JvmField public final val c: kotlin.Int = 3
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface C {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
public final val a: kotlin.Int = 3
|
||||||
|
@kotlin.jvm.JvmField public final val c: kotlin.Int = 3
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface D {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
@kotlin.jvm.JvmField public final var c: kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface E {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public companion object Companion {
|
||||||
|
private constructor Companion()
|
||||||
|
@kotlin.jvm.JvmField private final val a: kotlin.Int = 3
|
||||||
|
@kotlin.jvm.JvmField internal final val b: kotlin.Int = 3
|
||||||
|
@kotlin.jvm.JvmField protected final val c: kotlin.Int = 3
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+2
@@ -95,6 +95,8 @@ interface K {
|
|||||||
companion object {
|
companion object {
|
||||||
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
<!INAPPLICABLE_JVM_FIELD!>@JvmField<!>
|
||||||
var c = 3
|
var c = 3
|
||||||
|
|
||||||
|
var x = 3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
@@ -75,6 +75,7 @@ public interface K {
|
|||||||
public companion object Companion {
|
public companion object Companion {
|
||||||
private constructor Companion()
|
private constructor Companion()
|
||||||
@kotlin.jvm.JvmField public final var c: kotlin.Int
|
@kotlin.jvm.JvmField public final var c: kotlin.Int
|
||||||
|
public final var x: kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|||||||
Generated
+45
@@ -1637,6 +1637,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("boundJvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testBoundJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/bound/boundJvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("companionObjectReceiver.kt")
|
@TestMetadata("companionObjectReceiver.kt")
|
||||||
public void testCompanionObjectReceiver() throws Exception {
|
public void testCompanionObjectReceiver() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
||||||
@@ -11943,6 +11948,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmField"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmField"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotationCompanion.kt")
|
||||||
|
public void testAnnotationCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/annotationCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotationCompanionWithJava.kt")
|
||||||
|
public void testAnnotationCompanionWithJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/annotationCompanionWithJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("captureClassFields.kt")
|
@TestMetadata("captureClassFields.kt")
|
||||||
public void testCaptureClassFields() throws Exception {
|
public void testCaptureClassFields() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/jvmField/captureClassFields.kt");
|
runTest("compiler/testData/codegen/box/jvmField/captureClassFields.kt");
|
||||||
@@ -11973,6 +11988,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
|
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanion.kt")
|
||||||
|
public void testInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanionWithJava.kt")
|
||||||
|
public void testInterfaceCompanionWithJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanionWithJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("publicField.kt")
|
@TestMetadata("publicField.kt")
|
||||||
public void testPublicField() throws Exception {
|
public void testPublicField() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
|
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
|
||||||
@@ -17691,6 +17716,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt");
|
runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanionPropertyWithJvmField.kt")
|
||||||
|
public void testInterfaceCompanionPropertyWithJvmField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/mapping/interfaceCompanionPropertyWithJvmField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("mappedClassIsEqualToClassLiteral.kt")
|
@TestMetadata("mappedClassIsEqualToClassLiteral.kt")
|
||||||
public void testMappedClassIsEqualToClassLiteral() throws Exception {
|
public void testMappedClassIsEqualToClassLiteral() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt");
|
runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt");
|
||||||
@@ -18286,6 +18316,21 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInAnnotationCompanionWithAnnotation.kt")
|
||||||
|
public void testJvmFieldInAnnotationCompanionWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInAnnotationCompanionWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanionWithAnnotation.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanionWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInInterfaceCompanionWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
||||||
public void testKotlinPropertyInheritedInJava() throws Exception {
|
public void testKotlinPropertyInheritedInJava() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
||||||
|
|||||||
+5
@@ -556,6 +556,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interface13.kt")
|
||||||
|
public void testInterface13() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/interface13.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("jvmFieldApplicability.kt")
|
@TestMetadata("jvmFieldApplicability.kt")
|
||||||
public void testJvmFieldApplicability() throws Exception {
|
public void testJvmFieldApplicability() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt");
|
||||||
|
|||||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+5
@@ -556,6 +556,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/inSingleFileFacade.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interface13.kt")
|
||||||
|
public void testInterface13() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/interface13.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("jvmFieldApplicability.kt")
|
@TestMetadata("jvmFieldApplicability.kt")
|
||||||
public void testJvmFieldApplicability() throws Exception {
|
public void testJvmFieldApplicability() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmField/jvmFieldApplicability.kt");
|
||||||
|
|||||||
+45
@@ -1637,6 +1637,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("boundJvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testBoundJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/bound/boundJvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("companionObjectReceiver.kt")
|
@TestMetadata("companionObjectReceiver.kt")
|
||||||
public void testCompanionObjectReceiver() throws Exception {
|
public void testCompanionObjectReceiver() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
||||||
@@ -11943,6 +11948,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmField"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmField"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotationCompanion.kt")
|
||||||
|
public void testAnnotationCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/annotationCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotationCompanionWithJava.kt")
|
||||||
|
public void testAnnotationCompanionWithJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/annotationCompanionWithJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("captureClassFields.kt")
|
@TestMetadata("captureClassFields.kt")
|
||||||
public void testCaptureClassFields() throws Exception {
|
public void testCaptureClassFields() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/jvmField/captureClassFields.kt");
|
runTest("compiler/testData/codegen/box/jvmField/captureClassFields.kt");
|
||||||
@@ -11973,6 +11988,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
|
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanion.kt")
|
||||||
|
public void testInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanionWithJava.kt")
|
||||||
|
public void testInterfaceCompanionWithJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanionWithJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("publicField.kt")
|
@TestMetadata("publicField.kt")
|
||||||
public void testPublicField() throws Exception {
|
public void testPublicField() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
|
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
|
||||||
@@ -17691,6 +17716,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt");
|
runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanionPropertyWithJvmField.kt")
|
||||||
|
public void testInterfaceCompanionPropertyWithJvmField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/mapping/interfaceCompanionPropertyWithJvmField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("mappedClassIsEqualToClassLiteral.kt")
|
@TestMetadata("mappedClassIsEqualToClassLiteral.kt")
|
||||||
public void testMappedClassIsEqualToClassLiteral() throws Exception {
|
public void testMappedClassIsEqualToClassLiteral() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt");
|
runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt");
|
||||||
@@ -18286,6 +18316,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInAnnotationCompanionWithAnnotation.kt")
|
||||||
|
public void testJvmFieldInAnnotationCompanionWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInAnnotationCompanionWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanionWithAnnotation.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanionWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInInterfaceCompanionWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
||||||
public void testKotlinPropertyInheritedInJava() throws Exception {
|
public void testKotlinPropertyInheritedInJava() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
||||||
|
|||||||
+10
@@ -143,11 +143,21 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
|
|||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmField.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmField.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInAnnotationCompanion.kt")
|
||||||
|
public void testJvmFieldInAnnotationCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmFieldInAnnotationCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("jvmFieldInConstructor.kt")
|
@TestMetadata("jvmFieldInConstructor.kt")
|
||||||
public void testJvmFieldInConstructor() throws Exception {
|
public void testJvmFieldInConstructor() throws Exception {
|
||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmFieldInConstructor.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmFieldInConstructor.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("jvmNames.kt")
|
@TestMetadata("jvmNames.kt")
|
||||||
public void testJvmNames() throws Exception {
|
public void testJvmNames() throws Exception {
|
||||||
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmNames.kt");
|
runTest("compiler/testData/compileKotlinAgainstKotlin/jvmNames.kt");
|
||||||
|
|||||||
+45
@@ -1637,6 +1637,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("boundJvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testBoundJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/bound/boundJvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("companionObjectReceiver.kt")
|
@TestMetadata("companionObjectReceiver.kt")
|
||||||
public void testCompanionObjectReceiver() throws Exception {
|
public void testCompanionObjectReceiver() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
||||||
@@ -11943,6 +11948,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmField"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/jvmField"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotationCompanion.kt")
|
||||||
|
public void testAnnotationCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/annotationCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("annotationCompanionWithJava.kt")
|
||||||
|
public void testAnnotationCompanionWithJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/annotationCompanionWithJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("captureClassFields.kt")
|
@TestMetadata("captureClassFields.kt")
|
||||||
public void testCaptureClassFields() throws Exception {
|
public void testCaptureClassFields() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/jvmField/captureClassFields.kt");
|
runTest("compiler/testData/codegen/box/jvmField/captureClassFields.kt");
|
||||||
@@ -11973,6 +11988,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
|
runTest("compiler/testData/codegen/box/jvmField/constructorProperty.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanion.kt")
|
||||||
|
public void testInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanionWithJava.kt")
|
||||||
|
public void testInterfaceCompanionWithJava() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/jvmField/interfaceCompanionWithJava.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("publicField.kt")
|
@TestMetadata("publicField.kt")
|
||||||
public void testPublicField() throws Exception {
|
public void testPublicField() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
|
runTest("compiler/testData/codegen/box/jvmField/publicField.kt");
|
||||||
@@ -17691,6 +17716,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt");
|
runTest("compiler/testData/codegen/box/reflection/mapping/inlineReifiedFun.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("interfaceCompanionPropertyWithJvmField.kt")
|
||||||
|
public void testInterfaceCompanionPropertyWithJvmField() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/mapping/interfaceCompanionPropertyWithJvmField.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("mappedClassIsEqualToClassLiteral.kt")
|
@TestMetadata("mappedClassIsEqualToClassLiteral.kt")
|
||||||
public void testMappedClassIsEqualToClassLiteral() throws Exception {
|
public void testMappedClassIsEqualToClassLiteral() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt");
|
runTest("compiler/testData/codegen/box/reflection/mapping/mappedClassIsEqualToClassLiteral.kt");
|
||||||
@@ -18286,6 +18316,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInAnnotationCompanionWithAnnotation.kt")
|
||||||
|
public void testJvmFieldInAnnotationCompanionWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInAnnotationCompanionWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanionWithAnnotation.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanionWithAnnotation() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInInterfaceCompanionWithAnnotation.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
||||||
public void testKotlinPropertyInheritedInJava() throws Exception {
|
public void testKotlinPropertyInheritedInJava() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ enum class LanguageFeature(
|
|||||||
ProperForInArrayLoopRangeVariableAssignmentSemantic(KOTLIN_1_3, kind = BUG_FIX),
|
ProperForInArrayLoopRangeVariableAssignmentSemantic(KOTLIN_1_3, kind = BUG_FIX),
|
||||||
NestedClassesInAnnotations(KOTLIN_1_3),
|
NestedClassesInAnnotations(KOTLIN_1_3),
|
||||||
JvmStaticInInterface(KOTLIN_1_3, kind = UNSTABLE_FEATURE),
|
JvmStaticInInterface(KOTLIN_1_3, kind = UNSTABLE_FEATURE),
|
||||||
|
JvmFieldInInterface(KOTLIN_1_3, kind = UNSTABLE_FEATURE),
|
||||||
ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion(KOTLIN_1_3, kind = BUG_FIX),
|
ProhibitVisibilityOfNestedClassifiersFromSupertypesOfCompanion(KOTLIN_1_3, kind = BUG_FIX),
|
||||||
ProhibitNonConstValuesAsVarargsInAnnotations(KOTLIN_1_3, kind = BUG_FIX),
|
ProhibitNonConstValuesAsVarargsInAnnotations(KOTLIN_1_3, kind = BUG_FIX),
|
||||||
ReleaseCoroutines(KOTLIN_1_3, kind = UNSTABLE_FEATURE),
|
ReleaseCoroutines(KOTLIN_1_3, kind = UNSTABLE_FEATURE),
|
||||||
|
|||||||
@@ -7,21 +7,26 @@ package org.jetbrains.kotlin.load.java;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
import org.jetbrains.kotlin.builtins.CompanionObjectMapping;
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget;
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget;
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
|
|
||||||
import org.jetbrains.kotlin.name.ClassId;
|
import org.jetbrains.kotlin.name.ClassId;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter;
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt;
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.CapitalizeDecapitalizeKt;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isClassOrEnumClass;
|
import java.util.Collection;
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||||
|
|
||||||
public final class JvmAbi {
|
public final class JvmAbi {
|
||||||
public static final String DEFAULT_IMPLS_CLASS_NAME = "DefaultImpls";
|
public static final String DEFAULT_IMPLS_CLASS_NAME = "DefaultImpls";
|
||||||
public static final String ERASED_INLINE_CLASS_NAME = "Erased";
|
public static final String ERASED_INLINE_CLASS_NAME = "Erased";
|
||||||
|
public static final FqName JVM_FIELD_ANNOTATION_FQ_NAME = new FqName("kotlin.jvm.JvmField");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warning: use DEFAULT_IMPLS_CLASS_NAME and TypeMappingConfiguration.innerClassNameFactory when possible.
|
* Warning: use DEFAULT_IMPLS_CLASS_NAME and TypeMappingConfiguration.innerClassNameFactory when possible.
|
||||||
@@ -97,16 +102,54 @@ public final class JvmAbi {
|
|||||||
|
|
||||||
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
|
public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) {
|
||||||
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
return propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||||
isCompanionObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration());
|
(isCompanionObjectWithBackingFieldsInOuter(propertyDescriptor.getContainingDeclaration())
|
||||||
|
||
|
||||||
|
(isCompanionObject(propertyDescriptor.getContainingDeclaration()) &&
|
||||||
|
hasJvmFieldAnnotation(propertyDescriptor)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
|
public static boolean isCompanionObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
|
||||||
return isCompanionObject(companionObject) &&
|
return isCompanionObject(companionObject) &&
|
||||||
isClassOrEnumClass(companionObject.getContainingDeclaration()) &&
|
(isClassOrEnumClass(companionObject.getContainingDeclaration()) ||
|
||||||
|
isInterfaceCompanionWithBackingFieldsInOuter(companionObject)) &&
|
||||||
!isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
|
!isMappedIntrinsicCompanionObject((ClassDescriptor) companionObject);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isInterfaceCompanionWithBackingFieldsInOuter(@NotNull DeclarationDescriptor companionObject) {
|
||||||
|
DeclarationDescriptor interfaceClass = companionObject.getContainingDeclaration();
|
||||||
|
if (!isInterface(interfaceClass) && !isAnnotationClass(interfaceClass)) return false;
|
||||||
|
Collection<DeclarationDescriptor> descriptors = ((ClassDescriptor) companionObject).getUnsubstitutedMemberScope()
|
||||||
|
.getContributedDescriptors(DescriptorKindFilter.ALL, MemberScope.Companion.getALL_NAME_FILTER());
|
||||||
|
boolean hasJvmFieldAnnotation = false;
|
||||||
|
for (DeclarationDescriptor next : descriptors) {
|
||||||
|
if (!(next instanceof PropertyDescriptor)) continue;
|
||||||
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) next;
|
||||||
|
|
||||||
|
if (propertyDescriptor.getVisibility() != Visibilities.PUBLIC ||
|
||||||
|
propertyDescriptor.isVar() ||
|
||||||
|
propertyDescriptor.getModality() != Modality.FINAL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasJvmFieldAnnotation(propertyDescriptor)) return false;
|
||||||
|
hasJvmFieldAnnotation = true;
|
||||||
|
}
|
||||||
|
return hasJvmFieldAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isMappedIntrinsicCompanionObject(@NotNull ClassDescriptor companionObject) {
|
public static boolean isMappedIntrinsicCompanionObject(@NotNull ClassDescriptor companionObject) {
|
||||||
return CompanionObjectMapping.INSTANCE.isMappedIntrinsicCompanionObject(companionObject);
|
return CompanionObjectMapping.INSTANCE.isMappedIntrinsicCompanionObject(companionObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean hasJvmFieldAnnotation(@NotNull CallableMemberDescriptor memberDescriptor) {
|
||||||
|
List<AnnotationWithTarget> annotations = memberDescriptor.getAnnotations().getUseSiteTargetedAnnotations();
|
||||||
|
for (AnnotationWithTarget annotationWithTarget : annotations) {
|
||||||
|
if (AnnotationUseSiteTarget.FIELD.equals(annotationWithTarget.getTarget()) &&
|
||||||
|
JVM_FIELD_ANNOTATION_FQ_NAME.equals(annotationWithTarget.getAnnotation().getFqName())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return memberDescriptor.getAnnotations().hasAnnotation(JVM_FIELD_ANNOTATION_FQ_NAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+50
-9
@@ -99,13 +99,26 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
|
|||||||
val fieldSignature = getPropertySignature(proto, container.nameResolver, container.typeTable, field = true)
|
val fieldSignature = getPropertySignature(proto, container.nameResolver, container.typeTable, field = true)
|
||||||
|
|
||||||
val isConst = Flags.IS_CONST.get(proto.flags)
|
val isConst = Flags.IS_CONST.get(proto.flags)
|
||||||
|
val isMovedFromInterfaceCompanion = JvmProtoBufUtil.isMovedFromInterfaceCompanion(proto)
|
||||||
val propertyAnnotations = syntheticFunctionSignature?.let { sig ->
|
val propertyAnnotations = syntheticFunctionSignature?.let { sig ->
|
||||||
findClassAndLoadMemberAnnotations(container, sig, property = true, isConst = isConst)
|
findClassAndLoadMemberAnnotations(
|
||||||
|
container,
|
||||||
|
sig,
|
||||||
|
property = true,
|
||||||
|
isConst = isConst,
|
||||||
|
isMovedFromInterfaceCompanion = isMovedFromInterfaceCompanion
|
||||||
|
)
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
val fieldAnnotations = fieldSignature?.let { sig ->
|
val fieldAnnotations = fieldSignature?.let { sig ->
|
||||||
findClassAndLoadMemberAnnotations(container, sig, property = true, field = true, isConst = isConst)
|
findClassAndLoadMemberAnnotations(
|
||||||
|
container,
|
||||||
|
sig,
|
||||||
|
property = true,
|
||||||
|
field = true,
|
||||||
|
isConst = isConst,
|
||||||
|
isMovedFromInterfaceCompanion = isMovedFromInterfaceCompanion
|
||||||
|
)
|
||||||
}.orEmpty()
|
}.orEmpty()
|
||||||
|
|
||||||
// TODO: check delegate presence in some other way
|
// TODO: check delegate presence in some other way
|
||||||
@@ -136,11 +149,24 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
|
|||||||
protected abstract fun transformAnnotations(annotations: List<A>): List<T>
|
protected abstract fun transformAnnotations(annotations: List<A>): List<T>
|
||||||
|
|
||||||
private fun findClassAndLoadMemberAnnotations(
|
private fun findClassAndLoadMemberAnnotations(
|
||||||
container: ProtoContainer, signature: MemberSignature,
|
container: ProtoContainer,
|
||||||
property: Boolean = false, field: Boolean = false, isConst: Boolean? = null
|
signature: MemberSignature,
|
||||||
|
property: Boolean = false,
|
||||||
|
field: Boolean = false,
|
||||||
|
isConst: Boolean? = null,
|
||||||
|
isMovedFromInterfaceCompanion: Boolean = false
|
||||||
): List<A> {
|
): List<A> {
|
||||||
val kotlinClass =
|
val kotlinClass =
|
||||||
findClassWithAnnotationsAndInitializers(container, getSpecialCaseContainerClass(container, property, field, isConst))
|
findClassWithAnnotationsAndInitializers(
|
||||||
|
container,
|
||||||
|
getSpecialCaseContainerClass(
|
||||||
|
container,
|
||||||
|
property,
|
||||||
|
field,
|
||||||
|
isConst,
|
||||||
|
isMovedFromInterfaceCompanion
|
||||||
|
)
|
||||||
|
)
|
||||||
?: return listOf()
|
?: return listOf()
|
||||||
|
|
||||||
return storage(kotlinClass).memberAnnotations[signature] ?: listOf()
|
return storage(kotlinClass).memberAnnotations[signature] ?: listOf()
|
||||||
@@ -202,7 +228,13 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
|
|||||||
val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, AnnotatedCallableKind.PROPERTY)
|
val signature = getCallableSignature(proto, container.nameResolver, container.typeTable, AnnotatedCallableKind.PROPERTY)
|
||||||
?: return null
|
?: return null
|
||||||
|
|
||||||
val specialCase = getSpecialCaseContainerClass(container, property = true, field = true, isConst = Flags.IS_CONST.get(proto.flags))
|
val specialCase = getSpecialCaseContainerClass(
|
||||||
|
container,
|
||||||
|
property = true,
|
||||||
|
field = true,
|
||||||
|
isConst = Flags.IS_CONST.get(proto.flags),
|
||||||
|
isMovedFromInterfaceCompanion = JvmProtoBufUtil.isMovedFromInterfaceCompanion(proto)
|
||||||
|
)
|
||||||
val kotlinClass = findClassWithAnnotationsAndInitializers(container, specialCase) ?: return null
|
val kotlinClass = findClassWithAnnotationsAndInitializers(container, specialCase) ?: return null
|
||||||
|
|
||||||
val constant = storage(kotlinClass).propertyConstants[signature] ?: return null
|
val constant = storage(kotlinClass).propertyConstants[signature] ?: return null
|
||||||
@@ -222,7 +254,11 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
|
|||||||
// TODO: do not use KotlinClassFinder#findKotlinClass here because it traverses the file system in the compiler
|
// TODO: do not use KotlinClassFinder#findKotlinClass here because it traverses the file system in the compiler
|
||||||
// Introduce an API in KotlinJvmBinaryClass to find a class nearby instead
|
// Introduce an API in KotlinJvmBinaryClass to find a class nearby instead
|
||||||
private fun getSpecialCaseContainerClass(
|
private fun getSpecialCaseContainerClass(
|
||||||
container: ProtoContainer, property: Boolean, field: Boolean, isConst: Boolean?
|
container: ProtoContainer,
|
||||||
|
property: Boolean,
|
||||||
|
field: Boolean,
|
||||||
|
isConst: Boolean?,
|
||||||
|
isMovedFromInterfaceCompanion: Boolean
|
||||||
): KotlinJvmBinaryClass? {
|
): KotlinJvmBinaryClass? {
|
||||||
if (property) {
|
if (property) {
|
||||||
checkNotNull(isConst) { "isConst should not be null for property (container=$container)" }
|
checkNotNull(isConst) { "isConst should not be null for property (container=$container)" }
|
||||||
@@ -242,7 +278,12 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any,
|
|||||||
}
|
}
|
||||||
if (field && container is ProtoContainer.Class && container.kind == ProtoBuf.Class.Kind.COMPANION_OBJECT) {
|
if (field && container is ProtoContainer.Class && container.kind == ProtoBuf.Class.Kind.COMPANION_OBJECT) {
|
||||||
val outerClass = container.outerClass
|
val outerClass = container.outerClass
|
||||||
if (outerClass != null && (outerClass.kind == ProtoBuf.Class.Kind.CLASS || outerClass.kind == ProtoBuf.Class.Kind.ENUM_CLASS)) {
|
if (outerClass != null &&
|
||||||
|
(outerClass.kind == ProtoBuf.Class.Kind.CLASS || outerClass.kind == ProtoBuf.Class.Kind.ENUM_CLASS ||
|
||||||
|
(isMovedFromInterfaceCompanion &&
|
||||||
|
(outerClass.kind == ProtoBuf.Class.Kind.INTERFACE ||
|
||||||
|
outerClass.kind == ProtoBuf.Class.Kind.ANNOTATION_CLASS)))
|
||||||
|
) {
|
||||||
// Backing fields of properties of a companion object in a class are generated in the outer class
|
// Backing fields of properties of a companion object in a class are generated in the outer class
|
||||||
return outerClass.toBinaryClass()
|
return outerClass.toBinaryClass()
|
||||||
}
|
}
|
||||||
|
|||||||
+3
@@ -119,4 +119,7 @@ object JvmProtoBufUtil {
|
|||||||
private fun mapTypeDefault(type: ProtoBuf.Type, nameResolver: NameResolver): String? {
|
private fun mapTypeDefault(type: ProtoBuf.Type, nameResolver: NameResolver): String? {
|
||||||
return if (type.hasClassName()) ClassMapperLite.mapClass(nameResolver.getQualifiedClassName(type.className)) else null
|
return if (type.hasClassName()) ClassMapperLite.mapClass(nameResolver.getQualifiedClassName(type.className)) else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isMovedFromInterfaceCompanion(proto: ProtoBuf.Property) =
|
||||||
|
proto.getExtension(JvmProtoBuf.isMovedFromInterfaceCompanion).toInt().and(1) != 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ package kotlin.reflect.jvm.internal
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.getExtensionOrNull
|
||||||
|
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
import org.jetbrains.kotlin.resolve.DescriptorFactory
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
@@ -59,7 +61,9 @@ internal abstract class KPropertyImpl<out R> private constructor(
|
|||||||
is KotlinProperty -> {
|
is KotlinProperty -> {
|
||||||
val descriptor = jvmSignature.descriptor
|
val descriptor = jvmSignature.descriptor
|
||||||
JvmProtoBufUtil.getJvmFieldSignature(jvmSignature.proto, jvmSignature.nameResolver, jvmSignature.typeTable)?.let {
|
JvmProtoBufUtil.getJvmFieldSignature(jvmSignature.proto, jvmSignature.nameResolver, jvmSignature.typeTable)?.let {
|
||||||
val owner = if (JvmAbi.isCompanionObjectWithBackingFieldsInOuter(descriptor.containingDeclaration)) {
|
val owner = if (JvmAbi.isPropertyWithBackingFieldInOuterClass(descriptor) ||
|
||||||
|
JvmProtoBufUtil.isMovedFromInterfaceCompanion(jvmSignature.proto)
|
||||||
|
) {
|
||||||
container.jClass.enclosingClass
|
container.jClass.enclosingClass
|
||||||
} else descriptor.containingDeclaration.let { containingDeclaration ->
|
} else descriptor.containingDeclaration.let { containingDeclaration ->
|
||||||
if (containingDeclaration is ClassDescriptor) containingDeclaration.toJavaClass()
|
if (containingDeclaration is ClassDescriptor) containingDeclaration.toJavaClass()
|
||||||
@@ -188,6 +192,11 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
|
|||||||
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
|
!DescriptorUtils.isInterface(possibleCompanionObject.containingDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isInsideInterfaceCompanionObjectWithJvmField(): Boolean {
|
||||||
|
val possibleCompanionObject = property.descriptor.containingDeclaration
|
||||||
|
return JvmAbi.isInterfaceCompanionWithBackingFieldsInOuter(possibleCompanionObject)
|
||||||
|
}
|
||||||
|
|
||||||
fun isJvmStaticProperty() =
|
fun isJvmStaticProperty() =
|
||||||
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
|
property.descriptor.annotations.findAnnotation(JVM_STATIC) != null
|
||||||
|
|
||||||
@@ -195,7 +204,7 @@ private fun KPropertyImpl.Accessor<*, *>.computeCallerForAccessor(isGetter: Bool
|
|||||||
!TypeUtils.isNullableType(property.descriptor.type)
|
!TypeUtils.isNullableType(property.descriptor.type)
|
||||||
|
|
||||||
fun computeFieldCaller(field: Field): FunctionCaller<Field> = when {
|
fun computeFieldCaller(field: Field): FunctionCaller<Field> = when {
|
||||||
isInsideClassCompanionObject() -> {
|
isInsideClassCompanionObject() || isInsideInterfaceCompanionObjectWithJvmField() -> {
|
||||||
val klass = (descriptor.containingDeclaration as ClassDescriptor).toJavaClass()!!
|
val klass = (descriptor.containingDeclaration as ClassDescriptor).toJavaClass()!!
|
||||||
if (isGetter)
|
if (isGetter)
|
||||||
if (isBound) FunctionCaller.BoundClassCompanionFieldGetter(field, klass)
|
if (isBound) FunctionCaller.BoundClassCompanionFieldGetter(field, klass)
|
||||||
|
|||||||
+10
@@ -1562,6 +1562,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("boundJvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testBoundJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/bound/boundJvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("companionObjectReceiver.kt")
|
@TestMetadata("companionObjectReceiver.kt")
|
||||||
public void testCompanionObjectReceiver() throws Exception {
|
public void testCompanionObjectReceiver() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
||||||
@@ -16551,6 +16556,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
||||||
public void testKotlinPropertyInheritedInJava() throws Exception {
|
public void testKotlinPropertyInheritedInJava() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
||||||
|
|||||||
+10
@@ -1582,6 +1582,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/array.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("boundJvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testBoundJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/callableReference/bound/boundJvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("companionObjectReceiver.kt")
|
@TestMetadata("companionObjectReceiver.kt")
|
||||||
public void testCompanionObjectReceiver() throws Exception {
|
public void testCompanionObjectReceiver() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt");
|
||||||
@@ -17546,6 +17551,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/javaStaticField.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("jvmFieldInInterfaceCompanion.kt")
|
||||||
|
public void testJvmFieldInInterfaceCompanion() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/properties/jvmFieldInInterfaceCompanion.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
@TestMetadata("kotlinPropertyInheritedInJava.kt")
|
||||||
public void testKotlinPropertyInheritedInJava() throws Exception {
|
public void testKotlinPropertyInheritedInJava() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
runTest("compiler/testData/codegen/box/reflection/properties/kotlinPropertyInheritedInJava.kt");
|
||||||
|
|||||||
@@ -125,4 +125,4 @@ public annotation class JvmSuppressWildcards(val suppress: Boolean = true)
|
|||||||
@Target(AnnotationTarget.TYPE)
|
@Target(AnnotationTarget.TYPE)
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
@MustBeDocumented
|
@MustBeDocumented
|
||||||
public annotation class JvmWildcard
|
public annotation class JvmWildcard
|
||||||
|
|||||||
Reference in New Issue
Block a user