IrTypes in psi2ir (work in progress)

This commit is contained in:
Dmitry Petrov
2018-04-28 15:55:28 +03:00
parent 0e34ee5270
commit 326e4a160f
35 changed files with 399 additions and 323 deletions
@@ -25,7 +25,10 @@ import org.jetbrains.kotlin.psi.KtBlockExpression
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) { class AnonymousInitializerGenerator(
declarationGenerator: DeclarationGenerator
) : DeclarationGeneratorExtension(declarationGenerator) {
fun generateAnonymousInitializerDeclaration( fun generateAnonymousInitializerDeclaration(
ktAnonymousInitializer: KtAnonymousInitializer, ktAnonymousInitializer: KtAnonymousInitializer,
classDescriptor: ClassDescriptor classDescriptor: ClassDescriptor
@@ -46,18 +46,20 @@ fun StatementGenerator.generateReceiverOrNull(ktDefaultElement: KtElement, recei
fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: ReceiverValue): IntermediateValue = fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: ReceiverValue): IntermediateValue =
generateReceiver(ktDefaultElement.startOffset, ktDefaultElement.endOffset, receiver) generateReceiver(ktDefaultElement.startOffset, ktDefaultElement.endOffset, receiver)
fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue = fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue {
if (receiver is TransientReceiver) val irReceiverType = receiver.type.toIrType()
TransientReceiverValue(receiver.type)
else generateDelegatedValue(receiver.type) { if (receiver is TransientReceiver) return TransientReceiverValue(irReceiverType)
val receiverExpression = when (receiver) {
return generateDelegatedValue(irReceiverType) {
val receiverExpression: IrExpression = when (receiver) {
is ImplicitClassReceiver -> { is ImplicitClassReceiver -> {
val receiverClassDescriptor = receiver.classDescriptor val receiverClassDescriptor = receiver.classDescriptor
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor)) if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type) generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
else else
IrGetValueImpl( IrGetValueImpl(
defaultStartOffset, defaultEndOffset, defaultStartOffset, defaultEndOffset, irReceiverType,
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter) context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
) )
} }
@@ -69,12 +71,12 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
generateExpression(receiver.expression) generateExpression(receiver.expression)
is ClassValueReceiver -> is ClassValueReceiver ->
IrGetObjectValueImpl( IrGetObjectValueImpl(
receiver.expression.startOffset, receiver.expression.endOffset, receiver.type, receiver.expression.startOffset, receiver.expression.endOffset, irReceiverType,
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor) context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor)
) )
is ExtensionReceiver -> is ExtensionReceiver ->
IrGetValueImpl( IrGetValueImpl(
defaultStartOffset, defaultStartOffset, defaultStartOffset, defaultStartOffset, irReceiverType,
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!) context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
) )
else -> else ->
@@ -86,33 +88,37 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
else else
OnceExpressionValue(receiverExpression) OnceExpressionValue(receiverExpression)
} }
}
fun StatementGenerator.generateSingletonReference( fun StatementGenerator.generateSingletonReference(
descriptor: ClassDescriptor, descriptor: ClassDescriptor,
startOffset: Int, startOffset: Int,
endOffset: Int, endOffset: Int,
type: KotlinType type: KotlinType
): IrDeclarationReference = ): IrDeclarationReference {
when { val irType = type.toIrType()
return when {
DescriptorUtils.isObject(descriptor) -> DescriptorUtils.isObject(descriptor) ->
IrGetObjectValueImpl( IrGetObjectValueImpl(
startOffset, endOffset, type, startOffset, endOffset, irType,
context.symbolTable.referenceClass(descriptor) context.symbolTable.referenceClass(descriptor)
) )
DescriptorUtils.isEnumEntry(descriptor) -> DescriptorUtils.isEnumEntry(descriptor) ->
IrGetEnumValueImpl( IrGetEnumValueImpl(
startOffset, endOffset, type, startOffset, endOffset, irType,
context.symbolTable.referenceEnumEntry(descriptor) context.symbolTable.referenceEnumEntry(descriptor)
) )
else -> { else -> {
val companionObjectDescriptor = descriptor.companionObjectDescriptor val companionObjectDescriptor = descriptor.companionObjectDescriptor
?: throw java.lang.AssertionError("Class value without companion object: $descriptor") ?: throw java.lang.AssertionError("Class value without companion object: $descriptor")
IrGetObjectValueImpl( IrGetObjectValueImpl(
startOffset, endOffset, type, startOffset, endOffset, irType,
context.symbolTable.referenceClass(companionObjectDescriptor) context.symbolTable.referenceClass(companionObjectDescriptor)
) )
} }
} }
}
private fun StatementGenerator.shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor: ClassDescriptor): Boolean { private fun StatementGenerator.shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor: ClassDescriptor): Boolean {
return receiverClassDescriptor.kind.isSingleton && return receiverClassDescriptor.kind.isSingleton &&
@@ -126,6 +132,7 @@ private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverVal
val ktReceiver = expressionReceiver.expression val ktReceiver = expressionReceiver.expression
return IrGetValueImpl( return IrGetValueImpl(
ktReceiver.startOffset, ktReceiver.endOffset, ktReceiver.startOffset, ktReceiver.endOffset,
expressionReceiver.type.toIrType(),
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter) context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter)
) )
} }
@@ -192,7 +199,7 @@ private fun StatementGenerator.generateReceiverForCalleeImportedFromObject(
calleeDescriptor: ImportedFromObjectCallableDescriptor<*> calleeDescriptor: ImportedFromObjectCallableDescriptor<*>
): ExpressionValue { ): ExpressionValue {
val objectDescriptor = calleeDescriptor.containingObject val objectDescriptor = calleeDescriptor.containingObject
val objectType = objectDescriptor.defaultType val objectType = objectDescriptor.defaultType.toIrType()
return generateExpressionValue(objectType) { return generateExpressionValue(objectType) {
IrGetObjectValueImpl( IrGetObjectValueImpl(
startOffset, endOffset, objectType, startOffset, endOffset, objectType,
@@ -219,7 +226,7 @@ fun StatementGenerator.generateVarargExpression(
val varargElementType = val varargElementType =
valueParameter.varargElementType ?: throw AssertionError("Vararg argument for non-vararg parameter $valueParameter") valueParameter.varargElementType ?: throw AssertionError("Vararg argument for non-vararg parameter $valueParameter")
val irVararg = IrVarargImpl(varargStartOffset, varargEndOffset, valueParameter.type, varargElementType) val irVararg = IrVarargImpl(varargStartOffset, varargEndOffset, valueParameter.type.toIrType(), varargElementType.toIrType())
for (argument in varargArgument.arguments) { for (argument in varargArgument.arguments) {
val ktArgumentExpression = argument.getArgumentExpression() val ktArgumentExpression = argument.getArgumentExpression()
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
import org.jetbrains.kotlin.ir.builders.irBlock
import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irTemporary import org.jetbrains.kotlin.ir.builders.irTemporary
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -35,25 +36,25 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateAssignment(expression: KtBinaryExpression): IrExpression { fun generateAssignment(ktExpression: KtBinaryExpression): IrExpression {
val ktLeft = expression.left!! val ktLeft = ktExpression.left!!
val irRhs = expression.right!!.genExpr() val irRhs = ktExpression.right!!.genExpr()
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, IrStatementOrigin.EQ) val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, IrStatementOrigin.EQ)
return irAssignmentReceiver.assign(irRhs) return irAssignmentReceiver.assign(irRhs)
} }
fun generateAugmentedAssignment(expression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression { fun generateAugmentedAssignment(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(expression)!! val opResolvedCall = getResolvedCall(ktExpression)!!
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, ktExpression) ?: false
val ktLeft = expression.left!! val ktLeft = ktExpression.left!!
val ktRight = expression.right!! val ktRight = ktExpression.right!!
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, origin) val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, origin)
return irAssignmentReceiver.assign { irLValue -> return irAssignmentReceiver.assign { irLValue ->
val opCall = statementGenerator.pregenerateCallReceivers(opResolvedCall) val opCall = statementGenerator.pregenerateCallReceivers(opResolvedCall)
opCall.setExplicitReceiverValue(irLValue) opCall.setExplicitReceiverValue(irLValue)
opCall.irValueArgumentsByIndex[0] = ktRight.genExpr() opCall.irValueArgumentsByIndex[0] = ktRight.genExpr()
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin) val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
if (isSimpleAssignment) { if (isSimpleAssignment) {
// Set( Op( Get(), RHS ) ) // Set( Op( Get(), RHS ) )
@@ -65,35 +66,35 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
} }
} }
fun generatePrefixIncrementDecrement(expression: KtPrefixExpression, origin: IrStatementOrigin): IrExpression { fun generatePrefixIncrementDecrement(ktExpression: KtPrefixExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(expression)!! val opResolvedCall = getResolvedCall(ktExpression)!!
val ktBaseExpression = expression.baseExpression!! val ktBaseExpression = ktExpression.baseExpression!!
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, origin) val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, origin)
return irAssignmentReceiver.assign { irLValue -> return irAssignmentReceiver.assign { irLValue ->
irBlock(expression, origin, irLValue.type) { irBlock(ktExpression.startOffset, ktExpression.endOffset, origin, irLValue.type) {
val opCall = statementGenerator.pregenerateCall(opResolvedCall) val opCall = statementGenerator.pregenerateCall(opResolvedCall)
opCall.setExplicitReceiverValue(irLValue) opCall.setExplicitReceiverValue(irLValue)
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin) val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
+irLValue.store(irOpCall) +irLValue.store(irOpCall)
+irLValue.load() +irLValue.load()
} }
} }
} }
fun generatePostfixIncrementDecrement(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression { fun generatePostfixIncrementDecrement(ktExpression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(expression)!! val opResolvedCall = getResolvedCall(ktExpression)!!
val ktBaseExpression = expression.baseExpression!! val ktBaseExpression = ktExpression.baseExpression!!
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, origin) val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, origin)
return irAssignmentReceiver.assign { irLValue -> return irAssignmentReceiver.assign { irLValue ->
irBlock(expression, origin, irLValue.type) { irBlock(ktExpression.startOffset, ktExpression.endOffset, origin, irLValue.type) {
val temporary = irTemporary(irLValue.load()) val temporary = irTemporary(irLValue.load())
val opCall = statementGenerator.pregenerateCall(opResolvedCall) val opCall = statementGenerator.pregenerateCall(opResolvedCall)
opCall.setExplicitReceiverValue(VariableLValue(startOffset, endOffset, temporary.symbol)) opCall.setExplicitReceiverValue(VariableLValue(startOffset, endOffset, temporary.symbol))
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin) val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
+irLValue.store(irOpCall) +irLValue.store(irOpCall)
+irGet(temporary.symbol) +irGet(temporary.type, temporary.symbol)
} }
} }
} }
@@ -162,9 +163,12 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
): AssignmentReceiver = ): AssignmentReceiver =
if (isValInitializationInConstructor(descriptor, resolvedCall)) { if (isValInitializationInConstructor(descriptor, resolvedCall)) {
val thisClass = getThisClass() val thisClass = getThisClass()
val thisAsReceiverParameter = thisClass.thisAsReceiverParameter
val thisType = thisAsReceiverParameter.type.toIrType()
val irThis = IrGetValueImpl( val irThis = IrGetValueImpl(
ktLeft.startOffset, ktLeft.endOffset, ktLeft.startOffset, ktLeft.endOffset,
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter) thisType,
context.symbolTable.referenceValueParameter(thisAsReceiverParameter)
) )
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null) createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
} else { } else {
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
@@ -29,14 +30,19 @@ import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.types.KotlinType
import java.util.* import java.util.*
class BodyGenerator( class BodyGenerator(
val scopeOwnerSymbol: IrSymbol, val scopeOwnerSymbol: IrSymbol,
override val context: GeneratorContext override val context: GeneratorContext
) : GeneratorWithScope { ) : GeneratorWithScope {
val scopeOwner: DeclarationDescriptor get() = scopeOwnerSymbol.descriptor val scopeOwner: DeclarationDescriptor get() = scopeOwnerSymbol.descriptor
private val typeTranslator = TypeTranslator(context.moduleDescriptor, context.symbolTable)
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
override val scope = Scope(scopeOwnerSymbol) override val scope = Scope(scopeOwnerSymbol)
private val loopTable = HashMap<KtLoopExpression, IrLoop>() private val loopTable = HashMap<KtLoopExpression, IrLoop>()
@@ -85,7 +91,7 @@ class BodyGenerator(
generateReturnExpression( generateReturnExpression(
ktBody.startOffset, ktBody.endOffset, ktBody.startOffset, ktBody.endOffset,
IrGetObjectValueImpl( IrGetObjectValueImpl(
ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType, ktBody.startOffset, ktBody.endOffset, context.irBuiltIns.unitType,
context.symbolTable.referenceClass(context.builtIns.unit) context.symbolTable.referenceClass(context.builtIns.unit)
) )
) )
@@ -115,7 +121,7 @@ class BodyGenerator(
private fun generateReturnExpression(startOffset: Int, endOffset: Int, returnValue: IrExpression): IrReturnImpl { private fun generateReturnExpression(startOffset: Int, endOffset: Int, returnValue: IrExpression): IrReturnImpl {
val returnTarget = (scopeOwner as? CallableDescriptor) ?: throw AssertionError("'return' in a non-callable: $scopeOwner") val returnTarget = (scopeOwner as? CallableDescriptor) ?: throw AssertionError("'return' in a non-callable: $scopeOwner")
return IrReturnImpl( return IrReturnImpl(
startOffset, endOffset, context.builtIns.nothingType, startOffset, endOffset, context.irBuiltIns.nothingType,
context.symbolTable.referenceFunction(returnTarget), context.symbolTable.referenceFunction(returnTarget),
returnValue returnValue
) )
@@ -177,7 +183,8 @@ class BodyGenerator(
irBlockBody.statements.add( irBlockBody.statements.add(
IrInstanceInitializerCallImpl( IrInstanceInitializerCallImpl(
ktClassOrObject.startOffset, ktClassOrObject.endOffset, ktClassOrObject.startOffset, ktClassOrObject.endOffset,
context.symbolTable.referenceClass(classDescriptor) context.symbolTable.referenceClass(classDescriptor),
context.irBuiltIns.unitType
) )
) )
@@ -193,7 +200,8 @@ class BodyGenerator(
irBlockBody.statements.add( irBlockBody.statements.add(
IrInstanceInitializerCallImpl( IrInstanceInitializerCallImpl(
ktConstructor.startOffset, ktConstructor.endOffset, ktConstructor.startOffset, ktConstructor.endOffset,
context.symbolTable.referenceClass(classDescriptor) context.symbolTable.referenceClass(classDescriptor),
context.irBuiltIns.unitType
) )
) )
@@ -248,9 +256,9 @@ class BodyGenerator(
irBlockBody.statements.add( irBlockBody.statements.add(
IrDelegatingConstructorCallImpl( IrDelegatingConstructorCallImpl(
ktElement.startOffset, ktElement.endOffset, ktElement.startOffset, ktElement.endOffset,
context.irBuiltIns.unitType,
context.symbolTable.referenceConstructor(anyConstructor), context.symbolTable.referenceConstructor(anyConstructor),
anyConstructor, anyConstructor
null
) )
) )
} }
@@ -264,9 +272,12 @@ class BodyGenerator(
irBlockBody.statements.add( irBlockBody.statements.add(
IrEnumConstructorCallImpl( IrEnumConstructorCallImpl(
ktElement.startOffset, ktElement.endOffset, ktElement.startOffset, ktElement.endOffset,
context.irBuiltIns.unitType,
context.symbolTable.referenceConstructor(enumConstructor), context.symbolTable.referenceConstructor(enumConstructor),
mapOf(enumConstructor.typeParameters.single() to classDescriptor.defaultType) 1 // kotlin.Enum<T> has a single type parameter
) ).apply {
putTypeArgument(0, classDescriptor.defaultType.toIrType())
}
) )
} }
@@ -279,8 +290,9 @@ class BodyGenerator(
val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!! val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!!
return IrEnumConstructorCallImpl( return IrEnumConstructorCallImpl(
ktEnumEntry.startOffset, ktEnumEntry.endOffset, ktEnumEntry.startOffset, ktEnumEntry.endOffset,
context.irBuiltIns.unitType,
context.symbolTable.referenceConstructor(enumEntryConstructor), context.symbolTable.referenceConstructor(enumEntryConstructor),
null // enums can't be generic (so far) 0 // enums can't be generic
) )
} }
@@ -22,18 +22,20 @@ import org.jetbrains.kotlin.ir.builders.whenComma
import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi2ir.defaultLoad import org.jetbrains.kotlin.psi2ir.intermediate.defaultLoad
import org.jetbrains.kotlin.psi2ir.deparenthesize import org.jetbrains.kotlin.psi2ir.deparenthesize
import org.jetbrains.kotlin.psi2ir.intermediate.defaultLoad
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.SmartList import org.jetbrains.kotlin.utils.SmartList
class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateIfExpression(expression: KtIfExpression): IrExpression { fun generateIfExpression(expression: KtIfExpression): IrExpression {
val resultType = getInferredTypeWithImplicitCastsOrFail(expression) val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType()
var ktLastIf: KtIfExpression = expression var ktLastIf: KtIfExpression = expression
val irBranches = SmartList<IrBranch>() val irBranches = SmartList<IrBranch>()
@@ -63,7 +65,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
ktIf: KtIfExpression, ktIf: KtIfExpression,
irBranches: List<IrBranch>, irBranches: List<IrBranch>,
irElseResult: IrExpression?, irElseResult: IrExpression?,
resultType: KotlinType resultType: IrType
): IrWhen { ): IrWhen {
if (irBranches.size == 1) { if (irBranches.size == 1) {
return IrIfThenElseImpl( return IrIfThenElseImpl(
@@ -77,12 +79,18 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
irWhen.branches.addAll(irBranches) irWhen.branches.addAll(irBranches)
irElseResult?.let { irElseResult?.let {
irWhen.branches.add(IrBranchImpl.elseBranch(it)) irWhen.branches.add(elseBranch(it))
} }
return irWhen return irWhen
} }
private fun elseBranch(result: IrExpression) =
IrElseBranchImpl(
IrConstImpl.boolean(result.startOffset, result.endOffset, context.irBuiltIns.booleanType, true),
result
)
fun generateWhenExpression(expression: KtWhenExpression): IrExpression { fun generateWhenExpression(expression: KtWhenExpression): IrExpression {
val irSubject = generateWhenSubject(expression) val irSubject = generateWhenSubject(expression)
@@ -93,9 +101,9 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
val isExhaustive = expression.isExhaustiveWhen() val isExhaustive = expression.isExhaustiveWhen()
val resultType = when { val resultType = when {
isUsedAsExpression -> inferredType isUsedAsExpression -> inferredType.toIrType()
isExhaustive && KotlinBuiltIns.isNothing(inferredType) -> inferredType KotlinBuiltIns.isNothing(inferredType) -> inferredType.toIrType()
else -> context.builtIns.unitType else -> context.irBuiltIns.unitType
} }
val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrStatementOrigin.WHEN) val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrStatementOrigin.WHEN)
@@ -103,7 +111,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
for (ktEntry in expression.entries) { for (ktEntry in expression.entries) {
if (ktEntry.isElse) { if (ktEntry.isElse) {
val irElseResult = ktEntry.expression!!.genExpr() val irElseResult = ktEntry.expression!!.genExpr()
irWhen.branches.add(IrBranchImpl.elseBranch(irElseResult)) irWhen.branches.add(elseBranch(irElseResult))
break break
} }
@@ -141,8 +149,12 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
val isExhaustive = whenExpression.isExhaustiveWhen() val isExhaustive = whenExpression.isExhaustiveWhen()
if (isExhaustive) { if (isExhaustive) {
val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.noWhenBranchMatchedExceptionSymbol) val call = IrCallImpl(
irWhen.branches.add(IrBranchImpl.elseBranch(call)) UNDEFINED_OFFSET, UNDEFINED_OFFSET,
context.irBuiltIns.nothingType,
context.irBuiltIns.noWhenBranchMatchedExceptionSymbol
)
irWhen.branches.add(elseBranch(call))
} }
} }
} }
@@ -155,12 +167,12 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irWhen: IrWhen): IrExpression = private fun generateWhenBody(expression: KtWhenExpression, irSubject: IrVariable?, irWhen: IrWhen): IrExpression =
if (irSubject == null) { if (irSubject == null) {
if (irWhen.branches.isEmpty()) if (irWhen.branches.isEmpty())
IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN) IrBlockImpl(expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, IrStatementOrigin.WHEN)
else else
irWhen irWhen
} else { } else {
if (irWhen.branches.isEmpty()) { if (irWhen.branches.isEmpty()) {
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN) val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, context.irBuiltIns.unitType, IrStatementOrigin.WHEN)
irBlock.statements.add(irSubject) irBlock.statements.add(irSubject)
irBlock irBlock
} else { } else {
@@ -189,13 +201,13 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression { private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
val typeOperand = getOrFail(BindingContext.TYPE, ktCondition.typeReference) val typeOperand = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
val typeOperandDescriptor = typeOperand.constructor.declarationDescriptor val irTypeOperand = typeOperand.toIrType()
?: throw AssertionError("No declaration descriptor for type $typeOperand") val typeSymbol = irTypeOperand.classifierOrNull ?: throw AssertionError("Not a classifier type: $typeOperand")
val typeOperandSymbol = context.symbolTable.referenceClassifier(typeOperandDescriptor)
return IrTypeOperatorCallImpl( return IrTypeOperatorCallImpl(
ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType, ktCondition.startOffset, ktCondition.endOffset,
IrTypeOperator.INSTANCEOF, typeOperand, irSubject.defaultLoad(), typeOperandSymbol context.irBuiltIns.booleanType,
IrTypeOperator.INSTANCEOF, irTypeOperand, typeSymbol,
irSubject.defaultLoad()
) )
} }
@@ -210,6 +222,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
IrStatementOrigin.NOT_IN -> IrStatementOrigin.NOT_IN ->
IrUnaryPrimitiveImpl( IrUnaryPrimitiveImpl(
ktCondition.startOffset, ktCondition.endOffset, ktCondition.startOffset, ktCondition.endOffset,
context.irBuiltIns.booleanType,
IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol, IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol,
irInCall irInCall
) )
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -73,7 +71,8 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
is SyntheticFieldDescriptor -> { is SyntheticFieldDescriptor -> {
val receiver = statementGenerator.generateBackingFieldReceiver(startOffset, endOffset, resolvedCall, descriptor) val receiver = statementGenerator.generateBackingFieldReceiver(startOffset, endOffset, resolvedCall, descriptor)
val field = statementGenerator.context.symbolTable.referenceField(descriptor.propertyDescriptor) val field = statementGenerator.context.symbolTable.referenceField(descriptor.propertyDescriptor)
IrGetFieldImpl(startOffset, endOffset, field, receiver?.load()) val fieldType = descriptor.propertyDescriptor.type.toIrType()
IrGetFieldImpl(startOffset, endOffset, field, fieldType, receiver?.load())
} }
is VariableDescriptor -> is VariableDescriptor ->
generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin) generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin)
@@ -93,21 +92,29 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val getterDescriptor = descriptor.getter!! val getterDescriptor = descriptor.getter!!
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original) val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
IrCallImpl( IrCallImpl(
startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor, startOffset, endOffset, descriptor.type.toIrType(), getterSymbol, getterDescriptor,
typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY
) ).apply {
putTypeArguments(typeArguments) { it.toIrType() }
}
} else } else
IrGetValueImpl(startOffset, endOffset, context.symbolTable.referenceValue(descriptor), origin) IrGetValueImpl(startOffset, endOffset, descriptor.type.toIrType(), context.symbolTable.referenceValue(descriptor), origin)
fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder): IrExpression = fun generateDelegatingConstructorCall(startOffset: Int, endOffset: Int, call: CallBuilder): IrExpression =
call.callReceiver.call { dispatchReceiver, extensionReceiver -> call.callReceiver.call { dispatchReceiver, extensionReceiver ->
val descriptor = call.descriptor as? ClassConstructorDescriptor val descriptor = call.descriptor as? ClassConstructorDescriptor
?: throw AssertionError("Class constructor expected: ${call.descriptor}") ?: throw AssertionError("Class constructor expected: ${call.descriptor}")
val constructorSymbol = context.symbolTable.referenceConstructor(descriptor.original) val constructorSymbol = context.symbolTable.referenceConstructor(descriptor.original)
val irCall = val irCall = IrDelegatingConstructorCallImpl(
IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, call.typeArguments) startOffset, endOffset,
irCall.dispatchReceiver = dispatchReceiver?.load() descriptor.returnType.toIrType(),
irCall.extensionReceiver = extensionReceiver?.load() constructorSymbol,
descriptor
).apply {
putTypeArguments(call.typeArguments) { it.toIrType() }
this.dispatchReceiver = dispatchReceiver?.load()
this.extensionReceiver = extensionReceiver?.load()
}
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType) addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
} }
@@ -121,11 +128,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver") if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver")
if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver") if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver")
val constructorSymbol = context.symbolTable.referenceConstructor(constructorDescriptor.original) val constructorSymbol = context.symbolTable.referenceConstructor(constructorDescriptor.original)
val irCall = IrEnumConstructorCallImpl( val irCall = IrEnumConstructorCallImpl(startOffset, endOffset, constructorDescriptor.returnType.toIrType(), constructorSymbol)
startOffset, endOffset,
constructorSymbol,
call.typeArguments
)
addParametersToCall(startOffset, endOffset, call, irCall, constructorDescriptor.returnType) addParametersToCall(startOffset, endOffset, call, irCall, constructorDescriptor.returnType)
} }
} }
@@ -144,19 +147,24 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original) val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
IrGetterCallImpl( IrGetterCallImpl(
startOffset, endOffset, startOffset, endOffset,
descriptor.type.toIrType(),
getterSymbol, getterSymbol,
getterDescriptor, getterDescriptor,
call.typeArguments, descriptor.typeParametersCount,
dispatchReceiverValue?.load(), dispatchReceiverValue?.load(),
extensionReceiverValue?.load(), extensionReceiverValue?.load(),
IrStatementOrigin.GET_PROPERTY, IrStatementOrigin.GET_PROPERTY,
superQualifierSymbol superQualifierSymbol
) ).apply {
putTypeArguments(call.typeArguments) { it.toIrType() }
}
} else { } else {
val fieldSymbol = context.symbolTable.referenceField(descriptor.original) val fieldSymbol = context.symbolTable.referenceField(descriptor.original)
IrGetFieldImpl( IrGetFieldImpl(
startOffset, endOffset, startOffset, endOffset,
fieldSymbol, fieldSymbol,
descriptor.type.toIrType(),
dispatchReceiverValue?.load(), dispatchReceiverValue?.load(),
IrStatementOrigin.GET_PROPERTY, IrStatementOrigin.GET_PROPERTY,
superQualifierSymbol superQualifierSymbol
@@ -178,16 +186,16 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) } val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
val irCall = IrCallImpl( val irCall = IrCallImpl(
startOffset, endOffset, startOffset, endOffset,
returnType, returnType.toIrType(),
functionSymbol, functionSymbol,
functionDescriptor, functionDescriptor,
call.typeArguments,
origin, origin,
superQualifierSymbol superQualifierSymbol
) ).apply {
irCall.dispatchReceiver = dispatchReceiverValue?.load() putTypeArguments(call.typeArguments) { it.toIrType() }
irCall.extensionReceiver = extensionReceiverValue?.load() this.dispatchReceiver = dispatchReceiverValue?.load()
this.extensionReceiver = extensionReceiverValue?.load()
}
addParametersToCall(startOffset, endOffset, call, irCall, returnType) addParametersToCall(startOffset, endOffset, call, irCall, returnType)
} }
@@ -220,7 +228,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val valueArgumentsInEvaluationOrder = resolvedCall.valueArguments.values val valueArgumentsInEvaluationOrder = resolvedCall.valueArguments.values
val valueParameters = resolvedCall.resultingDescriptor.valueParameters val valueParameters = resolvedCall.resultingDescriptor.valueParameters
val irBlock = IrBlockImpl(startOffset, endOffset, resultType, IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL) val irBlock = IrBlockImpl(startOffset, endOffset, resultType.toIrType(), IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL)
val valueArgumentsToValueParameters = HashMap<ResolvedValueArgument, ValueParameterDescriptor>() val valueArgumentsToValueParameters = HashMap<ResolvedValueArgument, ValueParameterDescriptor>()
for ((index, valueArgument) in resolvedCall.valueArgumentsByIndex!!.withIndex()) { for ((index, valueArgument) in resolvedCall.valueArgumentsByIndex!!.withIndex()) {
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl import org.jetbrains.kotlin.ir.descriptors.IrImplementingDelegateDescriptorImpl
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.expressions.mapValueParameters import org.jetbrains.kotlin.ir.expressions.mapValueParameters
import org.jetbrains.kotlin.ir.expressions.putTypeArguments
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.ir.util.StableDescriptorsComparator import org.jetbrains.kotlin.ir.util.StableDescriptorsComparator
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
import org.jetbrains.kotlin.ir.util.isEnumClass import org.jetbrains.kotlin.ir.util.isEnumClass
@@ -39,7 +41,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
import java.lang.AssertionError import java.lang.AssertionError
class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) { class ClassGenerator(
declarationGenerator: DeclarationGenerator
) : DeclarationGeneratorExtension(declarationGenerator) {
fun generateClass(ktClassOrObject: KtClassOrObject): IrClass { fun generateClass(ktClassOrObject: KtClassOrObject): IrClass {
val descriptor = getOrFail(BindingContext.CLASS, ktClassOrObject) val descriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
val startOffset = ktClassOrObject.startOffset val startOffset = ktClassOrObject.startOffset
@@ -172,7 +177,10 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
val startOffset = irDelegate.startOffset val startOffset = irDelegate.startOffset
val endOffset = irDelegate.endOffset val endOffset = irDelegate.endOffset
val irProperty = IrPropertyImpl(startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER, false, delegated) val irProperty = IrPropertyImpl(
startOffset, endOffset, IrDeclarationOrigin.DELEGATED_MEMBER,
false, delegated, delegated.type.toIrType()
)
irProperty.getter = generateDelegatedFunction(irDelegate, delegated.getter!!, overridden.getter!!) irProperty.getter = generateDelegatedFunction(irDelegate, delegated.getter!!, overridden.getter!!)
@@ -216,30 +224,42 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset) val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
val substitutedOverridden = substituteOverriddenDescriptorForDelegate(delegated, overridden) val substitutedOverridden = substituteOverriddenDescriptorForDelegate(delegated, overridden)
val returnType = substitutedOverridden.returnType!! val returnType = substitutedOverridden.returnType!!
val irReturnType = returnType.toIrType()
val irCall = IrCallImpl( val irCall = IrCallImpl(
startOffset, endOffset, returnType, startOffset, endOffset, irReturnType,
context.symbolTable.referenceFunction(overridden.original), context.symbolTable.referenceFunction(overridden.original),
substitutedOverridden, substitutedOverridden,
getTypeArgumentsForOverriddenDescriptorDelegatingCall(delegated, overridden) substitutedOverridden.typeParametersCount
) ).apply {
val typeArguments = getTypeArgumentsForOverriddenDescriptorDelegatingCall(delegated, overridden)
putTypeArguments(typeArguments) { it.toIrType() }
}
val dispatchReceiverParameter = irDelegatedFunction.dispatchReceiverParameter!!
val dispatchReceiverType = dispatchReceiverParameter.type
irCall.dispatchReceiver = irCall.dispatchReceiver =
IrGetFieldImpl( IrGetFieldImpl(
startOffset, endOffset, irDelegate.symbol, startOffset, endOffset,
IrGetValueImpl(startOffset, endOffset, irDelegatedFunction.dispatchReceiverParameter!!.symbol) irDelegate.symbol,
dispatchReceiverType,
IrGetValueImpl(
startOffset, endOffset,
dispatchReceiverType,
dispatchReceiverParameter.symbol
)
) )
irCall.extensionReceiver = irCall.extensionReceiver =
irDelegatedFunction.extensionReceiverParameter?.let { extensionReceiver -> irDelegatedFunction.extensionReceiverParameter?.let { extensionReceiver ->
IrGetValueImpl(startOffset, endOffset, extensionReceiver.symbol) IrGetValueImpl(startOffset, endOffset, extensionReceiver.type, extensionReceiver.symbol)
} }
irCall.mapValueParameters { overriddenValueParameter -> irCall.mapValueParameters { overriddenValueParameter ->
val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index] val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index]
val irDelegatedValueParameter = irDelegatedFunction.getIrValueParameter(delegatedValueParameter) val irDelegatedValueParameter = irDelegatedFunction.getIrValueParameter(delegatedValueParameter)
IrGetValueImpl(startOffset, endOffset, irDelegatedValueParameter.symbol) IrGetValueImpl(startOffset, endOffset, irDelegatedValueParameter.type, irDelegatedValueParameter.symbol)
} }
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) { if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
irBlockBody.statements.add(irCall) irBlockBody.statements.add(irCall)
} else { } else {
val irReturn = IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, irDelegatedFunction.symbol, irCall) val irReturn = IrReturnImpl(startOffset, endOffset, context.irBuiltIns.nothingType, irDelegatedFunction.symbol, irCall)
irBlockBody.statements.add(irReturn) irBlockBody.statements.add(irReturn)
} }
return irBlockBody return irBlockBody
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.putDefault import org.jetbrains.kotlin.ir.declarations.putDefault
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
@@ -43,7 +42,10 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import java.lang.AssertionError import java.lang.AssertionError
class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) { class DataClassMembersGenerator(
declarationGenerator: DeclarationGenerator
) : DeclarationGeneratorExtension(declarationGenerator) {
fun generate(ktClassOrObject: KtClassOrObject, irClass: IrClass) { fun generate(ktClassOrObject: KtClassOrObject, irClass: IrClass) {
MyDataClassMethodGenerator(ktClassOrObject, irClass).generate() MyDataClassMethodGenerator(ktClassOrObject, irClass).generate()
} }
@@ -73,11 +75,23 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
irFunction.putDefault(parameter, irExprBody(value)) irFunction.putDefault(parameter, irExprBody(value))
} }
fun irThis(): IrExpression = fun irThis(): IrExpression {
IrGetValueImpl(startOffset, endOffset, irFunction.dispatchReceiverParameter!!.symbol) val irDispatchReceiverParameter = irFunction.dispatchReceiverParameter!!
return IrGetValueImpl(
startOffset, endOffset,
irDispatchReceiverParameter.type,
irDispatchReceiverParameter.symbol
)
}
fun irOther(): IrExpression = fun irOther(): IrExpression {
IrGetValueImpl(startOffset, endOffset, irFunction.valueParameters[0].symbol) val irFirstParameter = irFunction.valueParameters[0]
return IrGetValueImpl(
startOffset, endOffset,
irFirstParameter.type,
irFirstParameter.symbol
)
}
} }
private inner class MyDataClassMethodGenerator( private inner class MyDataClassMethodGenerator(
@@ -105,7 +119,7 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
?: throw AssertionError("No definition for data class constructor parameter $parameter") ?: throw AssertionError("No definition for data class constructor parameter $parameter")
buildMember(function, ktParameter) { buildMember(function, ktParameter) {
+irReturn(irGet(irThis(), getPropertyGetterSymbol(parameter))) +irReturn(irGet(function.returnType!!.toIrType(), irThis(), getPropertyGetterSymbol(parameter)))
} }
} }
@@ -124,17 +138,18 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
buildMember(function, declaration) { irFunction -> buildMember(function, declaration) { irFunction ->
function.valueParameters.forEach { parameter -> function.valueParameters.forEach { parameter ->
putDefault(parameter, irGet(irThis(), getPropertyGetterSymbol(parameter))) putDefault(parameter, irGet(parameter.type.toIrType(), irThis(), getPropertyGetterSymbol(parameter)))
} }
+irReturn( +irReturn(
irCall( irCall(
constructorSymbol, constructorSymbol,
dataClassConstructor.returnType, dataClassConstructor.returnType.toIrType(),
dataClassConstructor.typeParameters.associate { it to it.defaultType } dataClassConstructor.typeParameters.associate { it to it.defaultType }
).mapValueParameters { ).apply {
irGet(irFunction.valueParameters[it.index].symbol) mapValueParameters {
irGet(irFunction.valueParameters[it.index].symbol)
}
} }
)
} }
} }
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeAliasImpl import org.jetbrains.kotlin.ir.declarations.impl.IrTypeAliasImpl
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.ir.util.withScope import org.jetbrains.kotlin.ir.util.withScope
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -31,8 +32,14 @@ import org.jetbrains.kotlin.psi2ir.endOffsetOrUndefined
import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined import org.jetbrains.kotlin.psi2ir.startOffsetOrUndefined
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.types.KotlinType
class DeclarationGenerator(override val context: GeneratorContext) : Generator { class DeclarationGenerator(override val context: GeneratorContext) : Generator {
private val typeTranslator = TypeTranslator(context.moduleDescriptor, context.symbolTable)
fun KotlinType.toIrType() = typeTranslator.translateType(this)
fun generateMemberDeclaration(ktDeclaration: KtDeclaration): IrDeclaration = fun generateMemberDeclaration(ktDeclaration: KtDeclaration): IrDeclaration =
when (ktDeclaration) { when (ktDeclaration) {
is KtNamedFunction -> is KtNamedFunction ->
@@ -154,21 +161,27 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
} }
} }
private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtElement): IrProperty = private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtElement): IrProperty {
IrPropertyImpl( val backingField =
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
IrDeclarationOrigin.FAKE_OVERRIDE,
false,
propertyDescriptor,
if (propertyDescriptor.getter == null) if (propertyDescriptor.getter == null)
context.symbolTable.declareField( context.symbolTable.declareField(
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, IrDeclarationOrigin.FAKE_OVERRIDE, ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, IrDeclarationOrigin.FAKE_OVERRIDE,
propertyDescriptor propertyDescriptor
) )
else null, else
null
return IrPropertyImpl(
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
IrDeclarationOrigin.FAKE_OVERRIDE,
false,
propertyDescriptor,
propertyDescriptor.type.toIrType(),
backingField,
propertyDescriptor.getter?.let { generateFakeOverrideFunction(it, ktElement) }, propertyDescriptor.getter?.let { generateFakeOverrideFunction(it, ktElement) },
propertyDescriptor.setter?.let { generateFakeOverrideFunction(it, ktElement) } propertyDescriptor.setter?.let { generateFakeOverrideFunction(it, ktElement) }
) )
}
private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrSimpleFunction = private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrSimpleFunction =
FunctionGenerator(this).generateFakeOverrideFunction(functionDescriptor, ktElement) FunctionGenerator(this).generateFakeOverrideFunction(functionDescriptor, ktElement)
@@ -183,6 +196,8 @@ abstract class DeclarationGeneratorExtension(val declarationGenerator: Declarati
builder(irDeclaration) builder(irDeclaration)
} }
} }
fun KotlinType.toIrType() = with(declarationGenerator) { toIrType() }
} }
fun Generator.createBodyGenerator(scopeOwnerSymbol: IrSymbol) = fun Generator.createBodyGenerator(scopeOwnerSymbol: IrSymbol) =
@@ -35,15 +35,20 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression = fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression =
generateErrorExpression(ktElement, e) { generateErrorExpression(ktElement, e) {
val errorExpressionType =
if (ktElement is KtExpression)
getErrorExpressionType(ktElement)
else
ErrorUtils.createErrorType("")
IrErrorExpressionImpl( IrErrorExpressionImpl(
ktElement.startOffset, ktElement.endOffset, ktElement.startOffset, ktElement.endOffset,
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""), errorExpressionType.toIrType(),
e.message ?: "" e.message ?: ""
) )
} }
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) { fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) {
val type = getErrorExpressionType(ktCall) val type = getErrorExpressionType(ktCall).toIrType()
val irErrorCall = IrErrorCallExpressionImpl(ktCall.startOffset, ktCall.endOffset, type, "") // TODO problem description? val irErrorCall = IrErrorCallExpressionImpl(ktCall.startOffset, ktCall.endOffset, type, "") // TODO problem description?
irErrorCall.explicitReceiver = (ktCall.parent as? KtDotQualifiedExpression)?.run { irErrorCall.explicitReceiver = (ktCall.parent as? KtDotQualifiedExpression)?.run {
@@ -64,7 +69,7 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
getInferredTypeWithImplicitCasts(ktExpression) ?: ErrorUtils.createErrorType("") getInferredTypeWithImplicitCasts(ktExpression) ?: ErrorUtils.createErrorType("")
fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression(ktName) { fun generateErrorSimpleName(ktName: KtSimpleNameExpression): IrExpression = generateErrorExpression(ktName) {
val type = getErrorExpressionType(ktName) val type = getErrorExpressionType(ktName).toIrType()
val irErrorCall = IrErrorCallExpressionImpl(ktName.startOffset, ktName.endOffset, type, "") // TODO problem description? val irErrorCall = IrErrorCallExpressionImpl(ktName.startOffset, ktName.endOffset, type, "") // TODO problem description?
irErrorCall.explicitReceiver = (ktName.parent as? KtDotQualifiedExpression)?.let { ktParent -> irErrorCall.explicitReceiver = (ktName.parent as? KtDotQualifiedExpression)?.let { ktParent ->
@@ -27,9 +27,10 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class LocalClassGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { class LocalClassGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateObjectLiteral(ktObjectLiteral: KtObjectLiteralExpression): IrStatement { fun generateObjectLiteral(ktObjectLiteral: KtObjectLiteralExpression): IrStatement {
val objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral) val startOffset = ktObjectLiteral.startOffset
val irBlock = val endOffset = ktObjectLiteral.endOffset
IrBlockImpl(ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL) val objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral).toIrType()
val irBlock = IrBlockImpl(startOffset, endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL)
val irClass = DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktObjectLiteral.objectDeclaration) val irClass = DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktObjectLiteral.objectDeclaration)
irBlock.statements.add(irClass) irBlock.statements.add(irClass)
@@ -48,10 +49,9 @@ class LocalClassGenerator(statementGenerator: StatementGenerator) : StatementGen
irBlock.statements.add( irBlock.statements.add(
IrCallImpl( IrCallImpl(
ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType, startOffset, endOffset, objectLiteralType,
context.symbolTable.referenceConstructor(objectConstructor), context.symbolTable.referenceConstructor(objectConstructor),
objectConstructor, objectConstructor,
null,
IrStatementOrigin.OBJECT_LITERAL IrStatementOrigin.OBJECT_LITERAL
) )
) )
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class LocalFunctionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { class LocalFunctionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement { fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
val ktFun = ktLambda.functionLiteral val ktFun = ktLambda.functionLiteral
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda) val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda).toIrType()
val irLambdaFunction = FunctionGenerator(context).generateLambdaFunctionDeclaration(ktFun) val irLambdaFunction = FunctionGenerator(context).generateLambdaFunctionDeclaration(ktFun)
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrStatementOrigin.LAMBDA) val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrStatementOrigin.LAMBDA)
@@ -37,8 +37,8 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
irBlock.statements.add( irBlock.statements.add(
IrFunctionReferenceImpl( IrFunctionReferenceImpl(
ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType,
irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor, irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor, 0,
null, IrStatementOrigin.LAMBDA IrStatementOrigin.LAMBDA
) )
) )
return irBlock return irBlock
@@ -49,7 +49,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
generateFunctionDeclaration(ktFun) generateFunctionDeclaration(ktFun)
} else { } else {
// anonymous function expression // anonymous function expression
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun) val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun).toIrType()
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION) val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
val irFun = generateFunctionDeclaration(ktFun) val irFun = generateFunctionDeclaration(ktFun)
@@ -58,8 +58,8 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
irBlock.statements.add( irBlock.statements.add(
IrFunctionReferenceImpl( IrFunctionReferenceImpl(
ktFun.startOffset, ktFun.endOffset, funExpressionType, ktFun.startOffset, ktFun.endOffset, funExpressionType,
irFun.symbol, irFun.symbol.descriptor, irFun.symbol, irFun.symbol.descriptor, 0,
null, IrStatementOrigin.ANONYMOUS_FUNCTION IrStatementOrigin.ANONYMOUS_FUNCTION
) )
) )
@@ -33,7 +33,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression { fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression {
val irLoop = IrWhileLoopImpl( val irLoop = IrWhileLoopImpl(
ktWhile.startOffset, ktWhile.endOffset, ktWhile.startOffset, ktWhile.endOffset,
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP context.irBuiltIns.unitType, IrStatementOrigin.WHILE_LOOP
) )
irLoop.condition = ktWhile.condition!!.genExpr() irLoop.condition = ktWhile.condition!!.genExpr()
@@ -55,7 +55,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression { fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression {
val irLoop = IrDoWhileLoopImpl( val irLoop = IrDoWhileLoopImpl(
ktDoWhile.startOffset, ktDoWhile.endOffset, ktDoWhile.startOffset, ktDoWhile.endOffset,
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP context.irBuiltIns.unitType, IrStatementOrigin.DO_WHILE_LOOP
) )
statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop) statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop)
@@ -71,21 +71,21 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
irLoop.label = getLoopLabel(ktDoWhile) irLoop.label = getLoopLabel(ktDoWhile)
return IrBlockImpl(ktDoWhile.startOffset, ktDoWhile.endOffset, context.builtIns.unitType).apply { return IrBlockImpl(ktDoWhile.startOffset, ktDoWhile.endOffset, context.irBuiltIns.unitType).apply {
statements.add(irLoop) statements.add(irLoop)
} }
} }
private fun generateWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression = private fun generateWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
IrBlockImpl( IrBlockImpl(
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null, ktLoopBody.startOffset, ktLoopBody.endOffset, context.irBuiltIns.unitType, null,
ktLoopBody.statements.map { it.genStmt() } ktLoopBody.statements.map { it.genStmt() }
) )
private fun generateDoWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression = private fun generateDoWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
IrCompositeImpl( IrCompositeImpl(
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null, ktLoopBody.startOffset, ktLoopBody.endOffset, context.irBuiltIns.unitType, null,
ktLoopBody.statements.map { it.genStmt() } ktLoopBody.statements.map { it.genStmt() }
) )
@@ -93,7 +93,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val parentLoop = findParentLoop(ktBreak) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression( val parentLoop = findParentLoop(ktBreak) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
ktBreak, RuntimeException("Loop not found for break expression: ${ktBreak.text}") ktBreak, RuntimeException("Loop not found for break expression: ${ktBreak.text}")
) )
return IrBreakImpl(ktBreak.startOffset, ktBreak.endOffset, context.builtIns.nothingType, parentLoop).apply { return IrBreakImpl(ktBreak.startOffset, ktBreak.endOffset, context.irBuiltIns.nothingType, parentLoop).apply {
label = ktBreak.getLabelName() label = ktBreak.getLabelName()
} }
} }
@@ -102,7 +102,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val parentLoop = findParentLoop(ktContinue) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression( val parentLoop = findParentLoop(ktContinue) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
ktContinue, RuntimeException("Loop not found for continue expression: ${ktContinue.text}") ktContinue, RuntimeException("Loop not found for continue expression: ${ktContinue.text}")
) )
return IrContinueImpl(ktContinue.startOffset, ktContinue.endOffset, context.builtIns.nothingType, parentLoop).apply { return IrContinueImpl(ktContinue.startOffset, ktContinue.endOffset, context.irBuiltIns.nothingType, parentLoop).apply {
label = ktContinue.getLabelName() label = ktContinue.getLabelName()
} }
} }
@@ -154,7 +154,10 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val callGenerator = CallGenerator(statementGenerator) val callGenerator = CallGenerator(statementGenerator)
val irForBlock = IrBlockImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP) val startOffset = ktFor.startOffset
val endOffset = ktFor.endOffset
val irForBlock = IrBlockImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.FOR_LOOP)
val iteratorCall = statementGenerator.pregenerateCall(iteratorResolvedCall) val iteratorCall = statementGenerator.pregenerateCall(iteratorResolvedCall)
val irIteratorCall = callGenerator.generateCall(ktLoopRange, iteratorCall, IrStatementOrigin.FOR_LOOP_ITERATOR) val irIteratorCall = callGenerator.generateCall(ktLoopRange, iteratorCall, IrStatementOrigin.FOR_LOOP_ITERATOR)
@@ -162,8 +165,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val iteratorValue = VariableLValue(irIterator) val iteratorValue = VariableLValue(irIterator)
irForBlock.statements.add(irIterator) irForBlock.statements.add(irIterator)
val irInnerWhile = val irInnerWhile = IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
IrWhileLoopImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
irInnerWhile.label = getLoopLabel(ktFor) irInnerWhile.label = getLoopLabel(ktFor)
statementGenerator.bodyGenerator.putLoop(ktFor, irInnerWhile) statementGenerator.bodyGenerator.putLoop(ktFor, irInnerWhile)
irForBlock.statements.add(irInnerWhile) irForBlock.statements.add(irInnerWhile)
@@ -173,7 +175,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val irHasNextCall = callGenerator.generateCall(ktLoopRange, hasNextCall, IrStatementOrigin.FOR_LOOP_HAS_NEXT) val irHasNextCall = callGenerator.generateCall(ktLoopRange, hasNextCall, IrStatementOrigin.FOR_LOOP_HAS_NEXT)
irInnerWhile.condition = irHasNextCall irInnerWhile.condition = irHasNextCall
val irInnerBody = IrBlockImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE) val irInnerBody = IrBlockImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
irInnerWhile.body = irInnerBody irInnerWhile.body = irInnerBody
val nextCall = statementGenerator.pregenerateCall(nextResolvedCall) val nextCall = statementGenerator.pregenerateCall(nextResolvedCall)
@@ -92,8 +92,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return IrTypeOperatorCallImpl( return IrTypeOperatorCallImpl(
expression.startOffset, expression.endOffset, resultType, irOperator, rhsType, expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
expression.left.genExpr(), context.symbolTable.referenceClassifier(rhsType.constructor.declarationDescriptor!!),
context.symbolTable.referenceClassifier(rhsType.constructor.declarationDescriptor!!) expression.left.genExpr()
) )
} }
@@ -104,8 +104,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return IrTypeOperatorCallImpl( return IrTypeOperatorCallImpl(
expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator, expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
againstType, expression.leftHandSide.genExpr(), againstType, context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!),
context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!) expression.leftHandSide.genExpr()
) )
} }
@@ -34,7 +34,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
fun generateClassLiteral(ktClassLiteral: KtClassLiteralExpression): IrExpression { fun generateClassLiteral(ktClassLiteral: KtClassLiteralExpression): IrExpression {
val ktArgument = ktClassLiteral.receiverExpression!! val ktArgument = ktClassLiteral.receiverExpression!!
val lhs = getOrFail(BindingContext.DOUBLE_COLON_LHS, ktArgument) val lhs = getOrFail(BindingContext.DOUBLE_COLON_LHS, ktArgument)
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral) val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral).toIrType()
return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) { return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) {
IrGetClassImpl( IrGetClassImpl(
@@ -47,7 +47,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
?: throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration") ?: throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
IrClassReferenceImpl( IrClassReferenceImpl(
ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType, ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
context.symbolTable.referenceClassifier(typeClass), lhs.type context.symbolTable.referenceClassifier(typeClass), lhs.type.toIrType()
) )
} }
} }
@@ -119,7 +119,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it) } val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it) }
return IrLocalDelegatedPropertyReferenceImpl( return IrLocalDelegatedPropertyReferenceImpl(
startOffset, endOffset, type, startOffset, endOffset, type.toIrType(),
variableDescriptor, variableDescriptor,
irDelegateSymbol, getterSymbol, setterSymbol, irDelegateSymbol, getterSymbol, setterSymbol,
origin origin
@@ -142,12 +142,13 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) } val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
return IrPropertyReferenceImpl( return IrPropertyReferenceImpl(
startOffset, endOffset, type, startOffset, endOffset, type.toIrType(),
propertyDescriptor, propertyDescriptor, propertyDescriptor.typeParametersCount,
fieldSymbol, getterSymbol, setterSymbol, fieldSymbol, getterSymbol, setterSymbol,
typeArguments,
origin origin
) ).apply {
putTypeArguments(typeArguments) { it.toIrType()}
}
} }
private fun generateFunctionReference( private fun generateFunctionReference(
@@ -160,9 +161,10 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
origin: IrStatementOrigin? origin: IrStatementOrigin?
): IrFunctionReference = ): IrFunctionReference =
IrFunctionReferenceImpl( IrFunctionReferenceImpl(
startOffset, endOffset, type, startOffset, endOffset, type.toIrType(),
symbol, descriptor, symbol, descriptor, descriptor.typeParametersCount,
typeArguments,
origin origin
) ).apply {
putTypeArguments(typeArguments) { it.toIrType() }
}
} }
@@ -58,7 +58,7 @@ class StatementGenerator(
private val typeTranslator = TypeTranslator(context.moduleDescriptor, context.symbolTable) private val typeTranslator = TypeTranslator(context.moduleDescriptor, context.symbolTable)
private fun KotlinType.toIrType() = typeTranslator.translateType(this) fun KotlinType.toIrType() = typeTranslator.translateType(this)
fun generateStatement(ktElement: KtElement): IrStatement = fun generateStatement(ktElement: KtElement): IrStatement =
ktElement.genStmt() ktElement.genStmt()
@@ -408,4 +408,5 @@ abstract class StatementGeneratorExtension(val statementGenerator: StatementGene
fun KtExpression.genExpr() = statementGenerator.generateExpression(this) fun KtExpression.genExpr() = statementGenerator.generateExpression(this)
fun KtExpression.genStmt() = statementGenerator.generateStatement(this) fun KtExpression.genStmt() = statementGenerator.generateStatement(this)
fun KotlinType.toIrType() = with(statementGenerator) { toIrType() }
} }
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateTryCatch(ktTry: KtTryExpression): IrExpression { fun generateTryCatch(ktTry: KtTryExpression): IrExpression {
val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry) val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry).toIrType()
val irTryCatch = IrTryImpl(ktTry.startOffset, ktTry.endOffset, resultType) val irTryCatch = IrTryImpl(ktTry.startOffset, ktTry.endOffset, resultType)
irTryCatch.tryResult = ktTry.tryBlock.genExpr() irTryCatch.tryResult = ktTry.tryBlock.genExpr()
@@ -14,12 +14,12 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.psi2ir package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
fun IrVariable.defaultLoad(): IrExpression = fun IrVariable.defaultLoad(): IrExpression =
IrGetValueImpl(startOffset, endOffset, symbol) IrGetValueImpl(startOffset, endOffset, type, symbol)
@@ -1,41 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.psi2ir.generators.CallGenerator
import org.jetbrains.kotlin.psi2ir.generators.StatementGenerator
import org.jetbrains.kotlin.types.KotlinType
class OnceCallValue(
val startOffset: Int,
val endOffset: Int,
val statementGenerator: StatementGenerator,
val call: CallBuilder,
val origin: IrStatementOrigin? = null
) : IntermediateValue {
private var instantiated = false
override fun load(): IrExpression {
if (instantiated) throw AssertionError("Value for call ${call.descriptor} has already been instantiated")
instantiated = true
return CallGenerator(statementGenerator).generateCall(startOffset, endOffset, call, origin)
}
override val type: KotlinType get() = call.descriptor.returnType!!
}
@@ -17,17 +17,18 @@
package org.jetbrains.kotlin.psi2ir.intermediate package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
abstract class ExpressionValue(override val type: KotlinType) : IntermediateValue abstract class ExpressionValue(override val type: IrType) : IntermediateValue
inline fun generateExpressionValue(type: KotlinType, crossinline generate: () -> IrExpression) = inline fun generateExpressionValue(type: IrType, crossinline generate: () -> IrExpression) =
object : ExpressionValue(type) { object : ExpressionValue(type) {
override fun load(): IrExpression = generate() override fun load(): IrExpression = generate()
} }
inline fun generateDelegatedValue(type: KotlinType, crossinline generateValue: () -> IntermediateValue) = inline fun generateDelegatedValue(type: IrType, crossinline generateValue: () -> IntermediateValue) =
object : ExpressionValue(type) { object : ExpressionValue(type) {
val lazyDelegate by lazy { generateValue() } val lazyDelegate by lazy { generateValue() }
override fun load(): IrExpression = lazyDelegate.load() override fun load(): IrExpression = lazyDelegate.load()
@@ -42,7 +43,7 @@ class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentRe
return irExpression return irExpression
} }
override val type: KotlinType get() = irExpression.type override val type: IrType get() = irExpression.type
override fun store(irExpression: IrExpression): IrExpression { override fun store(irExpression: IrExpression): IrExpression {
throw AssertionError("Expression value ${irExpression.render()} can't be used in store operation") throw AssertionError("Expression value ${irExpression.render()} can't be used in store operation")
@@ -20,10 +20,11 @@ import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
class RematerializableValue(val irExpression: IrExpressionWithCopy) : IntermediateValue { class RematerializableValue(val irExpression: IrExpressionWithCopy) : IntermediateValue {
override val type: KotlinType get() = irExpression.type override val type: IrType get() = irExpression.type
override fun load(): IrExpression = irExpression.copy() override fun load(): IrExpression = irExpression.copy()
} }
@@ -17,9 +17,10 @@
package org.jetbrains.kotlin.psi2ir.intermediate package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
class TransientReceiverValue(override val type: KotlinType) : IntermediateValue { class TransientReceiverValue(override val type: IrType) : IntermediateValue {
override fun load(): IrExpression { override fun load(): IrExpression {
throw AssertionError("Transient receiver should not be instantiated") throw AssertionError("Transient receiver should not be instantiated")
} }
@@ -17,12 +17,13 @@
package org.jetbrains.kotlin.psi2ir.intermediate package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
interface IntermediateValue { interface IntermediateValue {
fun load(): IrExpression fun load(): IrExpression
fun loadIfExists(): IrExpression? = load() fun loadIfExists(): IrExpression? = load()
val type: KotlinType val type: IrType
} }
interface LValue : IntermediateValue { interface LValue : IntermediateValue {
@@ -229,9 +229,13 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
?: throw AssertionError("No declaration for target type: $targetType") ?: throw AssertionError("No declaration for target type: $targetType")
return IrTypeOperatorCallImpl( return IrTypeOperatorCallImpl(
startOffset, endOffset, startOffset,
targetType, typeOperator, targetType, this, endOffset,
resolveScopedTypeParameter(typeDescriptor) ?: symbolTable.referenceClassifier(typeDescriptor) targetType,
typeOperator,
targetType,
resolveScopedTypeParameter(typeDescriptor) ?: symbolTable.referenceClassifier(typeDescriptor),
this
) )
} }
@@ -243,8 +247,8 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
else else
IrTypeOperatorCallImpl( IrTypeOperatorCallImpl(
startOffset, endOffset, builtIns.unitType, startOffset, endOffset, builtIns.unitType,
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this, IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, symbolTable.referenceClass(builtIns.unit),
symbolTable.referenceClass(builtIns.unit) this
) )
} }
@@ -1,17 +1,6 @@
/* /*
* Copyright 2010-2016 JetBrains s.r.o. * 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.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ */
package org.jetbrains.kotlin.ir.builders package org.jetbrains.kotlin.ir.builders
@@ -24,7 +13,8 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.utils.addToStdlib.assertedCast import org.jetbrains.kotlin.utils.addToStdlib.assertedCast
@@ -87,7 +77,8 @@ fun IrBuilderWithScope.irExprBody(value: IrExpression) =
fun IrBuilderWithScope.irReturn(value: IrExpression) = fun IrBuilderWithScope.irReturn(value: IrExpression) =
IrReturnImpl( IrReturnImpl(
startOffset, endOffset, context.builtIns.nothingType, startOffset, endOffset,
context.irBuiltIns.nothingType,
scope.scopeOwnerSymbol.assertedCast<IrReturnTargetSymbol> { scope.scopeOwnerSymbol.assertedCast<IrReturnTargetSymbol> {
"Function scope expected: ${scope.scopeOwner}" "Function scope expected: ${scope.scopeOwner}"
}, },
@@ -95,37 +86,37 @@ fun IrBuilderWithScope.irReturn(value: IrExpression) =
) )
fun IrBuilderWithScope.irReturnTrue() = fun IrBuilderWithScope.irReturnTrue() =
irReturn(IrConstImpl(startOffset, endOffset, context.builtIns.booleanType, IrConstKind.Boolean, true)) irReturn(IrConstImpl(startOffset, endOffset, context.irBuiltIns.booleanType, IrConstKind.Boolean, true))
fun IrBuilderWithScope.irReturnFalse() = fun IrBuilderWithScope.irReturnFalse() =
irReturn(IrConstImpl(startOffset, endOffset, context.builtIns.booleanType, IrConstKind.Boolean, false)) irReturn(IrConstImpl(startOffset, endOffset, context.irBuiltIns.booleanType, IrConstKind.Boolean, false))
fun IrBuilderWithScope.irIfThenElse(type: KotlinType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression) = fun IrBuilderWithScope.irIfThenElse(type: IrType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
IrIfThenElseImpl(startOffset, endOffset, type, condition, thenPart, elsePart) IrIfThenElseImpl(startOffset, endOffset, type, condition, thenPart, elsePart)
fun IrBuilderWithScope.irIfNull(type: KotlinType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) = fun IrBuilderWithScope.irIfNull(type: IrType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart) irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart)
fun IrBuilderWithScope.irThrowNpe(origin: IrStatementOrigin) = fun IrBuilderWithScope.irThrowNpe(origin: IrStatementOrigin) =
IrNullaryPrimitiveImpl(startOffset, endOffset, origin, context.irBuiltIns.throwNpeSymbol) IrNullaryPrimitiveImpl(startOffset, endOffset, context.irBuiltIns.nothingType, origin, context.irBuiltIns.throwNpeSymbol)
fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) = fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnTrue()) IrIfThenElseImpl(startOffset, endOffset, context.irBuiltIns.unitType, condition, irReturnTrue())
fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) = fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) =
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnFalse()) IrIfThenElseImpl(startOffset, endOffset, context.irBuiltIns.unitType, condition, irReturnFalse())
fun IrBuilderWithScope.irGet(variable: IrValueSymbol) = fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
IrGetValueImpl(startOffset, endOffset, variable) IrGetValueImpl(startOffset, endOffset, type, variable)
fun IrBuilderWithScope.irSetVar(variable: IrVariableSymbol, value: IrExpression) = fun IrBuilderWithScope.irSetVar(variable: IrVariableSymbol, value: IrExpression) =
IrSetVariableImpl(startOffset, endOffset, variable, value, IrStatementOrigin.EQ) IrSetVariableImpl(startOffset, endOffset, context.irBuiltIns.unitType, variable, value, IrStatementOrigin.EQ)
fun IrBuilderWithScope.irEqeqeq(arg1: IrExpression, arg2: IrExpression) = fun IrBuilderWithScope.irEqeqeq(arg1: IrExpression, arg2: IrExpression) =
context.eqeqeq(startOffset, endOffset, arg1, arg2) context.eqeqeq(startOffset, endOffset, arg1, arg2)
fun IrBuilderWithScope.irNull() = fun IrBuilderWithScope.irNull() =
IrConstImpl.constNull(startOffset, endOffset, context.builtIns.nullableNothingType) IrConstImpl.constNull(startOffset, endOffset, context.irBuiltIns.nothingNType)
fun IrBuilderWithScope.irEqualsNull(argument: IrExpression) = fun IrBuilderWithScope.irEqualsNull(argument: IrExpression) =
primitiveOp2( primitiveOp2(
@@ -142,35 +133,23 @@ fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) =
) )
) )
fun IrBuilderWithScope.irGet(receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall = fun IrBuilderWithScope.irGet(type: IrType, receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall =
IrGetterCallImpl(startOffset, endOffset, getterSymbol, getterSymbol.descriptor, null, receiver, null, IrStatementOrigin.GET_PROPERTY) IrGetterCallImpl(
startOffset, endOffset,
type,
getterSymbol, getterSymbol.descriptor,
typeArgumentsCount = 0,
dispatchReceiver = receiver,
extensionReceiver = null,
origin = IrStatementOrigin.GET_PROPERTY
)
fun IrBuilderWithScope.irCall( fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, type: IrType): IrCall =
callee: IrFunctionSymbol, IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor)
type: KotlinType,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
): IrCall =
IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor, typeArguments)
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol): IrCall =
irCall(callee, callee.descriptor.returnType!!)
fun IrBuilderWithScope.irCall(
calleeSymbol: IrFunctionSymbol,
calleeDescriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
): IrCall =
IrCallImpl(startOffset, endOffset, calleeDescriptor.returnType!!, calleeSymbol, calleeDescriptor, typeArguments)
fun IrBuilderWithScope.irCallOp(callee: IrFunctionSymbol, dispatchReceiver: IrExpression, argument: IrExpression): IrCall =
irCall(callee, callee.descriptor.returnType!!).apply {
this.dispatchReceiver = dispatchReceiver
putValueArgument(0, argument)
}
fun IrBuilderWithScope.irCallOp( fun IrBuilderWithScope.irCallOp(
callee: IrFunctionSymbol, callee: IrFunctionSymbol,
type: KotlinType, type: IrType,
dispatchReceiver: IrExpression, dispatchReceiver: IrExpression,
argument: IrExpression argument: IrExpression
): IrCall = ): IrCall =
@@ -179,47 +158,35 @@ fun IrBuilderWithScope.irCallOp(
putValueArgument(0, argument) putValueArgument(0, argument)
} }
@Deprecated("Creates unbound symbol") fun IrBuilderWithScope.typeOperator(
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType) = resultType: IrType,
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument) argument: IrExpression,
typeOperator: IrTypeOperator,
typeOperand: IrType
) =
IrTypeOperatorCallImpl(startOffset, endOffset, resultType, typeOperator, typeOperand, typeOperand.classifierOrFail, argument)
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) = fun IrBuilderWithScope.irIs(argument: IrExpression, type: IrType) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument, typeClassifier) typeOperator(context.irBuiltIns.booleanType, argument, IrTypeOperator.INSTANCEOF, type)
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: IrType) =
typeOperator(context.irBuiltIns.booleanType, argument, IrTypeOperator.NOT_INSTANCEOF, type)
@Deprecated("Creates unbound symbol") fun IrBuilderWithScope.irAs(argument: IrExpression, type: IrType) =
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType) = IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, type.classifierOrFail, argument)
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.NOT_INSTANCEOF, type, argument)
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) = fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: IrType) =
IrTypeOperatorCallImpl( IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, type.classifierOrFail, argument)
startOffset, endOffset,
context.builtIns.booleanType,
IrTypeOperator.NOT_INSTANCEOF,
type, argument, typeClassifier
)
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: IrType, typeClassifier: IrClassifierSymbol) =
@Deprecated("Creates unbound symbol") IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, type.classifierOrFail, argument)
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument)
fun IrBuilderWithScope.irAs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, argument, typeClassifier)
@Deprecated("Creates unbound symbol")
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument)
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, argument, typeClassifier)
fun IrBuilderWithScope.irInt(value: Int) = fun IrBuilderWithScope.irInt(value: Int) =
IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, value) IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, value)
fun IrBuilderWithScope.irString(value: String) = fun IrBuilderWithScope.irString(value: String) =
IrConstImpl.string(startOffset, endOffset, context.builtIns.stringType, value) IrConstImpl.string(startOffset, endOffset, context.irBuiltIns.stringType, value)
fun IrBuilderWithScope.irConcat() = fun IrBuilderWithScope.irConcat() =
IrStringConcatenationImpl(startOffset, endOffset, context.builtIns.stringType) IrStringConcatenationImpl(startOffset, endOffset, context.irBuiltIns.stringType)
@@ -25,7 +25,8 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.* import java.util.*
abstract class IrBuilder( abstract class IrBuilder(
@@ -78,10 +79,12 @@ open class IrBlockBodyBuilder(
} }
class IrBlockBuilder( class IrBlockBuilder(
context: IrGeneratorContext, scope: Scope, context: IrGeneratorContext,
startOffset: Int, endOffset: Int, scope: Scope,
startOffset: Int,
endOffset: Int,
val origin: IrStatementOrigin? = null, val origin: IrStatementOrigin? = null,
var resultType: KotlinType? = null var resultType: IrType? = null
) : IrStatementsBuilder<IrBlock>(context, scope, startOffset, endOffset) { ) : IrStatementsBuilder<IrBlock>(context, scope, startOffset, endOffset) {
private val statements = ArrayList<IrStatement>() private val statements = ArrayList<IrStatement>()
@@ -95,22 +98,25 @@ class IrBlockBuilder(
} }
override fun doBuild(): IrBlock { override fun doBuild(): IrBlock {
val resultType = this.resultType ?: (statements.lastOrNull() as? IrExpression)?.type ?: context.builtIns.unitType val resultType = this.resultType
?: statements.lastOrNull().safeAs<IrExpression>()?.type
?: context.irBuiltIns.unitType
val irBlock = IrBlockImpl(startOffset, endOffset, resultType, origin) val irBlock = IrBlockImpl(startOffset, endOffset, resultType, origin)
irBlock.statements.addAll(statements) irBlock.statements.addAll(statements)
return irBlock return irBlock
} }
} }
fun <T : IrBuilder> T.at(startOffset: Int, endOffset: Int): T { fun <T : IrBuilder> T.at(startOffset: Int, endOffset: Int) = apply {
this.startOffset = startOffset this.startOffset = startOffset
this.endOffset = endOffset this.endOffset = endOffset
return this
} }
inline fun IrGeneratorWithScope.irBlock( inline fun IrGeneratorWithScope.irBlock(
startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET, startOffset: Int = UNDEFINED_OFFSET,
origin: IrStatementOrigin? = null, resultType: KotlinType? = null, endOffset: Int = UNDEFINED_OFFSET,
origin: IrStatementOrigin? = null,
resultType: IrType? = null,
body: IrBlockBuilder.() -> Unit body: IrBlockBuilder.() -> Unit
): IrExpression = ): IrExpression =
IrBlockBuilder( IrBlockBuilder(
@@ -129,3 +135,4 @@ inline fun IrGeneratorWithScope.irBlockBody(
startOffset, startOffset,
endOffset endOffset
).blockBody(body) ).blockBody(body)
@@ -87,8 +87,8 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns, outerSymbolTable: SymbolTable?) {
val anyNType = anyType.withHasQuestionMark(true) val anyNType = anyType.withHasQuestionMark(true)
val bool = builtIns.booleanType val bool = builtIns.booleanType
val boolType = bool.toIrType() val booleanType = bool.toIrType()
val boolClass = builtIns.boolean.toIrSymbol() val booleanClass = builtIns.boolean.toIrSymbol()
val char = builtIns.charType val char = builtIns.charType
val charType = char.toIrType() val charType = char.toIrType()
@@ -151,7 +151,7 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns, outerSymbolTable: SymbolTable?) {
val throwNpeFun = defineOperator("THROW_NPE", nothing, listOf()) val throwNpeFun = defineOperator("THROW_NPE", nothing, listOf())
val throwCceFun = defineOperator("THROW_CCE", nothing, listOf()) val throwCceFun = defineOperator("THROW_CCE", nothing, listOf())
val booleanNotFun = defineOperator("NOT", bool, listOf(bool)) val booleanNotFun = defineOperator("NOT", bool, listOf(bool))
val noWhenBranchMatchedExceptionFun = defineOperator("noWhenBranchMatchedException", unit, listOf()) val noWhenBranchMatchedExceptionFun = defineOperator("noWhenBranchMatchedException", nothing, listOf())
val eqeqeq = eqeqeqFun.descriptor val eqeqeq = eqeqeqFun.descriptor
val eqeq = eqeqFun.descriptor val eqeq = eqeqFun.descriptor
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType
interface IrMemberAccessExpression : IrExpression { interface IrMemberAccessExpression : IrExpression {
var dispatchReceiver: IrExpression? var dispatchReceiver: IrExpression?
@@ -49,7 +50,17 @@ fun IrMemberAccessExpression.copyTypeArgumentsFrom(other: IrMemberAccessExpressi
} }
} }
val CallableDescriptor.typeArgumentsCount: Int inline fun IrMemberAccessExpression.putTypeArguments(
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
toIrType: (KotlinType) -> IrType
) {
if (typeArguments == null) return
for ((typeParameter, typeArgument) in typeArguments) {
putTypeArgument(typeParameter.index, toIrType(typeArgument))
}
}
val CallableDescriptor.typeParametersCount: Int
get() = get() =
when (this) { when (this) {
is PropertyAccessorDescriptor -> correspondingProperty.typeParameters.size is PropertyAccessorDescriptor -> correspondingProperty.typeParameters.size
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.typeArgumentsCount import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
@@ -54,7 +54,7 @@ class IrCallImpl(
descriptor: FunctionDescriptor, descriptor: FunctionDescriptor,
origin: IrStatementOrigin? = null, origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, type, symbol, descriptor, descriptor.typeArgumentsCount, origin, superQualifierSymbol) ) : this(startOffset, endOffset, type, symbol, descriptor, descriptor.typeParametersCount, origin, superQualifierSymbol)
@Deprecated("Creates unbound symbols") @Deprecated("Creates unbound symbols")
constructor( constructor(
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
@@ -40,6 +41,14 @@ class IrDelegatingConstructorCallImpl(
), ),
IrDelegatingConstructorCall { IrDelegatingConstructorCall {
constructor(
startOffset: Int,
endOffset: Int,
type: IrType,
symbol: IrConstructorSymbol,
descriptor: ClassConstructorDescriptor
) : this(startOffset, endOffset, type, symbol, descriptor, descriptor.typeParametersCount)
@Deprecated("Creates unbound symbol") @Deprecated("Creates unbound symbol")
constructor( constructor(
startOffset: Int, startOffset: Int,
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
import org.jetbrains.kotlin.ir.expressions.typeParametersCount
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
@@ -39,6 +40,13 @@ class IrEnumConstructorCallImpl(
), ),
IrEnumConstructorCall { IrEnumConstructorCall {
constructor(
startOffset: Int,
endOffset: Int,
type: IrType,
symbol: IrConstructorSymbol
) : this(startOffset, endOffset, type, symbol, symbol.descriptor.typeParametersCount)
@Deprecated("Creates unbound symbols") @Deprecated("Creates unbound symbols")
constructor( constructor(
startOffset: Int, startOffset: Int,
@@ -68,8 +68,8 @@ class IrGetFieldImpl(
this( this(
startOffset, endOffset, startOffset, endOffset,
IrFieldSymbolImpl(propertyDescriptor), IrFieldSymbolImpl(propertyDescriptor),
receiver,
type, type,
receiver,
origin, origin,
createClassSymbolOrNull(superQualifier) createClassSymbolOrNull(superQualifier)
) )
@@ -78,8 +78,8 @@ class IrGetFieldImpl(
constructor( constructor(
startOffset: Int, endOffset: Int, startOffset: Int, endOffset: Int,
symbol: IrFieldSymbol, symbol: IrFieldSymbol,
receiver: IrExpression?,
type: IrType, type: IrType,
receiver: IrExpression?,
origin: IrStatementOrigin? = null, origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, type, origin, superQualifierSymbol) { ) : this(startOffset, endOffset, symbol, type, origin, superQualifierSymbol) {
@@ -43,8 +43,8 @@ class IrTypeOperatorCallImpl(
type: IrType, type: IrType,
operator: IrTypeOperator, operator: IrTypeOperator,
typeOperand: IrType, typeOperand: IrType,
argument: IrExpression, typeOperandClassifier: IrClassifierSymbol,
typeOperandClassifier: IrClassifierSymbol argument: IrExpression
) : this(startOffset, endOffset, type, operator, typeOperand) { ) : this(startOffset, endOffset, type, operator, typeOperand) {
this.argument = argument this.argument = argument
this.typeOperandClassifier = typeOperandClassifier this.typeOperandClassifier = typeOperandClassifier
@@ -541,7 +541,6 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.type, expression.type,
expression.operator, expression.operator,
expression.typeOperand, expression.typeOperand,
expression.argument.transform(),
run { run {
val oldTypeDescriptor = expression.typeOperandClassifier.descriptor val oldTypeDescriptor = expression.typeOperandClassifier.descriptor
val newTypeDescriptor = mapClassifierReference(oldTypeDescriptor) val newTypeDescriptor = mapClassifierReference(oldTypeDescriptor)
@@ -549,7 +548,8 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.typeOperandClassifier expression.typeOperandClassifier
else else
createUnboundClassifierSymbol(newTypeDescriptor) createUnboundClassifierSymbol(newTypeDescriptor)
} },
expression.argument.transform()
) )
override fun visitWhen(expression: IrWhen): IrWhen = override fun visitWhen(expression: IrWhen): IrWhen =
@@ -469,8 +469,8 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
expression.type, expression.type,
expression.operator, expression.operator,
expression.typeOperand, expression.typeOperand,
expression.argument.transform(), symbolRemapper.getReferencedClassifier(expression.typeOperandClassifier),
symbolRemapper.getReferencedClassifier(expression.typeOperandClassifier) expression.argument.transform()
) )
override fun visitWhen(expression: IrWhen): IrWhen = override fun visitWhen(expression: IrWhen): IrWhen =