Skip to content

Commit

Permalink
Support interfaces in IR
Browse files Browse the repository at this point in the history
  • Loading branch information
Him188 committed Aug 11, 2020
1 parent 64671af commit 5b7cf4b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.*
Expand All @@ -25,6 +26,7 @@ import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import java.util.*
import org.jetbrains.kotlin.ir.util.isInterface as isInterfaceKotlin


internal object IntrinsicRuntimeFunctions {
Expand All @@ -41,6 +43,12 @@ private fun IrPluginContext.referenceFunctionRunBlocking(): IrSimpleFunctionSymb
?: error("Internal error: Function ${IntrinsicRuntimeFunctions.RUN_SUSPEND} not found.")
}

private fun IrPluginContext.referenceJvmDefault(): IrClassSymbol {
val s = FqName("kotlin.jvm").child(Name.identifier("JvmDefault"))
return referenceClass(s)
?: error("Internal error: Function ${s} not found.")
}

@Suppress("ClassName")
private object Origin_JVM_BLOCKING_BRIDGE : IrDeclarationOriginImpl("JVM_BLOCKING_BRIDGE", isSynthetic = true)

Expand All @@ -51,8 +59,14 @@ internal fun IrFunction.isExplicitOrImplicitStatic(): Boolean {
internal fun IrPluginContext.createGeneratedBlockingBridgeConstructorCall(
symbol: IrSymbol,
): IrConstructorCall {
return createIrBuilder(symbol).run {
irCall(referenceClass(GENERATED_BLOCKING_BRIDGE_FQ_NAME)!!.constructors.first())
return createIrBuilder(symbol).irAnnotationConstructor(referenceClass(GENERATED_BLOCKING_BRIDGE_FQ_NAME)!!)
}

internal fun IrBuilderWithScope.irAnnotationConstructor(
clazz: IrClassSymbol,
): IrConstructorCall {
return run {
irCall(clazz.constructors.first())
}.run {
irConstructorCall(this, this.symbol)
}
Expand Down Expand Up @@ -83,6 +97,9 @@ internal fun IrType.isClassType(fqName: FqNameUnsafe, hasQuestionMark: Boolean?
return classifier.isClassWithFqName(fqName)
}

internal val IrDeclarationContainer.isInterface: Boolean
get() = (this as? IrClass)?.isInterfaceKotlin == true

fun IrPluginContext.generateJvmBlockingBridges(originFunction: IrFunction): List<IrDeclaration> {
val containingFileOrClass = originFunction.parentFileOrClass

Expand All @@ -94,7 +111,7 @@ fun IrPluginContext.generateJvmBlockingBridges(originFunction: IrFunction): List
origin = ORIGIN_JVM_BLOCKING_BRIDGE ?: originFunction.origin

name = originFunction.bridgeFunctionName
modality = if ((containingFileOrClass as? IrClass)?.isInterface == true) Modality.OPEN else Modality.FINAL
modality = if (containingFileOrClass.isInterface) Modality.OPEN else Modality.FINAL
returnType = originFunction.returnType

isSuspend = false
Expand All @@ -108,6 +125,10 @@ fun IrPluginContext.generateJvmBlockingBridges(originFunction: IrFunction): List
.filterNot { it.type.isClassType(JVM_BLOCKING_BRIDGE_FQ_NAME.toUnsafe()) }
.plus(createGeneratedBlockingBridgeConstructorCall(symbol))

if (containingFileOrClass.isInterface) {
this.annotations += createIrBuilder(symbol).irAnnotationConstructor(referenceJvmDefault())
}

this.parent = containingFileOrClass

this.extensionReceiverParameter = originFunction.extensionReceiverParameter?.copyTo(this@fn)
Expand Down
9 changes: 7 additions & 2 deletions compiler-plugin/src/test/kotlin/compiler/inheritance.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import testJvmCompile
import kotlin.test.assertFailsWith

internal class TestInheritanceJvmBackend : TestInheritanceCommon(ir = false)
internal class TestInheritanceIrBackend : TestInheritanceCommon(ir = true)
internal class TestInheritanceIrBackend : TestInheritanceCommon(ir = true) {
@Test
override fun `bridge for interface inheritance`() {
super.`bridge for interface inheritance`()
}
}

internal abstract class TestInheritanceCommon(
private val ir: Boolean,
Expand Down Expand Up @@ -69,7 +74,7 @@ internal abstract class TestInheritanceCommon(
}

@Test
fun `bridge for interface inheritance`() = testJvmCompile(
open fun `bridge for interface inheritance`() = testJvmCompile(
"""
interface Interface2 {
@JvmBlockingBridge
Expand Down

0 comments on commit 5b7cf4b

Please sign in to comment.