From 54e9a2bb7bcf06ca8f0c5734d06b93cc05a2346b Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Mon, 14 May 2018 15:07:38 +0300 Subject: [PATCH] IrTypes in psi2ir: generators (seem to be) complete --- .../psi2ir/generators/AssignmentGenerator.kt | 49 ++++++++++++------ .../kotlin/psi2ir/generators/BodyGenerator.kt | 2 + .../generators/DelegatedPropertyGenerator.kt | 5 +- .../generators/LoopExpressionGenerator.kt | 4 +- .../psi2ir/generators/PropertyGenerator.kt | 11 ++-- .../ReflectionReferencesGenerator.kt | 1 + .../psi2ir/generators/StatementGenerator.kt | 1 + .../ArrayAccessAssignmentReceiver.kt | 31 ++++++----- .../psi2ir/intermediate/BackingFieldLValue.kt | 20 +++++--- .../DelegatedLocalPropertyLValue.kt | 18 ++++--- .../ExtensionInvokeCallReceiver.kt | 7 +-- .../LValueWithGetterAndSetterCalls.kt | 4 +- .../psi2ir/intermediate/PropertyLValue.kt | 51 ++++++++++++++----- .../intermediate/RematerializableValue.kt | 1 + .../psi2ir/intermediate/SafeCallReceiver.kt | 19 ++++--- .../SafeExtensionInvokeCallReceiver.kt | 29 +++++------ .../psi2ir/intermediate/SimpleCallReceiver.kt | 5 +- .../intermediate/TransientReceiverValue.kt | 1 + .../psi2ir/intermediate/VariableLValue.kt | 17 ++++--- .../kotlin/ir/builders/Primitives.kt | 2 + .../org/jetbrains/kotlin/ir/types/irTypes.kt | 12 +++++ 21 files changed, 190 insertions(+), 100 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt index 735d4c4ad3f..7739421d8a0 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/AssignmentGenerator.kt @@ -92,7 +92,9 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen irBlock(ktExpression.startOffset, ktExpression.endOffset, origin, irLValue.type) { val temporary = irTemporary(irLValue.load()) val opCall = statementGenerator.pregenerateCall(opResolvedCall) - opCall.setExplicitReceiverValue(VariableLValue(startOffset, endOffset, temporary.symbol)) + opCall.setExplicitReceiverValue( + VariableLValue(context, startOffset, endOffset, temporary.symbol, temporary.type) + ) val irOpCall = CallGenerator(statementGenerator).generateCall(ktExpression, opCall, origin) +irLValue.store(irOpCall) +irGet(temporary.type, temporary.symbol) @@ -118,31 +120,37 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen @Suppress("DEPRECATION") if (descriptor.isDelegated) DelegatedLocalPropertyLValue( + context, ktLeft.startOffset, ktLeft.endOffset, - descriptor.type, + descriptor.type.toIrType(), descriptor.getter?.let { context.symbolTable.referenceDeclaredFunction(it) }, descriptor.setter?.let { context.symbolTable.referenceDeclaredFunction(it) }, origin ) else - VariableLValue( - ktLeft.startOffset, ktLeft.endOffset, - context.symbolTable.referenceVariable(descriptor), - origin - ) + createVariableValue(ktLeft, descriptor, origin) is PropertyDescriptor -> generateAssignmentReceiverForProperty(descriptor, origin, ktLeft, resolvedCall) is ValueDescriptor -> - VariableLValue( - ktLeft.startOffset, ktLeft.endOffset, - context.symbolTable.referenceValue(descriptor), - origin - ) + createVariableValue(ktLeft, descriptor, origin) else -> OnceExpressionValue(ktLeft.genExpr()) } } + private fun createVariableValue( + ktExpression: KtExpression, + descriptor: ValueDescriptor, + origin: IrStatementOrigin + ) = + VariableLValue( + context, + ktExpression.startOffset, ktExpression.endOffset, + context.symbolTable.referenceValue(descriptor), + descriptor.type.toIrType(), + origin + ) + private fun createBackingFieldLValue( ktExpression: KtExpression, descriptor: PropertyDescriptor, @@ -150,8 +158,9 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen origin: IrStatementOrigin? ): BackingFieldLValue = BackingFieldLValue( + context, ktExpression.startOffset, ktExpression.endOffset, - descriptor.type, + descriptor.type.toIrType(), context.symbolTable.referenceField(descriptor), receiverValue, origin ) @@ -189,7 +198,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen ktExpression: KtExpression, descriptor: PropertyDescriptor, propertyReceiver: CallReceiver, - typeArguments: Map?, + typeArgumentsMap: Map?, origin: IrStatementOrigin?, superQualifier: ClassDescriptor? ): PropertyLValueBase { @@ -201,24 +210,32 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen val setterDescriptor = descriptor.setter val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) } + val propertyIrType = descriptor.type.toIrType() return if (getterSymbol != null || setterSymbol != null) { + val typeArgumentsList = + typeArgumentsMap?.let { typeArguments -> + descriptor.typeParameters.map { typeArguments[it]!!.toIrType() } + } AccessorPropertyLValue( + context, scope, ktExpression.startOffset, ktExpression.endOffset, origin, - descriptor.type, + propertyIrType, getterSymbol, getterDescriptor, setterSymbol, setterDescriptor, - typeArguments, + typeArgumentsList, propertyReceiver, superQualifierSymbol ) } else FieldPropertyLValue( + context, scope, ktExpression.startOffset, ktExpression.endOffset, origin, context.symbolTable.referenceField(descriptor), + propertyIrType, propertyReceiver, superQualifierSymbol ) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt index d8ab87e2a3b..5c578d618a9 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BodyGenerator.kt @@ -72,8 +72,10 @@ class BodyGenerator( val ktDestructuringDeclaration = ktParameter.destructuringDeclaration ?: continue val valueParameter = getOrFail(BindingContext.VALUE_PARAMETER, ktParameter) val parameterValue = VariableLValue( + context, ktDestructuringDeclaration.startOffset, ktDestructuringDeclaration.endOffset, context.symbolTable.referenceValue(valueParameter), + valueParameter.type.toIrType(), IrStatementOrigin.DESTRUCTURING_DECLARATION ) statementGenerator.declareComponentVariablesInBlock(ktDestructuringDeclaration, irBlockBody, parameterValue) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt index 21ab3274d12..2b4b665cb08 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DelegatedPropertyGenerator.kt @@ -164,8 +164,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D ): IntermediateValue { val thisValue = createThisValueForDelegate(thisClass, ktDelegate) return BackingFieldLValue( + context, ktDelegate.startOffset, ktDelegate.endOffset, - irDelegateField.descriptor.type, + irDelegateField.descriptor.type.toIrType(), irDelegateField, thisValue, null @@ -327,7 +328,7 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D } private fun createVariableValueForDelegate(irDelegate: IrVariableSymbol, ktDelegate: KtPropertyDelegate) = - VariableLValue(ktDelegate.startOffset, ktDelegate.endOffset, irDelegate) + VariableLValue(context, ktDelegate.startOffset, ktDelegate.endOffset, irDelegate, irDelegate.descriptor.type.toIrType()) private inline fun createLocalPropertyAccessor( getterDescriptor: VariableAccessorDescriptor, diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LoopExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LoopExpressionGenerator.kt index 06147d9cabf..3645baa0125 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LoopExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/LoopExpressionGenerator.kt @@ -162,7 +162,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen val iteratorCall = statementGenerator.pregenerateCall(iteratorResolvedCall) val irIteratorCall = callGenerator.generateCall(ktLoopRange, iteratorCall, IrStatementOrigin.FOR_LOOP_ITERATOR) val irIterator = scope.createTemporaryVariable(irIteratorCall, "iterator", origin = IrDeclarationOrigin.FOR_LOOP_ITERATOR) - val iteratorValue = VariableLValue(irIterator) + val iteratorValue = VariableLValue(context, irIterator) irForBlock.statements.add(irIterator) val irInnerWhile = IrWhileLoopImpl(startOffset, endOffset, context.irBuiltIns.unitType, IrStatementOrigin.FOR_LOOP_INNER_WHILE) @@ -196,7 +196,7 @@ class LoopExpressionGenerator(statementGenerator: StatementGenerator) : Statemen statementGenerator.declareComponentVariablesInBlock( ktLoopDestructuringDeclaration, irInnerBody, - VariableLValue(irLoopParameter) + VariableLValue(context, irLoopParameter) ) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/PropertyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/PropertyGenerator.kt index 337866ed4fe..49ddcb79ae9 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/PropertyGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/PropertyGenerator.kt @@ -44,16 +44,19 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio fun generatePropertyForPrimaryConstructorParameter(ktParameter: KtParameter, irValueParameter: IrValueParameter): IrDeclaration { val propertyDescriptor = getOrFail(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, ktParameter) + val irPropertyType = propertyDescriptor.type.toIrType() return IrPropertyImpl( ktParameter.startOffset, ktParameter.endOffset, IrDeclarationOrigin.DEFINED, false, - propertyDescriptor + propertyDescriptor, + irPropertyType ).also { irProperty -> irProperty.backingField = generatePropertyBackingField(ktParameter, propertyDescriptor) { IrExpressionBodyImpl( IrGetValueImpl( ktParameter.startOffset, ktParameter.endOffset, + irPropertyType, irValueParameter.symbol, IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER ) @@ -99,8 +102,10 @@ class PropertyGenerator(declarationGenerator: DeclarationGenerator) : Declaratio private fun generateSimpleProperty(ktProperty: KtProperty, propertyDescriptor: PropertyDescriptor): IrProperty = IrPropertyImpl( ktProperty.startOffset, ktProperty.endOffset, - IrDeclarationOrigin.DEFINED, false, - propertyDescriptor + IrDeclarationOrigin.DEFINED, + false, + propertyDescriptor, + propertyDescriptor.type.toIrType() ).buildWithScope { irProperty -> irProperty.backingField = if (propertyDescriptor.hasBackingField()) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt index c4a34cb73b5..226824adde0 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ReflectionReferencesGenerator.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.expressions.DoubleColonLHS class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { + fun generateClassLiteral(ktClassLiteral: KtClassLiteralExpression): IrExpression { val ktArgument = ktClassLiteral.receiverExpression!! val lhs = getOrFail(BindingContext.DOUBLE_COLON_LHS, ktArgument) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt index 530790c2345..43a68e9fd82 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/StatementGenerator.kt @@ -409,4 +409,5 @@ abstract class StatementGeneratorExtension(val statementGenerator: StatementGene fun KtExpression.genExpr() = statementGenerator.generateExpression(this) fun KtExpression.genStmt() = statementGenerator.generateStatement(this) fun KotlinType.toIrType() = with(statementGenerator) { toIrType() } + fun translateType(kotlinType: KotlinType) = kotlinType.toIrType() } \ No newline at end of file diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ArrayAccessAssignmentReceiver.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ArrayAccessAssignmentReceiver.kt index ec943a3f26e..ab8130f7b0f 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ArrayAccessAssignmentReceiver.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ArrayAccessAssignmentReceiver.kt @@ -26,23 +26,25 @@ import org.jetbrains.kotlin.types.KotlinType import java.lang.AssertionError class ArrayAccessAssignmentReceiver( - val irArray: IrExpression, - val irIndices: List, - val indexedGetCall: CallBuilder?, - val indexedSetCall: CallBuilder?, - val callGenerator: CallGenerator, - val startOffset: Int, - val endOffset: Int, - val origin: IrStatementOrigin + private val irArray: IrExpression, + private val irIndices: List, + private val indexedGetCall: CallBuilder?, + private val indexedSetCall: CallBuilder?, + private val callGenerator: CallGenerator, + private val startOffset: Int, + private val endOffset: Int, + private val origin: IrStatementOrigin ) : AssignmentReceiver { - private val type: KotlinType = + + private val kotlinType: KotlinType = indexedGetCall?.run { descriptor.returnType!! } ?: indexedSetCall?.run { descriptor.valueParameters.last().type } ?: throw AssertionError("Array access should have either indexed-get call or indexed-set call") override fun assign(withLValue: (LValue) -> IrExpression): IrExpression { val hasResult = origin.isAssignmentOperatorWithResult() - val resultType = if (hasResult) type else callGenerator.context.builtIns.unitType - val irBlock = IrBlockImpl(startOffset, endOffset, resultType, origin) + val resultType = if (hasResult) kotlinType else callGenerator.context.builtIns.unitType + val irResultType = callGenerator.translateType(resultType) + val irBlock = IrBlockImpl(startOffset, endOffset, irResultType, origin) val irArrayValue = callGenerator.scope.createTemporaryVariableInBlock(irArray, irBlock, "array") @@ -52,7 +54,12 @@ class ArrayAccessAssignmentReceiver( indexedGetCall?.fillArrayAndIndexArguments(irArrayValue, irIndexValues) indexedSetCall?.fillArrayAndIndexArguments(irArrayValue, irIndexValues) - val irLValue = LValueWithGetterAndSetterCalls(callGenerator, indexedGetCall, indexedSetCall, type, startOffset, endOffset, origin) + val irLValue = LValueWithGetterAndSetterCalls( + callGenerator, + indexedGetCall, indexedSetCall, + callGenerator.translateType(kotlinType), + startOffset, endOffset, origin + ) irBlock.inlineStatement(withLValue(irLValue)) return irBlock diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/BackingFieldLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/BackingFieldLValue.kt index bbbabc42b5d..52bdb359352 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/BackingFieldLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/BackingFieldLValue.kt @@ -16,26 +16,30 @@ package org.jetbrains.kotlin.psi2ir.intermediate +import org.jetbrains.kotlin.ir.builders.IrGeneratorContext import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.types.KotlinType class BackingFieldLValue( - val startOffset: Int, - val endOffset: Int, - override val type: KotlinType, - val symbol: IrFieldSymbol, - val receiver: IntermediateValue?, - val origin: IrStatementOrigin? + private val context: IrGeneratorContext, + private val startOffset: Int, + private val endOffset: Int, + override val type: IrType, + private val symbol: IrFieldSymbol, + private val receiver: IntermediateValue?, + private val origin: IrStatementOrigin? ) : LValue, AssignmentReceiver { + override fun store(irExpression: IrExpression): IrExpression = - IrSetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), irExpression, origin) + IrSetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), irExpression, context.irBuiltIns.unitType, origin) override fun load(): IrExpression = - IrGetFieldImpl(startOffset, endOffset, symbol, receiver?.load(), origin) + IrGetFieldImpl(startOffset, endOffset, symbol, type, receiver?.load(), origin) override fun assign(withLValue: (LValue) -> IrExpression): IrExpression = withLValue(this) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/DelegatedLocalPropertyLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/DelegatedLocalPropertyLValue.kt index a76b979d848..82aa7678fbd 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/DelegatedLocalPropertyLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/DelegatedLocalPropertyLValue.kt @@ -16,25 +16,31 @@ package org.jetbrains.kotlin.psi2ir.intermediate +import org.jetbrains.kotlin.ir.builders.IrGeneratorContext import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.types.KotlinType class DelegatedLocalPropertyLValue( + private val context: IrGeneratorContext, val startOffset: Int, val endOffset: Int, - override val type: KotlinType, - val getterSymbol: IrSimpleFunctionSymbol?, - val setterSymbol: IrSimpleFunctionSymbol?, + override val type: IrType, + private val getterSymbol: IrSimpleFunctionSymbol?, + private val setterSymbol: IrSimpleFunctionSymbol?, val origin: IrStatementOrigin? = null -) : LValue, AssignmentReceiver { +) : + LValue, + AssignmentReceiver { + override fun load(): IrExpression = - IrCallImpl(startOffset, endOffset, type, getterSymbol!!, getterSymbol.descriptor, null, origin) + IrCallImpl(startOffset, endOffset, type, getterSymbol!!, getterSymbol.descriptor, origin) override fun store(irExpression: IrExpression): IrExpression = - IrCallImpl(startOffset, endOffset, type, setterSymbol!!, setterSymbol.descriptor, null, origin).apply { + IrCallImpl(startOffset, endOffset, context.irBuiltIns.unitType, setterSymbol!!, setterSymbol.descriptor, origin).apply { putValueArgument(0, irExpression) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ExtensionInvokeCallReceiver.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ExtensionInvokeCallReceiver.kt index c9d28261e9e..4742a5cc3ba 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ExtensionInvokeCallReceiver.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/ExtensionInvokeCallReceiver.kt @@ -19,10 +19,11 @@ package org.jetbrains.kotlin.psi2ir.intermediate import org.jetbrains.kotlin.ir.expressions.IrExpression class ExtensionInvokeCallReceiver( - val callBuilder: CallBuilder, - val functionReceiver: IntermediateValue, - val extensionInvokeReceiver: IntermediateValue + private val callBuilder: CallBuilder, + private val functionReceiver: IntermediateValue, + private val extensionInvokeReceiver: IntermediateValue ) : CallReceiver { + override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression { // extensionInvokeReceiver is actually a first argument: // receiver.extFun(p1, ..., pN) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/LValueWithGetterAndSetterCalls.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/LValueWithGetterAndSetterCalls.kt index 7ef8b015955..67d2a5f5ab9 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/LValueWithGetterAndSetterCalls.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/LValueWithGetterAndSetterCalls.kt @@ -19,6 +19,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.psi2ir.generators.CallGenerator import org.jetbrains.kotlin.types.KotlinType @@ -26,11 +27,12 @@ class LValueWithGetterAndSetterCalls( val callGenerator: CallGenerator, val getterCall: CallBuilder?, val setterCall: CallBuilder?, - override val type: KotlinType, + override val type: IrType, val startOffset: Int, val endOffset: Int, val origin: IrStatementOrigin? = null ) : LValue { + private val descriptor: CallableDescriptor = getterCall?.descriptor ?: setterCall?.descriptor ?: throw AssertionError("Call-based LValue should have either a getter or a setter call") diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/PropertyLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/PropertyLValue.kt index e37d504b5f0..82c24c239b1 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/PropertyLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/PropertyLValue.kt @@ -17,22 +17,24 @@ package org.jetbrains.kotlin.psi2ir.intermediate import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.ir.builders.IrGeneratorContext import org.jetbrains.kotlin.ir.builders.Scope import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol -import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.ir.types.IrType abstract class PropertyLValueBase( + protected val context: IrGeneratorContext, val scope: Scope, val startOffset: Int, val endOffset: Int, val origin: IrStatementOrigin?, - override val type: KotlinType, + override val type: IrType, val callReceiver: CallReceiver, val superQualifier: IrClassSymbol? ) : LValue, AssignmentReceiver { @@ -64,20 +66,25 @@ abstract class PropertyLValueBase( } class FieldPropertyLValue( + context: IrGeneratorContext, scope: Scope, startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, val field: IrFieldSymbol, + type: IrType, callReceiver: CallReceiver, superQualifier: IrClassSymbol? -) : PropertyLValueBase(scope, startOffset, endOffset, origin, field.descriptor.type, callReceiver, superQualifier) { +) : + PropertyLValueBase(context, scope, startOffset, endOffset, origin, type, callReceiver, superQualifier) { + override fun load(): IrExpression = callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> assert(extensionReceiverValue == null) { "Field can't have an extension receiver: ${field.descriptor}" } IrGetFieldImpl( startOffset, endOffset, field, + type, dispatchReceiverValue?.load(), origin, superQualifier @@ -92,6 +99,7 @@ class FieldPropertyLValue( field, dispatchReceiverValue?.load(), irExpression, + context.irBuiltIns.unitType, origin, superQualifier ) @@ -99,57 +107,76 @@ class FieldPropertyLValue( override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase = FieldPropertyLValue( + context, scope, startOffset, endOffset, origin, field, + type, SimpleCallReceiver(dispatchReceiver, extensionReceiver), superQualifier ) } class AccessorPropertyLValue( + context: IrGeneratorContext, scope: Scope, startOffset: Int, endOffset: Int, origin: IrStatementOrigin?, - type: KotlinType, + type: IrType, val getter: IrFunctionSymbol?, val getterDescriptor: FunctionDescriptor?, val setter: IrFunctionSymbol?, val setterDescriptor: FunctionDescriptor?, - val typeArguments: Map?, + val typeArguments: List?, callReceiver: CallReceiver, superQualifier: IrClassSymbol? -) : PropertyLValueBase(scope, startOffset, endOffset, origin, type, callReceiver, superQualifier) { +) : PropertyLValueBase(context, scope, startOffset, endOffset, origin, type, callReceiver, superQualifier) { + + private val typeArgumentsCount = typeArguments?.size ?: 0 + + private fun IrMemberAccessExpression.putTypeArguments() { + typeArguments?.forEachIndexed { index, irType -> + putTypeArgument(index, irType) + } + } + override fun load(): IrExpression = callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> IrGetterCallImpl( startOffset, endOffset, + type, getter!!, getterDescriptor!!, - typeArguments, + typeArgumentsCount, dispatchReceiverValue?.load(), extensionReceiverValue?.load(), origin, superQualifier - ) + ).apply { + putTypeArguments() + } } override fun store(irExpression: IrExpression) = callReceiver.call { dispatchReceiverValue, extensionReceiverValue -> IrSetterCallImpl( startOffset, endOffset, + context.irBuiltIns.unitType, setter!!, setterDescriptor!!, - typeArguments, + typeArgumentsCount, dispatchReceiverValue?.load(), extensionReceiverValue?.load(), irExpression, origin, superQualifier - ) + ).apply { + putTypeArguments() + } } override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase = AccessorPropertyLValue( - scope, startOffset, endOffset, origin, + context, scope, + startOffset, endOffset, origin, type, getter, getterDescriptor, setter, setterDescriptor, typeArguments, SimpleCallReceiver(dispatchReceiver, extensionReceiver), diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/RematerializableValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/RematerializableValue.kt index 304724fa4ed..ee8ad6bd476 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/RematerializableValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/RematerializableValue.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.types.KotlinType class RematerializableValue(val irExpression: IrExpressionWithCopy) : IntermediateValue { + override val type: IrType get() = irExpression.type override fun load(): IrExpression = irExpression.copy() diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SafeCallReceiver.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SafeCallReceiver.kt index bfbfbcaf8e6..5869b1ee29b 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SafeCallReceiver.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SafeCallReceiver.kt @@ -16,12 +16,12 @@ package org.jetbrains.kotlin.psi2ir.intermediate -import org.jetbrains.kotlin.ir.builders.constNull -import org.jetbrains.kotlin.ir.builders.equalsNull +import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl import org.jetbrains.kotlin.ir.expressions.impl.IrIfThenElseImpl +import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.psi2ir.generators.GeneratorWithScope import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.makeNullable @@ -35,6 +35,7 @@ class SafeCallReceiver( val dispatchReceiver: IntermediateValue?, val isAssignmentReceiver: Boolean ) : CallReceiver { + override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression { val irTmp = generator.scope.createTemporaryVariable(extensionReceiver?.load() ?: dispatchReceiver!!.load(), "safe_receiver") val safeReceiverValue = VariableLValue(irTmp) @@ -50,19 +51,17 @@ class SafeCallReceiver( } val irResult = withDispatchAndExtensionReceivers(dispatchReceiverValue, extensionReceiverValue) - val resultType = if (isAssignmentReceiver) irResult.type.builtIns.unitType else irResult.type.makeNullable() + + val resultType = if (isAssignmentReceiver) generator.context.irBuiltIns.unitType else irResult.type.makeNullable() val irBlock = IrBlockImpl(startOffset, endOffset, resultType, IrStatementOrigin.SAFE_CALL) irBlock.statements.add(irTmp) - val irIfThenElse = IrIfThenElseImpl( - startOffset, endOffset, resultType, - generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()), - generator.context.constNull(startOffset, endOffset), - irResult, - IrStatementOrigin.SAFE_CALL - ) + val irIfThenElse = + generator.buildStatement(startOffset, endOffset, IrStatementOrigin.SAFE_CALL) { + irIfNull(resultType, safeReceiverValue.load(), irNull(), irResult) + } irBlock.statements.add(irIfThenElse) return irBlock diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SafeExtensionInvokeCallReceiver.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SafeExtensionInvokeCallReceiver.kt index 05c6a0ed82f..93817469079 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SafeExtensionInvokeCallReceiver.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SafeExtensionInvokeCallReceiver.kt @@ -16,14 +16,13 @@ package org.jetbrains.kotlin.psi2ir.intermediate -import org.jetbrains.kotlin.ir.builders.constNull -import org.jetbrains.kotlin.ir.builders.equalsNull +import org.jetbrains.kotlin.ir.builders.irBlock +import org.jetbrains.kotlin.ir.builders.irIfNull +import org.jetbrains.kotlin.ir.builders.irNull import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin -import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrIfThenElseImpl +import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.psi2ir.generators.GeneratorWithScope -import org.jetbrains.kotlin.types.typeUtil.makeNullable class SafeExtensionInvokeCallReceiver( val generator: GeneratorWithScope, @@ -33,6 +32,7 @@ class SafeExtensionInvokeCallReceiver( val functionReceiver: IntermediateValue, val extensionInvokeReceiver: IntermediateValue ) : CallReceiver { + override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression { // extensionInvokeReceiver is actually a first argument: // receiver?.extFun(p1, ..., pN) @@ -53,19 +53,14 @@ class SafeExtensionInvokeCallReceiver( val resultType = irResult.type.makeNullable() - return IrBlockImpl( - startOffset, endOffset, resultType, IrStatementOrigin.SAFE_CALL, - arrayListOf( - irTmp, - IrIfThenElseImpl( - startOffset, endOffset, resultType, - generator.context.equalsNull(startOffset, endOffset, safeReceiverValue.load()), - generator.context.constNull(startOffset, endOffset), - irResult, - IrStatementOrigin.SAFE_CALL - ) + return generator.irBlock(startOffset, endOffset, IrStatementOrigin.SAFE_CALL, resultType) { + +irTmp + +irIfNull( + resultType, + safeReceiverValue.load(), irNull(), + irResult ) - ) + } } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimpleCallReceiver.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimpleCallReceiver.kt index 9689cabcc4d..365ec119d9c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimpleCallReceiver.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/SimpleCallReceiver.kt @@ -19,9 +19,10 @@ package org.jetbrains.kotlin.psi2ir.intermediate import org.jetbrains.kotlin.ir.expressions.IrExpression class SimpleCallReceiver( - val dispatchReceiverValue: IntermediateValue?, - val extensionReceiverValue: IntermediateValue? + private val dispatchReceiverValue: IntermediateValue?, + private val extensionReceiverValue: IntermediateValue? ) : CallReceiver { + override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression { return withDispatchAndExtensionReceivers(dispatchReceiverValue, extensionReceiverValue) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/TransientReceiverValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/TransientReceiverValue.kt index 84669ec0276..b1a20402a37 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/TransientReceiverValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/TransientReceiverValue.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.types.KotlinType class TransientReceiverValue(override val type: IrType) : IntermediateValue { + override fun load(): IrExpression { throw AssertionError("Transient receiver should not be instantiated") } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/VariableLValue.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/VariableLValue.kt index 1e8398faad8..7de4ffeec52 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/VariableLValue.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/intermediate/VariableLValue.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.psi2ir.intermediate +import org.jetbrains.kotlin.ir.builders.IrGeneratorContext import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin @@ -23,27 +24,31 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrSetVariableImpl import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol +import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.utils.addToStdlib.assertedCast class VariableLValue( + private val context: IrGeneratorContext, val startOffset: Int, val endOffset: Int, val symbol: IrValueSymbol, + override val type: IrType, val origin: IrStatementOrigin? = null -) : LValue, AssignmentReceiver { - constructor(irVariable: IrVariable, origin: IrStatementOrigin? = null) : this( - irVariable.startOffset, irVariable.endOffset, irVariable.symbol, origin - ) +) : + LValue, + AssignmentReceiver { - override val type: KotlinType get() = symbol.descriptor.type + constructor(context: IrGeneratorContext, irVariable: IrVariable, origin: IrStatementOrigin? = null) : + this(context, irVariable.startOffset, irVariable.endOffset, irVariable.symbol, irVariable.type, origin) override fun load(): IrExpression = - IrGetValueImpl(startOffset, endOffset, symbol, origin) + IrGetValueImpl(startOffset, endOffset, type, symbol, origin) override fun store(irExpression: IrExpression): IrExpression = IrSetVariableImpl( startOffset, endOffset, + context.irBuiltIns.unitType, symbol.assertedCast { "Not a variable: ${symbol.descriptor}" }, irExpression, origin ) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/Primitives.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/Primitives.kt index dd100136946..1e081a5bac6 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/Primitives.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/Primitives.kt @@ -22,6 +22,8 @@ import org.jetbrains.kotlin.ir.expressions.IrWhen import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol +// TODO rewrite using IR Builders + fun primitiveOp1( startOffset: Int, endOffset: Int, primitiveOpSymbol: IrSimpleFunctionSymbol, diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt index ea2c4db52f1..e8a7d5cdef3 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/types/irTypes.kt @@ -36,5 +36,17 @@ fun IrType.makeNotNull() = annotations, Variance.INVARIANT ) + else + this + +fun IrType.makeNullable() = + if (this is IrSimpleType && !this.hasQuestionMark) + IrSimpleTypeImpl( + classifier, + true, + arguments, + annotations, + Variance.INVARIANT + ) else this \ No newline at end of file