diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt index b392925cc33..e76713c2da3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom import org.jetbrains.kotlin.backend.common.lower.createIrBuilder @@ -164,7 +165,7 @@ internal val interfaceDefaultCallsPhase = makeIrFilePhase( description = "Redirect interface calls with default arguments to DefaultImpls" ) -private class InterfaceDefaultCallsLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass { +private class InterfaceDefaultCallsLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass { // TODO If there are no default _implementations_ we can avoid generating defaultImpls class entirely by moving default arg dispatchers to the interface class override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(this) @@ -181,6 +182,12 @@ private class InterfaceDefaultCallsLowering(val context: JvmBackendContext) : Ir } val redirectTarget = context.declarationFactory.getDefaultImplsFunction(callee as IrSimpleFunction) + + // InterfaceLowering bridges from DefaultImpls in compatibility mode -- if that's the case, + // this phase will inadvertently cause a recursive loop as the bridge on the DefaultImpls + // gets redirected to call itself. + if (redirectTarget == currentFunction?.irElement) return super.visitCall(expression) + val newCall = irCall(expression, redirectTarget, receiversAsArguments = true) return super.visitCall(newCall) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index f0e580b1df2..7673f286d88 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ir.copyBodyToStatic import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom -import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface @@ -17,10 +16,6 @@ import org.jetbrains.kotlin.backend.jvm.ir.hasJvmDefault import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET -import org.jetbrains.kotlin.ir.builders.irBlockBody -import org.jetbrains.kotlin.ir.builders.irExprBody -import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* @@ -74,7 +69,12 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran /** * 2) They inherit a default implementation from an interface this interface - * extends: create a bridge from companion to companion, if necessary: + * extends: create a bridge from companion to companion, unless + * - the implementation is private or belongs to java.lang.Object + * - we're in JVM Compatibility Default mode, in which case we go via + * accessors on the parent class rather than the DefaultImpls + * - we're in JVM Default mode, and we have that default implementation, + * in which case we simply leave it. * * ``` * interface A { fun foo() = 0 } @@ -91,11 +91,20 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran function.origin == IrDeclarationOrigin.FAKE_OVERRIDE -> { val implementation = function.resolveFakeOverride()!! - if (!Visibilities.isPrivate(implementation.visibility) - && !implementation.isMethodOfAny() - && (!implementation.hasJvmDefault() || context.state.jvmDefaultMode.isCompatibility) - ) { - delegateInheritedDefaultImplementationToDefaultImpls(function, implementation) + when { + Visibilities.isPrivate(implementation.visibility) || implementation.isMethodOfAny() -> + continue@loop + context.state.jvmDefaultMode.isCompatibility -> { + val defaultImpl = createDefaultImpl(function) + defaultImpl.bridgeViaAccessorTo(function) + } + !implementation.hasJvmDefault() -> { + val defaultImpl = createDefaultImpl(function) + context.declarationFactory.getDefaultImplsFunction(implementation).also { + defaultImpl.bridgeToStatic(it) + } + } + // else -> Do nothing. } } @@ -106,7 +115,9 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran Visibilities.isPrivate(function.visibility) || (function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER && !function.hasJvmDefault()) || function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS -> { - removedFunctions[function.symbol] = createDefaultImpl(function).symbol + val defaultImpl = createDefaultImpl(function) + function.copyImplementationTo(defaultImpl) + removedFunctions[function.symbol] = defaultImpl.symbol } /** @@ -114,7 +125,8 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran * an abstract stub is left. */ !function.hasJvmDefault() -> { - createDefaultImpl(function) + val defaultImpl = createDefaultImpl(function) + function.copyImplementationTo(defaultImpl) function.body = null //TODO reset modality to abstract } @@ -124,7 +136,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran */ context.state.jvmDefaultMode.isCompatibility -> { val defaultImpl = createDefaultImpl(function) - function.body = createDelegatingCall(defaultImpl, function) + defaultImpl.bridgeViaAccessorTo(function) } // 6) ... otherwise we simply leave the default function implementation on the interface. @@ -163,40 +175,52 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran } private fun createDefaultImpl(function: IrSimpleFunction): IrSimpleFunction = - context.declarationFactory.getDefaultImplsFunction(function).also { newFunction -> + context.declarationFactory.getDefaultImplsFunction(function).also {newFunction -> newFunction.body = function.body?.patchDeclarationParents(newFunction) - copyBodyToStatic(function, newFunction) newFunction.parentAsClass.declarations.add(newFunction) } - private fun createDelegatingCall(defaultImpls: IrFunction, interfaceMethod: IrFunction): IrExpressionBody { - val startOffset = interfaceMethod.startOffset - val endOffset = interfaceMethod.endOffset + private fun IrSimpleFunction.copyImplementationTo(target: IrSimpleFunction) { + copyBodyToStatic(this, target) + } - return IrExpressionBodyImpl(IrCallImpl(startOffset, endOffset, interfaceMethod.returnType, defaultImpls.symbol).apply { - passTypeArgumentsFrom(interfaceMethod) - - var offset = 0 - interfaceMethod.dispatchReceiverParameter?.let { - putValueArgument(offset++, IrGetValueImpl(startOffset, endOffset, it.symbol)) - } - interfaceMethod.extensionReceiverParameter?.let { - putValueArgument(offset++, IrGetValueImpl(startOffset, endOffset, it.symbol)) - } - interfaceMethod.valueParameters.forEachIndexed { i, it -> - putValueArgument(i + offset, IrGetValueImpl(startOffset, endOffset, it.symbol)) + // Bridge from static to static method - simply fill the arguments to the parameters. + // By nature of the generation of both source and target of bridge, they line up. + private fun IrFunction.bridgeToStatic(callTarget: IrFunction) { + body = IrExpressionBodyImpl(IrCallImpl(startOffset, endOffset, returnType, callTarget.symbol).also { call -> + call.passTypeArgumentsFrom(this) + valueParameters.forEachIndexed { i, it -> + call.putValueArgument(i, IrGetValueImpl(startOffset, endOffset, it.symbol)) } }) } - private fun delegateInheritedDefaultImplementationToDefaultImpls(fakeOverride: IrSimpleFunction, implementation: IrSimpleFunction) { - val defaultImplFun = context.declarationFactory.getDefaultImplsFunction(implementation) - val irFunction = context.declarationFactory.getDefaultImplsFunction(fakeOverride) + // Bridge from static DefaultImpl method to the interface method. Arguments need to + // be shifted in presence of dispatch and extension receiver. + private fun IrFunction.bridgeViaAccessorTo(callTarget: IrFunction) { + body = IrExpressionBodyImpl( + IrCallImpl( + startOffset, + endOffset, + returnType, + callTarget.symbol, + superQualifierSymbol = callTarget.parentAsClass.symbol + ).also { call -> + call.passTypeArgumentsFrom(this) - irFunction.parentAsClass.declarations.add(irFunction) - context.createIrBuilder(irFunction.symbol, UNDEFINED_OFFSET, UNDEFINED_OFFSET).apply { - irFunction.body = createDelegatingCall(defaultImplFun, irFunction) - } + var offset = 0 + callTarget.dispatchReceiverParameter?.let { + call.dispatchReceiver = IrGetValueImpl(startOffset, endOffset, valueParameters[offset].symbol) + offset += 1 + } + callTarget.extensionReceiverParameter?.let { + call.extensionReceiver = IrGetValueImpl(startOffset, endOffset, valueParameters[offset].symbol) + offset += 1 + } + for (i in offset until valueParameters.size) { + call.putValueArgument(i - 1, IrGetValueImpl(startOffset, endOffset, valueParameters[i].symbol)) + } + }) } override fun visitReturn(expression: IrReturn): IrExpression { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt index b8b0896cc13..d55f4c7f13d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom import org.jetbrains.kotlin.backend.common.ir.remapTypeParameters import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator import org.jetbrains.kotlin.backend.jvm.ir.isLambda @@ -187,48 +188,52 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle private fun IrSimpleFunction.makeSimpleFunctionAccessor(expression: IrCall): IrSimpleFunction { val source = this + + // Find the right container to insert the accessor. Simply put, when we call a function on a class A, + // we also need to put its accessor into A. However, due to the way that calls are implemented in the + // IR we generally need to look at the type of the dispatchReceiver *argument* in order to find the + // correct class. Consider the following code: + // + // fun run(f : () -> Int): Int = f() + // + // open class A { + // private fun f() = 0 + // fun g() = run { this.f() } + // } + // + // class B : A { + // override fun g() = 1 + // fun h() = run { super.g() } + // } + // + // We have calls to the private methods A.f from a generated Lambda subclass for the argument to `run` + // in class A and a super call to A.g from a generated Lambda subclass in class B. + // + // In the first case, we need to produce an accessor in class A to access the private member of A. + // Both the parent of the function f and the type of the dispatch receiver point to the correct class. + // In the second case we need to call A.g from within class B, since this is the only way to invoke + // a method of a superclass on the JVM. However, the IR for the call to super.g points directly to the + // function g in class A. Confusingly, the `superQualifier` on this call also points to class A. + // The only way to compute the actual enclosing class for the call is by looking at the type of the + // dispatch receiver argument, which points to B. + // + // Beyond this, there can be accessors that are needed because other lowerings produce code calling + // private methods (e.g., local functions for lambdas are private and called from generated + // SAM wrapper classes). In this case we rely on the parent field of the called function. + // + // Finally, we need to produce accessors for calls to protected static methods coming from Java, + // which we put in the closest enclosing class which has access to the method in question. + val dispatchReceiverType = expression.dispatchReceiver?.type + val parent = source.accessorParent(dispatchReceiverType?.classOrNull?.owner ?: source.parent) + return buildFun { origin = JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR name = source.accessorName() visibility = Visibilities.PUBLIC + modality = if (parent is IrClass && parent.isJvmInterface) Modality.OPEN else Modality.FINAL isSuspend = source.isSuspend // synthetic accessors of suspend functions are handled in codegen }.also { accessor -> - // Find the right container to insert the accessor. Simply put, when we call a function on a class A, - // we also need to put its accessor into A. However, due to the way that calls are implemented in the - // IR we generally need to look at the type of the dispatchReceiver *argument* in order to find the - // correct class. Consider the following code: - // - // fun run(f : () -> Int): Int = f() - // - // open class A { - // private fun f() = 0 - // fun g() = run { this.f() } - // } - // - // class B : A { - // override fun g() = 1 - // fun h() = run { super.g() } - // } - // - // We have calls to the private methods A.f from a generated Lambda subclass for the argument to `run` - // in class A and a super call to A.g from a generated Lambda subclass in class B. - // - // In the first case, we need to produce an accessor in class A to access the private member of A. - // Both the parent of the function f and the type of the dispatch receiver point to the correct class. - // In the second case we need to call A.g from within class B, since this is the only way to invoke - // a method of a superclass on the JVM. However, the IR for the call to super.g points directly to the - // function g in class A. Confusingly, the `superQualifier` on this call also points to class A. - // The only way to compute the actual enclosing class for the call is by looking at the type of the - // dispatch receiver argument, which points to B. - // - // Beyond this, there can be accessors that are needed because other lowerings produce code calling - // private methods (e.g., local functions for lambdas are private and called from generated - // SAM wrapper classes). In this case we rely on the parent field of the called function. - // - // Finally, we need to produce accessors for calls to protected static methods coming from Java, - // which we put in the closest enclosing class which has access to the method in question. - val dispatchReceiverType = expression.dispatchReceiver?.type - accessor.parent = source.accessorParent(dispatchReceiverType?.classOrNull?.owner ?: source.parent) + accessor.parent = parent pendingTransformations.add { (accessor.parent as IrDeclarationContainer).declarations.add(accessor) } accessor.copyTypeParametersFrom(source, JvmLoweredDeclarationOrigin.SYNTHETIC_ACCESSOR) diff --git a/compiler/testData/codegen/box/jvm8/defaults/compatibility/interfaceExtension.kt b/compiler/testData/codegen/box/jvm8/defaults/compatibility/interfaceExtension.kt new file mode 100644 index 00000000000..99206085bd7 --- /dev/null +++ b/compiler/testData/codegen/box/jvm8/defaults/compatibility/interfaceExtension.kt @@ -0,0 +1,11 @@ +// !JVM_DEFAULT_MODE: compatibility +// TARGET_BACKEND: JVM +// JVM_TARGET: 1.8 +// WITH_RUNTIME +interface A { + @JvmDefault + fun String.foo() = "OK" +} + +fun box(): String = + object : A { fun box() = "FAIL".foo() }.box() diff --git a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/defaultArgs.kt b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/defaultArgs.kt index f64de648f40..e135cac740b 100644 --- a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/defaultArgs.kt +++ b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/defaultArgs.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: compatibility -// IGNORE_BACKEND: JVM_IR // JVM_TARGET: 1.8 // FULL_JDK @@ -10,7 +9,7 @@ interface KInterface { } } -// 1 INVOKESTATIC KInterface.access\$test\$jd +// 1 INVOKESTATIC KInterface.access\$test\$ // 1 INVOKESTATIC KInterface.test\$default // from $default diff --git a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleDiamond.kt b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleDiamond.kt new file mode 100644 index 00000000000..e95fd1936d1 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleDiamond.kt @@ -0,0 +1,22 @@ +// !JVM_DEFAULT_MODE: compatibility +// JVM_TARGET: 1.8 + +interface A { + @JvmDefault + fun foo() = "FAIL" +} + +interface Left : A { } +interface Right : A { + @JvmDefault + override fun foo() = "OK" +} + +interface C : Left, Right {} + +fun box(): String { + val x = object : C {} + return x.foo() +} + +// 0 INVOKESTATIC .*\$DefaultImpls\.foo diff --git a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunction.kt b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunction.kt index 0051b12e7d2..523733c4279 100644 --- a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunction.kt +++ b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunction.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: compatibility -// IGNORE_BACKEND: JVM_IR // JVM_TARGET: 1.8 interface KInterface { @@ -13,8 +12,8 @@ interface KInterface2 : KInterface { } -// 1 INVOKESTATIC KInterface2.access\$test2\$jd -// 1 INVOKESTATIC KInterface.access\$test2\$jd +// 1 INVOKESTATIC KInterface2.access\$test2\$ +// 1 INVOKESTATIC KInterface.access\$test2\$ // 1 INVOKESPECIAL KInterface2.test2 // 1 INVOKESPECIAL KInterface.test2 diff --git a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunctionWithAbstractOverride.kt b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunctionWithAbstractOverride.kt index 904586556ad..32fe14cee28 100644 --- a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunctionWithAbstractOverride.kt +++ b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunctionWithAbstractOverride.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: compatibility -// IGNORE_BACKEND: JVM_IR // JVM_TARGET: 1.8 interface KInterface { @@ -14,11 +13,11 @@ interface KInterface2 : KInterface { abstract override fun test2(): String } -// 1 INVOKESTATIC KInterface.access\$test2\$jd -// + -// 0 INVOKESTATIC KInterface2.access\$test2\$jd -// = -// 1 INVOKESTATIC - // 1 INVOKESPECIAL KInterface.test2 // 0 INVOKESPECIAL KInterface2.test2 + +// 1 INVOKESTATIC KInterface.access\$test2\$ +// + +// 0 INVOKESTATIC KInterface2.access\$test2\$ +// = +// 1 INVOKESTATIC KInterface \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleProperty.kt b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleProperty.kt index b7e0f1c6654..673e8c8e188 100644 --- a/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleProperty.kt +++ b/compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleProperty.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: compatibility -// IGNORE_BACKEND: JVM_IR // JVM_TARGET: 1.8 interface KInterface { @@ -14,10 +13,10 @@ interface KInterface2 : KInterface { } -// 1 INVOKESTATIC KInterface2.access\$getBar\$jd -// 1 INVOKESTATIC KInterface2.access\$setBar\$jd -// 1 INVOKESTATIC KInterface.access\$getBar\$jd -// 1 INVOKESTATIC KInterface.access\$setBar\$jd +// 1 INVOKESTATIC KInterface2.access\$getBar\$ +// 1 INVOKESTATIC KInterface2.access\$setBar\$ +// 1 INVOKESTATIC KInterface.access\$getBar\$ +// 1 INVOKESTATIC KInterface.access\$setBar\$ // 1 INVOKESPECIAL KInterface2.getBar // 1 INVOKESPECIAL KInterface2.setBar diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 897b9ac6d2d..2b71472fe73 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -14863,6 +14863,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/inheritedJvmDefault.kt"); } + @TestMetadata("interfaceExtension.kt") + public void testInterfaceExtension() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/interfaceExtension.kt"); + } + @TestMetadata("propertyAnnotation.kt") public void testPropertyAnnotation() throws Exception { runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/propertyAnnotation.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index b5c2d930766..8da7dba167f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -3002,6 +3002,11 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/defaultArgs.kt"); } + @TestMetadata("simpleDiamond.kt") + public void testSimpleDiamond() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleDiamond.kt"); + } + @TestMetadata("simpleFunction.kt") public void testSimpleFunction() throws Exception { runTest("compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunction.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index bfdd62c684a..4f83826e2e8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -14863,6 +14863,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/inheritedJvmDefault.kt"); } + @TestMetadata("interfaceExtension.kt") + public void testInterfaceExtension() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/interfaceExtension.kt"); + } + @TestMetadata("propertyAnnotation.kt") public void testPropertyAnnotation() throws Exception { runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/propertyAnnotation.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 0423834c7f6..7de4d0f4831 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -13713,6 +13713,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/inheritedJvmDefault.kt"); } + @TestMetadata("interfaceExtension.kt") + public void testInterfaceExtension() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/interfaceExtension.kt"); + } + @TestMetadata("propertyAnnotation.kt") public void testPropertyAnnotation() throws Exception { runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/propertyAnnotation.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index bfbe6523be4..31ae43743ce 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -13713,6 +13713,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/inheritedJvmDefault.kt"); } + @TestMetadata("interfaceExtension.kt") + public void testInterfaceExtension() throws Exception { + runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/interfaceExtension.kt"); + } + @TestMetadata("propertyAnnotation.kt") public void testPropertyAnnotation() throws Exception { runTest("compiler/testData/codegen/box/jvm8/defaults/compatibility/propertyAnnotation.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java index 46ca9370a50..a593dd570d6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeTextTestGenerated.java @@ -3047,6 +3047,11 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/defaultArgs.kt"); } + @TestMetadata("simpleDiamond.kt") + public void testSimpleDiamond() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleDiamond.kt"); + } + @TestMetadata("simpleFunction.kt") public void testSimpleFunction() throws Exception { runTest("compiler/testData/codegen/bytecodeText/jvm8/jvmDefault/compatibility/simpleFunction.kt");