Support @JvmStatic and @JvmOverload in annotation companion

This commit is contained in:
Mikhael Bogdanov
2020-10-30 19:43:35 +01:00
parent 7ec2d036ae
commit e20093d762
5 changed files with 23 additions and 5 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.getDispatchReceiverParameterForConstructorCall
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.LanguageFeature
@@ -137,7 +138,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
val generateAsFinal =
(functionDescriptor.modality == Modality.FINAL ||
state.languageVersionSettings.supportsFeature(LanguageFeature.GenerateJvmOverloadsAsFinal)) &&
!isInterface(functionDescriptor.containingDeclaration)
!isJvmInterface(functionDescriptor.containingDeclaration)
val flags =
baseMethodFlags or
(if (isStatic) Opcodes.ACC_STATIC else 0) or
@@ -188,8 +188,7 @@ public class DescriptorAsmUtil {
if (functionDescriptor.getModality() == Modality.FINAL && !(functionDescriptor instanceof ConstructorDescriptor)) {
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
if (!(containingDeclaration instanceof ClassDescriptor) ||
((ClassDescriptor) containingDeclaration).getKind() != ClassKind.INTERFACE) {
if (!isJvmInterface(containingDeclaration)) {
flags |= ACC_FINAL;
}
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.codegen
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
import org.jetbrains.kotlin.codegen.context.CodegenContext
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext
@@ -244,7 +245,7 @@ fun CallableDescriptor.isJvmStaticInObjectOrClassOrInterface(): Boolean =
DescriptorUtils.isNonCompanionObject(it) ||
// This is necessary because for generation of @JvmStatic methods from companion of class A
// we create a synthesized descriptor containing in class A
DescriptorUtils.isClassOrEnumClass(it) || DescriptorUtils.isInterface(it)
DescriptorUtils.isClassOrEnumClass(it) || isJvmInterface(it)
}
fun CallableDescriptor.isJvmStaticInCompanionObject(): Boolean =
@@ -156,7 +156,7 @@ class FunctionCodegen(
origin == JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER -> 0
origin == IrDeclarationOrigin.ENUM_CLASS_SPECIAL_MEMBER -> 0
parentAsClass.isInterface && body != null -> 0
parentAsClass.isAnnotationClass && !isStatic -> Opcodes.ACC_ABSTRACT
parentAsClass.isAnnotationClass -> if (isStatic) 0 else Opcodes.ACC_ABSTRACT
else -> Opcodes.ACC_FINAL
}
Modality.ABSTRACT -> Opcodes.ACC_ABSTRACT
+17
View File
@@ -9,6 +9,10 @@ class Test {
public static String test1() {
return A.sayHello();
}
public static String test2() {
return B.sayHello();
}
}
// FILE: simpleCompanionObject.kt
@@ -22,8 +26,21 @@ interface A {
}
}
}
annotation class B {
companion object {
@JvmStatic
@JvmOverloads
fun sayHello(greeting: String = "OK"): String {
return greeting
}
}
}
fun box(): String {
if (Test.test1() != "OK") return "fail 1"
if (Test.test2() != "OK") return "fail 2"
return "OK"
}