[JS IR BE] Support coroutines

* Move FinallyBlockLowering to common part
* Fix catching of dynamic exception
* Fix bridges for suspend functions
* Disable explicit cast to Unit
* Run lowering per module
* Update some test data
This commit is contained in:
Roman Artemev
2018-06-18 20:01:39 +03:00
committed by romanart
parent 37fadb8ee5
commit c62e4b4fcf
127 changed files with 3539 additions and 256 deletions
@@ -183,8 +183,12 @@ fun IrBuilderWithScope.irGet(type: IrType, receiver: IrExpression, getterSymbol:
origin = IrStatementOrigin.GET_PROPERTY
)
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, type: IrType): IrCall =
IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor)
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, type: IrType, typeArguments: List<IrType> = emptyList()): IrCall =
IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor).apply {
typeArguments.forEachIndexed { index, irType ->
this.putTypeArgument(index, irType)
}
}
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol): IrCall =
IrCallImpl(startOffset, endOffset, callee.owner.returnType, callee, callee.descriptor)
@@ -237,3 +241,14 @@ fun IrBuilderWithScope.irString(value: String) =
fun IrBuilderWithScope.irConcat() =
IrStringConcatenationImpl(startOffset, endOffset, context.irBuiltIns.stringType)
fun IrBuilderWithScope.irSetField(receiver: IrExpression, irField: IrField, value: IrExpression): IrExpression =
IrSetFieldImpl(
startOffset,
endOffset,
irField.symbol,
receiver = receiver,
value = value,
type = context.irBuiltIns.unitType
)
@@ -19,12 +19,13 @@ package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.expressions.IrBlock
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
import org.jetbrains.kotlin.ir.expressions.IrContainerExpression
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.*
@@ -84,12 +85,13 @@ class IrBlockBuilder(
startOffset: Int,
endOffset: Int,
val origin: IrStatementOrigin? = null,
var resultType: IrType? = null
) : IrStatementsBuilder<IrBlock>(context, scope, startOffset, endOffset) {
var resultType: IrType? = null,
val isTransparent:Boolean = false
) : IrStatementsBuilder<IrContainerExpression>(context, scope, startOffset, endOffset) {
private val statements = ArrayList<IrStatement>()
inline fun block(body: IrBlockBuilder.() -> Unit): IrBlock {
inline fun block(body: IrBlockBuilder.() -> Unit): IrContainerExpression {
body()
return doBuild()
}
@@ -98,11 +100,11 @@ class IrBlockBuilder(
statements.add(irStatement)
}
override fun doBuild(): IrBlock {
override fun doBuild(): IrContainerExpression {
val resultType = this.resultType
?: statements.lastOrNull().safeAs<IrExpression>()?.type
?: context.irBuiltIns.unitType
val irBlock = IrBlockImpl(startOffset, endOffset, resultType, origin)
val irBlock = if (isTransparent) IrCompositeImpl(startOffset, endOffset, resultType, origin) else IrBlockImpl(startOffset, endOffset, resultType, origin)
irBlock.statements.addAll(statements)
return irBlock
}
@@ -154,6 +156,20 @@ inline fun IrGeneratorWithScope.irBlock(
origin, resultType
).block(body)
inline fun IrGeneratorWithScope.irComposite(
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET,
origin: IrStatementOrigin? = null,
resultType: IrType? = null,
body: IrBlockBuilder.() -> Unit
): IrExpression =
IrBlockBuilder(
context, scope,
startOffset,
endOffset,
origin, resultType, true
).block(body)
inline fun IrGeneratorWithScope.irBlockBody(
startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET,
body: IrBlockBodyBuilder.() -> Unit
@@ -8,6 +8,9 @@ package org.jetbrains.kotlin.ir.types
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
@@ -75,6 +78,17 @@ fun IrType.toKotlinType(): KotlinType {
}
}
fun IrType.getClass(): IrClass? =
(this.classifierOrNull as? IrClassSymbol)?.owner
fun IrClassSymbol.createType(hasQuestionMark: Boolean, arguments: List<IrTypeArgument>): IrSimpleType =
IrSimpleTypeImpl(
this,
hasQuestionMark,
arguments,
emptyList()
)
private fun makeKotlinType(
classifier: IrClassifierSymbol,
arguments: List<IrTypeArgument>,
@@ -95,6 +109,20 @@ fun ClassifierDescriptor.toIrType(hasQuestionMark: Boolean = false): IrType {
return IrSimpleTypeImpl(defaultType, symbol, hasQuestionMark, listOf(), listOf())
}
val IrTypeParameter.defaultType: IrType get() = symbol.owner.defaultType
fun IrClassifierSymbol.typeWith(vararg arguments: IrType): IrSimpleType = typeWith(arguments.toList())
fun IrClassifierSymbol.typeWith(arguments: List<IrType>): IrSimpleType =
IrSimpleTypeImpl(
this,
false,
arguments.map { makeTypeProjection(it, Variance.INVARIANT) },
emptyList()
)
fun IrClass.typeWith(arguments: List<IrType>) = this.symbol.typeWith(arguments)
fun KotlinType.toIrType(): IrType? {
if (isDynamic()) return IrDynamicTypeImpl(this, listOf(), Variance.INVARIANT)
@@ -113,6 +141,7 @@ fun KotlinType.toIrType(): IrType? {
return IrSimpleTypeImpl(this, symbol, isMarkedNullable, arguments, annotations)
}
// TODO: this function creates unbound symbol which is the great source of problems
private fun ClassifierDescriptor.getSymbol(): IrClassifierSymbol = when (this) {
is ClassDescriptor -> IrClassSymbolImpl(this)
is TypeParameterDescriptor -> IrTypeParameterSymbolImpl(this)
@@ -6,20 +6,30 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.toIrType
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.kotlin.types.KotlinType
/**
* Binds the arguments explicitly represented in the IR to the parameters of the accessed function.
@@ -168,6 +178,21 @@ fun IrFunction.createParameterDeclarations() {
}
}
fun IrClass.createParameterDeclarations() {
thisReceiver = IrValueParameterImpl(
startOffset, endOffset,
IrDeclarationOrigin.INSTANCE_RECEIVER,
descriptor.thisAsReceiverParameter,
this.symbol.typeWith(this.typeParameters.map { it.defaultType }),
null
).also { valueParameter ->
valueParameter.parent = this
}
assert(typeParameters.isEmpty())
assert(descriptor.declaredTypeParameters.isEmpty())
}
//fun IrClass.createParameterDeclarations() {
// descriptor.thisAsReceiverParameter.let {
// thisReceiver = IrValueParameterImpl(
@@ -311,6 +336,40 @@ fun IrValueParameter.copy(newDescriptor: ParameterDescriptor): IrValueParameter
)
}
fun createField(
startOffset: Int,
endOffset: Int,
type: IrType,
name: Name,
isMutable: Boolean,
origin: IrDeclarationOrigin,
owner: ClassDescriptor
): IrField {
val descriptor = PropertyDescriptorImpl.create(
/* containingDeclaration = */ owner,
/* annotations = */ Annotations.EMPTY,
/* modality = */ Modality.FINAL,
/* visibility = */ Visibilities.PRIVATE,
/* isVar = */ isMutable,
/* name = */ name,
/* kind = */ CallableMemberDescriptor.Kind.DECLARATION,
/* source = */ SourceElement.NO_SOURCE,
/* lateInit = */ false,
/* isConst = */ false,
/* isExpect = */ false,
/* isActual = */ false,
/* isExternal = */ false,
/* isDelegated = */ false
).apply {
initialize(null, null)
val receiverType: KotlinType? = null
setType(type.toKotlinType(), emptyList(), owner.thisAsReceiverParameter, receiverType)
}
return IrFieldImpl(startOffset, endOffset, origin, descriptor, type)
}
fun IrFunction.createDispatchReceiverParameter() {
assert(this.dispatchReceiverParameter == null)