IrTypes in psi2ir: generators (seem to be) complete
This commit is contained in:
+33
-16
@@ -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<TypeParameterDescriptor, KotlinType>?,
|
||||
typeArgumentsMap: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
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
|
||||
)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+3
-2
@@ -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,
|
||||
|
||||
+2
-2
@@ -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)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -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())
|
||||
|
||||
+1
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
+19
-12
@@ -26,23 +26,25 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.lang.AssertionError
|
||||
|
||||
class ArrayAccessAssignmentReceiver(
|
||||
val irArray: IrExpression,
|
||||
val irIndices: List<IrExpression>,
|
||||
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<IrExpression>,
|
||||
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
|
||||
|
||||
+12
-8
@@ -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)
|
||||
|
||||
+12
-6
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -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)
|
||||
|
||||
+3
-1
@@ -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")
|
||||
|
||||
+39
-12
@@ -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<TypeParameterDescriptor, KotlinType>?,
|
||||
val typeArguments: List<IrType>?,
|
||||
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),
|
||||
|
||||
+1
@@ -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()
|
||||
|
||||
+9
-10
@@ -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
|
||||
|
||||
+12
-17
@@ -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
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -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)
|
||||
}
|
||||
|
||||
+1
@@ -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")
|
||||
}
|
||||
|
||||
+11
-6
@@ -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<IrVariableSymbol> { "Not a variable: ${symbol.descriptor}" },
|
||||
irExpression, origin
|
||||
)
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user