Formatting: psi2ir

This commit is contained in:
Dmitry Petrov
2018-01-11 14:09:11 +03:00
parent 432c743771
commit 1f841e35bc
48 changed files with 1827 additions and 1614 deletions
-1
View File
@@ -1,4 +1,3 @@
apply { plugin("kotlin") } apply { plugin("kotlin") }
jvmTarget = "1.6" jvmTarget = "1.6"
@@ -48,8 +48,8 @@ fun KtElement.deparenthesize(): KtElement =
fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean { fun ResolvedCall<*>.isValueArgumentReorderingRequired(): Boolean {
var lastValueParameterIndex = -1 var lastValueParameterIndex = -1
for (valueArgument in call.valueArguments) { for (valueArgument in call.valueArguments) {
val argumentMapping = getArgumentMapping(valueArgument) as? ArgumentMatch ?: val argumentMapping =
throw Exception("Value argument in function call is mapped with error") getArgumentMapping(valueArgument) as? ArgumentMatch ?: throw Exception("Value argument in function call is mapped with error")
val argumentIndex = argumentMapping.valueParameter.index val argumentIndex = argumentMapping.valueParameter.index
if (argumentIndex < lastValueParameterIndex) { if (argumentIndex < lastValueParameterIndex) {
return true return true
@@ -35,7 +35,7 @@ class PsiSourceManager : SourceManager {
maxOffset = document.textLength maxOffset = document.textLength
lineStartOffsets = (0 .. document.lineCount - 1) lineStartOffsets = (0..document.lineCount - 1)
.map { document.getLineStartOffset(it) } .map { document.getLineStartOffset(it) }
.toIntArray() .toIntArray()
} }
@@ -26,7 +26,10 @@ 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(ktAnonymousInitializer: KtAnonymousInitializer, classDescriptor: ClassDescriptor): IrDeclaration = fun generateAnonymousInitializerDeclaration(
ktAnonymousInitializer: KtAnonymousInitializer,
classDescriptor: ClassDescriptor
): IrDeclaration =
context.symbolTable.declareAnonymousInitializer( context.symbolTable.declareAnonymousInitializer(
ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor ktAnonymousInitializer.startOffset, ktAnonymousInitializer.endOffset, IrDeclarationOrigin.DEFINED, classDescriptor
).buildWithScope { irAnonymousInitializer -> ).buildWithScope { irAnonymousInitializer ->
@@ -36,8 +39,7 @@ class AnonymousInitializerGenerator(declarationGenerator: DeclarationGenerator)
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset) val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
if (ktBody is KtBlockExpression) { if (ktBody is KtBlockExpression) {
statementGenerator.generateStatements(ktBody.statements, irBlockBody) statementGenerator.generateStatements(ktBody.statements, irBlockBody)
} } else {
else {
irBlockBody.statements.add(statementGenerator.generateStatement(ktBody)) irBlockBody.statements.add(statementGenerator.generateStatement(ktBody))
} }
irAnonymousInitializer.body = irBlockBody irAnonymousInitializer.body = irBlockBody
@@ -56,8 +56,10 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor)) if (shouldGenerateReceiverAsSingletonReference(receiverClassDescriptor))
generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type) generateSingletonReference(receiverClassDescriptor, defaultStartOffset, defaultEndOffset, receiver.type)
else else
IrGetValueImpl(defaultStartOffset, defaultEndOffset, IrGetValueImpl(
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)) defaultStartOffset, defaultEndOffset,
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
)
} }
is ThisClassReceiver -> is ThisClassReceiver ->
generateThisOrSuperReceiver(receiver, receiver.classDescriptor) generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
@@ -66,11 +68,15 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
is ExpressionReceiver -> is ExpressionReceiver ->
generateExpression(receiver.expression) generateExpression(receiver.expression)
is ClassValueReceiver -> is ClassValueReceiver ->
IrGetObjectValueImpl(receiver.expression.startOffset, receiver.expression.endOffset, receiver.type, IrGetObjectValueImpl(
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor)) receiver.expression.startOffset, receiver.expression.endOffset, receiver.type,
context.symbolTable.referenceClass(receiver.classQualifier.descriptor as ClassDescriptor)
)
is ExtensionReceiver -> is ExtensionReceiver ->
IrGetValueImpl(defaultStartOffset, defaultStartOffset, IrGetValueImpl(
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)) defaultStartOffset, defaultStartOffset,
context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
)
else -> else ->
TODO("Receiver: ${receiver::class.java.simpleName}") TODO("Receiver: ${receiver::class.java.simpleName}")
} }
@@ -81,19 +87,30 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
OnceExpressionValue(receiverExpression) OnceExpressionValue(receiverExpression)
} }
fun StatementGenerator.generateSingletonReference(descriptor: ClassDescriptor, startOffset: Int, endOffset: Int, type: KotlinType): IrDeclarationReference = fun StatementGenerator.generateSingletonReference(
descriptor: ClassDescriptor,
startOffset: Int,
endOffset: Int,
type: KotlinType
): IrDeclarationReference =
when { when {
DescriptorUtils.isObject(descriptor) -> DescriptorUtils.isObject(descriptor) ->
IrGetObjectValueImpl(startOffset, endOffset, type, IrGetObjectValueImpl(
context.symbolTable.referenceClass(descriptor)) startOffset, endOffset, type,
context.symbolTable.referenceClass(descriptor)
)
DescriptorUtils.isEnumEntry(descriptor) -> DescriptorUtils.isEnumEntry(descriptor) ->
IrGetEnumValueImpl(startOffset, endOffset, type, IrGetEnumValueImpl(
context.symbolTable.referenceEnumEntry(descriptor)) startOffset, endOffset, type,
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(startOffset, endOffset, type, IrGetObjectValueImpl(
context.symbolTable.referenceClass(companionObjectDescriptor)) startOffset, endOffset, type,
context.symbolTable.referenceClass(companionObjectDescriptor)
)
} }
} }
@@ -104,11 +121,13 @@ private fun StatementGenerator.shouldGenerateReceiverAsSingletonReference(receiv
} }
private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverValue, classDescriptor: ClassDescriptor): IrExpression { private fun StatementGenerator.generateThisOrSuperReceiver(receiver: ReceiverValue, classDescriptor: ClassDescriptor): IrExpression {
val expressionReceiver = receiver as? ExpressionReceiver ?: val expressionReceiver =
throw AssertionError("'this' or 'super' receiver should be an expression receiver") receiver as? ExpressionReceiver ?: throw AssertionError("'this' or 'super' receiver should be an expression receiver")
val ktReceiver = expressionReceiver.expression val ktReceiver = expressionReceiver.expression
return IrGetValueImpl(ktReceiver.startOffset, ktReceiver.endOffset, return IrGetValueImpl(
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter)) ktReceiver.startOffset, ktReceiver.endOffset,
context.symbolTable.referenceValueParameter(classDescriptor.thisAsReceiverParameter)
)
} }
fun StatementGenerator.generateBackingFieldReceiver( fun StatementGenerator.generateBackingFieldReceiver(
@@ -128,7 +147,7 @@ fun StatementGenerator.generateCallReceiver(
extensionReceiver: ReceiverValue?, extensionReceiver: ReceiverValue?,
isSafe: Boolean, isSafe: Boolean,
isAssignmentReceiver: Boolean = false isAssignmentReceiver: Boolean = false
) : CallReceiver { ): CallReceiver {
val dispatchReceiverValue: IntermediateValue? val dispatchReceiverValue: IntermediateValue?
val extensionReceiverValue: IntermediateValue? val extensionReceiverValue: IntermediateValue?
when (calleeDescriptor) { when (calleeDescriptor) {
@@ -136,7 +155,8 @@ fun StatementGenerator.generateCallReceiver(
assert(dispatchReceiver == null) { assert(dispatchReceiver == null) {
"Call for member imported from object $calleeDescriptor has non-null dispatch receiver $dispatchReceiver" "Call for member imported from object $calleeDescriptor has non-null dispatch receiver $dispatchReceiver"
} }
dispatchReceiverValue = generateReceiverForCalleeImportedFromObject(ktDefaultElement.startOffset, ktDefaultElement.endOffset, calleeDescriptor) dispatchReceiverValue =
generateReceiverForCalleeImportedFromObject(ktDefaultElement.startOffset, ktDefaultElement.endOffset, calleeDescriptor)
extensionReceiverValue = generateReceiverOrNull(ktDefaultElement, extensionReceiver) extensionReceiverValue = generateReceiverOrNull(ktDefaultElement, extensionReceiver)
} }
is TypeAliasConstructorDescriptor -> { is TypeAliasConstructorDescriptor -> {
@@ -156,9 +176,11 @@ fun StatementGenerator.generateCallReceiver(
return when { return when {
!isSafe -> !isSafe ->
SimpleCallReceiver(dispatchReceiverValue, extensionReceiverValue) SimpleCallReceiver(dispatchReceiverValue, extensionReceiverValue)
extensionReceiverValue != null || dispatchReceiverValue != null-> extensionReceiverValue != null || dispatchReceiverValue != null ->
SafeCallReceiver(this, ktDefaultElement.startOffset, ktDefaultElement.endOffset, SafeCallReceiver(
extensionReceiverValue, dispatchReceiverValue, isAssignmentReceiver) this, ktDefaultElement.startOffset, ktDefaultElement.endOffset,
extensionReceiverValue, dispatchReceiverValue, isAssignmentReceiver
)
else -> else ->
throw AssertionError("Safe call should have an explicit receiver: ${ktDefaultElement.text}") throw AssertionError("Safe call should have an explicit receiver: ${ktDefaultElement.text}")
} }
@@ -172,12 +194,17 @@ private fun StatementGenerator.generateReceiverForCalleeImportedFromObject(
val objectDescriptor = calleeDescriptor.containingObject val objectDescriptor = calleeDescriptor.containingObject
val objectType = objectDescriptor.defaultType val objectType = objectDescriptor.defaultType
return generateExpressionValue(objectType) { return generateExpressionValue(objectType) {
IrGetObjectValueImpl(startOffset, endOffset, objectType, IrGetObjectValueImpl(
context.symbolTable.referenceClass(objectDescriptor)) startOffset, endOffset, objectType,
context.symbolTable.referenceClass(objectDescriptor)
)
} }
} }
fun StatementGenerator.generateVarargExpression(varargArgument: VarargValueArgument, valueParameter: ValueParameterDescriptor) : IrExpression? { fun StatementGenerator.generateVarargExpression(
varargArgument: VarargValueArgument,
valueParameter: ValueParameterDescriptor
): IrExpression? {
if (varargArgument.arguments.isEmpty()) { if (varargArgument.arguments.isEmpty()) {
return null return null
} }
@@ -189,18 +216,20 @@ fun StatementGenerator.generateVarargExpression(varargArgument: VarargValueArgum
Math.max(maxEndOffset, argument.asElement().endOffset) Math.max(maxEndOffset, argument.asElement().endOffset)
} }
val varargElementType = valueParameter.varargElementType ?: val 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, varargElementType)
for (argument in varargArgument.arguments) { for (argument in varargArgument.arguments) {
val ktArgumentExpression = argument.getArgumentExpression() ?: val ktArgumentExpression = argument.getArgumentExpression()
throw AssertionError("No argument expression for vararg element ${argument.asElement().text}") ?: throw AssertionError("No argument expression for vararg element ${argument.asElement().text}")
val irVarargElement = val irVarargElement =
if (argument.getSpreadElement() != null) if (argument.getSpreadElement() != null)
IrSpreadElementImpl(ktArgumentExpression.startOffset, ktArgumentExpression.endOffset, IrSpreadElementImpl(
generateExpression(ktArgumentExpression)) ktArgumentExpression.startOffset, ktArgumentExpression.endOffset,
generateExpression(ktArgumentExpression)
)
else else
generateExpression(ktArgumentExpression) generateExpression(ktArgumentExpression)
@@ -210,7 +239,10 @@ fun StatementGenerator.generateVarargExpression(varargArgument: VarargValueArgum
return irVararg return irVararg
} }
fun StatementGenerator.generateValueArgument(valueArgument: ResolvedValueArgument, valueParameter: ValueParameterDescriptor): IrExpression? = fun StatementGenerator.generateValueArgument(
valueArgument: ResolvedValueArgument,
valueParameter: ValueParameterDescriptor
): IrExpression? =
when (valueArgument) { when (valueArgument) {
is DefaultValueArgument -> is DefaultValueArgument ->
null null
@@ -239,11 +271,12 @@ fun StatementGenerator.pregenerateCall(resolvedCall: ResolvedCall<*>): CallBuild
fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall<*>): CallBuilder { fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall<*>): CallBuilder {
val extensionInvoke = resolvedCall.resultingDescriptor val extensionInvoke = resolvedCall.resultingDescriptor
val functionNClass = extensionInvoke.containingDeclaration as? ClassDescriptor ?: val functionNClass = extensionInvoke.containingDeclaration as? ClassDescriptor
throw AssertionError("'invoke' should be a class member: $extensionInvoke") ?: throw AssertionError("'invoke' should be a class member: $extensionInvoke")
val unsubstitutedPlainInvokes = functionNClass.unsubstitutedMemberScope.getContributedFunctions(extensionInvoke.name, NoLookupLocation.FROM_BACKEND) val unsubstitutedPlainInvokes =
val unsubstitutedPlainInvoke = unsubstitutedPlainInvokes.singleOrNull() ?: functionNClass.unsubstitutedMemberScope.getContributedFunctions(extensionInvoke.name, NoLookupLocation.FROM_BACKEND)
throw AssertionError("There should be a single 'invoke' in FunctionN class: $unsubstitutedPlainInvokes") val unsubstitutedPlainInvoke = unsubstitutedPlainInvokes.singleOrNull()
?: throw AssertionError("There should be a single 'invoke' in FunctionN class: $unsubstitutedPlainInvokes")
val expectedValueParametersCount = extensionInvoke.valueParameters.size + 1 val expectedValueParametersCount = extensionInvoke.valueParameters.size + 1
assert(unsubstitutedPlainInvoke.valueParameters.size == expectedValueParametersCount) { assert(unsubstitutedPlainInvoke.valueParameters.size == expectedValueParametersCount) {
@@ -251,29 +284,31 @@ fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall
} }
val functionNType = extensionInvoke.dispatchReceiverParameter!!.type val functionNType = extensionInvoke.dispatchReceiverParameter!!.type
val plainInvoke = unsubstitutedPlainInvoke.substitute(TypeSubstitutor.create(functionNType)) ?: val plainInvoke = unsubstitutedPlainInvoke.substitute(TypeSubstitutor.create(functionNType))
throw AssertionError("Substitution failed for $unsubstitutedPlainInvoke, type=$functionNType") ?: throw AssertionError("Substitution failed for $unsubstitutedPlainInvoke, type=$functionNType")
val ktCallElement = resolvedCall.call.callElement val ktCallElement = resolvedCall.call.callElement
val call = CallBuilder(resolvedCall, plainInvoke, isExtensionInvokeCall = true) val call = CallBuilder(resolvedCall, plainInvoke, isExtensionInvokeCall = true)
val functionReceiverValue = run { val functionReceiverValue = run {
val dispatchReceiver = resolvedCall.dispatchReceiver ?: val dispatchReceiver =
throw AssertionError("Extension 'invoke' call should have a dispatch receiver") resolvedCall.dispatchReceiver ?: throw AssertionError("Extension 'invoke' call should have a dispatch receiver")
generateReceiver(ktCallElement, dispatchReceiver) generateReceiver(ktCallElement, dispatchReceiver)
} }
val extensionInvokeReceiverValue = run { val extensionInvokeReceiverValue = run {
val extensionReceiver = resolvedCall.extensionReceiver ?: val extensionReceiver =
throw AssertionError("Extension 'invoke' call should have an extension receiver") resolvedCall.extensionReceiver ?: throw AssertionError("Extension 'invoke' call should have an extension receiver")
generateReceiver(ktCallElement, extensionReceiver) generateReceiver(ktCallElement, extensionReceiver)
} }
call.callReceiver = call.callReceiver =
if (resolvedCall.call.isSafeCall()) if (resolvedCall.call.isSafeCall())
SafeExtensionInvokeCallReceiver(this, ktCallElement.startOffset, ktCallElement.endOffset, SafeExtensionInvokeCallReceiver(
call, functionReceiverValue, extensionInvokeReceiverValue) this, ktCallElement.startOffset, ktCallElement.endOffset,
call, functionReceiverValue, extensionInvokeReceiverValue
)
else else
ExtensionInvokeCallReceiver(call, functionReceiverValue, extensionInvokeReceiverValue) ExtensionInvokeCallReceiver(call, functionReceiverValue, extensionInvokeReceiverValue)
@@ -313,11 +348,13 @@ private fun StatementGenerator.pregenerateValueArguments(call: CallBuilder, reso
fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>): CallBuilder { fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>): CallBuilder {
val call = CallBuilder(resolvedCall, unwrapCallableDescriptor(resolvedCall.resultingDescriptor)) val call = CallBuilder(resolvedCall, unwrapCallableDescriptor(resolvedCall.resultingDescriptor))
call.callReceiver = generateCallReceiver(resolvedCall.call.callElement, call.callReceiver = generateCallReceiver(
resolvedCall.call.callElement,
resolvedCall.resultingDescriptor, resolvedCall.resultingDescriptor,
resolvedCall.dispatchReceiver, resolvedCall.dispatchReceiver,
resolvedCall.extensionReceiver, resolvedCall.extensionReceiver,
isSafe = resolvedCall.call.isSafeCall()) isSafe = resolvedCall.call.isSafeCall()
)
call.superQualifier = getSuperQualifier(resolvedCall) call.superQualifier = getSuperQualifier(resolvedCall)
@@ -58,8 +58,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
if (isSimpleAssignment) { if (isSimpleAssignment) {
// Set( Op( Get(), RHS ) ) // Set( Op( Get(), RHS ) )
irLValue.store(irOpCall) irLValue.store(irOpCall)
} } else {
else {
// Op( Get(), RHS ) // Op( Get(), RHS )
irOpCall irOpCall
} }
@@ -109,7 +108,8 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
return when (descriptor) { return when (descriptor) {
is SyntheticFieldDescriptor -> { is SyntheticFieldDescriptor -> {
val receiverValue = statementGenerator.generateBackingFieldReceiver(ktLeft.startOffset, ktLeft.endOffset, resolvedCall, descriptor) val receiverValue =
statementGenerator.generateBackingFieldReceiver(ktLeft.startOffset, ktLeft.endOffset, resolvedCall, descriptor)
createBackingFieldLValue(ktLeft, descriptor.propertyDescriptor, receiverValue, origin) createBackingFieldLValue(ktLeft, descriptor.propertyDescriptor, receiverValue, origin)
} }
is LocalVariableDescriptor -> is LocalVariableDescriptor ->
@@ -167,12 +167,12 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter) context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
) )
createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null) createBackingFieldLValue(ktLeft, descriptor, RematerializableValue(irThis), null)
} } else {
else {
val propertyReceiver = statementGenerator.generateCallReceiver( val propertyReceiver = statementGenerator.generateCallReceiver(
ktLeft, descriptor, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver, ktLeft, descriptor, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
isSafe = resolvedCall.call.isSafeCall(), isSafe = resolvedCall.call.isSafeCall(),
isAssignmentReceiver = true) isAssignmentReceiver = true
)
val superQualifier = getSuperQualifier(resolvedCall) val superQualifier = getSuperQualifier(resolvedCall)
@@ -208,8 +208,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
propertyReceiver, propertyReceiver,
superQualifierSymbol superQualifierSymbol
) )
} } else
else
FieldPropertyLValue( FieldPropertyLValue(
scope, scope,
ktExpression.startOffset, ktExpression.endOffset, origin, ktExpression.startOffset, ktExpression.endOffset, origin,
@@ -234,7 +233,10 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
} }
} }
private fun generateArrayAccessAssignmentReceiver(ktLeft: KtArrayAccessExpression, origin: IrStatementOrigin): ArrayAccessAssignmentReceiver { private fun generateArrayAccessAssignmentReceiver(
ktLeft: KtArrayAccessExpression,
origin: IrStatementOrigin
): ArrayAccessAssignmentReceiver {
val irArray = statementGenerator.generateExpression(ktLeft.arrayExpression!!) val irArray = statementGenerator.generateExpression(ktLeft.arrayExpression!!)
val irIndexExpressions = ktLeft.indexExpressions.map { statementGenerator.generateExpression(it) } val irIndexExpressions = ktLeft.indexExpressions.map { statementGenerator.generateExpression(it) }
@@ -244,9 +246,11 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
val indexedSetResolvedCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft) val indexedSetResolvedCall = get(BindingContext.INDEXED_LVALUE_SET, ktLeft)
val indexedSetCall = indexedSetResolvedCall?.let { statementGenerator.pregenerateCallReceivers(it) } val indexedSetCall = indexedSetResolvedCall?.let { statementGenerator.pregenerateCallReceivers(it) }
return ArrayAccessAssignmentReceiver(irArray, irIndexExpressions, indexedGetCall, indexedSetCall, return ArrayAccessAssignmentReceiver(
irArray, irIndexExpressions, indexedGetCall, indexedSetCall,
CallGenerator(statementGenerator), CallGenerator(statementGenerator),
ktLeft.startOffset, ktLeft.endOffset, origin) ktLeft.startOffset, ktLeft.endOffset, origin
)
} }
} }
@@ -48,8 +48,7 @@ class BodyGenerator(
val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset) val irBlockBody = IrBlockBodyImpl(ktBody.startOffset, ktBody.endOffset)
if (ktBody is KtBlockExpression) { if (ktBody is KtBlockExpression) {
statementGenerator.generateStatements(ktBody.statements, irBlockBody) statementGenerator.generateStatements(ktBody.statements, irBlockBody)
} } else {
else {
statementGenerator.generateReturnExpression(ktBody, irBlockBody) statementGenerator.generateReturnExpression(ktBody, irBlockBody)
} }
@@ -68,9 +67,11 @@ class BodyGenerator(
for (ktParameter in ktFun.valueParameters) { for (ktParameter in ktFun.valueParameters) {
val ktDestructuringDeclaration = ktParameter.destructuringDeclaration ?: continue val ktDestructuringDeclaration = ktParameter.destructuringDeclaration ?: continue
val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter) val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter)
val parameterValue = VariableLValue(ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset, val parameterValue = VariableLValue(
ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset,
context.symbolTable.referenceValue(valueParameter), context.symbolTable.referenceValue(valueParameter),
IrStatementOrigin.DESTRUCTURING_DECLARATION) IrStatementOrigin.DESTRUCTURING_DECLARATION
)
statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue) statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue)
} }
@@ -81,12 +82,16 @@ class BodyGenerator(
} }
val ktReturnedValue = ktBodyStatements.last() val ktReturnedValue = ktBodyStatements.last()
statementGenerator.generateReturnExpression(ktReturnedValue, irBlockBody) statementGenerator.generateReturnExpression(ktReturnedValue, irBlockBody)
} } else {
else { irBlockBody.statements.add(
irBlockBody.statements.add(generateReturnExpression( generateReturnExpression(
ktBody.startOffset, ktBody.endOffset, ktBody.startOffset, ktBody.endOffset,
IrGetObjectValueImpl(ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType, IrGetObjectValueImpl(
context.symbolTable.referenceClass(context.builtIns.unit)))) ktBody.startOffset, ktBody.endOffset, context.builtIns.unitType,
context.symbolTable.referenceClass(context.builtIns.unit)
)
)
)
} }
return irBlockBody return irBlockBody
@@ -96,8 +101,7 @@ class BodyGenerator(
val irReturnExpression = generateStatement(ktExpression) val irReturnExpression = generateStatement(ktExpression)
if (irReturnExpression is IrExpression) { if (irReturnExpression is IrExpression) {
irBlockBody.statements.add(irReturnExpression.wrapWithReturn()) irBlockBody.statements.add(irReturnExpression.wrapWithReturn())
} } else {
else {
irBlockBody.statements.add(irReturnExpression) irBlockBody.statements.add(irReturnExpression)
} }
} }
@@ -106,15 +110,17 @@ class BodyGenerator(
if (this is IrReturn || this is IrErrorExpression || this is IrThrow) if (this is IrReturn || this is IrErrorExpression || this is IrThrow)
this this
else { else {
generateReturnExpression(startOffset, endOffset, this) } generateReturnExpression(startOffset, endOffset, this)
}
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) ?: val returnTarget = (scopeOwner as? CallableDescriptor) ?: throw AssertionError("'return' in a non-callable: $scopeOwner")
throw AssertionError("'return' in a non-callable: $scopeOwner") return IrReturnImpl(
return IrReturnImpl(startOffset, endOffset, context.builtIns.nothingType, startOffset, endOffset, context.builtIns.nothingType,
context.symbolTable.referenceFunction(returnTarget), context.symbolTable.referenceFunction(returnTarget),
returnValue) returnValue
)
} }
@@ -140,8 +146,7 @@ class BodyGenerator(
if (delegatingConstructorResolvedCall == null) { if (delegatingConstructorResolvedCall == null) {
if (constructorDescriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) { if (constructorDescriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) {
generateEnumSuperConstructorCall(irBlockBody, ktConstructor) generateEnumSuperConstructorCall(irBlockBody, ktConstructor)
} } else {
else {
generateAnySuperConstructorCall(irBlockBody, ktConstructor) generateAnySuperConstructorCall(irBlockBody, ktConstructor)
} }
return return
@@ -150,7 +155,8 @@ class BodyGenerator(
val delegatingConstructorCall = statementGenerator.pregenerateCall(delegatingConstructorResolvedCall) val delegatingConstructorCall = statementGenerator.pregenerateCall(delegatingConstructorResolvedCall)
val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall( val irDelegatingConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset, ktDelegatingConstructorCall.startOffset, ktDelegatingConstructorCall.endOffset,
delegatingConstructorCall) delegatingConstructorCall
)
irBlockBody.statements.add(irDelegatingConstructorCall) irBlockBody.statements.add(irDelegatingConstructorCall)
} }
@@ -169,8 +175,12 @@ class BodyGenerator(
generateSuperConstructorCall(irBlockBody, ktClassOrObject) generateSuperConstructorCall(irBlockBody, ktClassOrObject)
val classDescriptor = (scopeOwner as ClassConstructorDescriptor).containingDeclaration val classDescriptor = (scopeOwner as ClassConstructorDescriptor).containingDeclaration
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktClassOrObject.startOffset, ktClassOrObject.endOffset, irBlockBody.statements.add(
context.symbolTable.referenceClass(classDescriptor))) IrInstanceInitializerCallImpl(
ktClassOrObject.startOffset, ktClassOrObject.endOffset,
context.symbolTable.referenceClass(classDescriptor)
)
)
return irBlockBody return irBlockBody
} }
@@ -181,8 +191,12 @@ class BodyGenerator(
generateDelegatingConstructorCall(irBlockBody, ktConstructor) generateDelegatingConstructorCall(irBlockBody, ktConstructor)
val classDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor).containingDeclaration as ClassDescriptor val classDescriptor = getOrFail(BindingContext.CONSTRUCTOR, ktConstructor).containingDeclaration as ClassDescriptor
irBlockBody.statements.add(IrInstanceInitializerCallImpl(ktConstructor.startOffset, ktConstructor.endOffset, irBlockBody.statements.add(
context.symbolTable.referenceClass(classDescriptor))) IrInstanceInitializerCallImpl(
ktConstructor.startOffset, ktConstructor.endOffset,
context.symbolTable.referenceClass(classDescriptor)
)
)
ktConstructor.bodyExpression?.let { ktBody -> ktConstructor.bodyExpression?.let { ktBody ->
createStatementGenerator().generateStatements(ktBody.statements, irBlockBody) createStatementGenerator().generateStatements(ktBody.statements, irBlockBody)
@@ -209,7 +223,8 @@ class BodyGenerator(
if (ktSuperTypeListEntry is KtSuperTypeCallEntry) { if (ktSuperTypeListEntry is KtSuperTypeCallEntry) {
val superConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktSuperTypeListEntry)!!) val superConstructorCall = statementGenerator.pregenerateCall(getResolvedCall(ktSuperTypeListEntry)!!)
val irSuperConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall( val irSuperConstructorCall = CallGenerator(statementGenerator).generateDelegatingConstructorCall(
ktSuperTypeListEntry.startOffset, ktSuperTypeListEntry.endOffset, superConstructorCall) ktSuperTypeListEntry.startOffset, ktSuperTypeListEntry.endOffset, superConstructorCall
)
irBlockBody.statements.add(irSuperConstructorCall) irBlockBody.statements.add(irSuperConstructorCall)
return return
} }
@@ -282,17 +297,22 @@ class BodyGenerator(
// Default enum entry constructor // Default enum entry constructor
val enumClassConstructor = val enumClassConstructor =
enumClassDescriptor.constructors.singleOrNull { it.valueParameters.all { it.hasDefaultValue() } } ?: enumClassDescriptor.constructors.singleOrNull { it.valueParameters.all { it.hasDefaultValue() } }
throw AssertionError("Enum class $enumClassDescriptor should have a default constructor") ?: throw AssertionError("Enum class $enumClassDescriptor should have a default constructor")
return IrEnumConstructorCallImpl( return IrEnumConstructorCallImpl(
ktEnumEntry.startOffset, ktEnumEntry.endOffset, ktEnumEntry.startOffset, ktEnumEntry.endOffset,
context.symbolTable.referenceConstructor(enumClassConstructor) context.symbolTable.referenceConstructor(enumClassConstructor)
) )
} }
private fun StatementGenerator.generateEnumConstructorCall(constructorCall: ResolvedCall<out CallableDescriptor>, ktEnumEntry: KtEnumEntry) = private fun StatementGenerator.generateEnumConstructorCall(
CallGenerator(this).generateEnumConstructorSuperCall(ktEnumEntry.startOffset, ktEnumEntry.endOffset, constructorCall: ResolvedCall<out CallableDescriptor>,
pregenerateCall(constructorCall)) ktEnumEntry: KtEnumEntry
) =
CallGenerator(this).generateEnumConstructorSuperCall(
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
pregenerateCall(constructorCall)
)
} }
@@ -39,7 +39,7 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
val irBranches = SmartList<IrBranch>() val irBranches = SmartList<IrBranch>()
var irElseBranch: IrExpression? = null var irElseBranch: IrExpression? = null
whenBranches@while (true) { whenBranches@ while (true) {
val irCondition = statementGenerator.generateExpression(ktLastIf.condition!!) val irCondition = statementGenerator.generateExpression(ktLastIf.condition!!)
val irThenBranch = statementGenerator.generateExpression(ktLastIf.then!!) val irThenBranch = statementGenerator.generateExpression(ktLastIf.then!!)
irBranches.add(IrBranchImpl(irCondition, irThenBranch)) irBranches.add(IrBranchImpl(irCondition, irThenBranch))
@@ -66,8 +66,10 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
resultType: KotlinType resultType: KotlinType
): IrWhen { ): IrWhen {
if (irBranches.size == 1) { if (irBranches.size == 1) {
return IrIfThenElseImpl(ktIf.startOffset, ktIf.endOffset, resultType, return IrIfThenElseImpl(
irBranches[0].condition, irBranches[0].result, irElseResult) ktIf.startOffset, ktIf.endOffset, resultType,
irBranches[0].condition, irBranches[0].result, irElseResult
)
} }
val irWhen = IrWhenImpl(ktIf.startOffset, ktIf.endOffset, resultType, IrStatementOrigin.WHEN) val irWhen = IrWhenImpl(ktIf.startOffset, ktIf.endOffset, resultType, IrStatementOrigin.WHEN)
@@ -146,14 +148,12 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, IrStatementOrigin.WHEN) IrBlockImpl(expression.startOffset, expression.endOffset, context.builtIns.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.builtIns.unitType, IrStatementOrigin.WHEN)
irBlock.statements.add(irSubject) irBlock.statements.add(irSubject)
irBlock irBlock
} } else {
else {
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irWhen.type, IrStatementOrigin.WHEN) val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, irWhen.type, IrStatementOrigin.WHEN)
irBlock.statements.add(irSubject) irBlock.statements.add(irSubject)
irBlock.statements.add(irWhen) irBlock.statements.add(irWhen)
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classValueType
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import java.util.* import java.util.*
class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorExtension(statementGenerator) { class CallGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateCall(startOffset: Int, endOffset: Int, call: CallBuilder, origin: IrStatementOrigin? = null): IrExpression { fun generateCall(startOffset: Int, endOffset: Int, call: CallBuilder, origin: IrStatementOrigin? = null): IrExpression {
val descriptor = call.descriptor val descriptor = call.descriptor
@@ -92,24 +92,26 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
if (descriptor is LocalVariableDescriptor && descriptor.isDelegated) { if (descriptor is LocalVariableDescriptor && descriptor.isDelegated) {
val getterDescriptor = descriptor.getter!! val getterDescriptor = descriptor.getter!!
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original) val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
IrCallImpl(startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor, IrCallImpl(
typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY) startOffset, endOffset, descriptor.type, getterSymbol, getterDescriptor,
} typeArguments, origin ?: IrStatementOrigin.GET_LOCAL_PROPERTY
else )
} else
IrGetValueImpl(startOffset, endOffset, context.symbolTable.referenceValue(descriptor), origin) IrGetValueImpl(startOffset, endOffset, 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 = IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, getTypeArguments(call.original)) val irCall =
IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, getTypeArguments(call.original))
irCall.dispatchReceiver = dispatchReceiver?.load() irCall.dispatchReceiver = dispatchReceiver?.load()
irCall.extensionReceiver = extensionReceiver?.load() irCall.extensionReceiver = extensionReceiver?.load()
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType) addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
} }
fun generateEnumConstructorSuperCall(startOffset: Int, endOffset: Int, call: CallBuilder) : IrExpression { fun generateEnumConstructorSuperCall(startOffset: Int, endOffset: Int, call: CallBuilder): IrExpression {
val constructorDescriptor = call.descriptor val constructorDescriptor = call.descriptor
if (constructorDescriptor !is ClassConstructorDescriptor) throw AssertionError("Constructor expected: $constructorDescriptor") if (constructorDescriptor !is ClassConstructorDescriptor) throw AssertionError("Constructor expected: $constructorDescriptor")
val classDescriptor = constructorDescriptor.containingDeclaration val classDescriptor = constructorDescriptor.containingDeclaration
@@ -146,8 +148,7 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
IrStatementOrigin.GET_PROPERTY, IrStatementOrigin.GET_PROPERTY,
superQualifierSymbol superQualifierSymbol
) )
} } else {
else {
val fieldSymbol = context.symbolTable.referenceField(descriptor) val fieldSymbol = context.symbolTable.referenceField(descriptor)
IrGetFieldImpl( IrGetFieldImpl(
startOffset, endOffset, startOffset, endOffset,
@@ -186,11 +187,16 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
addParametersToCall(startOffset, endOffset, call, irCall, returnType) addParametersToCall(startOffset, endOffset, call, irCall, returnType)
} }
private fun addParametersToCall(startOffset: Int, endOffset: Int, call: CallBuilder, irCall: IrFunctionAccessExpression, returnType: KotlinType): IrExpression = private fun addParametersToCall(
startOffset: Int,
endOffset: Int,
call: CallBuilder,
irCall: IrFunctionAccessExpression,
returnType: KotlinType
): IrExpression =
if (call.isValueArgumentReorderingRequired()) { if (call.isValueArgumentReorderingRequired()) {
generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType) generateCallWithArgumentReordering(irCall, startOffset, endOffset, call, returnType)
} } else {
else {
val valueArguments = call.getValueArgumentsInParameterOrder() val valueArguments = call.getValueArgumentsInParameterOrder()
for ((index, valueArgument) in valueArguments.withIndex()) { for ((index, valueArgument) in valueArguments.withIndex()) {
irCall.putValueArgument(index, valueArgument) irCall.putValueArgument(index, valueArgument)
@@ -23,12 +23,12 @@ 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.util.StableDescriptorsComparator
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
import org.jetbrains.kotlin.psi.KtEnumEntry import org.jetbrains.kotlin.psi.KtEnumEntry
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.ir.util.StableDescriptorsComparator
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
@@ -112,8 +112,8 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
val delegateType = getInferredTypeWithImplicitCastsOrFail(ktDelegateExpression) val delegateType = getInferredTypeWithImplicitCastsOrFail(ktDelegateExpression)
val superType = getOrFail(BindingContext.TYPE, ktEntry.typeReference!!) val superType = getOrFail(BindingContext.TYPE, ktEntry.typeReference!!)
val superTypeConstructorDescriptor = superType.constructor.declarationDescriptor val superTypeConstructorDescriptor = superType.constructor.declarationDescriptor
val superClass = superTypeConstructorDescriptor as? ClassDescriptor ?: val superClass = superTypeConstructorDescriptor as? ClassDescriptor
throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor") ?: throw AssertionError("Unexpected supertype constructor for delegation: $superTypeConstructorDescriptor")
val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType) val delegateDescriptor = IrImplementingDelegateDescriptorImpl(irClass.descriptor, delegateType, superType)
val irDelegateField = context.symbolTable.declareField( val irDelegateField = context.symbolTable.declareField(
ktDelegateExpression.startOffset, ktDelegateExpression.endOffset, ktDelegateExpression.startOffset, ktDelegateExpression.endOffset,
@@ -131,8 +131,10 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
} }
} }
private fun generateDelegatedMember(irClass: IrClass, irDelegate: IrField, private fun generateDelegatedMember(
delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor) { irClass: IrClass, irDelegate: IrField,
delegatedMember: CallableMemberDescriptor, overriddenMember: CallableMemberDescriptor
) {
when (delegatedMember) { when (delegatedMember) {
is FunctionDescriptor -> is FunctionDescriptor ->
generateDelegatedFunction(irClass, irDelegate, delegatedMember, overriddenMember as FunctionDescriptor) generateDelegatedFunction(irClass, irDelegate, delegatedMember, overriddenMember as FunctionDescriptor)
@@ -142,11 +144,20 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
} }
private fun generateDelegatedProperty(irClass: IrClass, irDelegate: IrField, delegated: PropertyDescriptor, overridden: PropertyDescriptor) { private fun generateDelegatedProperty(
irClass: IrClass,
irDelegate: IrField,
delegated: PropertyDescriptor,
overridden: PropertyDescriptor
) {
irClass.addMember(generateDelegatedProperty(irDelegate, delegated, overridden)) irClass.addMember(generateDelegatedProperty(irDelegate, delegated, overridden))
} }
private fun generateDelegatedProperty(irDelegate: IrField, delegated: PropertyDescriptor, overridden: PropertyDescriptor): IrPropertyImpl { private fun generateDelegatedProperty(
irDelegate: IrField,
delegated: PropertyDescriptor,
overridden: PropertyDescriptor
): IrPropertyImpl {
val startOffset = irDelegate.startOffset val startOffset = irDelegate.startOffset
val endOffset = irDelegate.endOffset val endOffset = irDelegate.endOffset
@@ -160,7 +171,12 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
return irProperty return irProperty
} }
private fun generateDelegatedFunction(irClass: IrClass, irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor) { private fun generateDelegatedFunction(
irClass: IrClass,
irDelegate: IrField,
delegated: FunctionDescriptor,
overridden: FunctionDescriptor
) {
irClass.addMember(generateDelegatedFunction(irDelegate, delegated, overridden)) irClass.addMember(generateDelegatedFunction(irDelegate, delegated, overridden))
} }
@@ -174,13 +190,16 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden, irFunction) irFunction.body = generateDelegateFunctionBody(irDelegate, delegated, overridden, irFunction)
} }
private fun generateDelegateFunctionBody(irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor, private fun generateDelegateFunctionBody(
irDelegatedFunction: IrSimpleFunction): IrBlockBodyImpl { irDelegate: IrField, delegated: FunctionDescriptor, overridden: FunctionDescriptor,
irDelegatedFunction: IrSimpleFunction
): IrBlockBodyImpl {
val startOffset = irDelegate.startOffset val startOffset = irDelegate.startOffset
val endOffset = irDelegate.endOffset val endOffset = irDelegate.endOffset
val irBlockBody = IrBlockBodyImpl(startOffset, endOffset) val irBlockBody = IrBlockBodyImpl(startOffset, endOffset)
val returnType = overridden.returnType!! val returnType = overridden.returnType!!
val irCall = IrCallImpl(startOffset, endOffset, returnType, context.symbolTable.referenceFunction(overridden.original), overridden, null) val irCall =
IrCallImpl(startOffset, endOffset, returnType, context.symbolTable.referenceFunction(overridden.original), overridden, null)
irCall.dispatchReceiver = irCall.dispatchReceiver =
IrGetFieldImpl( IrGetFieldImpl(
startOffset, endOffset, irDelegate.symbol, startOffset, endOffset, irDelegate.symbol,
@@ -197,8 +216,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
} }
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.builtIns.nothingType, irDelegatedFunction.symbol, irCall)
irBlockBody.statements.add(irReturn) irBlockBody.statements.add(irReturn)
} }
@@ -217,7 +235,8 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
val classDescriptor = irClass.descriptor val classDescriptor = irClass.descriptor
val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return null val primaryConstructorDescriptor = classDescriptor.unsubstitutedPrimaryConstructor ?: return null
val irPrimaryConstructor = FunctionGenerator(declarationGenerator).generatePrimaryConstructor(primaryConstructorDescriptor, ktClassOrObject) val irPrimaryConstructor =
FunctionGenerator(declarationGenerator).generatePrimaryConstructor(primaryConstructorDescriptor, ktClassOrObject)
if (!DescriptorUtils.isAnnotationClass(classDescriptor)) { if (!DescriptorUtils.isAnnotationClass(classDescriptor)) {
irClass.addMember(irPrimaryConstructor) irClass.addMember(irPrimaryConstructor)
@@ -100,8 +100,8 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
} }
override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) { override fun generateComponentFunction(function: FunctionDescriptor, parameter: ValueParameterDescriptor) {
val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter) ?: val ktParameter = DescriptorToSourceUtils.descriptorToDeclaration(parameter)
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(irThis(), getPropertyGetterSymbol(parameter)))
@@ -117,8 +117,8 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
context.symbolTable.referenceFunction(property.getter!!) context.symbolTable.referenceFunction(property.getter!!)
override fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>) { override fun generateCopyFunction(function: FunctionDescriptor, constructorParameters: List<KtParameter>) {
val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor ?: val dataClassConstructor = classDescriptor.unsubstitutedPrimaryConstructor
throw AssertionError("Data class should have a primary constructor: $classDescriptor") ?: throw AssertionError("Data class should have a primary constructor: $classDescriptor")
val constructorSymbol = context.symbolTable.referenceConstructor(dataClassConstructor) val constructorSymbol = context.symbolTable.referenceConstructor(dataClassConstructor)
buildMember(function, declaration) { irFunction -> buildMember(function, declaration) { irFunction ->
@@ -138,8 +138,11 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
val otherWithCast = irTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast") val otherWithCast = irTemporary(irAs(irOther(), classDescriptor.defaultType), "other_with_cast")
for (property in properties) { for (property in properties) {
+irIfThenReturnFalse( +irIfThenReturnFalse(
irNotEquals(irGet(irThis(), getPropertyGetterSymbol(property)), irNotEquals(
irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property)))) irGet(irThis(), getPropertyGetterSymbol(property)),
irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))
)
)
} }
+irReturnTrue() +irReturnTrue()
} }
@@ -163,9 +166,9 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
is ClassDescriptor -> { is ClassDescriptor -> {
if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)) { if (KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)) {
context.irBuiltIns.dataClassArrayMemberHashCodeSymbol context.irBuiltIns.dataClassArrayMemberHashCodeSymbol
} } else {
else { val hashCodeDescriptor: CallableDescriptor =
val hashCodeDescriptor: CallableDescriptor = typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() } typeConstructorDescriptor.findFirstFunction("hashCode") { it.valueParameters.isEmpty() }
context.symbolTable.referenceFunction(hashCodeDescriptor) context.symbolTable.referenceFunction(hashCodeDescriptor)
} }
} }
@@ -209,8 +212,7 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
irCall(getHashCodeFunction(irValue.type)).apply { irCall(getHashCodeFunction(irValue.type)).apply {
if (descriptor.dispatchReceiverParameter != null) { if (descriptor.dispatchReceiverParameter != null) {
dispatchReceiver = irValue dispatchReceiver = irValue
} } else {
else {
putValueArgument(0, irValue) putValueArgument(0, irValue)
} }
} }
@@ -69,8 +69,10 @@ class DeclarationGenerator(override val context: GeneratorContext) : Generator {
ClassGenerator(this).generateClass(ktClassOrObject) ClassGenerator(this).generateClass(ktClassOrObject)
fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration = fun generateTypeAliasDeclaration(ktDeclaration: KtTypeAlias): IrDeclaration =
IrTypeAliasImpl(ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED, IrTypeAliasImpl(
getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration)) ktDeclaration.startOffset, ktDeclaration.endOffset, IrDeclarationOrigin.DEFINED,
getOrFail(BindingContext.TYPE_ALIAS, ktDeclaration)
)
fun generateTypeParameterDeclarations( fun generateTypeParameterDeclarations(
@@ -105,7 +105,12 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
private fun getKPropertyTypeForDelegatedProperty(propertyDescriptor: PropertyDescriptor): KotlinType { private fun getKPropertyTypeForDelegatedProperty(propertyDescriptor: PropertyDescriptor): KotlinType {
val receivers = listOfNotNull(propertyDescriptor.extensionReceiverParameter, propertyDescriptor.dispatchReceiverParameter) val receivers = listOfNotNull(propertyDescriptor.extensionReceiverParameter, propertyDescriptor.dispatchReceiverParameter)
return context.reflectionTypes.getKPropertyType(Annotations.EMPTY, receivers.map{ it.type }, propertyDescriptor.type, propertyDescriptor.isVar) return context.reflectionTypes.getKPropertyType(
Annotations.EMPTY,
receivers.map { it.type },
propertyDescriptor.type,
propertyDescriptor.isVar
)
} }
private fun generateDelegateFieldForProperty( private fun generateDelegateFieldForProperty(
@@ -143,17 +148,24 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
val provideDelegateCall = statementGenerator.pregenerateCall(provideDelegateResolvedCall) val provideDelegateCall = statementGenerator.pregenerateCall(provideDelegateResolvedCall)
provideDelegateCall.setExplicitReceiverValue(OnceExpressionValue(irDelegateInitializer.expression)) provideDelegateCall.setExplicitReceiverValue(OnceExpressionValue(irDelegateInitializer.expression))
provideDelegateCall.irValueArgumentsByIndex[1] = createCallableReference(ktDelegate, kPropertyType, property, scopeOwner) provideDelegateCall.irValueArgumentsByIndex[1] = createCallableReference(ktDelegate, kPropertyType, property, scopeOwner)
val irProvideDelegate = CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, provideDelegateCall) val irProvideDelegate =
CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, provideDelegateCall)
return IrExpressionBodyImpl(irProvideDelegate) return IrExpressionBodyImpl(irProvideDelegate)
} }
private fun createBackingFieldValueForDelegate(irDelegateField: IrFieldSymbol, thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue { private fun createBackingFieldValueForDelegate(
irDelegateField: IrFieldSymbol,
thisClass: ClassDescriptor?,
ktDelegate: KtPropertyDelegate
): IntermediateValue {
val thisValue = createThisValueForDelegate(thisClass, ktDelegate) val thisValue = createThisValueForDelegate(thisClass, ktDelegate)
return BackingFieldLValue(ktDelegate.startOffset, ktDelegate.endOffset, return BackingFieldLValue(
ktDelegate.startOffset, ktDelegate.endOffset,
irDelegateField.descriptor.type, irDelegateField.descriptor.type,
irDelegateField, irDelegateField,
thisValue, thisValue,
null) null
)
} }
private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? = private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? =
@@ -224,7 +236,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
irLocalDelegatedProperty.getter = irLocalDelegatedProperty.getter =
createLocalPropertyAccessor(getterDescriptor, ktDelegate) { irGetter -> createLocalPropertyAccessor(getterDescriptor, ktDelegate) { irGetter ->
generateDelegatedPropertyGetterBody( generateDelegatedPropertyGetterBody(
irGetter,ktDelegate, getterDescriptor, delegateReceiverValue, irGetter, ktDelegate, getterDescriptor, delegateReceiverValue,
createLocalDelegatedPropertyReference( createLocalDelegatedPropertyReference(
ktDelegate, kPropertyType, ktDelegate, kPropertyType,
variableDescriptor, irDelegate.symbol, variableDescriptor, irDelegate.symbol,
@@ -293,8 +305,8 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
val ktDelegateExpression = ktDelegate.expression!! val ktDelegateExpression = ktDelegate.expression!!
val irDelegateInitializer = createBodyGenerator(scopeOwner).createStatementGenerator().generateExpression(ktDelegateExpression) val irDelegateInitializer = createBodyGenerator(scopeOwner).createStatementGenerator().generateExpression(ktDelegateExpression)
val provideDelegateResolvedCall = get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor) ?: val provideDelegateResolvedCall =
return irDelegateInitializer get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, variableDescriptor) ?: return irDelegateInitializer
val statementGenerator = createBodyGenerator(scopeOwner).createStatementGenerator() val statementGenerator = createBodyGenerator(scopeOwner).createStatementGenerator()
@@ -356,7 +368,13 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall) val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue) conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall)) +irReturn(
CallGenerator(statementGenerator).generateCall(
ktDelegate.startOffset,
ktDelegate.endOffset,
conventionMethodCall
)
)
} }
} }
@@ -35,9 +35,11 @@ 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) {
IrErrorExpressionImpl(ktElement.startOffset, ktElement.endOffset, IrErrorExpressionImpl(
ktElement.startOffset, ktElement.endOffset,
if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""), if (ktElement is KtExpression) getErrorExpressionType(ktElement) else ErrorUtils.createErrorType(""),
e.message ?: "") e.message ?: ""
)
} }
fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) { fun generateErrorCall(ktCall: KtCallExpression): IrExpression = generateErrorExpression(ktCall) {
@@ -131,7 +131,11 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
else -> throw AssertionError("Should be getter or setter: $accessor") else -> throw AssertionError("Should be getter or setter: $accessor")
} }
private fun generateDefaultGetterBody(ktProperty: KtElement, getter: PropertyGetterDescriptor, irAccessor: IrSimpleFunction): IrBlockBody { private fun generateDefaultGetterBody(
ktProperty: KtElement,
getter: PropertyGetterDescriptor,
irAccessor: IrSimpleFunction
): IrBlockBody {
val property = getter.correspondingProperty val property = getter.correspondingProperty
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset) val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
@@ -152,7 +156,11 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
return irBody return irBody
} }
private fun generateDefaultSetterBody(ktProperty: KtElement, setter: PropertySetterDescriptor, irAccessor: IrSimpleFunction): IrBlockBody { private fun generateDefaultSetterBody(
ktProperty: KtElement,
setter: PropertySetterDescriptor,
irAccessor: IrSimpleFunction
): IrBlockBody {
val property = setter.correspondingProperty val property = setter.correspondingProperty
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset) val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
@@ -175,8 +183,10 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
val containingDeclaration = property.containingDeclaration val containingDeclaration = property.containingDeclaration
return when (containingDeclaration) { return when (containingDeclaration) {
is ClassDescriptor -> is ClassDescriptor ->
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, IrGetValueImpl(
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter)) ktProperty.startOffset, ktProperty.endOffset,
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter)
)
else -> null else -> null
} }
} }
@@ -62,15 +62,21 @@ fun Generator.getResolvedCall(key: KtElement): ResolvedCall<out CallableDescript
key.getResolvedCall(context.bindingContext) key.getResolvedCall(context.bindingContext)
fun Generator.createDummyExpression(ktExpression: KtExpression, description: String): IrErrorExpressionImpl = fun Generator.createDummyExpression(ktExpression: KtExpression, description: String): IrErrorExpressionImpl =
IrErrorExpressionImpl(ktExpression.startOffset, ktExpression.endOffset, getInferredTypeWithImplicitCastsOrFail(ktExpression), description) IrErrorExpressionImpl(
ktExpression.startOffset,
ktExpression.endOffset,
getInferredTypeWithImplicitCastsOrFail(ktExpression),
description
)
inline fun GeneratorWithScope.irBlock(ktElement: KtElement?, inline fun GeneratorWithScope.irBlock(
ktElement: KtElement?,
origin: IrStatementOrigin? = null, resultType: KotlinType? = null, origin: IrStatementOrigin? = null, resultType: KotlinType? = null,
body: IrBlockBuilder.() -> Unit body: IrBlockBuilder.() -> Unit
): IrExpression = ): IrExpression =
this.irBlock(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, origin, resultType, body) this.irBlock(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, origin, resultType, body)
inline fun GeneratorWithScope.irBlockBody(ktElement: KtElement?, body: IrBlockBodyBuilder.() -> Unit) : IrBlockBody = inline fun GeneratorWithScope.irBlockBody(ktElement: KtElement?, body: IrBlockBodyBuilder.() -> Unit): IrBlockBody =
this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body) this.irBlockBody(ktElement.startOffsetOrUndefined, ktElement.endOffsetOrUndefined, body)
@@ -25,16 +25,17 @@ import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
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 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 objectLiteralType = getInferredTypeWithImplicitCastsOrFail(ktObjectLiteral)
val irBlock = IrBlockImpl(ktObjectLiteral.startOffset, ktObjectLiteral.endOffset, objectLiteralType, IrStatementOrigin.OBJECT_LITERAL) val irBlock =
IrBlockImpl(ktObjectLiteral.startOffset, ktObjectLiteral.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)
val objectConstructor = irClass.descriptor.unsubstitutedPrimaryConstructor ?: val objectConstructor = irClass.descriptor.unsubstitutedPrimaryConstructor
throw AssertionError("Object literal should have a primary constructor: ${irClass.descriptor}") ?: throw AssertionError("Object literal should have a primary constructor: ${irClass.descriptor}")
assert(objectConstructor.dispatchReceiverParameter == null) { assert(objectConstructor.dispatchReceiverParameter == null) {
"Object literal constructor should have no dispatch receiver parameter: $objectConstructor" "Object literal constructor should have no dispatch receiver parameter: $objectConstructor"
} }
@@ -47,8 +47,7 @@ class LocalFunctionGenerator(statementGenerator: StatementGenerator) : Statement
fun generateFunction(ktFun: KtNamedFunction): IrStatement = fun generateFunction(ktFun: KtNamedFunction): IrStatement =
if (ktFun.name != null) { if (ktFun.name != null) {
generateFunctionDeclaration(ktFun) generateFunctionDeclaration(ktFun)
} } else {
else {
// anonymous function expression // anonymous function expression
val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun) val funExpressionType = getInferredTypeWithImplicitCastsOrFail(ktFun)
val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION) val irBlock = IrBlockImpl(ktFun.startOffset, ktFun.endOffset, funExpressionType, IrStatementOrigin.ANONYMOUS_FUNCTION)
@@ -29,10 +29,12 @@ import org.jetbrains.kotlin.psi2ir.intermediate.VariableLValue
import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue import org.jetbrains.kotlin.psi2ir.intermediate.setExplicitReceiverValue
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
class LoopExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator){ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression { fun generateWhileLoop(ktWhile: KtWhileExpression): IrExpression {
val irLoop = IrWhileLoopImpl(ktWhile.startOffset, ktWhile.endOffset, val irLoop = IrWhileLoopImpl(
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP) ktWhile.startOffset, ktWhile.endOffset,
context.builtIns.unitType, IrStatementOrigin.WHILE_LOOP
)
irLoop.condition = statementGenerator.generateExpression(ktWhile.condition!!) irLoop.condition = statementGenerator.generateExpression(ktWhile.condition!!)
@@ -51,8 +53,10 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
} }
fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression { fun generateDoWhileLoop(ktDoWhile: KtDoWhileExpression): IrExpression {
val irLoop = IrDoWhileLoopImpl(ktDoWhile.startOffset, ktDoWhile.endOffset, val irLoop = IrDoWhileLoopImpl(
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP) ktDoWhile.startOffset, ktDoWhile.endOffset,
context.builtIns.unitType, IrStatementOrigin.DO_WHILE_LOOP
)
statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop) statementGenerator.bodyGenerator.putLoop(ktDoWhile, irLoop)
@@ -86,18 +90,18 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
) )
fun generateBreak(ktBreak: KtBreakExpression): IrExpression { fun generateBreak(ktBreak: KtBreakExpression): IrExpression {
val parentLoop = findParentLoop(ktBreak) ?: val parentLoop = findParentLoop(ktBreak) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
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.builtIns.nothingType, parentLoop).apply {
label = ktBreak.getLabelName() label = ktBreak.getLabelName()
} }
} }
fun generateContinue(ktContinue: KtContinueExpression): IrExpression { fun generateContinue(ktContinue: KtContinueExpression): IrExpression {
val parentLoop = findParentLoop(ktContinue) ?: val parentLoop = findParentLoop(ktContinue) ?: return ErrorExpressionGenerator(statementGenerator).generateErrorExpression(
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.builtIns.nothingType, parentLoop).apply {
label = ktContinue.getLabelName() label = ktContinue.getLabelName()
} }
@@ -118,8 +122,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
} }
if (targetLabel == null) { if (targetLabel == null) {
return getLoop(finger) ?: continue return getLoop(finger) ?: continue
} } else {
else {
val parent = finger.parent val parent = finger.parent
if (parent is KtLabeledExpression) { if (parent is KtLabeledExpression) {
val label = parent.getLabelName()!! val label = parent.getLabelName()!!
@@ -159,7 +162,8 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
val iteratorValue = VariableLValue(irIterator) val iteratorValue = VariableLValue(irIterator)
irForBlock.statements.add(irIterator) irForBlock.statements.add(irIterator)
val irInnerWhile = IrWhileLoopImpl(ktFor.startOffset, ktFor.endOffset, context.builtIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE) val irInnerWhile =
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)
@@ -187,7 +191,11 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen
irInnerBody.statements.add(irLoopParameter) irInnerBody.statements.add(irLoopParameter)
if (ktLoopDestructuringDeclaration != null) { if (ktLoopDestructuringDeclaration != null) {
statementGenerator.declareComponentVariablesInBlock(ktLoopDestructuringDeclaration, irInnerBody, VariableLValue(irLoopParameter)) statementGenerator.declareComponentVariablesInBlock(
ktLoopDestructuringDeclaration,
irInnerBody,
VariableLValue(irLoopParameter)
)
} }
if (ktForBody != null) { if (ktForBody != null) {
@@ -83,8 +83,17 @@ val AUGMENTED_ASSIGNMENTS =
setOf(IrStatementOrigin.PLUSEQ, IrStatementOrigin.MINUSEQ, IrStatementOrigin.MULTEQ, IrStatementOrigin.DIVEQ, IrStatementOrigin.PERCEQ) setOf(IrStatementOrigin.PLUSEQ, IrStatementOrigin.MINUSEQ, IrStatementOrigin.MULTEQ, IrStatementOrigin.DIVEQ, IrStatementOrigin.PERCEQ)
val OPERATORS_DESUGARED_TO_CALLS = val OPERATORS_DESUGARED_TO_CALLS =
setOf(IrStatementOrigin.PLUS, IrStatementOrigin.MINUS, IrStatementOrigin.MUL, IrStatementOrigin.DIV, IrStatementOrigin.PERC, IrStatementOrigin.RANGE, setOf(
IrStatementOrigin.EXCL, IrStatementOrigin.UMINUS, IrStatementOrigin.UPLUS) IrStatementOrigin.PLUS,
IrStatementOrigin.MINUS,
IrStatementOrigin.MUL,
IrStatementOrigin.DIV,
IrStatementOrigin.PERC,
IrStatementOrigin.RANGE,
IrStatementOrigin.EXCL,
IrStatementOrigin.UMINUS,
IrStatementOrigin.UPLUS
)
val COMPARISON_OPERATORS = val COMPARISON_OPERATORS =
setOf(IrStatementOrigin.LT, IrStatementOrigin.LTEQ, IrStatementOrigin.GT, IrStatementOrigin.GTEQ) setOf(IrStatementOrigin.LT, IrStatementOrigin.LTEQ, IrStatementOrigin.GT, IrStatementOrigin.GTEQ)
@@ -44,7 +44,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return when (irOperator) { return when (irOperator) {
null -> throw AssertionError("Unexpected prefix operator: $ktOperator") null -> throw AssertionError("Unexpected prefix operator: $ktOperator")
in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePrefixIncrementDecrement(expression, irOperator) in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePrefixIncrementDecrement(
expression,
irOperator
)
in OPERATORS_DESUGARED_TO_CALLS -> generatePrefixOperatorAsCall(expression, irOperator) in OPERATORS_DESUGARED_TO_CALLS -> generatePrefixOperatorAsCall(expression, irOperator)
else -> createDummyExpression(expression, ktOperator.toString()) else -> createDummyExpression(expression, ktOperator.toString())
} }
@@ -56,7 +59,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return when (irOperator) { return when (irOperator) {
null -> throw AssertionError("Unexpected postfix operator: $ktOperator") null -> throw AssertionError("Unexpected postfix operator: $ktOperator")
in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePostfixIncrementDecrement(expression, irOperator) in INCREMENT_DECREMENT_OPERATORS -> AssignmentGenerator(statementGenerator).generatePostfixIncrementDecrement(
expression,
irOperator
)
IrStatementOrigin.EXCLEXCL -> generateExclExclOperator(expression, irOperator) IrStatementOrigin.EXCLEXCL -> generateExclExclOperator(expression, irOperator)
else -> createDummyExpression(expression, ktOperator.toString()) else -> createDummyExpression(expression, ktOperator.toString())
} }
@@ -76,8 +82,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
throw AssertionError("Unexpected IrTypeOperator: $irOperator") throw AssertionError("Unexpected IrTypeOperator: $irOperator")
} }
return IrTypeOperatorCallImpl(expression.startOffset, expression.endOffset, resultType, irOperator, rhsType, return IrTypeOperatorCallImpl(
statementGenerator.generateExpression(expression.left)) expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
statementGenerator.generateExpression(expression.left)
)
} }
fun generateInstanceOfExpression(expression: KtIsExpression): IrStatement { fun generateInstanceOfExpression(expression: KtIsExpression): IrStatement {
@@ -85,8 +93,10 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val irOperator = getIrTypeOperator(ktOperator)!! val irOperator = getIrTypeOperator(ktOperator)!!
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference) val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
return IrTypeOperatorCallImpl(expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator, return IrTypeOperatorCallImpl(
againstType, statementGenerator.generateExpression(expression.leftHandSide)) expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
againstType, statementGenerator.generateExpression(expression.leftHandSide)
)
} }
fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression { fun generateBinaryExpression(expression: KtBinaryExpression): IrExpression {
@@ -140,15 +150,18 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrStatementOrigin): IrExpression { private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrStatementOrigin): IrExpression {
val containsCall = getResolvedCall(expression)!! val containsCall = getResolvedCall(expression)!!
val irContainsCall = CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(containsCall), irOperator) val irContainsCall =
CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(containsCall), irOperator)
return when (irOperator) { return when (irOperator) {
IrStatementOrigin.IN -> IrStatementOrigin.IN ->
irContainsCall irContainsCall
IrStatementOrigin.NOT_IN -> IrStatementOrigin.NOT_IN ->
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN, IrUnaryPrimitiveImpl(
expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN,
context.irBuiltIns.booleanNotSymbol, context.irBuiltIns.booleanNotSymbol,
irContainsCall) irContainsCall
)
else -> else ->
throw AssertionError("Unexpected in-operator $irOperator") throw AssertionError("Unexpected in-operator $irOperator")
} }
@@ -160,17 +173,21 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val irArgument1 = statementGenerator.generateExpression(expression.right!!) val irArgument1 = statementGenerator.generateExpression(expression.right!!)
val irIdentityEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset, irOperator, val irIdentityEquals = IrBinaryPrimitiveImpl(
expression.startOffset, expression.endOffset, irOperator,
context.irBuiltIns.eqeqeqSymbol, context.irBuiltIns.eqeqeqSymbol,
irArgument0, irArgument1) irArgument0, irArgument1
)
return when (irOperator) { return when (irOperator) {
IrStatementOrigin.EQEQEQ -> IrStatementOrigin.EQEQEQ ->
irIdentityEquals irIdentityEquals
IrStatementOrigin.EXCLEQEQ -> IrStatementOrigin.EXCLEQEQ ->
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ, IrUnaryPrimitiveImpl(
expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ,
context.irBuiltIns.booleanNotSymbol, context.irBuiltIns.booleanNotSymbol,
irIdentityEquals) irIdentityEquals
)
else -> else ->
throw AssertionError("Unexpected identity operator $irOperator") throw AssertionError("Unexpected identity operator $irOperator")
} }
@@ -181,18 +198,22 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
val irArgument0 = statementGenerator.generateExpression(expression.left!!) val irArgument0 = statementGenerator.generateExpression(expression.left!!)
val irArgument1 = statementGenerator.generateExpression(expression.right!!) val irArgument1 = statementGenerator.generateExpression(expression.right!!)
val irEquals = IrBinaryPrimitiveImpl(expression.startOffset, expression.endOffset, val irEquals = IrBinaryPrimitiveImpl(
expression.startOffset, expression.endOffset,
irOperator, irOperator,
context.irBuiltIns.eqeqSymbol, context.irBuiltIns.eqeqSymbol,
irArgument0, irArgument1) irArgument0, irArgument1
)
return when (irOperator) { return when (irOperator) {
IrStatementOrigin.EQEQ -> IrStatementOrigin.EQEQ ->
irEquals irEquals
IrStatementOrigin.EXCLEQ -> IrStatementOrigin.EXCLEQ ->
IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQ, IrUnaryPrimitiveImpl(
expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQ,
context.irBuiltIns.booleanNotSymbol, context.irBuiltIns.booleanNotSymbol,
irEquals) irEquals
)
else -> else ->
throw AssertionError("Unexpected equality operator $irOperator") throw AssertionError("Unexpected equality operator $irOperator")
} }
@@ -202,7 +223,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
private fun generateComparisonOperator(expression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression { private fun generateComparisonOperator(expression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
val compareToCall = getResolvedCall(expression)!! val compareToCall = getResolvedCall(expression)!!
val irCompareToCall = CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(compareToCall), origin) val irCompareToCall =
CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(compareToCall), origin)
val compareToZeroSymbol = when (origin) { val compareToZeroSymbol = when (origin) {
IrStatementOrigin.LT -> context.irBuiltIns.lt0Symbol IrStatementOrigin.LT -> context.irBuiltIns.lt0Symbol
@@ -51,21 +51,25 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
).also { irProperty -> ).also { irProperty ->
irProperty.backingField = irProperty.backingField =
generatePropertyBackingField(ktParameter, propertyDescriptor) { generatePropertyBackingField(ktParameter, propertyDescriptor) {
IrExpressionBodyImpl(IrGetValueImpl( IrExpressionBodyImpl(
IrGetValueImpl(
ktParameter.startOffset, ktParameter.endOffset, ktParameter.startOffset, ktParameter.endOffset,
irValueParameter.symbol, irValueParameter.symbol,
IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER
)) )
)
} }
val getter = propertyDescriptor.getter ?: val getter = propertyDescriptor.getter
throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor") ?: throw AssertionError("Property declared in primary constructor has no getter: $propertyDescriptor")
irProperty.getter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter) irProperty.getter =
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(getter, ktParameter)
if (propertyDescriptor.isVar) { if (propertyDescriptor.isVar) {
val setter = propertyDescriptor.setter ?: val setter = propertyDescriptor.setter
throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor") ?: throw AssertionError("Property declared in primary constructor has no setter: $propertyDescriptor")
irProperty.setter = FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktParameter) irProperty.setter =
FunctionGenerator(declarationGenerator).generateDefaultAccessorForPrimaryConstructorParameter(setter, ktParameter)
} }
} }
} }
@@ -74,7 +78,7 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
ktPropertyElement: KtElement, ktPropertyElement: KtElement,
propertyDescriptor: PropertyDescriptor, propertyDescriptor: PropertyDescriptor,
generateInitializer: (IrField) -> IrExpressionBody? generateInitializer: (IrField) -> IrExpressionBody?
) : IrField = ): IrField =
context.symbolTable.declareField( context.symbolTable.declareField(
ktPropertyElement.startOffset, ktPropertyElement.endOffset, ktPropertyElement.startOffset, ktPropertyElement.endOffset,
IrDeclarationOrigin.PROPERTY_BACKING_FIELD, IrDeclarationOrigin.PROPERTY_BACKING_FIELD,
@@ -37,15 +37,18 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral) val resultType = getInferredTypeWithImplicitCastsOrFail(ktClassLiteral)
return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) { return if (lhs is DoubleColonLHS.Expression && !lhs.isObjectQualifier) {
IrGetClassImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType, IrGetClassImpl(
statementGenerator.generateExpression(ktArgument)) ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
} statementGenerator.generateExpression(ktArgument)
else { )
} else {
val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor val typeConstructorDeclaration = lhs.type.constructor.declarationDescriptor
val typeClass = typeConstructorDeclaration ?: val typeClass = typeConstructorDeclaration
throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration") ?: throw AssertionError("Unexpected type constructor for ${lhs.type}: $typeConstructorDeclaration")
IrClassReferenceImpl(ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType, IrClassReferenceImpl(
context.symbolTable.referenceClassifier(typeClass), lhs.type) ktClassLiteral.startOffset, ktClassLiteral.endOffset, resultType,
context.symbolTable.referenceClassifier(typeClass), lhs.type
)
} }
} }
@@ -108,8 +111,8 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
irDelegateSymbol: IrVariableSymbol, irDelegateSymbol: IrVariableSymbol,
origin: IrStatementOrigin? origin: IrStatementOrigin?
): IrLocalDelegatedPropertyReference { ): IrLocalDelegatedPropertyReference {
val getterDescriptor = variableDescriptor.getter ?: val getterDescriptor =
throw AssertionError("Local delegated property should have a getter: $variableDescriptor") variableDescriptor.getter ?: throw AssertionError("Local delegated property should have a getter: $variableDescriptor")
val setterDescriptor = variableDescriptor.setter val setterDescriptor = variableDescriptor.setter
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor) val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor)
@@ -63,8 +63,7 @@ class StatementGenerator(
private fun KtElement.genStmt(): IrStatement = private fun KtElement.genStmt(): IrStatement =
try { try {
deparenthesize().accept(this@StatementGenerator, null) deparenthesize().accept(this@StatementGenerator, null)
} } catch (e: Exception) {
catch (e: Exception) {
ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e) ErrorExpressionGenerator(this@StatementGenerator).generateErrorExpression(this, e)
} }
@@ -78,8 +77,10 @@ class StatementGenerator(
val variableDescriptor = getOrFail(BindingContext.VARIABLE, property) val variableDescriptor = getOrFail(BindingContext.VARIABLE, property)
property.delegate?.let { ktDelegate -> property.delegate?.let { ktDelegate ->
return generateLocalDelegatedProperty(property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors, return generateLocalDelegatedProperty(
bodyGenerator.scopeOwnerSymbol) property, ktDelegate, variableDescriptor as VariableDescriptorWithAccessors,
bodyGenerator.scopeOwnerSymbol
)
} }
return context.symbolTable.declareVariable( return context.symbolTable.declareVariable(
@@ -98,8 +99,10 @@ class StatementGenerator(
.generateLocalDelegatedProperty(ktProperty, ktDelegate, variableDescriptor, scopeOwnerSymbol) .generateLocalDelegatedProperty(ktProperty, ktDelegate, variableDescriptor, scopeOwnerSymbol)
override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement { override fun visitDestructuringDeclaration(multiDeclaration: KtDestructuringDeclaration, data: Nothing?): IrStatement {
val irBlock = IrCompositeImpl(multiDeclaration.startOffset, multiDeclaration.endOffset, val irBlock = IrCompositeImpl(
context.builtIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION) multiDeclaration.startOffset, multiDeclaration.endOffset,
context.builtIns.unitType, IrStatementOrigin.DESTRUCTURING_DECLARATION
)
val ktInitializer = multiDeclaration.initializer!! val ktInitializer = multiDeclaration.initializer!!
val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container") val containerValue = scope.createTemporaryVariableInBlock(ktInitializer.genExpr(), irBlock, "container")
@@ -108,7 +111,11 @@ class StatementGenerator(
return irBlock return irBlock
} }
fun declareComponentVariablesInBlock(multiDeclaration: KtDestructuringDeclaration, irBlock: IrStatementContainer, containerValue: IntermediateValue) { fun declareComponentVariablesInBlock(
multiDeclaration: KtDestructuringDeclaration,
irBlock: IrStatementContainer,
containerValue: IntermediateValue
) {
val callGenerator = CallGenerator(this) val callGenerator = CallGenerator(this)
for ((index, ktEntry) in multiDeclaration.entries.withIndex()) { for ((index, ktEntry) in multiDeclaration.entries.withIndex()) {
val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry) val componentResolvedCall = getOrFail(BindingContext.COMPONENT_RESOLVED_CALL, ktEntry)
@@ -121,8 +128,10 @@ class StatementGenerator(
// componentN for '_' SHOULD NOT be evaluated // componentN for '_' SHOULD NOT be evaluated
if (componentVariable.name.isSpecial) continue if (componentVariable.name.isSpecial) continue
val irComponentCall = callGenerator.generateCall(ktEntry.startOffset, ktEntry.endOffset, componentSubstitutedCall, val irComponentCall = callGenerator.generateCall(
IrStatementOrigin.COMPONENT_N.withIndex(index + 1)) ktEntry.startOffset, ktEntry.endOffset, componentSubstitutedCall,
IrStatementOrigin.COMPONENT_N.withIndex(index + 1)
)
val irComponentVar = context.symbolTable.declareVariable( val irComponentVar = context.symbolTable.declareVariable(
ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED, ktEntry.startOffset, ktEntry.endOffset, IrDeclarationOrigin.DEFINED,
componentVariable, irComponentCall componentVariable, irComponentCall
@@ -147,11 +156,14 @@ class StatementGenerator(
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement { override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
val returnTarget = getReturnExpressionTarget(expression) val returnTarget = getReturnExpressionTarget(expression)
val irReturnedExpression = expression.returnedExpression?.genExpr() ?: val irReturnedExpression = expression.returnedExpression?.genExpr() ?: IrGetObjectValueImpl(
IrGetObjectValueImpl(expression.startOffset, expression.endOffset, context.builtIns.unitType, expression.startOffset, expression.endOffset, context.builtIns.unitType,
context.symbolTable.referenceClass(context.builtIns.unit)) context.symbolTable.referenceClass(context.builtIns.unit)
return IrReturnImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType, )
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression) return IrReturnImpl(
expression.startOffset, expression.endOffset, context.builtIns.nothingType,
context.symbolTable.referenceFunction(returnTarget), irReturnedExpression
)
} }
private fun scopeOwnerAsCallable() = private fun scopeOwnerAsCallable() =
@@ -160,8 +172,7 @@ class StatementGenerator(
private fun getReturnExpressionTarget(expression: KtReturnExpression): CallableDescriptor = private fun getReturnExpressionTarget(expression: KtReturnExpression): CallableDescriptor =
if (!ExpressionTypingUtils.isFunctionLiteral(scopeOwner) && !ExpressionTypingUtils.isFunctionExpression(scopeOwner)) { if (!ExpressionTypingUtils.isFunctionLiteral(scopeOwner) && !ExpressionTypingUtils.isFunctionExpression(scopeOwner)) {
scopeOwnerAsCallable() scopeOwnerAsCallable()
} } else {
else {
val label = expression.getTargetLabel() val label = expression.getTargetLabel()
when { when {
label != null -> { label != null -> {
@@ -179,13 +190,20 @@ class StatementGenerator(
} }
override fun visitThrowExpression(expression: KtThrowExpression, data: Nothing?): IrStatement { override fun visitThrowExpression(expression: KtThrowExpression, data: Nothing?): IrStatement {
return IrThrowImpl(expression.startOffset, expression.endOffset, context.builtIns.nothingType, expression.thrownExpression!!.genExpr()) return IrThrowImpl(
expression.startOffset,
expression.endOffset,
context.builtIns.nothingType,
expression.thrownExpression!!.genExpr()
)
} }
override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression = override fun visitConstantExpression(expression: KtConstantExpression, data: Nothing?): IrExpression =
generateConstantExpression(expression, generateConstantExpression(
ConstantExpressionEvaluator.getConstant(expression, context.bindingContext) ?: expression,
error("KtConstantExpression was not evaluated: ${expression.text}")) ConstantExpressionEvaluator.getConstant(expression, context.bindingContext)
?: error("KtConstantExpression was not evaluated: ${expression.text}")
)
fun generateConstantExpression(expression: KtExpression, constant: CompileTimeConstant<*>): IrExpression { fun generateConstantExpression(expression: KtExpression, constant: CompileTimeConstant<*>): IrExpression {
val constantValue = constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression)) val constantValue = constant.toConstantValue(getInferredTypeWithImplicitCastsOrFail(expression))
@@ -277,8 +295,7 @@ class StatementGenerator(
) )
override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrStatement { override fun visitCallExpression(expression: KtCallExpression, data: Nothing?): IrStatement {
val resolvedCall = getResolvedCall(expression) ?: val resolvedCall = getResolvedCall(expression) ?: return ErrorExpressionGenerator(this).generateErrorCall(expression)
return ErrorExpressionGenerator(this).generateErrorCall(expression)
if (resolvedCall is VariableAsFunctionResolvedCall) { if (resolvedCall is VariableAsFunctionResolvedCall) {
val functionCall = pregenerateCall(resolvedCall.functionCall) val functionCall = pregenerateCall(resolvedCall.functionCall)
@@ -291,8 +308,10 @@ class StatementGenerator(
override fun visitArrayAccessExpression(expression: KtArrayAccessExpression, data: Nothing?): IrStatement { override fun visitArrayAccessExpression(expression: KtArrayAccessExpression, data: Nothing?): IrStatement {
val indexedGetCall = getOrFail(BindingContext.INDEXED_LVALUE_GET, expression) val indexedGetCall = getOrFail(BindingContext.INDEXED_LVALUE_GET, expression)
return CallGenerator(this).generateCall(expression.startOffset, expression.endOffset, return CallGenerator(this).generateCall(
pregenerateCall(indexedGetCall), IrStatementOrigin.GET_ARRAY_ELEMENT) expression.startOffset, expression.endOffset,
pregenerateCall(indexedGetCall), IrStatementOrigin.GET_ARRAY_ELEMENT
)
} }
override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrStatement = override fun visitDotQualifiedExpression(expression: KtDotQualifiedExpression, data: Nothing?): IrStatement =
@@ -305,12 +324,16 @@ class StatementGenerator(
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" } val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
return when (referenceTarget) { return when (referenceTarget) {
is ClassDescriptor -> is ClassDescriptor ->
IrGetValueImpl(expression.startOffset, expression.endOffset, IrGetValueImpl(
context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter)) expression.startOffset, expression.endOffset,
context.symbolTable.referenceValueParameter(referenceTarget.thisAsReceiverParameter)
)
is CallableDescriptor -> { is CallableDescriptor -> {
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget") val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
IrGetValueImpl(expression.startOffset, expression.endOffset, IrGetValueImpl(
context.symbolTable.referenceValueParameter(extensionReceiver)) expression.startOffset, expression.endOffset,
context.symbolTable.referenceValueParameter(extensionReceiver)
)
} }
else -> else ->
error("Expected this or receiver: $referenceTarget") error("Expected this or receiver: $referenceTarget")
@@ -369,8 +392,10 @@ class StatementGenerator(
LocalClassGenerator(this).generateLocalClass(classOrObject) LocalClassGenerator(this).generateLocalClass(classOrObject)
override fun visitTypeAlias(typeAlias: KtTypeAlias, data: Nothing?): IrStatement = override fun visitTypeAlias(typeAlias: KtTypeAlias, data: Nothing?): IrStatement =
IrTypeAliasImpl(typeAlias.startOffset, typeAlias.endOffset, IrDeclarationOrigin.DEFINED, IrTypeAliasImpl(
getOrFail(BindingContext.TYPE_ALIAS, typeAlias)) typeAlias.startOffset, typeAlias.endOffset, IrDeclarationOrigin.DEFINED,
getOrFail(BindingContext.TYPE_ALIAS, typeAlias)
)
override fun visitClassLiteralExpression(expression: KtClassLiteralExpression, data: Nothing?): IrStatement = override fun visitClassLiteralExpression(expression: KtClassLiteralExpression, data: Nothing?): IrStatement =
ReflectionReferencesGenerator(this).generateClassLiteral(expression) ReflectionReferencesGenerator(this).generateClassLiteral(expression)
@@ -51,7 +51,7 @@ class TryCatchExpressionGenerator(statementGenerator: StatementGenerator) : Stat
irTryCatch.catches.add(irCatch) irTryCatch.catches.add(irCatch)
} }
irTryCatch.finallyExpression = ktTry.finallyBlock?.let{ statementGenerator.generateExpression(it.finalExpression) } irTryCatch.finallyExpression = ktTry.finallyBlock?.let { statementGenerator.generateExpression(it.finalExpression) }
return irTryCatch return irTryCatch
} }
@@ -35,9 +35,9 @@ class ArrayAccessAssignmentReceiver(
val endOffset: Int, val endOffset: Int,
val origin: IrStatementOrigin val origin: IrStatementOrigin
) : AssignmentReceiver { ) : AssignmentReceiver {
private val type: KotlinType = indexedGetCall?.run { descriptor.returnType!! } ?: private val type: KotlinType =
indexedSetCall?.run { descriptor.valueParameters.last().type } ?: indexedGetCall?.run { descriptor.returnType!! } ?: indexedSetCall?.run { descriptor.valueParameters.last().type }
throw AssertionError("Array access should have either indexed-get call or indexed-set call") ?: throw AssertionError("Array access should have either indexed-get call or indexed-set call")
override fun assign(withLValue: (LValue) -> IrExpression): IrExpression { override fun assign(withLValue: (LValue) -> IrExpression): IrExpression {
val hasResult = origin.isAssignmentOperatorWithResult() val hasResult = origin.isAssignmentOperatorWithResult()
@@ -42,7 +42,8 @@ class CallBuilder(
irValueArgumentsByIndex[valueParameterDescriptor.index + parametersOffset] irValueArgumentsByIndex[valueParameterDescriptor.index + parametersOffset]
} }
val CallBuilder.argumentsCount: Int get() = val CallBuilder.argumentsCount: Int
get() =
irValueArgumentsByIndex.size irValueArgumentsByIndex.size
var CallBuilder.lastArgument: IrExpression? var CallBuilder.lastArgument: IrExpression?
@@ -57,22 +58,28 @@ fun CallBuilder.getValueArgumentsInParameterOrder(): List<IrExpression?> =
fun CallBuilder.isValueArgumentReorderingRequired() = fun CallBuilder.isValueArgumentReorderingRequired() =
original.isValueArgumentReorderingRequired() original.isValueArgumentReorderingRequired()
val CallBuilder.hasExtensionReceiver: Boolean get() = val CallBuilder.hasExtensionReceiver: Boolean
get() =
descriptor.extensionReceiverParameter != null descriptor.extensionReceiverParameter != null
val CallBuilder.hasDispatchReceiver: Boolean get() = val CallBuilder.hasDispatchReceiver: Boolean
get() =
descriptor.dispatchReceiverParameter != null descriptor.dispatchReceiverParameter != null
val CallBuilder.extensionReceiverType: KotlinType? get() = val CallBuilder.extensionReceiverType: KotlinType?
get() =
descriptor.extensionReceiverParameter?.type descriptor.extensionReceiverParameter?.type
val CallBuilder.dispatchReceiverType: KotlinType? get() = val CallBuilder.dispatchReceiverType: KotlinType?
get() =
descriptor.dispatchReceiverParameter?.type descriptor.dispatchReceiverParameter?.type
val CallBuilder.explicitReceiverParameter: ReceiverParameterDescriptor? get() = val CallBuilder.explicitReceiverParameter: ReceiverParameterDescriptor?
get() =
descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter
val CallBuilder.explicitReceiverType: KotlinType? get() = val CallBuilder.explicitReceiverType: KotlinType?
get() =
explicitReceiverParameter?.type explicitReceiverParameter?.type
fun CallBuilder.setExplicitReceiverValue(explicitReceiverValue: IntermediateValue) { fun CallBuilder.setExplicitReceiverValue(explicitReceiverValue: IntermediateValue) {
@@ -32,9 +32,8 @@ class LValueWithGetterAndSetterCalls(
val origin: IrStatementOrigin? = null val origin: IrStatementOrigin? = null
) : LValue { ) : LValue {
private val descriptor: CallableDescriptor = private val descriptor: CallableDescriptor =
getterCall?.descriptor ?: getterCall?.descriptor ?: setterCall?.descriptor
setterCall?.descriptor ?: ?: throw AssertionError("Call-based LValue should have either a getter or a setter call")
throw AssertionError("Call-based LValue should have either a getter or a setter call")
override fun load(): IrExpression { override fun load(): IrExpression {
if (getterCall == null) throw AssertionError("No getter call for $descriptor") if (getterCall == null) throw AssertionError("No getter call for $descriptor")
@@ -28,7 +28,7 @@ class OnceCallValue(
val statementGenerator: StatementGenerator, val statementGenerator: StatementGenerator,
val call: CallBuilder, val call: CallBuilder,
val origin: IrStatementOrigin? = null val origin: IrStatementOrigin? = null
): IntermediateValue { ) : IntermediateValue {
private var instantiated = false private var instantiated = false
override fun load(): IrExpression { override fun load(): IrExpression {
@@ -28,7 +28,11 @@ class RematerializableValue(val irExpression: IrExpressionWithCopy) : Intermedia
override fun load(): IrExpression = irExpression.copy() override fun load(): IrExpression = irExpression.copy()
} }
fun Scope.createTemporaryVariableInBlock(irExpression: IrExpression, block: IrContainerExpressionBase, nameHint: String? = null): IntermediateValue { fun Scope.createTemporaryVariableInBlock(
irExpression: IrExpression,
block: IrContainerExpressionBase,
nameHint: String? = null
): IntermediateValue {
val temporaryVariable = createTemporaryVariable(irExpression, nameHint) val temporaryVariable = createTemporaryVariable(irExpression, nameHint)
block.statements.add(temporaryVariable) block.statements.add(temporaryVariable)
return VariableLValue(temporaryVariable) return VariableLValue(temporaryVariable)
@@ -44,8 +44,7 @@ class SafeCallReceiver(
if (extensionReceiver != null) { if (extensionReceiver != null) {
dispatchReceiverValue = dispatchReceiver dispatchReceiverValue = dispatchReceiver
extensionReceiverValue = safeReceiverValue extensionReceiverValue = safeReceiverValue
} } else {
else {
dispatchReceiverValue = safeReceiverValue dispatchReceiverValue = safeReceiverValue
extensionReceiverValue = null extensionReceiverValue = null
} }
@@ -57,11 +56,13 @@ class SafeCallReceiver(
irBlock.statements.add(irTmp) irBlock.statements.add(irTmp)
val irIfThenElse = IrIfThenElseImpl(startOffset, endOffset, resultType, val irIfThenElse = IrIfThenElseImpl(
startOffset, endOffset, resultType,
generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()), generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()),
generator.context.constNull(startOffset, endOffset), generator.context.constNull(startOffset, endOffset),
irResult, irResult,
IrStatementOrigin.SAFE_CALL) IrStatementOrigin.SAFE_CALL
)
irBlock.statements.add(irIfThenElse) irBlock.statements.add(irIfThenElse)
return irBlock return irBlock
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
class TransientReceiverValue(override val type: KotlinType): IntermediateValue { class TransientReceiverValue(override val type: KotlinType) : 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")
} }
@@ -33,7 +33,8 @@ class VariableLValue(
val origin: IrStatementOrigin? = null val origin: IrStatementOrigin? = null
) : LValue, AssignmentReceiver { ) : LValue, AssignmentReceiver {
constructor(irVariable: IrVariable, origin: IrStatementOrigin? = null) : this( constructor(irVariable: IrVariable, origin: IrStatementOrigin? = null) : this(
irVariable.startOffset, irVariable.endOffset, irVariable.symbol, origin) irVariable.startOffset, irVariable.endOffset, irVariable.symbol, origin
)
override val type: KotlinType get() = symbol.descriptor.type override val type: KotlinType get() = symbol.descriptor.type
@@ -17,8 +17,6 @@
package org.jetbrains.kotlin.psi2ir.transformations package org.jetbrains.kotlin.psi2ir.transformations
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.isBuiltinExtensionFunctionalType
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrField
@@ -27,7 +25,6 @@ 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.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.psi2ir.containsNull import org.jetbrains.kotlin.psi2ir.containsNull
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -40,7 +37,7 @@ fun insertImplicitCasts(builtIns: KotlinBuiltIns, element: IrElement) {
element.transformChildren(InsertImplicitCasts(builtIns), null) element.transformChildren(InsertImplicitCasts(builtIns), null)
} }
class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoid() { class InsertImplicitCasts(val builtIns: KotlinBuiltIns) : IrElementTransformerVoid() {
override fun visitCallableReference(expression: IrCallableReference): IrExpression = override fun visitCallableReference(expression: IrCallableReference): IrExpression =
expression.transformPostfix { expression.transformPostfix {
transformReceiverArguments() transformReceiverArguments()
@@ -185,11 +182,15 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType) -> KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType.makeNotNullable(), expectedType) ->
this this
KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() -> KotlinBuiltIns.isInt(valueType) && notNullableExpectedType.isBuiltInIntegerType() ->
IrTypeOperatorCallImpl(startOffset, endOffset, notNullableExpectedType, IrTypeOperatorCallImpl(
IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this) startOffset, endOffset, notNullableExpectedType,
IrTypeOperator.IMPLICIT_INTEGER_COERCION, notNullableExpectedType, this
)
else -> else ->
IrTypeOperatorCallImpl(startOffset, endOffset, expectedType, IrTypeOperatorCallImpl(
IrTypeOperator.IMPLICIT_CAST, expectedType, this) startOffset, endOffset, expectedType,
IrTypeOperator.IMPLICIT_CAST, expectedType, this
)
} }
} }
@@ -199,8 +200,10 @@ class InsertImplicitCasts(val builtIns: KotlinBuiltIns): IrElementTransformerVoi
return if (KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, builtIns.unitType)) return if (KotlinTypeChecker.DEFAULT.isSubtypeOf(valueType, builtIns.unitType))
this this
else else
IrTypeOperatorCallImpl(startOffset, endOffset, builtIns.unitType, IrTypeOperatorCallImpl(
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this) startOffset, endOffset, builtIns.unitType,
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, builtIns.unitType, this
)
} }
private fun KotlinType.isBuiltInIntegerType(): Boolean = private fun KotlinType.isBuiltInIntegerType(): Boolean =