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.startOffset
class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
class AnonymousInitializerGenerator(
declarationGenerator: DeclarationGenerator
) : DeclarationGeneratorExtension(declarationGenerator) {
fun generateAnonymousInitializerDeclaration(
ktAnonymousInitializer: KtAnonymousInitializer,
classDescriptor: ClassDescriptor
@@ -46,18 +46,20 @@ fun StatementGenerator.generateReceiverOrNull(ktDefaultElement: KtElement, recei
fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: ReceiverValue): IntermediateValue =
generateReceiver(ktDefaultElement.startOffset, ktDefaultElement.endOffset, receiver)
fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue =
if (receiver is TransientReceiver)
TransientReceiverValue(receiver.type)
else generateDelegatedValue(receiver.type) {
val receiverExpression = when (receiver) {
fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue {
val irReceiverType = receiver.type.toIrType()
if (receiver is TransientReceiver) return TransientReceiverValue(irReceiverType)
return generateDelegatedValue(irReceiverType) {
val receiverExpression: IrExpression = when (receiver) {
is ImplicitClassReceiver -> {
val receiverClassDescriptor = receiver.classDescriptor
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
else
IrGetValueImpl(
defaultStartOffset, defaultEndOffset,
defaultStartOffset, defaultEndOffset, irReceiverType,
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
)
}
@@ -69,12 +71,12 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
generateExpression(receiver.expression)
is ClassValueReceiver ->
IrGetObjectValueImpl(
receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
receiver.expression.startOffset, receiver.expression.endOffset, irReceiverType,
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor)
)
is ExtensionReceiver ->
IrGetValueImpl(
defaultStartOffset, defaultStartOffset,
defaultStartOffset, defaultStartOffset, irReceiverType,
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
)
else ->
@@ -86,33 +88,37 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
else
OnceExpressionValue(receiverExpression)
}
}
fun StatementGenerator.generateSingletonReference(
descriptor: ClassDescriptor,
startOffset: Int,
endOffset: Int,
type: KotlinType
): IrDeclarationReference =
when {
): IrDeclarationReference {
val irType = type.toIrType()
return when {
DescriptorUtils.isObject(descriptor) ->
IrGetObjectValueImpl(
startOffset, endOffset, type,
startOffset, endOffset, irType,
context.symbolTable.referenceClass(descriptor)
)
DescriptorUtils.isEnumEntry(descriptor) ->
IrGetEnumValueImpl(
startOffset, endOffset, type,
startOffset, endOffset, irType,
context.symbolTable.referenceEnumEntry(descriptor)
)
else -> {
val companionObjectDescriptor = descriptor.companionObjectDescriptor
?: throw java.lang.AssertionError("Class value without companion object: $descriptor")
IrGetObjectValueImpl(
startOffset, endOffset, type,
startOffset, endOffset, irType,
context.symbolTable.referenceClass(companionObjectDescriptor)
)
}
}
}
private fun StatementGenerator.shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor: ClassDescriptor): Boolean {
return receiverClassDescriptor.kind.isSingleton &&
@@ -126,6 +132,7 @@ private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverVal
val ktReceiver = expressionReceiver.expression
return IrGetValueImpl(
ktReceiver.startOffset, ktReceiver.endOffset,
expressionReceiver.type.toIrType(),
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter)
)
}
@@ -192,7 +199,7 @@ private fun StatementGenerator.generateReceiverForCalleeImportedFromObject(
calleeDescriptor: ImportedFromObjectCallableDescriptor<*>
): ExpressionValue {
val objectDescriptor = calleeDescriptor.containingObject
val objectType = objectDescriptor.defaultType
val objectType = objectDescriptor.defaultType.toIrType()
return generateExpressionValue(objectType) {
IrGetObjectValueImpl(
startOffset, endOffset, objectType,
@@ -219,7 +226,7 @@ fun StatementGenerator.generateVarargExpression(
val varargElementType =
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) {
val ktArgumentExpression = argument.getArgumentExpression()
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
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.irTemporary
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
class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateAssignment(expression: KtBinaryExpression): IrExpression {
val ktLeft = expression.left!!
val irRhs = expression.right!!.genExpr()
fun generateAssignment(ktExpression: KtBinaryExpression): IrExpression {
val ktLeft = ktExpression.left!!
val irRhs = ktExpression.right!!.genExpr()
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, IrStatementOrigin.EQ)
return irAssignmentReceiver.assign(irRhs)
}
fun generateAugmentedAssignment(expression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(expression)!!
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, expression) ?: false
val ktLeft = expression.left!!
val ktRight = expression.right!!
fun generateAugmentedAssignment(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(ktExpression)!!
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, ktExpression) ?: false
val ktLeft = ktExpression.left!!
val ktRight = ktExpression.right!!
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, origin)
return irAssignmentReceiver.assign { irLValue ->
val opCall = statementGenerator.pregenerateCallReceivers(opResolvedCall)
opCall.setExplicitReceiverValue(irLValue)
opCall.irValueArgumentsByIndex[0] = ktRight.genExpr()
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin)
val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
if (isSimpleAssignment) {
// Set( Op( Get(), RHS ) )
@@ -65,35 +66,35 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
}
}
fun generatePrefixIncrementDecrement(expression: KtPrefixExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(expression)!!
val ktBaseExpression = expression.baseExpression!!
fun generatePrefixIncrementDecrement(ktExpression: KtPrefixExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(ktExpression)!!
val ktBaseExpression = ktExpression.baseExpression!!
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, origin)
return irAssignmentReceiver.assign { irLValue ->
irBlock(expression, origin, irLValue.type) {
irBlock(ktExpression.startOffset, ktExpression.endOffset, origin, irLValue.type) {
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
opCall.setExplicitReceiverValue(irLValue)
val irOpCall = CallGenerator(statementGenerator).generateCall(expression, opCall, origin)
val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin)
+irLValue.store(irOpCall)
+irLValue.load()
}
}
}
fun generatePostfixIncrementDecrement(expression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(expression)!!
val ktBaseExpression = expression.baseExpression!!
fun generatePostfixIncrementDecrement(ktExpression: KtPostfixExpression, origin: IrStatementOrigin): IrExpression {
val opResolvedCall = getResolvedCall(ktExpression)!!
val ktBaseExpression = ktExpression.baseExpression!!
val irAssignmentReceiver = generateAssignmentReceiver(ktBaseExpression, origin)
return irAssignmentReceiver.assign { irLValue ->
irBlock(expression, origin, irLValue.type) {
irBlock(ktExpression.startOffset, ktExpression.endOffset, origin, irLValue.type) {
val temporary = irTemporary(irLValue.load())
val opCall = statementGenerator.pregenerateCall(opResolvedCall)
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)
+irGet(temporary.symbol)
+irGet(temporary.type, temporary.symbol)
}
}
}
@@ -162,9 +163,12 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
): AssignmentReceiver =
if (isValInitializationInConstructor(descriptor, resolvedCall)) {
val thisClass = getThisClass()
val thisAsReceiverParameter = thisClass.thisAsReceiverParameter
val thisType = thisAsReceiverParameter.type.toIrType()
val irThis = IrGetValueImpl(
ktLeft.startOffset, ktLeft.endOffset,
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
thisType,
context.symbolTable.referenceValueParameter(thisAsReceiverParameter)
)
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
} else {
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
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.calls.model.ResolvedCall
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassOrAny
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
class BodyGenerator(
val scopeOwnerSymbol: IrSymbol,
override val context: GeneratorContext
) : GeneratorWithScope {
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)
private val loopTable = HashMap<KtLoopExpression, IrLoop>()
@@ -85,7 +91,7 @@ class BodyGenerator(
generateReturnExpression(
ktBody.startOffset, ktBody.endOffset,
IrGetObjectValueImpl(
ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType,
ktBody.startOffset, ktBody.endOffset, context.irBuiltIns.unitType,
context.symbolTable.referenceClass(context.builtIns.unit)
)
)
@@ -115,7 +121,7 @@ class BodyGenerator(
private fun generateReturnExpression(startOffset: Int, endOffset: Int, returnValue: IrExpression): IrReturnImpl {
val returnTarget = (scopeOwner as? CallableDescriptor) ?: throw AssertionError("'return' in a non-callable: $scopeOwner")
return IrReturnImpl(
startOffset, endOffset, context.builtIns.nothingType,
startOffset, endOffset, context.irBuiltIns.nothingType,
context.symbolTable.referenceFunction(returnTarget),
returnValue
)
@@ -177,7 +183,8 @@ class BodyGenerator(
irBlockBody.statements.add(
IrInstanceInitializerCallImpl(
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
context.symbolTable.referenceClass(classDescriptor)
context.symbolTable.referenceClass(classDescriptor),
context.irBuiltIns.unitType
)
)
@@ -193,7 +200,8 @@ class BodyGenerator(
irBlockBody.statements.add(
IrInstanceInitializerCallImpl(
ktConstructor.startOffset, ktConstructor.endOffset,
context.symbolTable.referenceClass(classDescriptor)
context.symbolTable.referenceClass(classDescriptor),
context.irBuiltIns.unitType
)
)
@@ -248,9 +256,9 @@ class BodyGenerator(
irBlockBody.statements.add(
IrDelegatingConstructorCallImpl(
ktElement.startOffset, ktElement.endOffset,
context.irBuiltIns.unitType,
context.symbolTable.referenceConstructor(anyConstructor),
anyConstructor,
null
anyConstructor
)
)
}
@@ -264,9 +272,12 @@ class BodyGenerator(
irBlockBody.statements.add(
IrEnumConstructorCallImpl(
ktElement.startOffset, ktElement.endOffset,
context.irBuiltIns.unitType,
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!!
return IrEnumConstructorCallImpl(
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
context.irBuiltIns.unitType,
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.expressions.*
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.psiUtil.endOffset
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.intermediate.defaultLoad
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.SmartList
class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateIfExpression(expression: KtIfExpression): IrExpression {
val resultType = getInferredTypeWithImplicitCastsOrFail(expression)
val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType()
var ktLastIf: KtIfExpression = expression
val irBranches = SmartList<IrBranch>()
@@ -63,7 +65,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
ktIf: KtIfExpression,
irBranches: List<IrBranch>,
irElseResult: IrExpression?,
resultType: KotlinType
resultType: IrType
): IrWhen {
if (irBranches.size == 1) {
return IrIfThenElseImpl(
@@ -77,12 +79,18 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
irWhen.branches.addAll(irBranches)
irElseResult?.let {
irWhen.branches.add(IrBranchImpl.elseBranch(it))
irWhen.branches.add(elseBranch(it))
}
return irWhen
}
private fun elseBranch(result: IrExpression) =
IrElseBranchImpl(
IrConstImpl.boolean(result.startOffset, result.endOffset, context.irBuiltIns.booleanType, true),
result
)
fun generateWhenExpression(expression: KtWhenExpression): IrExpression {
val irSubject = generateWhenSubject(expression)
@@ -93,9 +101,9 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
val isExhaustive = expression.isExhaustiveWhen()
val resultType = when {
isUsedAsExpression -> inferredType
isExhaustive && KotlinBuiltIns.isNothing(inferredType) -> inferredType
else -> context.builtIns.unitType
isUsedAsExpression -> inferredType.toIrType()
KotlinBuiltIns.isNothing(inferredType) -> inferredType.toIrType()
else -> context.irBuiltIns.unitType
}
val irWhen = IrWhenImpl(expression.startOffset, expression.endOffset, resultType, IrStatementOrigin.WHEN)
@@ -103,7 +111,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
for (ktEntry in expression.entries) {
if (ktEntry.isElse) {
val irElseResult = ktEntry.expression!!.genExpr()
irWhen.branches.add(IrBranchImpl.elseBranch(irElseResult))
irWhen.branches.add(elseBranch(irElseResult))
break
}
@@ -141,8 +149,12 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
val isExhaustive = whenExpression.isExhaustiveWhen()
if (isExhaustive) {
val call = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.noWhenBranchMatchedExceptionSymbol)
irWhen.branches.add(IrBranchImpl.elseBranch(call))
val call = IrCallImpl(
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 =
if (irSubject == null) {
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
irWhen
} else {
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
} else {
@@ -189,13 +201,13 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
private fun generateIsPatternCondition(irSubject: IrVariable, ktCondition: KtWhenConditionIsPattern): IrExpression {
val typeOperand = getOrFail(BindingContext.TYPE, ktCondition.typeReference)
val typeOperandDescriptor = typeOperand.constructor.declarationDescriptor
?: throw AssertionError("No declaration descriptor for type $typeOperand")
val typeOperandSymbol = context.symbolTable.referenceClassifier(typeOperandDescriptor)
val irTypeOperand = typeOperand.toIrType()
val typeSymbol = irTypeOperand.classifierOrNull ?: throw AssertionError("Not a classifier type: $typeOperand")
return IrTypeOperatorCallImpl(
ktCondition.startOffset, ktCondition.endOffset, context.builtIns.booleanType,
IrTypeOperator.INSTANCEOF, typeOperand, irSubject.defaultLoad(), typeOperandSymbol
ktCondition.startOffset, ktCondition.endOffset,
context.irBuiltIns.booleanType,
IrTypeOperator.INSTANCEOF, irTypeOperand, typeSymbol,
irSubject.defaultLoad()
)
}
@@ -210,6 +222,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
IrStatementOrigin.NOT_IN ->
IrUnaryPrimitiveImpl(
ktCondition.startOffset, ktCondition.endOffset,
context.irBuiltIns.booleanType,
IrStatementOrigin.EXCL, context.irBuiltIns.booleanNotSymbol,
irInCall
)
@@ -19,9 +19,7 @@ package org.jetbrains.kotlin.psi2ir.generators
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.psiUtil.endOffset
@@ -73,7 +71,8 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
is SyntheticFieldDescriptor -> {
val receiver = statementGenerator.generateBackingFieldReceiver(startOffset, endOffset, resolvedCall, descriptor)
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 ->
generateGetVariable(startOffset, endOffset, descriptor, getTypeArguments(resolvedCall), origin)
@@ -93,21 +92,29 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val getterDescriptor = descriptor.getter!!
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
IrCallImpl(
startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor,
typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY
)
startOffset, endOffset, descriptor.type.toIrType(), getterSymbol, getterDescriptor,
origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY
).apply {
putTypeArguments(typeArguments) { it.toIrType() }
}
} 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 =
call.callReceiver.call { dispatchReceiver, extensionReceiver ->
val descriptor = call.descriptor as? ClassConstructorDescriptor
?: throw AssertionError("Class constructor expected: ${call.descriptor}")
val constructorSymbol = context.symbolTable.referenceConstructor(descriptor.original)
val irCall =
IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, call.typeArguments)
irCall.dispatchReceiver = dispatchReceiver?.load()
irCall.extensionReceiver = extensionReceiver?.load()
val irCall = IrDelegatingConstructorCallImpl(
startOffset, endOffset,
descriptor.returnType.toIrType(),
constructorSymbol,
descriptor
).apply {
putTypeArguments(call.typeArguments) { it.toIrType() }
this.dispatchReceiver = dispatchReceiver?.load()
this.extensionReceiver = extensionReceiver?.load()
}
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 (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver")
val constructorSymbol = context.symbolTable.referenceConstructor(constructorDescriptor.original)
val irCall = IrEnumConstructorCallImpl(
startOffset, endOffset,
constructorSymbol,
call.typeArguments
)
val irCall = IrEnumConstructorCallImpl(startOffset, endOffset, constructorDescriptor.returnType.toIrType(), constructorSymbol)
addParametersToCall(startOffset, endOffset, call, irCall, constructorDescriptor.returnType)
}
}
@@ -144,19 +147,24 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
IrGetterCallImpl(
startOffset, endOffset,
descriptor.type.toIrType(),
getterSymbol,
getterDescriptor,
call.typeArguments,
descriptor.typeParametersCount,
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
IrStatementOrigin.GET_PROPERTY,
superQualifierSymbol
)
).apply {
putTypeArguments(call.typeArguments) { it.toIrType() }
}
} else {
val fieldSymbol = context.symbolTable.referenceField(descriptor.original)
IrGetFieldImpl(
startOffset, endOffset,
fieldSymbol,
descriptor.type.toIrType(),
dispatchReceiverValue?.load(),
IrStatementOrigin.GET_PROPERTY,
superQualifierSymbol
@@ -178,16 +186,16 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
val irCall = IrCallImpl(
startOffset, endOffset,
returnType,
returnType.toIrType(),
functionSymbol,
functionDescriptor,
call.typeArguments,
origin,
superQualifierSymbol
)
irCall.dispatchReceiver = dispatchReceiverValue?.load()
irCall.extensionReceiver = extensionReceiverValue?.load()
).apply {
putTypeArguments(call.typeArguments) { it.toIrType() }
this.dispatchReceiver = dispatchReceiverValue?.load()
this.extensionReceiver = extensionReceiverValue?.load()
}
addParametersToCall(startOffset, endOffset, call, irCall, returnType)
}
@@ -220,7 +228,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
val valueArgumentsInEvaluationOrder = resolvedCall.valueArguments.values
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>()
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.expressions.impl.*
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.declareSimpleFunctionWithOverrides
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 java.lang.AssertionError
class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
class ClassGenerator(
declarationGenerator: DeclarationGenerator
) : DeclarationGeneratorExtension(declarationGenerator) {
fun generateClass(ktClassOrObject: KtClassOrObject): IrClass {
val descriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
val startOffset = ktClassOrObject.startOffset
@@ -172,7 +177,10 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
val startOffset = irDelegate.startOffset
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!!)
@@ -216,30 +224,42 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
val substitutedOverridden = substituteOverriddenDescriptorForDelegate(delegated, overridden)
val returnType = substitutedOverridden.returnType!!
val irReturnType = returnType.toIrType()
val irCall = IrCallImpl(
startOffset, endOffset, returnType,
startOffset, endOffset, irReturnType,
context.symbolTable.referenceFunction(overridden.original),
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 =
IrGetFieldImpl(
startOffset, endOffset, irDelegate.symbol,
IrGetValueImpl(startOffset, endOffset, irDelegatedFunction.dispatchReceiverParameter!!.symbol)
startOffset, endOffset,
irDelegate.symbol,
dispatchReceiverType,
IrGetValueImpl(
startOffset, endOffset,
dispatchReceiverType,
dispatchReceiverParameter.symbol
)
)
irCall.extensionReceiver =
irDelegatedFunction.extensionReceiverParameter?.let { extensionReceiver ->
IrGetValueImpl(startOffset, endOffset, extensionReceiver.symbol)
IrGetValueImpl(startOffset, endOffset, extensionReceiver.type, extensionReceiver.symbol)
}
irCall.mapValueParameters { overriddenValueParameter ->
val delegatedValueParameter = delegated.valueParameters[overriddenValueParameter.index]
val irDelegatedValueParameter = irDelegatedFunction.getIrValueParameter(delegatedValueParameter)
IrGetValueImpl(startOffset, endOffset, irDelegatedValueParameter.symbol)
IrGetValueImpl(startOffset, endOffset, irDelegatedValueParameter.type, irDelegatedValueParameter.symbol)
}
if (KotlinBuiltIns.isUnit(returnType) || KotlinBuiltIns.isNothing(returnType)) {
irBlockBody.statements.add(irCall)
} 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)
}
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.expressions.IrExpression
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.util.declareSimpleFunctionWithOverrides
import org.jetbrains.kotlin.psi.KtClassOrObject
@@ -43,7 +42,10 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import java.lang.AssertionError
class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
class DataClassMembersGenerator(
declarationGenerator: DeclarationGenerator
) : DeclarationGeneratorExtension(declarationGenerator) {
fun generate(ktClassOrObject: KtClassOrObject, irClass: IrClass) {
MyDataClassMethodGenerator(ktClassOrObject, irClass).generate()
}
@@ -73,11 +75,23 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
irFunction.putDefault(parameter, irExprBody(value))
}
fun irThis(): IrExpression =
IrGetValueImpl(startOffset, endOffset, irFunction.dispatchReceiverParameter!!.symbol)
fun irThis(): IrExpression {
val irDispatchReceiverParameter = irFunction.dispatchReceiverParameter!!
return IrGetValueImpl(
startOffset, endOffset,
irDispatchReceiverParameter.type,
irDispatchReceiverParameter.symbol
)
}
fun irOther(): IrExpression =
IrGetValueImpl(startOffset, endOffset, irFunction.valueParameters[0].symbol)
fun irOther(): IrExpression {
val irFirstParameter = irFunction.valueParameters[0]
return IrGetValueImpl(
startOffset, endOffset,
irFirstParameter.type,
irFirstParameter.symbol
)
}
}
private inner class MyDataClassMethodGenerator(
@@ -105,7 +119,7 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
?: throw AssertionError("No definition for data class constructor parameter $parameter")
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 ->
function.valueParameters.forEach { parameter ->
putDefault(parameter, irGet(irThis(), getPropertyGetterSymbol(parameter)))
putDefault(parameter, irGet(parameter.type.toIrType(), irThis(), getPropertyGetterSymbol(parameter)))
}
+irReturn(
irCall(
constructorSymbol,
dataClassConstructor.returnType,
dataClassConstructor.returnType.toIrType(),
dataClassConstructor.typeParameters.associate { it to it.defaultType }
).mapValueParameters {
irGet(irFunction.valueParameters[it.index].symbol)
).apply {
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.expressions.IrExpressionBody
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.psi.*
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.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.types.KotlinType
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 =
when (ktDeclaration) {
is KtNamedFunction ->
@@ -154,21 +161,27 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
}
}
private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtElement): IrProperty =
IrPropertyImpl(
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined,
IrDeclarationOrigin.FAKE_OVERRIDE,
false,
propertyDescriptor,
private fun generateFakeOverrideProperty(propertyDescriptor: PropertyDescriptor, ktElement: KtElement): IrProperty {
val backingField =
if (propertyDescriptor.getter == null)
context.symbolTable.declareField(
ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, IrDeclarationOrigin.FAKE_OVERRIDE,
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.setter?.let { generateFakeOverrideFunction(it, ktElement) }
)
}
private fun generateFakeOverrideFunction(functionDescriptor: FunctionDescriptor, ktElement: KtElement): IrSimpleFunction =
FunctionGenerator(this).generateFakeOverrideFunction(functionDescriptor, ktElement)
@@ -183,6 +196,8 @@ abstract class DeclarationGeneratorExtension(val declarationGenerator: Declarati
builder(irDeclaration)
}
}
fun KotlinType.toIrType() = with(declarationGenerator) { toIrType() }
}
fun Generator.createBodyGenerator(scopeOwnerSymbol: IrSymbol) =
@@ -35,15 +35,20 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
fun generateErrorExpression(ktElement: KtElement, e: Exception): IrExpression =
generateErrorExpression(ktElement, e) {
val errorExpressionType =
if (ktElement is KtExpression)
getErrorExpressionType(ktElement)
else
ErrorUtils.createErrorType("")
IrErrorExpressionImpl(
ktElement.startOffset, ktElement.endOffset,
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""),
errorExpressionType.toIrType(),
e.message ?: ""
)
}
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?
irErrorCall.explicitReceiver = (ktCall.parent as? KtDotQualifiedExpression)?.run {
@@ -64,7 +69,7 @@ class ErrorExpressionGenerator(statementGenerator: StatementGenerator) : Stateme
getInferredTypeWithImplicitCasts(ktExpression) ?: ErrorUtils.createErrorType("")
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?
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) {
fun generateObjectLiteral(ktObjectLiteral: KtObjectLiteralExpression): IrStatement {
val objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral)
val irBlock =
IrBlockImpl(ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL)
val startOffset = ktObjectLiteral.startOffset
val endOffset = ktObjectLiteral.endOffset
val objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral).toIrType()
val irBlock = IrBlockImpl(startOffset, endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL)
val irClass = DeclarationGenerator(statementGenerator.context).generateClassOrObjectDeclaration(ktObjectLiteral.objectDeclaration)
irBlock.statements.add(irClass)
@@ -48,10 +49,9 @@ class LocalClassGenerator(statementGenerator: StatementGenerator) : StatementGen
irBlock.statements.add(
IrCallImpl(
ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType,
startOffset, endOffset, objectLiteralType,
context.symbolTable.referenceConstructor(objectConstructor),
objectConstructor,
null,
IrStatementOrigin.OBJECT_LITERAL
)
)
@@ -29,7 +29,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
class LocalFunctionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateLambda(ktLambda: KtLambdaExpression): IrStatement {
val ktFun = ktLambda.functionLiteral
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda)
val lambdaExpressionType = getInferredTypeWithImplicitCastsOrFail(ktLambda).toIrType()
val irLambdaFunction = FunctionGenerator(context).generateLambdaFunctionDeclaration(ktFun)
val irBlock = IrBlockImpl(ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType, IrStatementOrigin.LAMBDA)
@@ -37,8 +37,8 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
irBlock.statements.add(
IrFunctionReferenceImpl(
ktLambda.startOffset, ktLambda.endOffset, lambdaExpressionType,
irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor,
null, IrStatementOrigin.LAMBDA
irLambdaFunction.symbol, irLambdaFunction.symbol.descriptor, 0,
IrStatementOrigin.LAMBDA
)
)
return irBlock
@@ -49,7 +49,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
generateFunctionDeclaration(ktFun)
} else {
// anonymous function expression
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun)
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun).toIrType()
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
val irFun = generateFunctionDeclaration(ktFun)
@@ -58,8 +58,8 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
irBlock.statements.add(
IrFunctionReferenceImpl(
ktFun.startOffset, ktFun.endOffset, funExpressionType,
irFun.symbol, irFun.symbol.descriptor,
null, IrStatementOrigin.ANONYMOUS_FUNCTION
irFun.symbol, irFun.symbol.descriptor, 0,
IrStatementOrigin.ANONYMOUS_FUNCTION
)
)
@@ -33,7 +33,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression {
val irLoop = IrWhileLoopImpl(
ktWhile.startOffset, ktWhile.endOffset,
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP
context.irBuiltIns.unitType, IrStatementOrigin.WHILE_LOOP
)
irLoop.condition = ktWhile.condition!!.genExpr()
@@ -55,7 +55,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression {
val irLoop = IrDoWhileLoopImpl(
ktDoWhile.startOffset, ktDoWhile.endOffset,
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP
context.irBuiltIns.unitType, IrStatementOrigin.DO_WHILE_LOOP
)
statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop)
@@ -71,21 +71,21 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
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)
}
}
private fun generateWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
IrBlockImpl(
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
ktLoopBody.startOffset, ktLoopBody.endOffset, context.irBuiltIns.unitType, null,
ktLoopBody.statements.map { it.genStmt() }
)
private fun generateDoWhileLoopBody(ktLoopBody: KtBlockExpression): IrExpression =
IrCompositeImpl(
ktLoopBody.startOffset, ktLoopBody.endOffset, context.builtIns.unitType, null,
ktLoopBody.startOffset, ktLoopBody.endOffset, context.irBuiltIns.unitType, null,
ktLoopBody.statements.map { it.genStmt() }
)
@@ -93,7 +93,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val parentLoop = findParentLoop(ktBreak) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
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()
}
}
@@ -102,7 +102,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val parentLoop = findParentLoop(ktContinue) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
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()
}
}
@@ -154,7 +154,10 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
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 irIteratorCall = callGenerator.generateCall(ktLoopRange, iteratorCall, IrStatementOrigin.FOR_LOOP_ITERATOR)
@@ -162,8 +165,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val iteratorValue = VariableLValue(irIterator)
irForBlock.statements.add(irIterator)
val irInnerWhile =
IrWhileLoopImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
val irInnerWhile = IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE)
irInnerWhile.label = getLoopLabel(ktFor)
statementGenerator.bodyGenerator.putLoop(ktFor, 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)
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
val nextCall = statementGenerator.pregenerateCall(nextResolvedCall)
@@ -92,8 +92,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return IrTypeOperatorCallImpl(
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(
expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
againstType, expression.leftHandSide.genExpr(),
context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!)
againstType, context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!),
expression.leftHandSide.genExpr()
)
}
@@ -34,7 +34,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
fun generateClassLiteral(ktClassLiteral: KtClassLiteralExpression): IrExpression {
val ktArgument = ktClassLiteral.receiverExpression!!
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) {
IrGetClassImpl(
@@ -47,7 +47,7 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
?: throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
IrClassReferenceImpl(
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) }
return IrLocalDelegatedPropertyReferenceImpl(
startOffset, endOffset, type,
startOffset, endOffset, type.toIrType(),
variableDescriptor,
irDelegateSymbol, getterSymbol, setterSymbol,
origin
@@ -142,12 +142,13 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
return IrPropertyReferenceImpl(
startOffset, endOffset, type,
propertyDescriptor,
startOffset, endOffset, type.toIrType(),
propertyDescriptor, propertyDescriptor.typeParametersCount,
fieldSymbol, getterSymbol, setterSymbol,
typeArguments,
origin
)
).apply {
putTypeArguments(typeArguments) { it.toIrType()}
}
}
private fun generateFunctionReference(
@@ -160,9 +161,10 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
origin: IrStatementOrigin?
): IrFunctionReference =
IrFunctionReferenceImpl(
startOffset, endOffset, type,
symbol, descriptor,
typeArguments,
startOffset, endOffset, type.toIrType(),
symbol, descriptor, descriptor.typeParametersCount,
origin
)
).apply {
putTypeArguments(typeArguments) { it.toIrType() }
}
}
@@ -58,7 +58,7 @@ class StatementGenerator(
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 =
ktElement.genStmt()
@@ -408,4 +408,5 @@ abstract class StatementGeneratorExtension(val statementGenerator: StatementGene
fun KtExpression.genExpr() = statementGenerator.generateExpression(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) {
fun generateTryCatch(ktTry: KtTryExpression): IrExpression {
val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry)
val resultType = getInferredTypeWithImplicitCastsOrFail(ktTry).toIrType()
val irTryCatch = IrTryImpl(ktTry.startOffset, ktTry.endOffset, resultType)
irTryCatch.tryResult = ktTry.tryBlock.genExpr()
@@ -14,12 +14,12 @@
* 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.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
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
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.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) {
override fun load(): IrExpression = generate()
}
inline fun generateDelegatedValue(type: KotlinType, crossinline generateValue: () -> IntermediateValue) =
inline fun generateDelegatedValue(type: IrType, crossinline generateValue: () -> IntermediateValue) =
object : ExpressionValue(type) {
val lazyDelegate by lazy { generateValue() }
override fun load(): IrExpression = lazyDelegate.load()
@@ -42,7 +43,7 @@ class OnceExpressionValue(val irExpression: IrExpression) : LValue, AssignmentRe
return irExpression
}
override val type: KotlinType get() = irExpression.type
override val type: IrType get() = irExpression.type
override fun store(irExpression: IrExpression): IrExpression {
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.IrExpressionWithCopy
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType
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()
}
@@ -17,9 +17,10 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType
class TransientReceiverValue(override val type: KotlinType) : IntermediateValue {
class TransientReceiverValue(override val type: IrType) : IntermediateValue {
override fun load(): IrExpression {
throw AssertionError("Transient receiver should not be instantiated")
}
@@ -17,12 +17,13 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType
interface IntermediateValue {
fun load(): IrExpression
fun loadIfExists(): IrExpression? = load()
val type: KotlinType
val type: IrType
}
interface LValue : IntermediateValue {
@@ -229,9 +229,13 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
?: throw AssertionError("No declaration for target type: $targetType")
return IrTypeOperatorCallImpl(
startOffset, endOffset,
targetType, typeOperator, targetType, this,
resolveScopedTypeParameter(typeDescriptor) ?: symbolTable.referenceClassifier(typeDescriptor)
startOffset,
endOffset,
targetType,
typeOperator,
targetType,
resolveScopedTypeParameter(typeDescriptor) ?: symbolTable.referenceClassifier(typeDescriptor),
this
)
}
@@ -243,8 +247,8 @@ class InsertImplicitCasts(private val builtIns: KotlinBuiltIns, private val symb
else
IrTypeOperatorCallImpl(
startOffset, endOffset, builtIns.unitType,
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this,
symbolTable.referenceClass(builtIns.unit)
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, symbolTable.referenceClass(builtIns.unit),
this
)
}
@@ -1,17 +1,6 @@
/*
* 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.
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.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.impl.*
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
@@ -87,7 +77,8 @@ fun IrBuilderWithScope.irExprBody(value: IrExpression) =
fun IrBuilderWithScope.irReturn(value: IrExpression) =
IrReturnImpl(
startOffset, endOffset, context.builtIns.nothingType,
startOffset, endOffset,
context.irBuiltIns.nothingType,
scope.scopeOwnerSymbol.assertedCast<IrReturnTargetSymbol> {
"Function scope expected: ${scope.scopeOwner}"
},
@@ -95,37 +86,37 @@ fun IrBuilderWithScope.irReturn(value: IrExpression) =
)
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() =
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)
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)
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) =
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnTrue())
IrIfThenElseImpl(startOffset, endOffset, context.irBuiltIns.unitType, condition, irReturnTrue())
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) =
IrGetValueImpl(startOffset, endOffset, variable)
fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
IrGetValueImpl(startOffset, endOffset, type, variable)
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) =
context.eqeqeq(startOffset, endOffset, arg1, arg2)
fun IrBuilderWithScope.irNull() =
IrConstImpl.constNull(startOffset, endOffset, context.builtIns.nullableNothingType)
IrConstImpl.constNull(startOffset, endOffset, context.irBuiltIns.nothingNType)
fun IrBuilderWithScope.irEqualsNull(argument: IrExpression) =
primitiveOp2(
@@ -142,35 +133,23 @@ fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) =
)
)
fun IrBuilderWithScope.irGet(receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall =
IrGetterCallImpl(startOffset, endOffset, getterSymbol, getterSymbol.descriptor, null, receiver, null, IrStatementOrigin.GET_PROPERTY)
fun IrBuilderWithScope.irGet(type: IrType, receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall =
IrGetterCallImpl(
startOffset, endOffset,
type,
getterSymbol, getterSymbol.descriptor,
typeArgumentsCount = 0,
dispatchReceiver = receiver,
extensionReceiver = null,
origin = IrStatementOrigin.GET_PROPERTY
)
fun IrBuilderWithScope.irCall(
callee: IrFunctionSymbol,
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.irCall(callee: IrFunctionSymbol, type: IrType): IrCall =
IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor)
fun IrBuilderWithScope.irCallOp(
callee: IrFunctionSymbol,
type: KotlinType,
type: IrType,
dispatchReceiver: IrExpression,
argument: IrExpression
): IrCall =
@@ -179,47 +158,35 @@ fun IrBuilderWithScope.irCallOp(
putValueArgument(0, argument)
}
@Deprecated("Creates unbound symbol")
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument)
fun IrBuilderWithScope.typeOperator(
resultType: IrType,
argument: IrExpression,
typeOperator: IrTypeOperator,
typeOperand: IrType
) =
IrTypeOperatorCallImpl(startOffset, endOffset, resultType, typeOperator, typeOperand, typeOperand.classifierOrFail, argument)
fun IrBuilderWithScope.irIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.INSTANCEOF, type, argument, typeClassifier)
fun IrBuilderWithScope.irIs(argument: IrExpression, type: IrType) =
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.irNotIs(argument: IrExpression, type: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.booleanType, IrTypeOperator.NOT_INSTANCEOF, type, argument)
fun IrBuilderWithScope.irAs(argument: IrExpression, type: IrType) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, type, type.classifierOrFail, argument)
fun IrBuilderWithScope.irNotIs(argument: IrExpression, type: KotlinType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(
startOffset, endOffset,
context.builtIns.booleanType,
IrTypeOperator.NOT_INSTANCEOF,
type, argument, typeClassifier
)
fun IrBuilderWithScope.irImplicitCast(argument: IrExpression, type: IrType) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, type.classifierOrFail, argument)
@Deprecated("Creates unbound symbol")
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.irImplicitCast(argument: IrExpression, type: IrType, typeClassifier: IrClassifierSymbol) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, type.classifierOrFail, argument)
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) =
IrConstImpl.string(startOffset, endOffset, context.builtIns.stringType, value)
IrConstImpl.string(startOffset, endOffset, context.irBuiltIns.stringType, value)
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.impl.IrBlockBodyImpl
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.*
abstract class IrBuilder(
@@ -78,10 +79,12 @@ open class IrBlockBodyBuilder(
}
class IrBlockBuilder(
context: IrGeneratorContext, scope: Scope,
startOffset: Int, endOffset: Int,
context: IrGeneratorContext,
scope: Scope,
startOffset: Int,
endOffset: Int,
val origin: IrStatementOrigin? = null,
var resultType: KotlinType? = null
var resultType: IrType? = null
) : IrStatementsBuilder<IrBlock>(context, scope, startOffset, endOffset) {
private val statements = ArrayList<IrStatement>()
@@ -95,22 +98,25 @@ class IrBlockBuilder(
}
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)
irBlock.statements.addAll(statements)
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.endOffset = endOffset
return this
}
inline fun IrGeneratorWithScope.irBlock(
startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET,
origin: IrStatementOrigin? = null, resultType: KotlinType? = null,
startOffset: Int = UNDEFINED_OFFSET,
endOffset: Int = UNDEFINED_OFFSET,
origin: IrStatementOrigin? = null,
resultType: IrType? = null,
body: IrBlockBuilder.() -> Unit
): IrExpression =
IrBlockBuilder(
@@ -129,3 +135,4 @@ inline fun IrGeneratorWithScope.irBlockBody(
startOffset,
endOffset
).blockBody(body)
@@ -87,8 +87,8 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns, outerSymbolTable: SymbolTable?) {
val anyNType = anyType.withHasQuestionMark(true)
val bool = builtIns.booleanType
val boolType = bool.toIrType()
val boolClass = builtIns.boolean.toIrSymbol()
val booleanType = bool.toIrType()
val booleanClass = builtIns.boolean.toIrSymbol()
val char = builtIns.charType
val charType = char.toIrType()
@@ -151,7 +151,7 @@ class IrBuiltIns(val builtIns: KotlinBuiltIns, outerSymbolTable: SymbolTable?) {
val throwNpeFun = defineOperator("THROW_NPE", nothing, listOf())
val throwCceFun = defineOperator("THROW_CCE", nothing, listOf())
val booleanNotFun = defineOperator("NOT", bool, listOf(bool))
val noWhenBranchMatchedExceptionFun = defineOperator("noWhenBranchMatchedException", unit, listOf())
val noWhenBranchMatchedExceptionFun = defineOperator("noWhenBranchMatchedException", nothing, listOf())
val eqeqeq = eqeqeqFun.descriptor
val eqeq = eqeqFun.descriptor
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.expressions
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.types.KotlinType
interface IrMemberAccessExpression : 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() =
when (this) {
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.ir.expressions.IrCall
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.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
@@ -54,7 +54,7 @@ class IrCallImpl(
descriptor: FunctionDescriptor,
origin: IrStatementOrigin? = 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")
constructor(
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
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.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
@@ -40,6 +41,14 @@ class IrDelegatingConstructorCallImpl(
),
IrDelegatingConstructorCall {
constructor(
startOffset: Int,
endOffset: Int,
type: IrType,
symbol: IrConstructorSymbol,
descriptor: ClassConstructorDescriptor
) : this(startOffset, endOffset, type, symbol, descriptor, descriptor.typeParametersCount)
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int,
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
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.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType
@@ -39,6 +40,13 @@ class IrEnumConstructorCallImpl(
),
IrEnumConstructorCall {
constructor(
startOffset: Int,
endOffset: Int,
type: IrType,
symbol: IrConstructorSymbol
) : this(startOffset, endOffset, type, symbol, symbol.descriptor.typeParametersCount)
@Deprecated("Creates unbound symbols")
constructor(
startOffset: Int,
@@ -68,8 +68,8 @@ class IrGetFieldImpl(
this(
startOffset, endOffset,
IrFieldSymbolImpl(propertyDescriptor),
receiver,
type,
receiver,
origin,
createClassSymbolOrNull(superQualifier)
)
@@ -78,8 +78,8 @@ class IrGetFieldImpl(
constructor(
startOffset: Int, endOffset: Int,
symbol: IrFieldSymbol,
receiver: IrExpression?,
type: IrType,
receiver: IrExpression?,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, type, origin, superQualifierSymbol) {
@@ -43,8 +43,8 @@ class IrTypeOperatorCallImpl(
type: IrType,
operator: IrTypeOperator,
typeOperand: IrType,
argument: IrExpression,
typeOperandClassifier: IrClassifierSymbol
typeOperandClassifier: IrClassifierSymbol,
argument: IrExpression
) : this(startOffset, endOffset, type, operator, typeOperand) {
this.argument = argument
this.typeOperandClassifier = typeOperandClassifier
@@ -541,7 +541,6 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.type,
expression.operator,
expression.typeOperand,
expression.argument.transform(),
run {
val oldTypeDescriptor = expression.typeOperandClassifier.descriptor
val newTypeDescriptor = mapClassifierReference(oldTypeDescriptor)
@@ -549,7 +548,8 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.typeOperandClassifier
else
createUnboundClassifierSymbol(newTypeDescriptor)
}
},
expression.argument.transform()
)
override fun visitWhen(expression: IrWhen): IrWhen =
@@ -469,8 +469,8 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
expression.type,
expression.operator,
expression.typeOperand,
expression.argument.transform(),
symbolRemapper.getReferencedClassifier(expression.typeOperandClassifier)
symbolRemapper.getReferencedClassifier(expression.typeOperandClassifier),
expression.argument.transform()
)
override fun visitWhen(expression: IrWhen): IrWhen =