diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java index dd68dfd1994..43ce22b24c0 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/FunctionCodegen.java @@ -77,7 +77,6 @@ import java.util.Set; import static org.jetbrains.kotlin.builtins.KotlinBuiltIns.isNullableAny; import static org.jetbrains.kotlin.codegen.AsmUtil.*; -import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isAnnotationOrJvmInterfaceWithoutDefaults; import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvm8InterfaceWithDefaultsMember; import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.METHOD_FOR_FUNCTION; import static org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind.DECLARATION; @@ -101,7 +100,7 @@ public class FunctionCodegen { private final Function1 IS_PURE_INTERFACE_CHECKER = new Function1() { @Override public Boolean invoke(DeclarationDescriptor descriptor) { - return JvmCodegenUtil.isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, state); + return JvmCodegenUtil.isInterfaceWithoutDefaults(descriptor, state); } }; @@ -866,7 +865,7 @@ public class FunctionCodegen { public void generateBridges(@NotNull FunctionDescriptor descriptor) { if (descriptor instanceof ConstructorDescriptor) return; if (owner.getContextKind() == OwnerKind.DEFAULT_IMPLS) return; - if (isAnnotationOrJvmInterfaceWithoutDefaults(descriptor.getContainingDeclaration(), state)) return; + if (IS_PURE_INTERFACE_CHECKER.invoke(descriptor.getContainingDeclaration())) return; // equals(Any?), hashCode(), toString() never need bridges if (isMethodOfAny(descriptor)) return; diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index 9fcc02e1c16..3fffcd23a7f 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -1338,7 +1338,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateTraitMethods() { - if (isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, state)) return; + if (isInterfaceWithoutDefaults(descriptor, state)) return; List restrictedInheritance = new ArrayList<>(); for (Map.Entry entry : CodegenUtil.getNonPrivateTraitMethods(descriptor).entrySet()) { diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java index d0dce133e4a..5c3a7e2cc50 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/JvmCodegenUtil.java @@ -42,7 +42,6 @@ import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.inline.InlineUtil; -import org.jetbrains.kotlin.resolve.jvm.JvmConstantsKt; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor; import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor; @@ -63,15 +62,12 @@ public class JvmCodegenUtil { private JvmCodegenUtil() { } - public static boolean isAnnotationOrJvmInterfaceWithoutDefaults(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) { - return isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, state.isJvm8Target(), state.isJvm8TargetWithDefaults()); + public static boolean isInterfaceWithoutDefaults(@NotNull DeclarationDescriptor descriptor, @NotNull GenerationState state) { + return isInterfaceWithoutDefaults(descriptor, state.isJvm8Target(), state.isJvm8TargetWithDefaults()); } - private static boolean isAnnotationOrJvmInterfaceWithoutDefaults(@NotNull DeclarationDescriptor descriptor, boolean isJvm8Target, boolean isJvm8TargetWithDefaults) { - if (!isJvmInterface(descriptor)) { - return false; - } - if (ANNOTATION_CLASS == ((ClassDescriptor) descriptor).getKind()) return true; + private static boolean isInterfaceWithoutDefaults(@NotNull DeclarationDescriptor descriptor, boolean isJvm8Target, boolean isJvm8TargetWithDefaults) { + if (!DescriptorUtils.isInterface(descriptor)) return false; if (descriptor instanceof DeserializedClassDescriptor) { SourceElement source = ((DeserializedClassDescriptor) descriptor).getSource(); @@ -91,7 +87,7 @@ public class JvmCodegenUtil { } public static boolean isJvm8InterfaceWithDefaults(@NotNull DeclarationDescriptor descriptor, boolean isJvm8Target, boolean isJvm8TargetWithDefaults) { - return DescriptorUtils.isInterface(descriptor) && !isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, isJvm8Target, isJvm8TargetWithDefaults); + return DescriptorUtils.isInterface(descriptor) && !isInterfaceWithoutDefaults(descriptor, isJvm8Target, isJvm8TargetWithDefaults); } public static boolean isJvm8InterfaceWithDefaultsMember(@NotNull CallableMemberDescriptor descriptor, @NotNull GenerationState state) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index 2b2ba58a21b..770ed6b955d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -58,15 +58,14 @@ import org.jetbrains.org.objectweb.asm.commons.Method class BridgeLowering(val state: GenerationState) : ClassLoweringPass { - val typeMapper = state.typeMapper + private val typeMapper = state.typeMapper - private val IS_PURE_INTERFACE_CHECKER = fun(descriptor: DeclarationDescriptor): Boolean { - return JvmCodegenUtil.isAnnotationOrJvmInterfaceWithoutDefaults(descriptor, state) - } + private val IS_PURE_INTERFACE_CHECKER = fun(descriptor: DeclarationDescriptor): Boolean = + JvmCodegenUtil.isInterfaceWithoutDefaults(descriptor, state) override fun lower(irClass: IrClass) { val classDescriptor = irClass.descriptor - if (JvmCodegenUtil.isAnnotationOrJvmInterfaceWithoutDefaults(classDescriptor, state) || classDescriptor is FileClassDescriptor) return + if (IS_PURE_INTERFACE_CHECKER(classDescriptor) || classDescriptor is FileClassDescriptor) return if (classDescriptor is DefaultImplsClassDescriptor) { return /*TODO?*/ diff --git a/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass.kt b/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass.kt new file mode 100644 index 00000000000..17b9a770ad2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass.kt @@ -0,0 +1,4 @@ +// !DIAGNOSTICS: -FINAL_SUPERTYPE +// This error needs to be suppressed to cause light class generation + +class Foo : Target() diff --git a/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass.txt b/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass.txt new file mode 100644 index 00000000000..35b7a414e9f --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass.txt @@ -0,0 +1,9 @@ +package + +public final class Foo : kotlin.annotation.Target { + public constructor Foo() + public final override /*1*/ /*fake_override*/ val allowedTargets: kotlin.Array + 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 +} diff --git a/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass2.kt b/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass2.kt new file mode 100644 index 00000000000..c0b15937482 --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass2.kt @@ -0,0 +1,25 @@ +// !DIAGNOSTICS: -SUPERTYPES_FOR_ANNOTATION_CLASS -VIRTUAL_MEMBER_HIDDEN -FINAL_SUPERTYPE +// These errors need to be suppressed to cause light class generation +// FILE: test.kt + +annotation class Ann : Target() + +annotation class Ann2(vararg val allowedTargets: AnnotationTarget) : Target() + +interface I : J { + override fun foo(): List = throw Exception() +} +class C : I { + fun bar(): Set = throw Exception() +} +annotation class Ann3 : C() +annotation class Ann4 : I + +// FILE: J.java + +import java.util.Collection; +import kotlin.annotation.Target; + +public interface J extends Target { + Collection foo(); +} diff --git a/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass2.txt b/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass2.txt new file mode 100644 index 00000000000..b2400c819ee --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass2.txt @@ -0,0 +1,42 @@ +package + +public final annotation class Ann : kotlin.annotation.Target { + public constructor Ann() + public final override /*1*/ /*fake_override*/ val allowedTargets: kotlin.Array + 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 final annotation class Ann2 : kotlin.annotation.Target { + public constructor Ann2(/*0*/ vararg allowedTargets: kotlin.annotation.AnnotationTarget /*kotlin.Array*/) + public final override /*1*/ val allowedTargets: kotlin.Array + 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 final annotation class Ann3 : C { + public constructor Ann3() + public final override /*1*/ /*fake_override*/ fun bar(): kotlin.collections.Set + public open override /*1*/ /*fake_override*/ fun foo(): kotlin.collections.List +} + +public final annotation class Ann4 : I { + public constructor Ann4() + public open override /*1*/ /*fake_override*/ fun foo(): kotlin.collections.List +} + +public final class C : I { + public constructor C() + public final fun bar(): kotlin.collections.Set + public open override /*1*/ /*fake_override*/ fun foo(): kotlin.collections.List +} + +public interface I : J { + public open override /*1*/ fun foo(): kotlin.collections.List +} + +public interface J : Target { + public abstract fun foo(): kotlin.collections.(Mutable)Collection! +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java index 0742ef41725..3ed8e455d86 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestGenerated.java @@ -1084,6 +1084,18 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest { doTest(fileName); } + @TestMetadata("inheritFromAnnotationClass.kt") + public void testInheritFromAnnotationClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass.kt"); + doTest(fileName); + } + + @TestMetadata("inheritFromAnnotationClass2.kt") + public void testInheritFromAnnotationClass2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass2.kt"); + doTest(fileName); + } + @TestMetadata("invalidTypesInAnnotationConstructor.kt") public void testInvalidTypesInAnnotationConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java index e85d05d584d..73664e77e53 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsUsingJavacTestGenerated.java @@ -1084,6 +1084,18 @@ public class DiagnosticsUsingJavacTestGenerated extends AbstractDiagnosticsUsing doTest(fileName); } + @TestMetadata("inheritFromAnnotationClass.kt") + public void testInheritFromAnnotationClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass.kt"); + doTest(fileName); + } + + @TestMetadata("inheritFromAnnotationClass2.kt") + public void testInheritFromAnnotationClass2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/inheritFromAnnotationClass2.kt"); + doTest(fileName); + } + @TestMetadata("invalidTypesInAnnotationConstructor.kt") public void testInvalidTypesInAnnotationConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/annotations/invalidTypesInAnnotationConstructor.kt");