diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt index f443441b892..8071325661c 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/CodegenUtil.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.common import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.Errors @@ -24,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.util.getExceptionMessage +import org.jetbrains.kotlin.util.getNonPrivateTraitMembersForDelegation import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments @@ -55,14 +55,8 @@ object CodegenUtil { @JvmOverloads fun getNonPrivateTraitMethods(descriptor: ClassDescriptor, copy: Boolean = true): Map { val result = linkedMapOf() - for (declaration in DescriptorUtils.getAllDescriptors(descriptor.defaultType.memberScope)) { - if (declaration !is CallableMemberDescriptor) continue - - val traitMember = findInterfaceImplementation(declaration) - if (traitMember == null || - Visibilities.isPrivate(traitMember.visibility) || - traitMember.visibility == Visibilities.INVISIBLE_FAKE) continue + for ((declaration, traitMember) in getNonPrivateTraitMembersForDelegation(descriptor)) { assert(traitMember.modality !== Modality.ABSTRACT) { "Cannot delegate to abstract trait method: $declaration" } // inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here diff --git a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/impl.kt b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/impl.kt index 024ab849243..5cca2aa6c5e 100644 --- a/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/impl.kt +++ b/compiler/backend-common/src/org/jetbrains/kotlin/backend/common/bridges/impl.kt @@ -24,6 +24,8 @@ import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.util.findImplementationFromInterface +import org.jetbrains.kotlin.util.findInterfaceImplementation fun generateBridgesForFunctionDescriptor( descriptor: FunctionDescriptor, @@ -81,60 +83,4 @@ open class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : F override fun toString(): String { return descriptor.toString() } -} - - -/** - * Given a fake override in a class, returns an overridden declaration with implementation in trait, such that a method delegating to that - * trait implementation should be generated into the class containing the fake override; or null if the given function is not a fake - * override of any trait implementation or such method was already generated into the superclass or is a method from Any. - */ -fun findInterfaceImplementation(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? { - if (descriptor.kind.isReal) return null - if (isOrOverridesSynthesized(descriptor)) return null - - val implementation = findImplementationFromInterface(descriptor) ?: return null - val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null - - if (!DescriptorUtils.isInterface(immediateConcreteSuper.containingDeclaration)) { - // If this implementation is already generated into the superclass, we need not generate it again, it'll be inherited - return null - } - - return immediateConcreteSuper -} - -/** - * Given a fake override, returns an overridden non-abstract function from an interface which is the actual implementation of this function - * that should be called when the given fake override is called. - */ -fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? { - val overridden = OverridingUtil.getOverriddenDeclarations(descriptor) - val filtered = OverridingUtil.filterOutOverridden(overridden) - - val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null - - if (DescriptorUtils.isClassOrEnumClass(result.containingDeclaration)) return null - - return result -} - -/** - * Given a fake override and its implementation (non-abstract declaration) somewhere in supertypes, - * returns the first immediate super function of the given fake override which overrides that implementation. - * The returned function should be called from TImpl-bridges generated for the given fake override. - */ -fun firstSuperMethodFromKotlin( - descriptor: CallableMemberDescriptor, - implementation: CallableMemberDescriptor -): CallableMemberDescriptor? { - return descriptor.overriddenDescriptors.firstOrNull { overridden -> - overridden.modality != Modality.ABSTRACT && - (overridden == implementation || OverridingUtil.overrides( - overridden, - implementation, - overridden.module.isTypeRefinementEnabled(), - true - )) - } -} +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java index a83d7ffc767..cab52ea6fd5 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBodyCodegen.java @@ -39,6 +39,8 @@ import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedS import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.descriptorToDeclaration; import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; import static org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind.CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL; +import static org.jetbrains.kotlin.util.DeclarationUtilKt.findImplementationFromInterface; +import static org.jetbrains.kotlin.util.DeclarationUtilKt.findInterfaceImplementation; public abstract class ClassBodyCodegen extends MemberCodegen { @NotNull @@ -125,7 +127,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen val reportOn = DescriptorToSourceUtils.getSourceFromAnnotation(annotationDescriptor) ?: declaration - if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) { + if (!isInterface(descriptor.containingDeclaration)) { context.trace.report(ErrorsJvm.JVM_DEFAULT_NOT_IN_INTERFACE.on(reportOn)) } else if (jvmTarget == JvmTarget.JVM_1_6) { context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_JVM6_TARGET.on(reportOn, "JvmDefault")) @@ -60,23 +60,78 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker { } - if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) return - val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return - if (descriptor is PropertyAccessorDescriptor) return + if (isInterface(descriptor.containingDeclaration)) { + val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return + if (descriptor is PropertyAccessorDescriptor) return - if (memberDescriptor.overriddenDescriptors.any { it.annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME) }) { - context.trace.report(ErrorsJvm.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE.on(declaration)) - } else if (jvmDefaultMode.isEnabled) { - descriptor.overriddenDescriptors.flatMap { OverridingUtil.getOverriddenDeclarations(it) }.toSet().let { - for (realDescriptor in OverridingUtil.filterOutOverridden(it)) { - if (realDescriptor is JavaMethodDescriptor && realDescriptor.modality != Modality.ABSTRACT) { - return context.trace.report(ErrorsJvm.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT.on(declaration)) + if (memberDescriptor.overriddenDescriptors.any { it.annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME) }) { + context.trace.report(ErrorsJvm.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE.on(declaration)) + } else if (jvmDefaultMode.isEnabled) { + descriptor.overriddenDescriptors.flatMap { OverridingUtil.getOverriddenDeclarations(it) }.toSet().let { + for (realDescriptor in OverridingUtil.filterOutOverridden(it)) { + if (realDescriptor is JavaMethodDescriptor && realDescriptor.modality != Modality.ABSTRACT) { + return context.trace.report(ErrorsJvm.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT.on(declaration)) + } + } + } + } + } else if (jvmDefaultMode.isCompatibility && + !isInterface(descriptor) && + !isAnnotationClass(descriptor) && + descriptor is ClassDescriptor && + !descriptor.hasJvmDefaultNoCompatibilityAnnotation() + ) { + val modality = descriptor.modality + //TODO: maybe remove this check for jvm compatibility + if (modality !== Modality.OPEN && modality !== Modality.ABSTRACT || descriptor.isEffectivelyPrivateApi) return + for ((inheritedMember, actualImplementation) in getNonPrivateTraitMembersForDelegation( + descriptor, + returnImplNotDelegate = true + )) { + if (actualImplementation.isCallableMemberCompiledToJvmDefault(jvmDefaultMode)) { + if (actualImplementation is FunctionDescriptor && inheritedMember is FunctionDescriptor) { + processMember(inheritedMember, actualImplementation, context, declaration) + } else if (actualImplementation is PropertyDescriptor && inheritedMember is PropertyDescriptor) { + val getterImpl = actualImplementation.getter + val getterInherited = inheritedMember.getter + if (getterImpl == null || getterInherited == null || processMember(getterImpl, getterImpl, context, declaration)) { + if (actualImplementation.isVar && inheritedMember.isVar) { + val setterImpl = actualImplementation.setter + val setterInherited = inheritedMember.setter + if (setterImpl != null && setterInherited != null) { + processMember(setterImpl, setterImpl, context, declaration) + } + } + } } } } } } + private fun processMember( + inheritedFun: FunctionDescriptor, + actualImplementation: FunctionDescriptor, + context: DeclarationCheckerContext, + declaration: KtDeclaration + ): Boolean { + val inheritedSignature = inheritedFun.computeJvmDescriptor(withReturnType = true, withName = false) + val originalImplementation = actualImplementation.original + val actualSignature = originalImplementation.computeJvmDescriptor(withReturnType = true, withName = false) + if (inheritedSignature != actualSignature) { + //NB: this diagnostics should be a bit tuned, see box/jvm8/defaults/allCompatibility/kt14243_2.kt for details + context.trace.report( + ErrorsJvm.EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE.on( + declaration, + getDirectMember(inheritedFun), + getDirectMember(originalImplementation) + ) + ) + return false + } + return true + } + private fun checkJvmDefaultsInHierarchy(descriptor: DeclarationDescriptor, jvmDefaultMode: JvmDefaultMode): Boolean { if (jvmDefaultMode.isEnabled) return true diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java index 38c93cdda74..7041fc961be 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/DefaultErrorMessagesJvm.java @@ -159,6 +159,12 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { MAP.put(FUNCTION_DELEGATE_MEMBER_NAME_CLASH, "Functional interface member cannot have this name on JVM because it clashes with an internal member getFunctionDelegate"); + + MAP.put(EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE, + "Compatibility mode requires to explicitly override ''{1}'' with specialization ''{0}'', " + + "or annotate the class with @JvmDefaultWithoutCompatibility. " + + "Please refer to KT-39603 for details", + COMPACT, SHORT_NAMES_IN_TYPES); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java index 46d30da6435..2cac1e51c0b 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/diagnostics/ErrorsJvm.java @@ -139,6 +139,8 @@ public interface ErrorsJvm { DiagnosticFactory0 FUNCTION_DELEGATE_MEMBER_NAME_CLASH = DiagnosticFactory0.create(ERROR); + DiagnosticFactory2 EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE = DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT); + @SuppressWarnings("UnusedDeclaration") Object _initializer = new Object() { { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/util/declarationUtil.kt b/compiler/frontend/src/org/jetbrains/kotlin/util/declarationUtil.kt index bd3ca2b5e62..fa10a19da93 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/util/declarationUtil.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/util/declarationUtil.kt @@ -6,11 +6,17 @@ package org.jetbrains.kotlin.util import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtPsiUtil +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.OverridingUtil +import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized +import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled +import org.jetbrains.kotlin.resolve.descriptorUtil.module fun KtElement.containingNonLocalDeclaration(): KtDeclaration? { var container = this.containingDeclarationForPseudocode @@ -27,3 +33,78 @@ val KtDeclaration.isOrdinaryClass !this.isInterface() val KtDeclaration.isAnnotated get() = this.annotationEntries.isNotEmpty() + +/** + * Given a fake override, returns an overridden non-abstract function from an interface which is the actual implementation of this function + * that should be called when the given fake override is called. + */ +fun findImplementationFromInterface(descriptor: CallableMemberDescriptor): CallableMemberDescriptor? { + val overridden = OverridingUtil.getOverriddenDeclarations(descriptor) + val filtered = OverridingUtil.filterOutOverridden(overridden) + + val result = filtered.firstOrNull { it.modality != Modality.ABSTRACT } ?: return null + + if (DescriptorUtils.isClassOrEnumClass(result.containingDeclaration)) return null + + return result +} + +/** + * Given a fake override in a class, returns an overridden declaration with implementation in trait, such that a method delegating to that + * trait implementation should be generated into the class containing the fake override; or null if the given function is not a fake + * override of any trait implementation or such method was already generated into the superclass or is a method from Any. + */ +@JvmOverloads +fun findInterfaceImplementation(descriptor: CallableMemberDescriptor, returnImplNotDelegate: Boolean = false): CallableMemberDescriptor? { + if (descriptor.kind.isReal) return null + if (isOrOverridesSynthesized(descriptor)) return null + + val implementation = findImplementationFromInterface(descriptor) ?: return null + val immediateConcreteSuper = firstSuperMethodFromKotlin(descriptor, implementation) ?: return null + + if (!DescriptorUtils.isInterface(immediateConcreteSuper.containingDeclaration)) { + // If this implementation is already generated into the superclass, we need not generate it again, it'll be inherited + return null + } + + return if (returnImplNotDelegate) implementation else immediateConcreteSuper +} + +/** + * Given a fake override and its implementation (non-abstract declaration) somewhere in supertypes, + * returns the first immediate super function of the given fake override which overrides that implementation. + * The returned function should be called from TImpl-bridges generated for the given fake override. + */ +fun firstSuperMethodFromKotlin( + descriptor: CallableMemberDescriptor, + implementation: CallableMemberDescriptor +): CallableMemberDescriptor? { + return descriptor.overriddenDescriptors.firstOrNull { overridden -> + overridden.modality != Modality.ABSTRACT && + (overridden == implementation || OverridingUtil.overrides( + overridden, + implementation, + overridden.module.isTypeRefinementEnabled(), + true + )) + } +} + + +fun getNonPrivateTraitMembersForDelegation( + descriptor: ClassDescriptor, + returnImplNotDelegate: Boolean = false, +): Map { + val result = linkedMapOf() + for (declaration in DescriptorUtils.getAllDescriptors(descriptor.defaultType.memberScope)) { + if (declaration !is CallableMemberDescriptor) continue + + val traitMember = findInterfaceImplementation(declaration, returnImplNotDelegate) + if (traitMember == null || + Visibilities.isPrivate(traitMember.visibility) || + traitMember.visibility == Visibilities.INVISIBLE_FAKE + ) continue + result[declaration] = traitMember + } + return result +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243.kt b/compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243.kt index d38a169b5f7..8ea4f009cd3 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243.kt @@ -9,6 +9,7 @@ interface Z { } } +@JvmDefaultWithoutCompatibility open class ZImpl : Z class ZImpl2 : ZImpl() { diff --git a/compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243_2.kt b/compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243_2.kt index 9f9385a843d..445c1d8891b 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243_2.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/allCompatibility/kt14243_2.kt @@ -9,8 +9,11 @@ interface Z { } } +@JvmDefaultWithoutCompatibility open class ZImpl : Z +//TODO: this is redundant, revise diagnostic +@JvmDefaultWithoutCompatibility open class ZImpl2 : Z, ZImpl() class ZImpl3 : ZImpl2() { diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization/basic.kt b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization/basic.kt new file mode 100644 index 00000000000..126e3a25111 --- /dev/null +++ b/compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization/basic.kt @@ -0,0 +1,18 @@ +// TARGET_BACKEND: JVM +// !JVM_DEFAULT_MODE: all +// JVM_TARGET: 1.8 +// IGNORE_BACKEND_FIR: JVM_IR +interface Foo { + fun test(p: T) = p + val T.prop: T + get() = this +} + +open class BaseSpecialized : Foo { + +} + +fun box(): String { + val base = BaseSpecialized() + return base.test("O") + with(base) { "K".prop } +} diff --git a/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndAny.kt b/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndAny.kt new file mode 100644 index 00000000000..0198aacbe9e --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndAny.kt @@ -0,0 +1,17 @@ +// !JVM_DEFAULT_MODE: all-compatibility +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// IGNORE_BACKEND: JVM_IR + +interface Base { + fun test(): Int? = 0 +} + +interface Derived: Base { + override fun test(): Int = 1 +} + +interface Mixed: Base, Derived + +open class A: Base, Derived +open class B: Mixed \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndAny.txt b/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndAny.txt new file mode 100644 index 00000000000..ddefe138132 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndAny.txt @@ -0,0 +1,47 @@ +@kotlin.Metadata +public class A { + public method (): void +} + +@kotlin.Metadata +public class B { + public method (): void +} + +@kotlin.Metadata +public final class Base$DefaultImpls { + inner class Base$DefaultImpls + public static @org.jetbrains.annotations.Nullable method test(@org.jetbrains.annotations.NotNull p0: Base): java.lang.Integer +} + +@kotlin.Metadata +public interface Base { + inner class Base$DefaultImpls + public synthetic static method access$test$jd(p0: Base): java.lang.Integer + public @org.jetbrains.annotations.Nullable method test(): java.lang.Integer +} + +@kotlin.Metadata +public final class Derived$DefaultImpls { + inner class Derived$DefaultImpls + public static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: Derived): java.lang.Integer +} + +@kotlin.Metadata +public interface Derived { + inner class Derived$DefaultImpls + public synthetic static method access$test$jd(p0: Derived): int + public @org.jetbrains.annotations.NotNull method test(): java.lang.Integer +} + +@kotlin.Metadata +public final class Mixed$DefaultImpls { + inner class Mixed$DefaultImpls + public static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: Mixed): java.lang.Integer +} + +@kotlin.Metadata +public interface Mixed { + inner class Mixed$DefaultImpls + public synthetic static method access$test$jd(p0: Mixed): int +} diff --git a/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndNullable.kt b/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndNullable.kt new file mode 100644 index 00000000000..6193e630dcb --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndNullable.kt @@ -0,0 +1,16 @@ +// !JVM_DEFAULT_MODE: all-compatibility +// JVM_TARGET: 1.8 +// WITH_RUNTIME +// IGNORE_BACKEND: JVM_IR +interface Base { + fun test(): Int? = 0 +} + +interface Derived: Base { + override fun test(): Int = 1 +} + +interface Mixed: Base, Derived + +open class A: Base, Derived +open class B: Mixed diff --git a/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndNullable.txt b/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndNullable.txt new file mode 100644 index 00000000000..ddefe138132 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndNullable.txt @@ -0,0 +1,47 @@ +@kotlin.Metadata +public class A { + public method (): void +} + +@kotlin.Metadata +public class B { + public method (): void +} + +@kotlin.Metadata +public final class Base$DefaultImpls { + inner class Base$DefaultImpls + public static @org.jetbrains.annotations.Nullable method test(@org.jetbrains.annotations.NotNull p0: Base): java.lang.Integer +} + +@kotlin.Metadata +public interface Base { + inner class Base$DefaultImpls + public synthetic static method access$test$jd(p0: Base): java.lang.Integer + public @org.jetbrains.annotations.Nullable method test(): java.lang.Integer +} + +@kotlin.Metadata +public final class Derived$DefaultImpls { + inner class Derived$DefaultImpls + public static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: Derived): java.lang.Integer +} + +@kotlin.Metadata +public interface Derived { + inner class Derived$DefaultImpls + public synthetic static method access$test$jd(p0: Derived): int + public @org.jetbrains.annotations.NotNull method test(): java.lang.Integer +} + +@kotlin.Metadata +public final class Mixed$DefaultImpls { + inner class Mixed$DefaultImpls + public static @org.jetbrains.annotations.NotNull method test(@org.jetbrains.annotations.NotNull p0: Mixed): java.lang.Integer +} + +@kotlin.Metadata +public interface Mixed { + inner class Mixed$DefaultImpls + public synthetic static method access$test$jd(p0: Mixed): int +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.fir.kt new file mode 100644 index 00000000000..a9ec15cf7fc --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.fir.kt @@ -0,0 +1,69 @@ +// !JVM_DEFAULT_MODE: all-compatibility +// JVM_TARGET: 1.8 +// WITH_RUNTIME + +interface Foo { + fun test(p: T) = "fail" + val T.prop: String + get() = "fail" +} + +interface FooDerived: Foo + +class Unspecialized : Foo + +open class UnspecializedFromDerived : FooDerived + +abstract class AbstractUnspecializedFromDerived : FooDerived + +open class Specialized : Foo + +abstract class AbstractSpecialized : Foo + + +@JvmDefaultWithoutCompatibility +open class UnspecializedFromDerivedNC : FooDerived + +@JvmDefaultWithoutCompatibility +abstract class AbstractUnspecializedFromDerivedNC : FooDerived + +@JvmDefaultWithoutCompatibility +open class SpecializedNC : Foo + +@JvmDefaultWithoutCompatibility +abstract class AbstractSpecializedNC : Foo + + +final class FinalSpecialized : Foo + +sealed class SealedSpecialized : Foo { + open class A : SealedSpecialized(); +} + +enum class EnumSpecialized : Foo { + ENTRY { + fun test() = 123 + } +} + +object ObjectSpecialized : Foo + +private class Outer { + + open class InnerSpecialized: Foo +} + +fun local() { + object : Foo {} +} + +fun interface F : Foo { + fun invoke(o: String): String +} + +fun test(): String { + if (F { o -> o + "K" }.invoke("O") != "OK") return "Fail" + + val lambda: (String) -> String = { o -> o + "K" } + return F(lambda).invoke("O") +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.kt new file mode 100644 index 00000000000..d07b9930e26 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.kt @@ -0,0 +1,69 @@ +// !JVM_DEFAULT_MODE: all-compatibility +// JVM_TARGET: 1.8 +// WITH_RUNTIME + +interface Foo { + fun test(p: T) = "fail" + val T.prop: String + get() = "fail" +} + +interface FooDerived: Foo + +class Unspecialized : Foo + +open class UnspecializedFromDerived : FooDerived + +abstract class AbstractUnspecializedFromDerived : FooDerived + +open class Specialized : Foo + +abstract class AbstractSpecialized : Foo + + +@JvmDefaultWithoutCompatibility +open class UnspecializedFromDerivedNC : FooDerived + +@JvmDefaultWithoutCompatibility +abstract class AbstractUnspecializedFromDerivedNC : FooDerived + +@JvmDefaultWithoutCompatibility +open class SpecializedNC : Foo + +@JvmDefaultWithoutCompatibility +abstract class AbstractSpecializedNC : Foo + + +final class FinalSpecialized : Foo + +sealed class SealedSpecialized : Foo { + open class A : SealedSpecialized(); +} + +enum class EnumSpecialized : Foo { + ENTRY { + fun test() = 123 + } +} + +object ObjectSpecialized : Foo + +private class Outer { + + open class InnerSpecialized: Foo +} + +fun local() { + object : Foo {} +} + +fun interface F : Foo { + fun invoke(o: String): String +} + +fun test(): String { + if (F { o -> o + "K" }.invoke("O") != "OK") return "Fail" + + val lambda: (String) -> String = { o -> o + "K" } + return F(lambda).invoke("O") +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.txt b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.txt new file mode 100644 index 00000000000..24d71c99ca1 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.txt @@ -0,0 +1,183 @@ +package + +public fun local(): kotlin.Unit +public fun test(): kotlin.String + +public abstract class AbstractSpecialized : Foo { + public constructor AbstractSpecialized() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.jvm.JvmDefaultWithoutCompatibility public abstract class AbstractSpecializedNC : Foo { + public constructor AbstractSpecializedNC() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public abstract class AbstractUnspecializedFromDerived : FooDerived { + public constructor AbstractUnspecializedFromDerived() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.jvm.JvmDefaultWithoutCompatibility public abstract class AbstractUnspecializedFromDerivedNC : FooDerived { + public constructor AbstractUnspecializedFromDerivedNC() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final enum class EnumSpecialized : kotlin.Enum, Foo { + enum entry ENTRY + + private constructor EnumSpecialized() + public final override /*1*/ /*fake_override*/ val name: kotlin.String + public final override /*1*/ /*fake_override*/ val ordinal: kotlin.Int + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + protected final override /*1*/ /*fake_override*/ fun clone(): kotlin.Any + public final override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: EnumSpecialized): kotlin.Int + public final override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + protected/*protected and package*/ final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun finalize(): kotlin.Unit + public final override /*1*/ /*fake_override*/ /*isHiddenForResolutionEverywhereBesideSupercalls*/ fun getDeclaringClass(): java.lang.Class! + public final override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun test(/*0*/ p: kotlin.String): kotlin.String + public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String + + // Static members + public final /*synthesized*/ fun valueOf(/*0*/ value: kotlin.String): EnumSpecialized + public final /*synthesized*/ fun values(): kotlin.Array +} + +public fun interface F : Foo { + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 abstract fun invoke(/*0*/ o: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class FinalSpecialized : Foo { + public constructor FinalSpecialized() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface Foo { + public open val T.prop: kotlin.String + 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 fun test(/*0*/ p: T): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public interface FooDerived : Foo { + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public object ObjectSpecialized : Foo { + private constructor ObjectSpecialized() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +private final class Outer { + public constructor Outer() + 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 open class InnerSpecialized : Foo { + public constructor InnerSpecialized() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public sealed class SealedSpecialized : Foo { + private constructor SealedSpecialized() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + + public open class A : SealedSpecialized { + public constructor A() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} + +public open class Specialized : Foo { + public constructor Specialized() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.jvm.JvmDefaultWithoutCompatibility public open class SpecializedNC : Foo { + public constructor SpecializedNC() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public final class Unspecialized : Foo { + public constructor Unspecialized() + public open override /*1*/ /*fake_override*/ val Y.prop: kotlin.String + 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 test(/*0*/ p: Y): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +public open class UnspecializedFromDerived : FooDerived { + public constructor UnspecializedFromDerived() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} + +@kotlin.jvm.JvmDefaultWithoutCompatibility public open class UnspecializedFromDerivedNC : FooDerived { + public constructor UnspecializedFromDerivedNC() + public open override /*1*/ /*fake_override*/ val kotlin.String.prop: kotlin.String + 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 test(/*0*/ p: kotlin.String): kotlin.String + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index cffdd33a6e1..84dac9551e2 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -563,6 +563,24 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt"); } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class AllCompatibility extends AbstractDiagnosticsTestWithStdLib { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInAllCompatibility() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @TestMetadata("specialization.kt") + public void testSpecialization() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.kt"); + } + } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index e7ef7fa2d41..7c4cb994745 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -563,6 +563,24 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt"); } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class AllCompatibility extends AbstractDiagnosticsTestWithStdLibUsingJavac { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInAllCompatibility() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true); + } + + @TestMetadata("specialization.kt") + public void testSpecialization() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/allCompatibility/specialization.kt"); + } + } + @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 4963fb8e3b0..9160334c5c4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -16993,6 +16993,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy/simpleProperty.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Specialization extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInSpecialization() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("basic.kt") + public void testBasic() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization/basic.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 7a44540b849..a566aedf865 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -531,6 +531,29 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { public void testNoDefaultImplsOnEmptySubInterface() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/noDefaultImplsOnEmptySubInterface.kt"); } + + @TestMetadata("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Specialization extends AbstractBytecodeListingTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInSpecialization() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("primitiveAndAny.kt") + public void testPrimitiveAndAny() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndAny.kt"); + } + + @TestMetadata("primitiveAndNullable.kt") + public void testPrimitiveAndNullable() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndNullable.kt"); + } + } } } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index d1bceae8d90..db3745a8f7c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16993,6 +16993,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy/simpleProperty.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Specialization extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInSpecialization() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); + } + + @TestMetadata("basic.kt") + public void testBasic() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization/basic.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index d349c954911..7a4b29cd5cd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -15773,6 +15773,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy/simpleProperty.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Specialization extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInSpecialization() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("basic.kt") + public void testBasic() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization/basic.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index abaae84a2ad..c54d5fcd780 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -501,6 +501,29 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes public void testNoDefaultImplsOnEmptySubInterface() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/noDefaultImplsOnEmptySubInterface.kt"); } + + @TestMetadata("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Specialization extends AbstractIrBytecodeListingTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInSpecialization() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); + } + + @TestMetadata("primitiveAndAny.kt") + public void testPrimitiveAndAny() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndAny.kt"); + } + + @TestMetadata("primitiveAndNullable.kt") + public void testPrimitiveAndNullable() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/specialization/primitiveAndNullable.kt"); + } + } } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 733dccc556c..ca4aeb8837a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -13073,6 +13073,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } } + + @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Specialization extends AbstractIrJsCodegenBoxES6Test { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath); + } + + public void testAllFilesPresentInSpecialization() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); + } + } } @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index bac7b66be3a..a11166bd34c 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -13083,6 +13083,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } } + + @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Specialization extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInSpecialization() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); + } + } } @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index d3a6f215777..93fac60d316 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -13148,6 +13148,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } } + + @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Specialization extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInSpecialization() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/specialization"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); + } + } } @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation")