提交 9c0b96af 编写于 作者: M Mikhail Bogdanov

Report error on missed specialization in compatibility mode

 #KT-39603 Fixed
上级 a150e7b6
...@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.common ...@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.common
import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.backend.common.bridges.findInterfaceImplementation
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.DiagnosticSink
import org.jetbrains.kotlin.diagnostics.Errors import org.jetbrains.kotlin.diagnostics.Errors
...@@ -24,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall ...@@ -24,6 +23,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.util.getExceptionMessage import org.jetbrains.kotlin.util.getExceptionMessage
import org.jetbrains.kotlin.util.getNonPrivateTraitMembersForDelegation
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
...@@ -55,14 +55,8 @@ object CodegenUtil { ...@@ -55,14 +55,8 @@ object CodegenUtil {
@JvmOverloads @JvmOverloads
fun getNonPrivateTraitMethods(descriptor: ClassDescriptor, copy: Boolean = true): Map<FunctionDescriptor, FunctionDescriptor> { fun getNonPrivateTraitMethods(descriptor: ClassDescriptor, copy: Boolean = true): Map<FunctionDescriptor, FunctionDescriptor> {
val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>() val result = linkedMapOf<FunctionDescriptor, FunctionDescriptor>()
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" } 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 // inheritedMember can be abstract here. In order for FunctionCodegen to generate the method body, we're creating a copy here
......
...@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.resolve.OverridingUtil ...@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isOrOverridesSynthesized
import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled import org.jetbrains.kotlin.resolve.descriptorUtil.isTypeRefinementEnabled
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.util.findImplementationFromInterface
import org.jetbrains.kotlin.util.findInterfaceImplementation
fun <Signature> generateBridgesForFunctionDescriptor( fun <Signature> generateBridgesForFunctionDescriptor(
descriptor: FunctionDescriptor, descriptor: FunctionDescriptor,
...@@ -81,60 +83,4 @@ open class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : F ...@@ -81,60 +83,4 @@ open class DescriptorBasedFunctionHandle(val descriptor: FunctionDescriptor) : F
override fun toString(): String { override fun toString(): String {
return descriptor.toString() return descriptor.toString()
} }
} }
\ No newline at end of file
/**
* 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
))
}
}
...@@ -39,6 +39,8 @@ import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.enumEntryNeedS ...@@ -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.DescriptorToSourceUtils.descriptorToDeclaration;
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE; 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.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<KtPureClassOrObject> { public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject> {
@NotNull @NotNull
...@@ -125,7 +127,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject ...@@ -125,7 +127,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) { for (DeclarationDescriptor memberDescriptor : DescriptorUtils.getAllDescriptors(descriptor.getDefaultType().getMemberScope())) {
if (memberDescriptor instanceof CallableMemberDescriptor) { if (memberDescriptor instanceof CallableMemberDescriptor) {
CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor; CallableMemberDescriptor member = (CallableMemberDescriptor) memberDescriptor;
if (!member.getKind().isReal() && ImplKt.findInterfaceImplementation(member) == null) { if (!member.getKind().isReal() && findInterfaceImplementation(member) == null) {
if (member instanceof FunctionDescriptor) { if (member instanceof FunctionDescriptor) {
functionCodegen.generateBridges((FunctionDescriptor) member); functionCodegen.generateBridges((FunctionDescriptor) member);
} }
...@@ -242,7 +244,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject ...@@ -242,7 +244,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
} }
CallableMemberDescriptor actualImplementation = CallableMemberDescriptor actualImplementation =
interfaceFun.getKind().isReal() ? interfaceFun : ImplKt.findImplementationFromInterface(interfaceFun); interfaceFun.getKind().isReal() ? interfaceFun : findImplementationFromInterface(interfaceFun);
assert actualImplementation != null : "Can't find actual implementation for " + interfaceFun; assert actualImplementation != null : "Can't find actual implementation for " + interfaceFun;
if (JvmAnnotationUtilKt.isCallableMemberCompiledToJvmDefault(actualImplementation, state.getJvmDefaultMode())) { if (JvmAnnotationUtilKt.isCallableMemberCompiledToJvmDefault(actualImplementation, state.getJvmDefaultMode())) {
return; return;
......
...@@ -608,7 +608,7 @@ public class FunctionCodegen { ...@@ -608,7 +608,7 @@ public class FunctionCodegen {
true, mv, true, mv,
method.getAsmMethod(), method.getAsmMethod(),
method.getOwner().getInternalName(), method.getOwner().getInternalName(),
true); true, signature.getReturnType());
methodEnd = new Label(); methodEnd = new Label();
} }
else { else {
...@@ -850,7 +850,8 @@ public class FunctionCodegen { ...@@ -850,7 +850,8 @@ public class FunctionCodegen {
@NotNull Method asmMethod, @NotNull Method asmMethod,
@NotNull String classToDelegateTo, @NotNull String classToDelegateTo,
int opcode, int opcode,
boolean isInterface boolean isInterface,
@NotNull Type returnType
) { ) {
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
Type[] argTypes = asmMethod.getArgumentTypes(); Type[] argTypes = asmMethod.getArgumentTypes();
...@@ -872,7 +873,8 @@ public class FunctionCodegen { ...@@ -872,7 +873,8 @@ public class FunctionCodegen {
paramIndex += argType.getSize(); paramIndex += argType.getSize();
} }
iv.visitMethodInsn(opcode, classToDelegateTo, asmMethod.getName(), asmMethod.getDescriptor(), isInterface); iv.visitMethodInsn(opcode, classToDelegateTo, asmMethod.getName(), asmMethod.getDescriptor(), isInterface);
iv.areturn(asmMethod.getReturnType()); StackValue.onStack(asmMethod.getReturnType()).coerceTo(returnType, null, iv);
iv.areturn(returnType);
} }
private static void generateDelegateToStaticErasedVersion( private static void generateDelegateToStaticErasedVersion(
...@@ -911,7 +913,19 @@ public class FunctionCodegen { ...@@ -911,7 +913,19 @@ public class FunctionCodegen {
@NotNull String classToDelegateTo, @NotNull String classToDelegateTo,
boolean isInterfaceMethodCall boolean isInterfaceMethodCall
) { ) {
generateDelegateToMethodBody(isStatic ? 0 : 1, mv, asmMethod, classToDelegateTo, Opcodes.INVOKESTATIC, isInterfaceMethodCall); generateDelegateToStaticMethodBody(isStatic, mv, asmMethod, classToDelegateTo, isInterfaceMethodCall, asmMethod.getReturnType());
}
private static void generateDelegateToStaticMethodBody(
boolean isStatic,
@NotNull MethodVisitor mv,
@NotNull Method asmMethod,
@NotNull String classToDelegateTo,
boolean isInterfaceMethodCall,
@NotNull Type returnType
) {
generateDelegateToMethodBody(isStatic ? 0 : 1, mv, asmMethod, classToDelegateTo, Opcodes.INVOKESTATIC, isInterfaceMethodCall, returnType);
} }
private static boolean needIndexForVar(JvmMethodParameterKind kind) { private static boolean needIndexForVar(JvmMethodParameterKind kind) {
......
...@@ -17,8 +17,7 @@ ...@@ -17,8 +17,7 @@
package org.jetbrains.kotlin.codegen package org.jetbrains.kotlin.codegen
import com.intellij.util.ArrayUtil import com.intellij.util.ArrayUtil
import org.jetbrains.kotlin.backend.common.bridges.findImplementationFromInterface import org.jetbrains.kotlin.util.findImplementationFromInterface
import org.jetbrains.kotlin.backend.common.bridges.firstSuperMethodFromKotlin
import org.jetbrains.kotlin.codegen.context.ClassContext import org.jetbrains.kotlin.codegen.context.ClassContext
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.JvmMethodExceptionTypes import org.jetbrains.kotlin.codegen.state.JvmMethodExceptionTypes
...@@ -29,6 +28,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils ...@@ -29,6 +28,7 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
import org.jetbrains.kotlin.util.firstSuperMethodFromKotlin
import org.jetbrains.org.objectweb.asm.MethodVisitor import org.jetbrains.org.objectweb.asm.MethodVisitor
import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Opcodes.*
......
...@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyD ...@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyD
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.annotations.isCompiledToJvmDefault import org.jetbrains.kotlin.resolve.jvm.annotations.isCompiledToJvmDefault
import org.jetbrains.kotlin.resolve.jvm.annotations.hasPlatformDependentAnnotation import org.jetbrains.kotlin.resolve.jvm.annotations.hasPlatformDependentAnnotation
import org.jetbrains.kotlin.util.findImplementationFromInterface
import org.jetbrains.kotlin.util.findInterfaceImplementation
class DescriptorBasedFunctionHandleForJvm( class DescriptorBasedFunctionHandleForJvm(
descriptor: FunctionDescriptor, descriptor: FunctionDescriptor,
......
...@@ -562,6 +562,24 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi ...@@ -562,6 +562,24 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt"); 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 AbstractFirOldFrontendDiagnosticsTestWithStdlib {
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") @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
......
...@@ -15773,6 +15773,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT ...@@ -15773,6 +15773,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy/simpleProperty.kt"); 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 AbstractFirBlackBoxCodegenTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
}
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") @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation")
...@@ -10,17 +10,17 @@ import org.jetbrains.kotlin.config.JvmDefaultMode ...@@ -10,17 +10,17 @@ import org.jetbrains.kotlin.config.JvmDefaultMode
import org.jetbrains.kotlin.config.JvmTarget import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils.*
import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker import org.jetbrains.kotlin.resolve.checkers.DeclarationChecker
import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext import org.jetbrains.kotlin.resolve.checkers.DeclarationCheckerContext
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_FQ_NAME import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyPrivateApi
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_NO_COMPATIBILITY_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.annotations.*
import org.jetbrains.kotlin.resolve.jvm.annotations.isCompiledToJvmDefault
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
import org.jetbrains.kotlin.util.getNonPrivateTraitMembersForDelegation
class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker { class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
...@@ -29,7 +29,7 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker { ...@@ -29,7 +29,7 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
descriptor.annotations.findAnnotation(JVM_DEFAULT_FQ_NAME)?.let { annotationDescriptor -> descriptor.annotations.findAnnotation(JVM_DEFAULT_FQ_NAME)?.let { annotationDescriptor ->
val reportOn = DescriptorToSourceUtils.getSourceFromAnnotation(annotationDescriptor) ?: declaration 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)) context.trace.report(ErrorsJvm.JVM_DEFAULT_NOT_IN_INTERFACE.on(reportOn))
} else if (jvmTarget == JvmTarget.JVM_1_6) { } else if (jvmTarget == JvmTarget.JVM_1_6) {
context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_JVM6_TARGET.on(reportOn, "JvmDefault")) context.trace.report(ErrorsJvm.JVM_DEFAULT_IN_JVM6_TARGET.on(reportOn, "JvmDefault"))
...@@ -60,21 +60,76 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker { ...@@ -60,21 +60,76 @@ class JvmDefaultChecker(val jvmTarget: JvmTarget) : DeclarationChecker {
} }
if (!DescriptorUtils.isInterface(descriptor.containingDeclaration)) return if (isInterface(descriptor.containingDeclaration)) {
val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return val memberDescriptor = descriptor as? CallableMemberDescriptor ?: return
if (descriptor is PropertyAccessorDescriptor) return if (descriptor is PropertyAccessorDescriptor) return
if (memberDescriptor.overriddenDescriptors.any { it.annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME) }) { if (memberDescriptor.overriddenDescriptors.any { it.annotations.hasAnnotation(JVM_DEFAULT_FQ_NAME) }) {
context.trace.report(ErrorsJvm.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE.on(declaration)) context.trace.report(ErrorsJvm.JVM_DEFAULT_REQUIRED_FOR_OVERRIDE.on(declaration))
} else if (jvmDefaultMode.isEnabled) { } else if (jvmDefaultMode.isEnabled) {
descriptor.overriddenDescriptors.flatMap { OverridingUtil.getOverriddenDeclarations(it) }.toSet().let { descriptor.overriddenDescriptors.flatMap { OverridingUtil.getOverriddenDeclarations(it) }.toSet().let {
for (realDescriptor in OverridingUtil.filterOutOverridden(it)) { for (realDescriptor in OverridingUtil.filterOutOverridden(it)) {
if (realDescriptor is JavaMethodDescriptor && realDescriptor.modality != Modality.ABSTRACT) { if (realDescriptor is JavaMethodDescriptor && realDescriptor.modality != Modality.ABSTRACT) {
return context.trace.report(ErrorsJvm.NON_JVM_DEFAULT_OVERRIDES_JAVA_DEFAULT.on(declaration)) 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 { private fun checkJvmDefaultsInHierarchy(descriptor: DeclarationDescriptor, jvmDefaultMode: JvmDefaultMode): Boolean {
......
...@@ -159,6 +159,12 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension { ...@@ -159,6 +159,12 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
MAP.put(FUNCTION_DELEGATE_MEMBER_NAME_CLASH, MAP.put(FUNCTION_DELEGATE_MEMBER_NAME_CLASH,
"Functional interface member cannot have this name on JVM because it clashes with an internal member getFunctionDelegate"); "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 @NotNull
......
...@@ -139,6 +139,8 @@ public interface ErrorsJvm { ...@@ -139,6 +139,8 @@ public interface ErrorsJvm {
DiagnosticFactory0<PsiElement> FUNCTION_DELEGATE_MEMBER_NAME_CLASH = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<PsiElement> FUNCTION_DELEGATE_MEMBER_NAME_CLASH = DiagnosticFactory0.create(ERROR);
DiagnosticFactory2<KtDeclaration, CallableDescriptor, CallableDescriptor> EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE = DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
Object _initializer = new Object() { Object _initializer = new Object() {
{ {
......
...@@ -6,11 +6,17 @@ ...@@ -6,11 +6,17 @@
package org.jetbrains.kotlin.util package org.jetbrains.kotlin.util
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtPsiUtil 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? { fun KtElement.containingNonLocalDeclaration(): KtDeclaration? {
var container = this.containingDeclarationForPseudocode var container = this.containingDeclarationForPseudocode
...@@ -27,3 +33,78 @@ val KtDeclaration.isOrdinaryClass ...@@ -27,3 +33,78 @@ val KtDeclaration.isOrdinaryClass
!this.isInterface() !this.isInterface()
val KtDeclaration.isAnnotated get() = this.annotationEntries.isNotEmpty() 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<CallableMemberDescriptor, CallableMemberDescriptor> {
val result = linkedMapOf<CallableMemberDescriptor, CallableMemberDescriptor>()
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
...@@ -9,6 +9,7 @@ interface Z<T> { ...@@ -9,6 +9,7 @@ interface Z<T> {
} }
} }
@JvmDefaultWithoutCompatibility
open class ZImpl : Z<String> open class ZImpl : Z<String>
class ZImpl2 : ZImpl() { class ZImpl2 : ZImpl() {
......
...@@ -9,8 +9,11 @@ interface Z<T> { ...@@ -9,8 +9,11 @@ interface Z<T> {
} }
} }
@JvmDefaultWithoutCompatibility
open class ZImpl : Z<String> open class ZImpl : Z<String>
//TODO: this is redundant, revise diagnostic
@JvmDefaultWithoutCompatibility
open class ZImpl2 : Z<String>, ZImpl() open class ZImpl2 : Z<String>, ZImpl()
class ZImpl3 : ZImpl2() { class ZImpl3 : ZImpl2() {
......
// TARGET_BACKEND: JVM
// !JVM_DEFAULT_MODE: all
// JVM_TARGET: 1.8
// IGNORE_BACKEND_FIR: JVM_IR
interface Foo<T> {
fun test(p: T) = p
val T.prop: T
get() = this
}
open class BaseSpecialized : Foo<String> {
}
fun box(): String {
val base = BaseSpecialized()
return base.test("O") + with(base) { "K".prop }
}
// !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
@kotlin.Metadata
public class A {
public method <init>(): void
}
@kotlin.Metadata
public class B {
public method <init>(): 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
}
// !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
@kotlin.Metadata
public class A {
public method <init>(): void
}
@kotlin.Metadata
public class B {
public method <init>(): 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
}
// !JVM_DEFAULT_MODE: all-compatibility
// JVM_TARGET: 1.8
// WITH_RUNTIME
interface Foo<T> {
fun test(p: T) = "fail"
val T.prop: String
get() = "fail"
}
interface FooDerived: Foo<String>
class Unspecialized<Y> : Foo<Y>
open class UnspecializedFromDerived : FooDerived
abstract class AbstractUnspecializedFromDerived : FooDerived
open class Specialized : Foo<String>
abstract class AbstractSpecialized : Foo<String>
@JvmDefaultWithoutCompatibility
open class UnspecializedFromDerivedNC : FooDerived
@JvmDefaultWithoutCompatibility
abstract class AbstractUnspecializedFromDerivedNC : FooDerived
@JvmDefaultWithoutCompatibility
open class SpecializedNC : Foo<String>
@JvmDefaultWithoutCompatibility
abstract class AbstractSpecializedNC : Foo<String>
final class FinalSpecialized : Foo<String>
sealed class SealedSpecialized : Foo<String> {
open class A : SealedSpecialized();
}
enum class EnumSpecialized : Foo<String> {
ENTRY {
fun test() = 123
}
}
object ObjectSpecialized : Foo<String>
private class Outer {
open class InnerSpecialized: Foo<String>
}
fun local() {
object : Foo<String> {}
}
fun interface F : Foo<String> {
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")
}
// !JVM_DEFAULT_MODE: all-compatibility
// JVM_TARGET: 1.8
// WITH_RUNTIME
interface Foo<T> {
fun test(p: T) = "fail"
val T.prop: String
get() = "fail"
}
interface FooDerived: Foo<String>
class Unspecialized<Y> : Foo<Y>
open class <!EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE, EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE!>UnspecializedFromDerived<!> : FooDerived
abstract class <!EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE, EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE!>AbstractUnspecializedFromDerived<!> : FooDerived
open class <!EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE, EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE!>Specialized<!> : Foo<String>
abstract class <!EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE, EXPLICIT_OVERRIDE_REQUIRED_IN_COMPATIBILITY_MODE!>AbstractSpecialized<!> : Foo<String>
@JvmDefaultWithoutCompatibility
open class UnspecializedFromDerivedNC : FooDerived
@JvmDefaultWithoutCompatibility
abstract class AbstractUnspecializedFromDerivedNC : FooDerived
@JvmDefaultWithoutCompatibility
open class SpecializedNC : Foo<String>
@JvmDefaultWithoutCompatibility
abstract class AbstractSpecializedNC : Foo<String>
final class FinalSpecialized : Foo<String>
sealed class SealedSpecialized : Foo<String> {
open class A : SealedSpecialized();
}
enum class EnumSpecialized : Foo<String> {
ENTRY {
fun test() = 123
}
}
object ObjectSpecialized : Foo<String>
private class Outer {
open class InnerSpecialized: Foo<String>
}
fun local() {
object : Foo<String> {}
}
fun interface F : Foo<String> {
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")
}
package
public fun local(): kotlin.Unit
public fun test(): kotlin.String
public abstract class AbstractSpecialized : Foo<kotlin.String> {
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<kotlin.String> {
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<EnumSpecialized>, Foo<kotlin.String> {
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<EnumSpecialized!>!
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<EnumSpecialized>
}
public fun interface F : Foo<kotlin.String> {
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<kotlin.String> {
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</*0*/ T> {
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<kotlin.String> {
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<kotlin.String> {
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<kotlin.String> {
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<kotlin.String> {
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<kotlin.String> {
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<kotlin.String> {
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</*0*/ Y> : Foo<Y> {
public constructor Unspecialized</*0*/ Y>()
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
}
...@@ -563,6 +563,24 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW ...@@ -563,6 +563,24 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt"); 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") @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
......
...@@ -563,6 +563,24 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno ...@@ -563,6 +563,24 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
runTest("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/target8.kt"); 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") @TestMetadata("compiler/testData/diagnostics/testsWithStdLib/annotations/jvmDefault/jvmDefaultWithoutCompatibility")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)
......
...@@ -16993,6 +16993,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { ...@@ -16993,6 +16993,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy/simpleProperty.kt"); 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") @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation")
...@@ -531,6 +531,29 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { ...@@ -531,6 +531,29 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
public void testNoDefaultImplsOnEmptySubInterface() throws Exception { public void testNoDefaultImplsOnEmptySubInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/noDefaultImplsOnEmptySubInterface.kt"); 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");
}
}
} }
} }
} }
......
...@@ -16993,6 +16993,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes ...@@ -16993,6 +16993,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy/simpleProperty.kt"); 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") @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation")
...@@ -15773,6 +15773,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes ...@@ -15773,6 +15773,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/jvm8/defaults/noDefaultImpls/delegationBy/simpleProperty.kt"); 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") @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation")
...@@ -501,6 +501,29 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes ...@@ -501,6 +501,29 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes
public void testNoDefaultImplsOnEmptySubInterface() throws Exception { public void testNoDefaultImplsOnEmptySubInterface() throws Exception {
runTest("compiler/testData/codegen/bytecodeListing/jvm8/defaults/allCompatibility/noDefaultImplsOnEmptySubInterface.kt"); 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");
}
}
} }
} }
} }
......
...@@ -13073,6 +13073,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes ...@@ -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); 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") @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation")
...@@ -13083,6 +13083,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { ...@@ -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); 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") @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation")
...@@ -13148,6 +13148,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { ...@@ -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); 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") @TestMetadata("compiler/testData/codegen/box/jvm8/defaults/noDelegation")
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册