Support @JvmStatic for interface companion objects in backend
This commit is contained in:
+1
-1
@@ -45,7 +45,7 @@ public class AccessorForFunctionDescriptor extends AbstractAccessorForFunctionDe
|
||||
this.nameSuffix = nameSuffix;
|
||||
|
||||
initialize(DescriptorUtils.getReceiverParameterType(descriptor.getExtensionReceiverParameter()),
|
||||
descriptor instanceof ConstructorDescriptor || CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)
|
||||
descriptor instanceof ConstructorDescriptor || CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(descriptor)
|
||||
? null
|
||||
: descriptor.getDispatchReceiverParameter(),
|
||||
copyTypeParameters(descriptor),
|
||||
|
||||
+1
-1
@@ -47,7 +47,7 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl implem
|
||||
) {
|
||||
this(property, property.getType(), DescriptorUtils.getReceiverParameterType(property.getExtensionReceiverParameter()),
|
||||
/* dispatchReceiverParameter = */
|
||||
CodegenUtilKt.isJvmStaticInObjectOrClass(property) ? null : property.getDispatchReceiverParameter(),
|
||||
CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(property) ? null : property.getDispatchReceiverParameter(),
|
||||
containingDeclaration, superCallTarget, nameSuffix,
|
||||
getterAccessorRequired, setterAccessorRequired);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.codegen.serialization.JvmStringTable;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||
import org.jetbrains.kotlin.config.JvmTarget;
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
@@ -194,7 +193,7 @@ public class AsmUtil {
|
||||
public static boolean isStaticMethod(OwnerKind kind, CallableMemberDescriptor functionDescriptor) {
|
||||
return isStaticKind(kind) ||
|
||||
KotlinTypeMapper.isStaticAccessor(functionDescriptor) ||
|
||||
CodegenUtilKt.isJvmStaticInObjectOrClass(functionDescriptor);
|
||||
CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
|
||||
}
|
||||
|
||||
public static boolean isStaticKind(OwnerKind kind) {
|
||||
|
||||
@@ -92,7 +92,7 @@ public class CallReceiver extends StackValue {
|
||||
|
||||
CallableDescriptor descriptor = resolvedCall.getResultingDescriptor();
|
||||
|
||||
if (CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)) {
|
||||
if (CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(descriptor)) {
|
||||
return Type.VOID_TYPE;
|
||||
}
|
||||
|
||||
|
||||
@@ -2631,7 +2631,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
||||
}
|
||||
|
||||
if (thisOrOuterClass.equals(context.getThisDescriptor()) &&
|
||||
!CodegenUtilKt.isJvmStaticInObjectOrClass(context.getFunctionDescriptor())) {
|
||||
!CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(context.getFunctionDescriptor())) {
|
||||
return StackValue.local(0, typeMapper.mapType(thisOrOuterClass));
|
||||
}
|
||||
else if (shouldGenerateSingletonAsThisOrOuterFromContext(thisOrOuterClass)) {
|
||||
|
||||
@@ -822,7 +822,7 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
((AccessorForCallableDescriptor) accessorDescriptor).getSuperCallTarget() != null
|
||||
);
|
||||
|
||||
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClass(functionDescriptor);
|
||||
boolean isJvmStaticInObjectOrClass = CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
|
||||
boolean hasDispatchReceiver = !isStaticDeclaration(functionDescriptor) &&
|
||||
!isNonDefaultInterfaceMember(functionDescriptor, state) &&
|
||||
!isJvmStaticInObjectOrClass;
|
||||
|
||||
@@ -593,7 +593,7 @@ public abstract class StackValue {
|
||||
}
|
||||
|
||||
private static StackValue platformStaticCallIfPresent(@NotNull StackValue resultReceiver, @NotNull CallableDescriptor descriptor) {
|
||||
if (CodegenUtilKt.isJvmStaticInObjectOrClass(descriptor)) {
|
||||
if (CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(descriptor)) {
|
||||
if (resultReceiver.canHaveSideEffects()) {
|
||||
return coercion(resultReceiver, Type.VOID_TYPE);
|
||||
}
|
||||
|
||||
@@ -253,12 +253,12 @@ fun reportTarget6InheritanceErrorIfNeeded(
|
||||
}
|
||||
}
|
||||
|
||||
fun CallableDescriptor.isJvmStaticInObjectOrClass(): Boolean =
|
||||
fun CallableDescriptor.isJvmStaticInObjectOrClassOrInterface(): Boolean =
|
||||
isJvmStaticIn {
|
||||
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.isClassOrEnumClass(it) || DescriptorUtils.isInterface(it)
|
||||
}
|
||||
|
||||
fun CallableDescriptor.isJvmStaticInCompanionObject(): Boolean =
|
||||
|
||||
@@ -742,7 +742,7 @@ public class KotlinTypeMapper {
|
||||
boolean isStaticInvocation = (isStaticDeclaration(functionDescriptor) &&
|
||||
!(functionDescriptor instanceof ImportedFromObjectCallableDescriptor)) ||
|
||||
isStaticAccessor(functionDescriptor) ||
|
||||
CodegenUtilKt.isJvmStaticInObjectOrClass(functionDescriptor);
|
||||
CodegenUtilKt.isJvmStaticInObjectOrClassOrInterface(functionDescriptor);
|
||||
if (isStaticInvocation) {
|
||||
invokeOpcode = INVOKESTATIC;
|
||||
isInterfaceMember = currentIsInterface && currentOwner instanceof JavaClassDescriptor;
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// !LANGUAGE: +JvmStaticInInterface
|
||||
// WITH_RUNTIME
|
||||
// TARGET_BACKEND: JVM
|
||||
// JVM_TARGET: 1.8
|
||||
// FILE: test.kt
|
||||
fun box(): String {
|
||||
return Java.test()
|
||||
}
|
||||
|
||||
interface Foo {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun foo() = "O"
|
||||
|
||||
@JvmStatic
|
||||
var fooProp = ""
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Java.java
|
||||
public class Java {
|
||||
public static String test() {
|
||||
Foo.setFooProp("K");
|
||||
return Foo.foo() + Foo.getFooProp();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// !LANGUAGE: +JvmStaticInInterface
|
||||
// WITH_RUNTIME
|
||||
// TARGET_BACKEND: JVM
|
||||
// JVM_TARGET: 1.8
|
||||
// FILE: test.kt
|
||||
fun box(): String {
|
||||
return Java.test()
|
||||
}
|
||||
|
||||
interface Foo {
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun foo() = "O"
|
||||
|
||||
|
||||
val fooProp = "K"
|
||||
@JvmStatic get
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Java.java
|
||||
public class Java {
|
||||
public static String test() {
|
||||
return Foo.foo() + Foo.getFooProp();
|
||||
}
|
||||
}
|
||||
Generated
+12
@@ -11415,6 +11415,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6301.kt")
|
||||
public void testKt6301() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt6301.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6301_2.kt")
|
||||
public void testKt6301_2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt6301_2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9897_static.kt")
|
||||
public void testKt9897_static() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt9897_static.kt");
|
||||
|
||||
+12
@@ -11415,6 +11415,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6301.kt")
|
||||
public void testKt6301() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt6301.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6301_2.kt")
|
||||
public void testKt6301_2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt6301_2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9897_static.kt")
|
||||
public void testKt9897_static() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt9897_static.kt");
|
||||
|
||||
+12
@@ -11415,6 +11415,18 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6301.kt")
|
||||
public void testKt6301() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt6301.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6301_2.kt")
|
||||
public void testKt6301_2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt6301_2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt9897_static.kt")
|
||||
public void testKt9897_static() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/jvmStatic/kt9897_static.kt");
|
||||
|
||||
Reference in New Issue
Block a user