[IR BE] Use pure IrType instead of KotlinType
* clean up code
This commit is contained in:
+33
-38
@@ -16,11 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
@@ -28,12 +28,11 @@ import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
typealias ReportError = (element: IrElement, message: String) -> Unit
|
||||
|
||||
class CheckIrElementVisitor(
|
||||
val builtIns: KotlinBuiltIns,
|
||||
val irBuiltIns: IrBuiltIns,
|
||||
val reportError: ReportError,
|
||||
val config: IrValidatorConfig
|
||||
) : IrElementVisitorVoid {
|
||||
@@ -50,13 +49,13 @@ class CheckIrElementVisitor(
|
||||
// Nothing to do.
|
||||
}
|
||||
|
||||
private fun IrExpression.ensureTypeIs(expectedType: KotlinType) {
|
||||
private fun IrExpression.ensureTypeIs(expectedType: IrType) {
|
||||
if (!config.checkTypes)
|
||||
return
|
||||
|
||||
// TODO: compare IR types instead.
|
||||
if (expectedType != type.toKotlinType()) {
|
||||
reportError(this, "unexpected expression.type: expected $expectedType, got ${type.toKotlinType()}")
|
||||
if (expectedType.isEqualTo(type)) {
|
||||
reportError(this, "unexpected expression.type: expected $expectedType, got ${type.render()}")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,16 +69,16 @@ class CheckIrElementVisitor(
|
||||
super.visitConst(expression)
|
||||
|
||||
val naturalType = when (expression.kind) {
|
||||
IrConstKind.Null -> builtIns.nullableNothingType
|
||||
IrConstKind.Boolean -> builtIns.booleanType
|
||||
IrConstKind.Char -> builtIns.charType
|
||||
IrConstKind.Byte -> builtIns.byteType
|
||||
IrConstKind.Short -> builtIns.shortType
|
||||
IrConstKind.Int -> builtIns.intType
|
||||
IrConstKind.Long -> builtIns.longType
|
||||
IrConstKind.String -> builtIns.stringType
|
||||
IrConstKind.Float -> builtIns.floatType
|
||||
IrConstKind.Double -> builtIns.doubleType
|
||||
IrConstKind.Null -> irBuiltIns.nothingNType
|
||||
IrConstKind.Boolean -> irBuiltIns.booleanType
|
||||
IrConstKind.Char -> irBuiltIns.charType
|
||||
IrConstKind.Byte -> irBuiltIns.byteType
|
||||
IrConstKind.Short -> irBuiltIns.shortType
|
||||
IrConstKind.Int -> irBuiltIns.intType
|
||||
IrConstKind.Long -> irBuiltIns.longType
|
||||
IrConstKind.String -> irBuiltIns.stringType
|
||||
IrConstKind.Float -> irBuiltIns.floatType
|
||||
IrConstKind.Double -> irBuiltIns.doubleType
|
||||
}
|
||||
|
||||
expression.ensureTypeIs(naturalType)
|
||||
@@ -88,13 +87,13 @@ class CheckIrElementVisitor(
|
||||
override fun visitStringConcatenation(expression: IrStringConcatenation) {
|
||||
super.visitStringConcatenation(expression)
|
||||
|
||||
expression.ensureTypeIs(builtIns.stringType)
|
||||
expression.ensureTypeIs(irBuiltIns.stringType)
|
||||
}
|
||||
|
||||
override fun visitGetObjectValue(expression: IrGetObjectValue) {
|
||||
super.visitGetObjectValue(expression)
|
||||
|
||||
expression.ensureTypeIs(expression.descriptor.defaultType)
|
||||
expression.ensureTypeIs(expression.symbol.createType(false, emptyList()))
|
||||
}
|
||||
|
||||
// TODO: visitGetEnumValue
|
||||
@@ -102,25 +101,25 @@ class CheckIrElementVisitor(
|
||||
override fun visitGetValue(expression: IrGetValue) {
|
||||
super.visitGetValue(expression)
|
||||
|
||||
expression.ensureTypeIs(expression.descriptor.type)
|
||||
expression.ensureTypeIs(expression.symbol.owner.type)
|
||||
}
|
||||
|
||||
override fun visitSetVariable(expression: IrSetVariable) {
|
||||
super.visitSetVariable(expression)
|
||||
|
||||
expression.ensureTypeIs(builtIns.unitType)
|
||||
expression.ensureTypeIs(irBuiltIns.unitType)
|
||||
}
|
||||
|
||||
override fun visitGetField(expression: IrGetField) {
|
||||
super.visitGetField(expression)
|
||||
|
||||
expression.ensureTypeIs(expression.descriptor.type)
|
||||
expression.ensureTypeIs(expression.symbol.owner.type)
|
||||
}
|
||||
|
||||
override fun visitSetField(expression: IrSetField) {
|
||||
super.visitSetField(expression)
|
||||
|
||||
expression.ensureTypeIs(builtIns.unitType)
|
||||
expression.ensureTypeIs(irBuiltIns.unitType)
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall) {
|
||||
@@ -132,12 +131,8 @@ class CheckIrElementVisitor(
|
||||
reportError(expression, "Dispatch receivers with 'dynamic' type are not allowed")
|
||||
}
|
||||
|
||||
val returnType = expression.descriptor.returnType
|
||||
if (returnType == null) {
|
||||
reportError(expression, "${expression.descriptor} return type is null")
|
||||
} else {
|
||||
expression.ensureTypeIs(returnType)
|
||||
}
|
||||
val returnType = expression.symbol.owner.returnType
|
||||
expression.ensureTypeIs(returnType)
|
||||
|
||||
expression.superQualifierSymbol?.ensureBound(expression)
|
||||
}
|
||||
@@ -145,19 +140,19 @@ class CheckIrElementVisitor(
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall) {
|
||||
super.visitDelegatingConstructorCall(expression)
|
||||
|
||||
expression.ensureTypeIs(builtIns.unitType)
|
||||
expression.ensureTypeIs(irBuiltIns.unitType)
|
||||
}
|
||||
|
||||
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall) {
|
||||
super.visitEnumConstructorCall(expression)
|
||||
|
||||
expression.ensureTypeIs(builtIns.unitType)
|
||||
expression.ensureTypeIs(irBuiltIns.unitType)
|
||||
}
|
||||
|
||||
override fun visitInstanceInitializerCall(expression: IrInstanceInitializerCall) {
|
||||
super.visitInstanceInitializerCall(expression)
|
||||
|
||||
expression.ensureTypeIs(builtIns.unitType)
|
||||
expression.ensureTypeIs(irBuiltIns.unitType)
|
||||
expression.classSymbol.ensureBound(expression)
|
||||
}
|
||||
|
||||
@@ -173,11 +168,11 @@ class CheckIrElementVisitor(
|
||||
IrTypeOperator.IMPLICIT_NOTNULL,
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||
IrTypeOperator.IMPLICIT_INTEGER_COERCION,
|
||||
IrTypeOperator.SAM_CONVERSION -> typeOperand.toKotlinType()
|
||||
IrTypeOperator.SAM_CONVERSION -> typeOperand
|
||||
|
||||
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable().toKotlinType()
|
||||
IrTypeOperator.SAFE_CAST -> typeOperand.makeNullable()
|
||||
|
||||
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> builtIns.booleanType
|
||||
IrTypeOperator.INSTANCEOF, IrTypeOperator.NOT_INSTANCEOF -> irBuiltIns.booleanType
|
||||
}
|
||||
|
||||
if (operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT && !typeOperand.isUnit()) {
|
||||
@@ -192,26 +187,26 @@ class CheckIrElementVisitor(
|
||||
override fun visitLoop(loop: IrLoop) {
|
||||
super.visitLoop(loop)
|
||||
|
||||
loop.ensureTypeIs(builtIns.unitType)
|
||||
loop.ensureTypeIs(irBuiltIns.unitType)
|
||||
}
|
||||
|
||||
override fun visitBreakContinue(jump: IrBreakContinue) {
|
||||
super.visitBreakContinue(jump)
|
||||
|
||||
jump.ensureTypeIs(builtIns.nothingType)
|
||||
jump.ensureTypeIs(irBuiltIns.nothingType)
|
||||
}
|
||||
|
||||
override fun visitReturn(expression: IrReturn) {
|
||||
super.visitReturn(expression)
|
||||
|
||||
expression.ensureTypeIs(builtIns.nothingType)
|
||||
expression.ensureTypeIs(irBuiltIns.nothingType)
|
||||
expression.returnTargetSymbol.ensureBound(expression)
|
||||
}
|
||||
|
||||
override fun visitThrow(expression: IrThrow) {
|
||||
super.visitThrow(expression)
|
||||
|
||||
expression.ensureTypeIs(builtIns.nothingType)
|
||||
expression.ensureTypeIs(irBuiltIns.nothingType)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
|
||||
+9
-9
@@ -16,9 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.common
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTreeWithSymbols
|
||||
import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
|
||||
@@ -29,15 +31,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : IrElement> T.deepCopyWithVariables(): T {
|
||||
val descriptorsRemapper = object : DescriptorsRemapper {
|
||||
override fun remapDeclaredVariable(descriptor: VariableDescriptor) = LocalVariableDescriptor(
|
||||
/* containingDeclaration = */ descriptor.containingDeclaration,
|
||||
/* annotations = */ descriptor.annotations,
|
||||
/* name = */ descriptor.name,
|
||||
/* type = */ descriptor.type,
|
||||
/* mutable = */ descriptor.isVar,
|
||||
/* isDelegated = */ false,
|
||||
/* source = */ descriptor.source
|
||||
)
|
||||
override fun remapDeclaredVariable(descriptor: VariableDescriptor) = WrappedVariableDescriptor()
|
||||
}
|
||||
|
||||
val symbolsRemapper = DeepCopySymbolRemapper(descriptorsRemapper)
|
||||
@@ -50,6 +44,12 @@ fun <T : IrElement> T.deepCopyWithVariables(): T {
|
||||
override fun getNonTransformedLoop(irLoop: IrLoop): IrLoop {
|
||||
return irLoop
|
||||
}
|
||||
|
||||
override fun visitVariable(declaration: IrVariable): IrVariable {
|
||||
val variable = super.visitVariable(declaration)
|
||||
variable.descriptor.let { if (it is WrappedVariableDescriptor) it.bind(variable) }
|
||||
return variable
|
||||
}
|
||||
},
|
||||
null
|
||||
) as T
|
||||
|
||||
@@ -58,7 +58,7 @@ data class IrValidatorConfig(
|
||||
|
||||
class IrValidator(val context: CommonBackendContext, val config: IrValidatorConfig) : IrElementVisitorVoid {
|
||||
|
||||
val builtIns = context.builtIns
|
||||
val irBuiltIns = context.irBuiltIns
|
||||
var currentFile: IrFile? = null
|
||||
|
||||
override fun visitFile(declaration: IrFile) {
|
||||
@@ -79,7 +79,7 @@ class IrValidator(val context: CommonBackendContext, val config: IrValidatorConf
|
||||
}
|
||||
}
|
||||
|
||||
private val elementChecker = CheckIrElementVisitor(builtIns, this::error, config)
|
||||
private val elementChecker = CheckIrElementVisitor(irBuiltIns, this::error, config)
|
||||
|
||||
override fun visitElement(element: IrElement) {
|
||||
element.acceptVoid(elementChecker)
|
||||
|
||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.builders.IrStatementsBuilder
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
|
||||
@@ -61,34 +60,6 @@ fun ir2stringWhole(ir: IrElement?, withDescriptors: Boolean = false): String {
|
||||
return strWriter.toString()
|
||||
}
|
||||
|
||||
fun DeclarationDescriptor.createFakeOverrideDescriptor(owner: ClassDescriptor): DeclarationDescriptor? {
|
||||
// We need to copy descriptors for vtable building, thus take only functions and properties.
|
||||
return when (this) {
|
||||
is CallableMemberDescriptor ->
|
||||
copy(
|
||||
/* newOwner = */ owner,
|
||||
/* modality = */ modality,
|
||||
/* visibility = */ visibility,
|
||||
/* kind = */ CallableMemberDescriptor.Kind.FAKE_OVERRIDE,
|
||||
/* copyOverrides = */ true
|
||||
).apply {
|
||||
overriddenDescriptors += this@createFakeOverrideDescriptor
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun FunctionDescriptor.createOverriddenDescriptor(owner: ClassDescriptor, final: Boolean = true): FunctionDescriptor {
|
||||
return this.newCopyBuilder()
|
||||
.setOwner(owner)
|
||||
.setCopyOverrides(true)
|
||||
.setModality(if (final) Modality.FINAL else Modality.OPEN)
|
||||
.setDispatchReceiverParameter(owner.thisAsReceiverParameter)
|
||||
.build()!!.apply {
|
||||
overriddenDescriptors += this@createOverriddenDescriptor
|
||||
}
|
||||
}
|
||||
|
||||
fun IrClass.addSimpleDelegatingConstructor(
|
||||
superConstructor: IrConstructor,
|
||||
irBuiltIns: IrBuiltIns,
|
||||
@@ -311,11 +282,6 @@ fun IrDeclarationContainer.addChild(declaration: IrDeclaration) {
|
||||
declaration.accept(SetDeclarationsParentVisitor, this)
|
||||
}
|
||||
|
||||
fun <T: IrElement> T.setDeclarationsParent(parent: IrDeclarationParent): T {
|
||||
accept(SetDeclarationsParentVisitor, parent)
|
||||
return this
|
||||
}
|
||||
|
||||
object SetDeclarationsParentVisitor : IrElementVisitor<Unit, IrDeclarationParent> {
|
||||
override fun visitElement(element: IrElement, data: IrDeclarationParent) {
|
||||
if (element !is IrDeclarationParent) {
|
||||
@@ -336,14 +302,6 @@ val IrFunction.isStatic: Boolean
|
||||
val IrDeclaration.isTopLevel: Boolean
|
||||
get() = parent is IrPackageFragment
|
||||
|
||||
fun <T : IrElement> IrStatementsBuilder<T>.irTemporaryWithWrappedDescriptor(
|
||||
value: IrExpression,
|
||||
nameHint: String? = null): IrVariable {
|
||||
val temporary = scope.createTemporaryVariableWithWrappedDescriptor(value, nameHint)
|
||||
+temporary
|
||||
return temporary
|
||||
}
|
||||
|
||||
|
||||
fun Scope.createTemporaryVariableWithWrappedDescriptor(
|
||||
irExpression: IrExpression,
|
||||
@@ -357,8 +315,6 @@ fun Scope.createTemporaryVariableWithWrappedDescriptor(
|
||||
).apply { descriptor.bind(this) }
|
||||
}
|
||||
|
||||
val IrFunction.isOverridable: Boolean get() = this is IrSimpleFunction && this.isOverridable
|
||||
|
||||
fun IrClass.createImplicitParameterDeclarationWithWrappedDescriptor() {
|
||||
val thisReceiverDescriptor = WrappedReceiverParameterDescriptor()
|
||||
thisReceiver = IrValueParameterImpl(
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ open class DefaultArgumentStubGenerator(
|
||||
irGet(parameter)
|
||||
}
|
||||
|
||||
val temporaryVariable = irTemporary(argument, nameHint = parameter.name.asString())
|
||||
val temporaryVariable = createTmpVariable(argument, nameHint = parameter.name.asString())
|
||||
temporaryVariable.parent = newIrFunction
|
||||
|
||||
params.add(temporaryVariable)
|
||||
|
||||
+25
-48
@@ -6,28 +6,23 @@
|
||||
package org.jetbrains.kotlin.backend.common.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrTemporaryVariableDescriptorImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnTargetSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrReturnableBlockSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrSimpleType
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
|
||||
class FinallyBlocksLowering(val context: CommonBackendContext, private val throwableType: IrType): FileLoweringPass, IrElementTransformerVoidWithContext() {
|
||||
|
||||
@@ -65,7 +60,7 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
|
||||
private abstract class Scope
|
||||
|
||||
private class ReturnableScope(val descriptor: CallableDescriptor): Scope()
|
||||
private class ReturnableScope(val symbol: IrReturnTargetSymbol) : Scope()
|
||||
|
||||
private class LoopScope(val loop: IrLoop): Scope()
|
||||
|
||||
@@ -92,7 +87,7 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
}
|
||||
|
||||
override fun visitFunctionNew(declaration: IrFunction): IrStatement {
|
||||
using(ReturnableScope(declaration.descriptor)) {
|
||||
using(ReturnableScope(declaration.symbol)) {
|
||||
return super.visitFunctionNew(declaration)
|
||||
}
|
||||
}
|
||||
@@ -101,7 +96,7 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
if (expression !is IrReturnableBlockImpl)
|
||||
return super.visitContainerExpression(expression)
|
||||
|
||||
using(ReturnableScope(expression.descriptor)) {
|
||||
using(ReturnableScope(expression.symbol)) {
|
||||
return super.visitContainerExpression(expression)
|
||||
}
|
||||
}
|
||||
@@ -121,7 +116,7 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
jump = Break(jump.loop),
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
value = irBuilder.irGetObject(context.ir.symbols.unit)
|
||||
value = irBuilder.irGetObject(context.irBuiltIns.unitClass)
|
||||
) ?: jump
|
||||
}
|
||||
|
||||
@@ -134,7 +129,7 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
jump = Continue(jump.loop),
|
||||
startOffset = startOffset,
|
||||
endOffset = endOffset,
|
||||
value = irBuilder.irGetObject(context.ir.symbols.unit)
|
||||
value = irBuilder.irGetObject(context.irBuiltIns.unitClass)
|
||||
) ?: jump
|
||||
}
|
||||
|
||||
@@ -142,7 +137,7 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
return performHighLevelJump(
|
||||
targetScopePredicate = { it is ReturnableScope && it.descriptor == expression.returnTarget },
|
||||
targetScopePredicate = { it is ReturnableScope && it.symbol == expression.returnTargetSymbol },
|
||||
jump = Return(expression.returnTargetSymbol),
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
@@ -186,7 +181,8 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
val currentTryScope = tryScopes[index]
|
||||
currentTryScope.jumps.getOrPut(jump) {
|
||||
val type = (jump as? Return)?.target?.owner?.returnType ?: value.type
|
||||
val symbol = getIrReturnableBlockSymbol(jump.toString(), type)
|
||||
jump.toString()
|
||||
val symbol = IrReturnableBlockSymbolImpl(WrappedSimpleFunctionDescriptor())
|
||||
with(currentTryScope) {
|
||||
irBuilder.run {
|
||||
val inlinedFinally = irInlineFinally(symbol, type, expression, finallyExpression)
|
||||
@@ -226,15 +222,13 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
type = context.irBuiltIns.unitType
|
||||
)
|
||||
val transformedFinallyExpression = finallyExpression.transform(transformer, null)
|
||||
val parameter = IrTemporaryVariableDescriptorImpl(
|
||||
containingDeclaration = currentScope!!.scope.scopeOwner,
|
||||
name = Name.identifier("t"),
|
||||
outType = throwableType.toKotlinType()
|
||||
)
|
||||
val parameter = WrappedVariableDescriptor()
|
||||
val catchParameter = IrVariableImpl(
|
||||
startOffset, endOffset, IrDeclarationOrigin.CATCH_PARAMETER, parameter,
|
||||
throwableType
|
||||
)
|
||||
startOffset, endOffset, IrDeclarationOrigin.CATCH_PARAMETER, IrVariableSymbolImpl(parameter),
|
||||
Name.identifier("t"), throwableType, isVar = false, isConst = false, isLateinit = false
|
||||
).also { parameter.bind(it) }
|
||||
|
||||
catchParameter.parent = scope.getLocalDeclarationParent()
|
||||
|
||||
val syntheticTry = IrTryImpl(
|
||||
startOffset = startOffset,
|
||||
@@ -252,7 +246,7 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
)
|
||||
using(TryScope(syntheticTry, transformedFinallyExpression, this)) {
|
||||
val fallThroughType = aTry.type
|
||||
val fallThroughSymbol = getIrReturnableBlockSymbol("fallThrough", fallThroughType)
|
||||
val fallThroughSymbol = IrReturnableBlockSymbolImpl(WrappedSimpleFunctionDescriptor())
|
||||
val transformedResult = aTry.tryResult.transform(transformer, null)
|
||||
transformedTry.tryResult = irReturn(fallThroughSymbol, transformedResult)
|
||||
for (aCatch in aTry.catches) {
|
||||
@@ -269,16 +263,16 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
value: IrExpression,
|
||||
finallyExpression: IrExpression
|
||||
): IrExpression {
|
||||
val returnType = symbol.descriptor.returnType!!
|
||||
return when {
|
||||
returnType.isUnit() || returnType.isNothing() -> irBlock(value, null, type) {
|
||||
val returnTypeClassifier = (type as? IrSimpleType)?.classifier
|
||||
return when (returnTypeClassifier) {
|
||||
context.irBuiltIns.unitClass, context.irBuiltIns.nothingClass -> irBlock(value, null, type) {
|
||||
+irReturnableBlock(symbol, type) {
|
||||
+value
|
||||
}
|
||||
+finallyExpression.copy()
|
||||
}
|
||||
else -> irComposite(value, null, type) {
|
||||
val tmp = irTemporary(irReturnableBlock(symbol, type) {
|
||||
else -> irBlock(value, null, type) {
|
||||
val tmp = createTmpVariable(irReturnableBlock(symbol, type) {
|
||||
+irReturn(symbol, value)
|
||||
})
|
||||
+finallyExpression.copy()
|
||||
@@ -287,29 +281,12 @@ class FinallyBlocksLowering(val context: CommonBackendContext, private val throw
|
||||
}
|
||||
}
|
||||
|
||||
private fun getFakeFunctionDescriptor(name: String, returnType: KotlinType) =
|
||||
SimpleFunctionDescriptorImpl.create(
|
||||
currentScope!!.scope.scopeOwner,
|
||||
Annotations.EMPTY,
|
||||
name.synthesizedName,
|
||||
CallableMemberDescriptor.Kind.SYNTHESIZED,
|
||||
SourceElement.NO_SOURCE
|
||||
).apply {
|
||||
initialize(null, null, emptyList(), emptyList(), returnType,
|
||||
Modality.ABSTRACT,
|
||||
Visibilities.PRIVATE
|
||||
)
|
||||
}
|
||||
|
||||
private fun getIrReturnableBlockSymbol(name: String, returnType: IrType): IrReturnableBlockSymbol =
|
||||
IrReturnableBlockSymbolImpl(getFakeFunctionDescriptor(name, returnType.toKotlinType()))
|
||||
|
||||
private inline fun <reified T : IrElement> T.copy() = this.deepCopyWithVariables()
|
||||
|
||||
fun IrBuilderWithScope.irReturn(target: IrReturnTargetSymbol, value: IrExpression) =
|
||||
IrReturnImpl(startOffset, endOffset, context.irBuiltIns.nothingType, target, value)
|
||||
|
||||
inline fun IrBuilderWithScope.irReturnableBlock(symbol: IrReturnableBlockSymbol, type: IrType, body: IrBlockBuilder.() -> Unit) =
|
||||
private inline fun IrBuilderWithScope.irReturnableBlock(symbol: IrReturnableBlockSymbol, type: IrType, body: IrBlockBuilder.() -> Unit) =
|
||||
IrReturnableBlockImpl(
|
||||
startOffset, endOffset, type, symbol, null,
|
||||
IrBlockBuilder(context, scope, startOffset, endOffset, null, type, true)
|
||||
|
||||
+2
-4
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
@@ -61,7 +60,7 @@ class InlineClassLowering(val context: BackendContext) {
|
||||
// Secondary ctors of inline class must delegate to some other constructors.
|
||||
// Use these delegating call later to initialize this variable.
|
||||
lateinit var thisVar: IrVariable
|
||||
val parameterMapping = result.valueParameters.associateBy { it ->
|
||||
val parameterMapping = result.valueParameters.associateBy {
|
||||
irConstructor.valueParameters[it.index].symbol
|
||||
}
|
||||
|
||||
@@ -70,9 +69,8 @@ class InlineClassLowering(val context: BackendContext) {
|
||||
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrExpression {
|
||||
expression.transformChildrenVoid()
|
||||
return irBlock(expression) {
|
||||
thisVar = irTemporary(
|
||||
thisVar = createTmpVariable(
|
||||
expression,
|
||||
typeHint = irClass.defaultType.toKotlinType(),
|
||||
irType = irClass.defaultType
|
||||
)
|
||||
thisVar.parent = result
|
||||
|
||||
+5
-15
@@ -19,28 +19,20 @@ package org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
|
||||
import org.jetbrains.kotlin.ir.builders.irCall
|
||||
import org.jetbrains.kotlin.ir.builders.irGet
|
||||
import org.jetbrains.kotlin.ir.builders.irTemporary
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolDeclaration
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStringConcatenation
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isNullableAny
|
||||
import org.jetbrains.kotlin.ir.types.toIrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
|
||||
/**
|
||||
@@ -56,11 +48,9 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
||||
|
||||
private val buildersStack = mutableListOf<IrBuilderWithScope>()
|
||||
private val context = lower.context
|
||||
private val builtIns = context.builtIns
|
||||
private val irBuiltIns = context.irBuiltIns
|
||||
|
||||
private val typesWithSpecialAppendFunction =
|
||||
PrimitiveType.values().map { builtIns.getPrimitiveKotlinType(it).toIrType()!! } + irBuiltIns.stringType
|
||||
private val typesWithSpecialAppendFunction = irBuiltIns.primitiveIrTypes + irBuiltIns.stringType
|
||||
|
||||
private val nameToString = Name.identifier("toString")
|
||||
private val nameAppend = Name.identifier("append")
|
||||
@@ -87,7 +77,7 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
||||
type to stringBuilder.functions.toList().atMostOne {
|
||||
it.name == nameAppend &&
|
||||
it.valueParameters.size == 1 &&
|
||||
it.valueParameters.single().type.toKotlinType() == type
|
||||
it.valueParameters.single().type.isEqualTo(type)
|
||||
}
|
||||
}.toMap()
|
||||
|
||||
@@ -101,7 +91,7 @@ private class StringConcatenationTransformer(val lower: StringConcatenationLower
|
||||
expression.transformChildrenVoid(this)
|
||||
val blockBuilder = buildersStack.last()
|
||||
return blockBuilder.irBlock(expression) {
|
||||
val stringBuilderImpl = irTemporary(irCall(constructor))
|
||||
val stringBuilderImpl = createTmpVariable(irCall(constructor))
|
||||
expression.arguments.forEach { arg ->
|
||||
val appendFunction = typeToAppendFunction(arg.type)
|
||||
+irCall(appendFunction).apply {
|
||||
|
||||
+2
-2
@@ -60,7 +60,7 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
||||
irFunction.body = builder.irBlockBody {
|
||||
// Define variables containing current values of parameters:
|
||||
val parameterToVariable = parameters.associate {
|
||||
it to irTemporaryVar(irGet(it), nameHint = it.symbol.suggestVariableName())
|
||||
it to createTmpVariable(irGet(it), nameHint = it.symbol.suggestVariableName(), isMutable = true)
|
||||
}
|
||||
// (these variables are to be updated on any tail call).
|
||||
|
||||
@@ -72,7 +72,7 @@ private fun lowerTailRecursionCalls(context: BackendContext, irFunction: IrFunct
|
||||
// Read variables containing current values of parameters:
|
||||
val parameterToNew = parameters.associate {
|
||||
val variable = parameterToVariable[it]!!
|
||||
it to irTemporary(irGet(variable), nameHint = it.symbol.suggestVariableName())
|
||||
it to createTmpVariable(irGet(variable), nameHint = it.symbol.suggestVariableName())
|
||||
}
|
||||
|
||||
val transformer = BodyTransformer(
|
||||
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.common.utils
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
|
||||
// TODO: implement pure Ir-based function (see IrTypeUtils.kt)
|
||||
|
||||
@Deprecated("Use pure Ir helper")
|
||||
fun IrType.getPrimitiveArrayElementType() = KotlinBuiltIns.getPrimitiveArrayElementType(toKotlinType())
|
||||
@@ -16,11 +16,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.builders
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrLoop
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
fun IrBuilderWithScope.irWhile(origin: IrStatementOrigin? = null) =
|
||||
IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, origin)
|
||||
@@ -33,3 +42,43 @@ fun IrBuilderWithScope.irContinue(loop: IrLoop) =
|
||||
|
||||
fun IrBuilderWithScope.irGetObject(classSymbol: IrClassSymbol) =
|
||||
IrGetObjectValueImpl(startOffset, endOffset, IrSimpleTypeImpl(classSymbol, false, emptyList(), emptyList()), classSymbol)
|
||||
|
||||
// Also adds created variable into building block
|
||||
fun <T : IrElement> IrStatementsBuilder<T>.createTmpVariable(
|
||||
irExpression: IrExpression,
|
||||
nameHint: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
irType: IrType? = null
|
||||
): IrVariable {
|
||||
val variable = scope.createTmpVariable(irExpression, nameHint, isMutable, origin, irType)
|
||||
+variable
|
||||
return variable
|
||||
}
|
||||
|
||||
fun Scope.createTmpVariable(
|
||||
irExpression: IrExpression,
|
||||
nameHint: String? = null,
|
||||
isMutable: Boolean = false,
|
||||
origin: IrDeclarationOrigin = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE,
|
||||
irType: IrType? = null
|
||||
): IrVariable {
|
||||
val varType = irType ?: irExpression.type
|
||||
val descriptor = WrappedVariableDescriptor()
|
||||
val symbol = IrVariableSymbolImpl(descriptor)
|
||||
return IrVariableImpl(
|
||||
irExpression.startOffset,
|
||||
irExpression.endOffset,
|
||||
origin,
|
||||
symbol,
|
||||
Name.identifier(nameHint ?: "tmp"),
|
||||
varType,
|
||||
isMutable,
|
||||
false,
|
||||
false
|
||||
).apply {
|
||||
initializer = irExpression
|
||||
parent = getLocalDeclarationParent()
|
||||
descriptor.bind(this)
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.util
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.fqName
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns.FQ_NAMES
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
@@ -81,3 +82,7 @@ private inline fun IrType.isTypeFromKotlinPackage(namePredicate: (Name) -> Boole
|
||||
}
|
||||
|
||||
fun IrType.isPrimitiveArray() = isTypeFromKotlinPackage { it in FQ_NAMES.primitiveArrayTypeShortNames }
|
||||
|
||||
fun IrType.getPrimitiveArrayElementType() = (this as? IrSimpleType)?.let {
|
||||
(it.classifier.owner as? IrClass)?.fqName?.toUnsafe()?.let { fqn -> FQ_NAMES.arrayClassFqNameToPrimitiveType[fqn] }
|
||||
}
|
||||
Reference in New Issue
Block a user