IrTypes in psi2ir (work in progress)
This commit is contained in:
+1
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||||
|
|
||||||
fun generateAssignment(ktExpression: KtBinaryExpression): IrExpression {
|
fun generateAssignment(ktExpression: KtBinaryExpression): IrExpression {
|
||||||
val ktLeft = ktExpression.left!!
|
val ktLeft = ktExpression.left!!
|
||||||
val irRhs = ktExpression.right!!.genExpr()
|
val irRhs = ktExpression.right!!.genExpr()
|
||||||
|
|||||||
+7
-5
@@ -18,6 +18,8 @@ package org.jetbrains.kotlin.psi2ir.generators
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
|
import org.jetbrains.kotlin.ir.builders.buildStatement
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irIfThenMaybeElse
|
||||||
import org.jetbrains.kotlin.ir.builders.whenComma
|
import org.jetbrains.kotlin.ir.builders.whenComma
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
@@ -27,13 +29,13 @@ import org.jetbrains.kotlin.ir.types.classifierOrNull
|
|||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||||
import org.jetbrains.kotlin.psi2ir.intermediate.defaultLoad
|
|
||||||
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
import org.jetbrains.kotlin.psi2ir.deparenthesize
|
||||||
import org.jetbrains.kotlin.psi2ir.intermediate.defaultLoad
|
import org.jetbrains.kotlin.psi2ir.intermediate.defaultLoad
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||||
|
|
||||||
fun generateIfExpression(expression: KtIfExpression): IrExpression {
|
fun generateIfExpression(expression: KtIfExpression): IrExpression {
|
||||||
val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType()
|
val resultType = getInferredTypeWithImplicitCastsOrFail(expression).toIrType()
|
||||||
|
|
||||||
@@ -68,10 +70,10 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta
|
|||||||
resultType: IrType
|
resultType: IrType
|
||||||
): IrWhen {
|
): IrWhen {
|
||||||
if (irBranches.size == 1) {
|
if (irBranches.size == 1) {
|
||||||
return IrIfThenElseImpl(
|
val irBranch0 = irBranches[0]
|
||||||
ktIf.startOffset, ktIf.endOffset, resultType,
|
return buildStatement(ktIf.startOffset, ktIf.endOffset) {
|
||||||
irBranches[0].condition, irBranches[0].result, irElseResult
|
irIfThenMaybeElse(resultType, irBranch0.condition, irBranch0.result, irElseResult)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val irWhen = IrWhenImpl(ktIf.startOffset, ktIf.endOffset, resultType, IrStatementOrigin.WHEN)
|
val irWhen = IrWhenImpl(ktIf.startOffset, ktIf.endOffset, resultType, IrStatementOrigin.WHEN)
|
||||||
|
|||||||
+54
-17
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
|
|||||||
import org.jetbrains.kotlin.ir.declarations.putDefault
|
import org.jetbrains.kotlin.ir.declarations.putDefault
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.mapTypeParameters
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.mapValueParameters
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
|
import org.jetbrains.kotlin.ir.util.declareSimpleFunctionWithOverrides
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
@@ -143,24 +145,29 @@ class DataClassMembersGenerator(
|
|||||||
+irReturn(
|
+irReturn(
|
||||||
irCall(
|
irCall(
|
||||||
constructorSymbol,
|
constructorSymbol,
|
||||||
dataClassConstructor.returnType.toIrType(),
|
dataClassConstructor.returnType.toIrType()
|
||||||
dataClassConstructor.typeParameters.associate { it to it.defaultType }
|
|
||||||
).apply {
|
).apply {
|
||||||
|
mapTypeParameters { it.defaultType.toIrType() }
|
||||||
mapValueParameters {
|
mapValueParameters {
|
||||||
irGet(irFunction.valueParameters[it.index].symbol)
|
val irValueParameter = irFunction.valueParameters[it.index]
|
||||||
|
irGet(irValueParameter.type, irValueParameter.symbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
override fun generateEqualsMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||||
buildMember(function, declaration) {
|
buildMember(function, declaration) {
|
||||||
|
val irType = classDescriptor.defaultType.toIrType()
|
||||||
|
|
||||||
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
|
+irIfThenReturnTrue(irEqeqeq(irThis(), irOther()))
|
||||||
+irIfThenReturnFalse(irNotIs(irOther(), classDescriptor.defaultType, irClass.symbol))
|
+irIfThenReturnFalse(irNotIs(irOther(), irType))
|
||||||
val otherWithCast = irTemporary(irImplicitCast(irOther(), classDescriptor.defaultType, irClass.symbol), "other_with_cast")
|
val otherWithCast = irTemporary(irAs(irOther(), irType), "other_with_cast")
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
val arg1 = irGet(irThis(), getPropertyGetterSymbol(property))
|
val irPropertyType = property.type.toIrType()
|
||||||
val arg2 = irGet(irGet(otherWithCast.symbol), getPropertyGetterSymbol(property))
|
val arg1 = irGet(irPropertyType, irThis(), getPropertyGetterSymbol(property))
|
||||||
|
val arg2 = irGet(irPropertyType, irGet(irPropertyType, otherWithCast.symbol), getPropertyGetterSymbol(property))
|
||||||
+irIfThenReturnFalse(irNotEquals(arg1, arg2))
|
+irIfThenReturnFalse(irNotEquals(arg1, arg2))
|
||||||
}
|
}
|
||||||
+irReturnTrue()
|
+irReturnTrue()
|
||||||
@@ -199,34 +206,58 @@ class DataClassMembersGenerator(
|
|||||||
|
|
||||||
override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
override fun generateHashCodeMethod(function: FunctionDescriptor, properties: List<PropertyDescriptor>) {
|
||||||
buildMember(function, declaration) {
|
buildMember(function, declaration) {
|
||||||
|
val irIntType = context.irBuiltIns.intType
|
||||||
val result = irTemporaryVar(irInt(0), "result").symbol
|
val result = irTemporaryVar(irInt(0), "result").symbol
|
||||||
var first = true
|
var first = true
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
|
val hashCodeOfProperty = getHashCodeOfProperty(irThis(), property)
|
||||||
val irNewValue =
|
val irNewValue =
|
||||||
if (first) hashCodeOfProperty
|
if (first) hashCodeOfProperty
|
||||||
else irCallOp(intPlus, irCallOp(intTimes, irGet(result), irInt(31)), hashCodeOfProperty)
|
else
|
||||||
|
irCallOp(
|
||||||
|
intPlus,
|
||||||
|
irIntType,
|
||||||
|
irCallOp(
|
||||||
|
intTimes, irIntType, irGet(irIntType, result), irInt(31)
|
||||||
|
),
|
||||||
|
hashCodeOfProperty
|
||||||
|
)
|
||||||
+irSetVar(result, irNewValue)
|
+irSetVar(result, irNewValue)
|
||||||
first = false
|
first = false
|
||||||
}
|
}
|
||||||
+irReturn(irGet(result))
|
+irReturn(irGet(irIntType, result))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression {
|
private fun MemberFunctionBuilder.getHashCodeOfProperty(receiver: IrExpression, property: PropertyDescriptor): IrExpression {
|
||||||
val getterSymbol = getPropertyGetterSymbol(property)
|
val getterSymbol = getPropertyGetterSymbol(property)
|
||||||
|
val propertyType = property.type
|
||||||
|
val irPropertyType = propertyType.toIrType()
|
||||||
return when {
|
return when {
|
||||||
property.type.containsNull() ->
|
propertyType.containsNull() ->
|
||||||
irLetS(irGet(receiver, getterSymbol)) { variable ->
|
irLetS(
|
||||||
irIfNull(context.builtIns.intType, irGet(variable), irInt(0), getHashCodeOf(irGet(variable)))
|
irGet(irPropertyType, receiver, getterSymbol)
|
||||||
|
) { variable ->
|
||||||
|
irIfNull(
|
||||||
|
context.irBuiltIns.intType,
|
||||||
|
irGet(irPropertyType, variable),
|
||||||
|
irInt(0),
|
||||||
|
getHashCodeOf(
|
||||||
|
propertyType,
|
||||||
|
irGet(irPropertyType, variable)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
else ->
|
else ->
|
||||||
getHashCodeOf(irGet(receiver, getterSymbol))
|
getHashCodeOf(
|
||||||
|
propertyType,
|
||||||
|
irGet(irPropertyType, receiver, getterSymbol)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MemberFunctionBuilder.getHashCodeOf(irValue: IrExpression): IrExpression {
|
private fun MemberFunctionBuilder.getHashCodeOf(kotlinType: KotlinType, irValue: IrExpression): IrExpression {
|
||||||
val hashCodeFunctionDescriptor = getHashCodeFunction(irValue.type)
|
val hashCodeFunctionDescriptor = getHashCodeFunction(kotlinType)
|
||||||
val hashCodeFunctionSymbol = declarationGenerator.context.symbolTable.referenceFunction(hashCodeFunctionDescriptor.original)
|
val hashCodeFunctionSymbol = declarationGenerator.context.symbolTable.referenceFunction(hashCodeFunctionDescriptor.original)
|
||||||
return irCall(hashCodeFunctionSymbol, hashCodeFunctionDescriptor).apply {
|
return irCall(hashCodeFunctionSymbol, hashCodeFunctionDescriptor).apply {
|
||||||
if (descriptor.dispatchReceiverParameter != null) {
|
if (descriptor.dispatchReceiverParameter != null) {
|
||||||
@@ -243,19 +274,25 @@ class DataClassMembersGenerator(
|
|||||||
irConcat.addArgument(irString(classDescriptor.name.asString() + "("))
|
irConcat.addArgument(irString(classDescriptor.name.asString() + "("))
|
||||||
var first = true
|
var first = true
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
|
val irPropertyType = property.type.toIrType()
|
||||||
|
|
||||||
if (!first) irConcat.addArgument(irString(", "))
|
if (!first) irConcat.addArgument(irString(", "))
|
||||||
|
|
||||||
irConcat.addArgument(irString(property.name.asString() + "="))
|
irConcat.addArgument(irString(property.name.asString() + "="))
|
||||||
val irPropertyValue = irGet(irThis(), getPropertyGetterSymbol(property))
|
|
||||||
|
val irPropertyValue = irGet(irPropertyType, irThis(), getPropertyGetterSymbol(property))
|
||||||
|
|
||||||
val typeConstructorDescriptor = property.type.constructor.declarationDescriptor
|
val typeConstructorDescriptor = property.type.constructor.declarationDescriptor
|
||||||
val irPropertyStringValue =
|
val irPropertyStringValue =
|
||||||
if (typeConstructorDescriptor is ClassDescriptor &&
|
if (typeConstructorDescriptor is ClassDescriptor &&
|
||||||
KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)
|
KotlinBuiltIns.isArrayOrPrimitiveArray(typeConstructorDescriptor)
|
||||||
)
|
)
|
||||||
irCall(context.irBuiltIns.dataClassArrayMemberToStringSymbol).apply {
|
irCall(context.irBuiltIns.dataClassArrayMemberToStringSymbol, context.irBuiltIns.stringType).apply {
|
||||||
putValueArgument(0, irPropertyValue)
|
putValueArgument(0, irPropertyValue)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
irPropertyValue
|
irPropertyValue
|
||||||
|
|
||||||
irConcat.addArgument(irPropertyStringValue)
|
irConcat.addArgument(irPropertyStringValue)
|
||||||
first = false
|
first = false
|
||||||
}
|
}
|
||||||
|
|||||||
+22
-11
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.psi2ir.generators
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irBlockBody
|
||||||
import org.jetbrains.kotlin.ir.builders.irGet
|
import org.jetbrains.kotlin.ir.builders.irGet
|
||||||
import org.jetbrains.kotlin.ir.builders.irReturn
|
import org.jetbrains.kotlin.ir.builders.irReturn
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -55,8 +56,10 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
val kPropertyType = getKPropertyTypeForDelegatedProperty(propertyDescriptor)
|
val kPropertyType = getKPropertyTypeForDelegatedProperty(propertyDescriptor)
|
||||||
|
|
||||||
val irProperty = IrPropertyImpl(
|
val irProperty = IrPropertyImpl(
|
||||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED, true,
|
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||||
propertyDescriptor
|
isDelegated = true,
|
||||||
|
descriptor = propertyDescriptor,
|
||||||
|
type = propertyDescriptor.type.toIrType()
|
||||||
).apply {
|
).apply {
|
||||||
backingField = generateDelegateFieldForProperty(propertyDescriptor, kPropertyType, ktDelegate)
|
backingField = generateDelegateFieldForProperty(propertyDescriptor, kPropertyType, ktDelegate)
|
||||||
}
|
}
|
||||||
@@ -171,10 +174,12 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
|
|
||||||
private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? =
|
private fun createThisValueForDelegate(thisClass: ClassDescriptor?, ktDelegate: KtPropertyDelegate): IntermediateValue? =
|
||||||
thisClass?.let {
|
thisClass?.let {
|
||||||
generateExpressionValue(it.thisAsReceiverParameter.type) {
|
generateExpressionValue(it.thisAsReceiverParameter.type.toIrType()) {
|
||||||
|
val thisAsReceiverParameter = thisClass.thisAsReceiverParameter
|
||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
ktDelegate.startOffset, ktDelegate.endOffset,
|
ktDelegate.startOffset, ktDelegate.endOffset,
|
||||||
context.symbolTable.referenceValueParameter(thisClass.thisAsReceiverParameter)
|
thisAsReceiverParameter.type.toIrType(),
|
||||||
|
context.symbolTable.referenceValueParameter(thisAsReceiverParameter)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -225,7 +230,8 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
|
|
||||||
val irLocalDelegatedProperty = IrLocalDelegatedPropertyImpl(
|
val irLocalDelegatedProperty = IrLocalDelegatedPropertyImpl(
|
||||||
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
ktProperty.startOffset, ktProperty.endOffset, IrDeclarationOrigin.DEFINED,
|
||||||
variableDescriptor
|
variableDescriptor,
|
||||||
|
variableDescriptor.type.toIrType()
|
||||||
).apply {
|
).apply {
|
||||||
delegate = generateDelegateVariableForLocalDelegatedProperty(ktDelegate, variableDescriptor, kPropertyType, scopeOwnerSymbol)
|
delegate = generateDelegateVariableForLocalDelegatedProperty(ktDelegate, variableDescriptor, kPropertyType, scopeOwnerSymbol)
|
||||||
}
|
}
|
||||||
@@ -363,7 +369,9 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
irPropertyReference: IrCallableReference
|
irPropertyReference: IrCallableReference
|
||||||
): IrBody =
|
): IrBody =
|
||||||
with(createBodyGenerator(irGetter.symbol)) {
|
with(createBodyGenerator(irGetter.symbol)) {
|
||||||
irBlockBody(ktDelegate) {
|
val startOffset = ktDelegate.startOffset
|
||||||
|
val endOffset = ktDelegate.endOffset
|
||||||
|
irBlockBody(startOffset, endOffset) {
|
||||||
val statementGenerator = createStatementGenerator()
|
val statementGenerator = createStatementGenerator()
|
||||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
|
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getterDescriptor)
|
||||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||||
@@ -371,8 +379,8 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||||
+irReturn(
|
+irReturn(
|
||||||
CallGenerator(statementGenerator).generateCall(
|
CallGenerator(statementGenerator).generateCall(
|
||||||
ktDelegate.startOffset,
|
startOffset,
|
||||||
ktDelegate.endOffset,
|
endOffset,
|
||||||
conventionMethodCall
|
conventionMethodCall
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -386,14 +394,17 @@ class DelegatedPropertyGenerator(declarationGenerator: DeclarationGenerator) : D
|
|||||||
delegateReceiverValue: IntermediateValue,
|
delegateReceiverValue: IntermediateValue,
|
||||||
irPropertyReference: IrCallableReference
|
irPropertyReference: IrCallableReference
|
||||||
): IrBody = with(createBodyGenerator(irSetter.symbol)) {
|
): IrBody = with(createBodyGenerator(irSetter.symbol)) {
|
||||||
irBlockBody(ktDelegate) {
|
val startOffset = ktDelegate.startOffset
|
||||||
|
val endOffset = ktDelegate.endOffset
|
||||||
|
irBlockBody(startOffset, endOffset) {
|
||||||
val statementGenerator = createStatementGenerator()
|
val statementGenerator = createStatementGenerator()
|
||||||
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
|
val conventionMethodResolvedCall = getOrFail(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, setterDescriptor)
|
||||||
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
val conventionMethodCall = statementGenerator.pregenerateCall(conventionMethodResolvedCall)
|
||||||
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
conventionMethodCall.setExplicitReceiverValue(delegateReceiverValue)
|
||||||
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
conventionMethodCall.irValueArgumentsByIndex[1] = irPropertyReference
|
||||||
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(irSetter.valueParameters[0].symbol)
|
val irSetterParameter = irSetter.valueParameters[0]
|
||||||
+irReturn(CallGenerator(statementGenerator).generateCall(ktDelegate.startOffset, ktDelegate.endOffset, conventionMethodCall))
|
conventionMethodCall.irValueArgumentsByIndex[2] = irGet(irSetterParameter.type, irSetterParameter.symbol)
|
||||||
|
+irReturn(CallGenerator(statementGenerator).generateCall(startOffset, endOffset, conventionMethodCall))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+18
-9
@@ -142,17 +142,20 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
): IrBlockBody {
|
): IrBlockBody {
|
||||||
val property = getter.correspondingProperty
|
val property = getter.correspondingProperty
|
||||||
|
|
||||||
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
val startOffset = ktProperty.startOffset
|
||||||
|
val endOffset = ktProperty.endOffset
|
||||||
|
val irBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||||
|
|
||||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
||||||
|
|
||||||
irBody.statements.add(
|
irBody.statements.add(
|
||||||
IrReturnImpl(
|
IrReturnImpl(
|
||||||
ktProperty.startOffset, ktProperty.endOffset, context.builtIns.nothingType,
|
startOffset, endOffset, context.irBuiltIns.nothingType,
|
||||||
irAccessor.symbol,
|
irAccessor.symbol,
|
||||||
IrGetFieldImpl(
|
IrGetFieldImpl(
|
||||||
ktProperty.startOffset, ktProperty.endOffset,
|
startOffset, endOffset,
|
||||||
context.symbolTable.referenceField(property),
|
context.symbolTable.referenceField(property),
|
||||||
|
property.type.toIrType(),
|
||||||
receiver
|
receiver
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -167,17 +170,20 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
): IrBlockBody {
|
): IrBlockBody {
|
||||||
val property = setter.correspondingProperty
|
val property = setter.correspondingProperty
|
||||||
|
|
||||||
val irBody = IrBlockBodyImpl(ktProperty.startOffset, ktProperty.endOffset)
|
val startOffset = ktProperty.startOffset
|
||||||
|
val endOffset = ktProperty.endOffset
|
||||||
|
val irBody = IrBlockBodyImpl(startOffset, endOffset)
|
||||||
|
|
||||||
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
val receiver = generateReceiverExpressionForDefaultPropertyAccessor(ktProperty, property)
|
||||||
|
|
||||||
val setterParameter = irAccessor.valueParameters.single().symbol
|
val irValueParameter = irAccessor.valueParameters.single()
|
||||||
irBody.statements.add(
|
irBody.statements.add(
|
||||||
IrSetFieldImpl(
|
IrSetFieldImpl(
|
||||||
ktProperty.startOffset, ktProperty.endOffset,
|
startOffset, endOffset,
|
||||||
context.symbolTable.referenceField(property),
|
context.symbolTable.referenceField(property),
|
||||||
receiver,
|
receiver,
|
||||||
IrGetValueImpl(ktProperty.startOffset, ktProperty.endOffset, setterParameter)
|
IrGetValueImpl(startOffset, endOffset, irValueParameter.type, irValueParameter.symbol),
|
||||||
|
context.irBuiltIns.unitType
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
return irBody
|
return irBody
|
||||||
@@ -186,11 +192,14 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
private fun generateReceiverExpressionForDefaultPropertyAccessor(ktProperty: KtElement, property: PropertyDescriptor): IrExpression? {
|
private fun generateReceiverExpressionForDefaultPropertyAccessor(ktProperty: KtElement, property: PropertyDescriptor): IrExpression? {
|
||||||
val containingDeclaration = property.containingDeclaration
|
val containingDeclaration = property.containingDeclaration
|
||||||
return when (containingDeclaration) {
|
return when (containingDeclaration) {
|
||||||
is ClassDescriptor ->
|
is ClassDescriptor -> {
|
||||||
|
val thisAsReceiverParameter = containingDeclaration.thisAsReceiverParameter
|
||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
ktProperty.startOffset, ktProperty.endOffset,
|
ktProperty.startOffset, ktProperty.endOffset,
|
||||||
context.symbolTable.referenceValue(containingDeclaration.thisAsReceiverParameter)
|
thisAsReceiverParameter.type.toIrType(),
|
||||||
|
context.symbolTable.referenceValue(thisAsReceiverParameter)
|
||||||
)
|
)
|
||||||
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+59
-23
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.makeNotNull
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -46,6 +47,14 @@ import java.lang.AssertionError
|
|||||||
|
|
||||||
class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
|
||||||
|
|
||||||
|
private fun createErrorExpression(ktExpression: KtExpression, text: String) =
|
||||||
|
IrErrorExpressionImpl(
|
||||||
|
ktExpression.startOffset,
|
||||||
|
ktExpression.endOffset,
|
||||||
|
context.irBuiltIns.nothingType,
|
||||||
|
text
|
||||||
|
)
|
||||||
|
|
||||||
fun generatePrefixExpression(expression: KtPrefixExpression): IrExpression {
|
fun generatePrefixExpression(expression: KtPrefixExpression): IrExpression {
|
||||||
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
val ktOperator = expression.operationReference.getReferencedNameElementType()
|
||||||
val irOperator = getPrefixOperator(ktOperator)
|
val irOperator = getPrefixOperator(ktOperator)
|
||||||
@@ -57,7 +66,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
irOperator
|
irOperator
|
||||||
)
|
)
|
||||||
in OPERATORS_DESUGARED_TO_CALLS -> generatePrefixOperatorAsCall(expression, irOperator)
|
in OPERATORS_DESUGARED_TO_CALLS -> generatePrefixOperatorAsCall(expression, irOperator)
|
||||||
else -> createDummyExpression(expression, ktOperator.toString())
|
else -> createErrorExpression(expression, ktOperator.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +81,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
irOperator
|
irOperator
|
||||||
)
|
)
|
||||||
IrStatementOrigin.EXCLEXCL -> generateExclExclOperator(expression, irOperator)
|
IrStatementOrigin.EXCLEXCL -> generateExclExclOperator(expression, irOperator)
|
||||||
else -> createDummyExpression(expression, ktOperator.toString())
|
else -> createErrorExpression(expression, ktOperator.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +100,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
}
|
}
|
||||||
|
|
||||||
return IrTypeOperatorCallImpl(
|
return IrTypeOperatorCallImpl(
|
||||||
expression.startOffset, expression.endOffset, resultType, irOperator, rhsType,
|
expression.startOffset, expression.endOffset, resultType.toIrType(), irOperator, rhsType.toIrType(),
|
||||||
context.symbolTable.referenceClassifier(rhsType.constructor.declarationDescriptor!!),
|
context.symbolTable.referenceClassifier(rhsType.constructor.declarationDescriptor!!),
|
||||||
expression.left.genExpr()
|
expression.left.genExpr()
|
||||||
)
|
)
|
||||||
@@ -103,8 +112,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
|
val againstType = getOrFail(BindingContext.TYPE, expression.typeReference)
|
||||||
|
|
||||||
return IrTypeOperatorCallImpl(
|
return IrTypeOperatorCallImpl(
|
||||||
expression.startOffset, expression.endOffset, context.builtIns.booleanType, irOperator,
|
expression.startOffset, expression.endOffset, context.irBuiltIns.booleanType, irOperator,
|
||||||
againstType, context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!),
|
againstType.toIrType(),
|
||||||
|
context.symbolTable.referenceClassifier(againstType.constructor.declarationDescriptor!!),
|
||||||
expression.leftHandSide.genExpr()
|
expression.leftHandSide.genExpr()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -128,19 +138,24 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
in IDENTITY_OPERATORS -> generateIdentityOperator(expression, irOperator)
|
in IDENTITY_OPERATORS -> generateIdentityOperator(expression, irOperator)
|
||||||
in IN_OPERATORS -> generateInOperator(expression, irOperator)
|
in IN_OPERATORS -> generateInOperator(expression, irOperator)
|
||||||
in BINARY_BOOLEAN_OPERATORS -> generateBinaryBooleanOperator(expression, irOperator)
|
in BINARY_BOOLEAN_OPERATORS -> generateBinaryBooleanOperator(expression, irOperator)
|
||||||
else -> createDummyExpression(expression, ktOperator.toString())
|
else -> createErrorExpression(expression, ktOperator.toString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
|
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
|
||||||
val specialCallForElvis = getResolvedCall(expression)!!
|
val specialCallForElvis = getResolvedCall(expression)!!
|
||||||
val resultType = specialCallForElvis.resultingDescriptor.returnType!!
|
val resultType = specialCallForElvis.resultingDescriptor.returnType!!.toIrType()
|
||||||
val irArgument0 = expression.left!!.genExpr()
|
val irArgument0 = expression.left!!.genExpr()
|
||||||
val irArgument1 = expression.right!!.genExpr()
|
val irArgument1 = expression.right!!.genExpr()
|
||||||
|
|
||||||
return irBlock(expression, IrStatementOrigin.ELVIS, resultType) {
|
return irBlock(expression.startOffset, expression.endOffset, IrStatementOrigin.ELVIS, resultType) {
|
||||||
val temporary = irTemporary(irArgument0, "elvis_lhs")
|
val temporary = irTemporary(irArgument0, "elvis_lhs")
|
||||||
+irIfNull(resultType, irGet(temporary.symbol), irArgument1, irGet(temporary.symbol))
|
+irIfNull(
|
||||||
|
resultType,
|
||||||
|
irGet(temporary.type, temporary.symbol),
|
||||||
|
irArgument1,
|
||||||
|
irGet(temporary.type, temporary.symbol)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,7 +182,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
irContainsCall
|
irContainsCall
|
||||||
IrStatementOrigin.NOT_IN ->
|
IrStatementOrigin.NOT_IN ->
|
||||||
IrUnaryPrimitiveImpl(
|
IrUnaryPrimitiveImpl(
|
||||||
expression.startOffset, expression.endOffset, IrStatementOrigin.NOT_IN,
|
expression.startOffset, expression.endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
|
IrStatementOrigin.NOT_IN,
|
||||||
context.irBuiltIns.booleanNotSymbol,
|
context.irBuiltIns.booleanNotSymbol,
|
||||||
irContainsCall
|
irContainsCall
|
||||||
)
|
)
|
||||||
@@ -182,7 +199,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
val irArgument1 = expression.right!!.genExpr()
|
val irArgument1 = expression.right!!.genExpr()
|
||||||
|
|
||||||
val irIdentityEquals = IrBinaryPrimitiveImpl(
|
val irIdentityEquals = IrBinaryPrimitiveImpl(
|
||||||
expression.startOffset, expression.endOffset, irOperator,
|
expression.startOffset, expression.endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
|
irOperator,
|
||||||
context.irBuiltIns.eqeqeqSymbol,
|
context.irBuiltIns.eqeqeqSymbol,
|
||||||
irArgument0, irArgument1
|
irArgument0, irArgument1
|
||||||
)
|
)
|
||||||
@@ -192,7 +211,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
irIdentityEquals
|
irIdentityEquals
|
||||||
IrStatementOrigin.EXCLEQEQ ->
|
IrStatementOrigin.EXCLEQEQ ->
|
||||||
IrUnaryPrimitiveImpl(
|
IrUnaryPrimitiveImpl(
|
||||||
expression.startOffset, expression.endOffset, IrStatementOrigin.EXCLEQEQ,
|
expression.startOffset, expression.endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
|
IrStatementOrigin.EXCLEQEQ,
|
||||||
context.irBuiltIns.booleanNotSymbol,
|
context.irBuiltIns.booleanNotSymbol,
|
||||||
irIdentityEquals
|
irIdentityEquals
|
||||||
)
|
)
|
||||||
@@ -218,6 +239,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
|
|
||||||
val irEquals = IrBinaryPrimitiveImpl(
|
val irEquals = IrBinaryPrimitiveImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
irOperator,
|
irOperator,
|
||||||
eqeqSymbol,
|
eqeqSymbol,
|
||||||
expression.left!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo?.leftType, comparisonType),
|
expression.left!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo?.leftType, comparisonType),
|
||||||
@@ -230,6 +252,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
IrStatementOrigin.EXCLEQ ->
|
IrStatementOrigin.EXCLEQ ->
|
||||||
IrUnaryPrimitiveImpl(
|
IrUnaryPrimitiveImpl(
|
||||||
expression.startOffset, expression.endOffset,
|
expression.startOffset, expression.endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
IrStatementOrigin.EXCLEQ,
|
IrStatementOrigin.EXCLEQ,
|
||||||
context.irBuiltIns.booleanNotSymbol,
|
context.irBuiltIns.booleanNotSymbol,
|
||||||
irEquals
|
irEquals
|
||||||
@@ -253,14 +276,18 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType]?.symbol
|
context.irBuiltIns.ieee754equalsFunByOperandType[comparisonType]?.symbol
|
||||||
?: context.irBuiltIns.eqeqSymbol
|
?: context.irBuiltIns.eqeqSymbol
|
||||||
IrBinaryPrimitiveImpl(
|
IrBinaryPrimitiveImpl(
|
||||||
startOffset, endOffset, irOperator,
|
startOffset, endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
|
irOperator,
|
||||||
eqeqSymbol,
|
eqeqSymbol,
|
||||||
arg1.promoteToPrimitiveNumericType(comparisonInfo.leftType, comparisonType),
|
arg1.promoteToPrimitiveNumericType(comparisonInfo.leftType, comparisonType),
|
||||||
arg2.promoteToPrimitiveNumericType(comparisonInfo.rightType, comparisonType)
|
arg2.promoteToPrimitiveNumericType(comparisonInfo.rightType, comparisonType)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
IrBinaryPrimitiveImpl(
|
IrBinaryPrimitiveImpl(
|
||||||
startOffset, endOffset, irOperator,
|
startOffset, endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
|
irOperator,
|
||||||
context.irBuiltIns.eqeqSymbol,
|
context.irBuiltIns.eqeqSymbol,
|
||||||
arg1, arg2
|
arg1, arg2
|
||||||
)
|
)
|
||||||
@@ -281,7 +308,8 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
operandType == targetType || operandNNType == targetType ->
|
operandType == targetType || operandNNType == targetType ->
|
||||||
this
|
this
|
||||||
|
|
||||||
type.containsNull() ->
|
// TODO operandType may have inaccurate nullability
|
||||||
|
operandType.containsNull() ->
|
||||||
safeCallOnDispatchReceiver(this@OperatorExpressionGenerator, startOffset, endOffset) { dispatchReceiver ->
|
safeCallOnDispatchReceiver(this@OperatorExpressionGenerator, startOffset, endOffset) { dispatchReceiver ->
|
||||||
invokeConversionFunction(
|
invokeConversionFunction(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
@@ -308,10 +336,9 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
IrCallImpl(
|
IrCallImpl(
|
||||||
startOffset,
|
startOffset,
|
||||||
endOffset,
|
endOffset,
|
||||||
functionDescriptor.returnType!!,
|
functionDescriptor.returnType!!.toIrType(),
|
||||||
context.symbolTable.referenceFunction(functionDescriptor.original),
|
context.symbolTable.referenceFunction(functionDescriptor.original),
|
||||||
functionDescriptor,
|
functionDescriptor,
|
||||||
typeArguments = null,
|
|
||||||
origin = null, // TODO origin for widening conversions?
|
origin = null, // TODO origin for widening conversions?
|
||||||
superQualifierSymbol = null
|
superQualifierSymbol = null
|
||||||
).apply {
|
).apply {
|
||||||
@@ -331,17 +358,21 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
|
|
||||||
return if (comparisonInfo != null) {
|
return if (comparisonInfo != null) {
|
||||||
IrBinaryPrimitiveImpl(
|
IrBinaryPrimitiveImpl(
|
||||||
startOffset, endOffset, origin,
|
startOffset, endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
|
origin,
|
||||||
getComparisonOperatorSymbol(origin, comparisonInfo.comparisonType),
|
getComparisonOperatorSymbol(origin, comparisonInfo.comparisonType),
|
||||||
expression.left!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.leftType, comparisonInfo.comparisonType),
|
expression.left!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.leftType, comparisonInfo.comparisonType),
|
||||||
expression.right!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.rightType, comparisonInfo.comparisonType)
|
expression.right!!.generateAsPrimitiveNumericComparisonOperand(comparisonInfo.rightType, comparisonInfo.comparisonType)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
IrBinaryPrimitiveImpl(
|
IrBinaryPrimitiveImpl(
|
||||||
startOffset, endOffset, origin,
|
startOffset, endOffset,
|
||||||
|
context.irBuiltIns.booleanType,
|
||||||
|
origin,
|
||||||
getComparisonOperatorSymbol(origin, context.irBuiltIns.int),
|
getComparisonOperatorSymbol(origin, context.irBuiltIns.int),
|
||||||
generateCall(getResolvedCall(expression)!!, expression, origin),
|
generateCall(getResolvedCall(expression)!!, expression, origin),
|
||||||
IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, 0)
|
IrConstImpl.int(startOffset, endOffset, context.irBuiltIns.intType, 0)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -367,11 +398,16 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
val irArgument = ktArgument.genExpr()
|
val irArgument = ktArgument.genExpr()
|
||||||
val ktOperator = expression.operationReference
|
val ktOperator = expression.operationReference
|
||||||
|
|
||||||
val resultType = irArgument.type.makeNotNullable()
|
val resultType = irArgument.type.makeNotNull()
|
||||||
|
|
||||||
return irBlock(ktOperator, origin, resultType) {
|
return irBlock(ktOperator.startOffset, ktOperator.endOffset, origin, resultType) {
|
||||||
val temporary = irTemporary(irArgument, "notnull")
|
val temporary = irTemporary(irArgument, "notnull")
|
||||||
+irIfNull(resultType, irGet(temporary.symbol), irThrowNpe(origin), irGet(temporary.symbol))
|
+irIfNull(
|
||||||
|
resultType,
|
||||||
|
irGet(temporary.type, temporary.symbol),
|
||||||
|
irThrowNpe(origin),
|
||||||
|
irGet(temporary.type, temporary.symbol)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,14 +85,33 @@ fun IrBuilderWithScope.irReturn(value: IrExpression) =
|
|||||||
value
|
value
|
||||||
)
|
)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irReturnTrue() =
|
fun IrBuilderWithScope.irBoolean(value: Boolean) =
|
||||||
irReturn(IrConstImpl(startOffset, endOffset, context.irBuiltIns.booleanType, IrConstKind.Boolean, true))
|
IrConstImpl(startOffset, endOffset, context.irBuiltIns.booleanType, IrConstKind.Boolean, value)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irReturnFalse() =
|
fun IrBuilderWithScope.irTrue() = irBoolean(true)
|
||||||
irReturn(IrConstImpl(startOffset, endOffset, context.irBuiltIns.booleanType, IrConstKind.Boolean, false))
|
fun IrBuilderWithScope.irFalse() = irBoolean(false)
|
||||||
|
fun IrBuilderWithScope.irReturnTrue() = irReturn(irTrue())
|
||||||
|
fun IrBuilderWithScope.irReturnFalse() = irReturn(irFalse())
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irElseBranch(expression: IrExpression) =
|
||||||
|
IrElseBranchImpl(startOffset, endOffset, irTrue(), expression)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irIfThen(type: IrType, condition: IrExpression, thenPart: IrExpression) =
|
||||||
|
IrIfThenElseImpl(startOffset, endOffset, type).apply {
|
||||||
|
branches.add(IrBranchImpl(startOffset, endOffset, condition, thenPart))
|
||||||
|
}
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThenElse(type: IrType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
fun IrBuilderWithScope.irIfThenElse(type: IrType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
||||||
IrIfThenElseImpl(startOffset, endOffset, type, condition, thenPart, elsePart)
|
IrIfThenElseImpl(startOffset, endOffset, type).apply {
|
||||||
|
branches.add(IrBranchImpl(startOffset, endOffset, condition, thenPart))
|
||||||
|
branches.add(irElseBranch(elsePart))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irIfThenMaybeElse(type: IrType, condition: IrExpression, thenPart: IrExpression, elsePart: IrExpression?) =
|
||||||
|
if (elsePart != null)
|
||||||
|
irIfThenElse(type, condition, thenPart, elsePart)
|
||||||
|
else
|
||||||
|
irIfThen(type, condition, thenPart)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfNull(type: IrType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
fun IrBuilderWithScope.irIfNull(type: IrType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
||||||
irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart)
|
irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart)
|
||||||
@@ -101,10 +120,10 @@ fun IrBuilderWithScope.irThrowNpe(origin: IrStatementOrigin) =
|
|||||||
IrNullaryPrimitiveImpl(startOffset, endOffset, context.irBuiltIns.nothingType, origin, context.irBuiltIns.throwNpeSymbol)
|
IrNullaryPrimitiveImpl(startOffset, endOffset, context.irBuiltIns.nothingType, origin, context.irBuiltIns.throwNpeSymbol)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
|
fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
|
||||||
IrIfThenElseImpl(startOffset, endOffset, context.irBuiltIns.unitType, condition, irReturnTrue())
|
irIfThen(context.irBuiltIns.unitType, condition, irReturnTrue())
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) =
|
fun IrBuilderWithScope.irIfThenReturnFalse(condition: IrExpression) =
|
||||||
IrIfThenElseImpl(startOffset, endOffset, context.irBuiltIns.unitType, condition, irReturnFalse())
|
irIfThen(context.irBuiltIns.unitType, condition, irReturnFalse())
|
||||||
|
|
||||||
fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
|
fun IrBuilderWithScope.irGet(type: IrType, variable: IrValueSymbol) =
|
||||||
IrGetValueImpl(startOffset, endOffset, type, variable)
|
IrGetValueImpl(startOffset, endOffset, type, variable)
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ class IrBlockBuilder(
|
|||||||
val origin: IrStatementOrigin? = null,
|
val origin: IrStatementOrigin? = null,
|
||||||
var resultType: IrType? = null
|
var resultType: IrType? = null
|
||||||
) : IrStatementsBuilder<IrBlock>(context, scope, startOffset, endOffset) {
|
) : IrStatementsBuilder<IrBlock>(context, scope, startOffset, endOffset) {
|
||||||
|
|
||||||
private val statements = ArrayList<IrStatement>()
|
private val statements = ArrayList<IrStatement>()
|
||||||
|
|
||||||
inline fun block(body: IrBlockBuilder.() -> Unit): IrBlock {
|
inline fun block(body: IrBlockBuilder.() -> Unit): IrBlock {
|
||||||
@@ -107,6 +108,33 @@ class IrBlockBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class IrSingleStatementBuilder(
|
||||||
|
context: IrGeneratorContext,
|
||||||
|
scope: Scope,
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
val origin: IrStatementOrigin? = null
|
||||||
|
) : IrBuilderWithScope(context, scope, startOffset, endOffset) {
|
||||||
|
|
||||||
|
inline fun <T : IrElement> build(statementBuilder: IrSingleStatementBuilder.() -> T): T =
|
||||||
|
statementBuilder()
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T : IrElement> IrGeneratorWithScope.buildStatement(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
origin: IrStatementOrigin?,
|
||||||
|
builder: IrSingleStatementBuilder.() -> T
|
||||||
|
) =
|
||||||
|
IrSingleStatementBuilder(context, scope, startOffset, endOffset, origin).builder()
|
||||||
|
|
||||||
|
inline fun <T : IrElement> IrGeneratorWithScope.buildStatement(
|
||||||
|
startOffset: Int,
|
||||||
|
endOffset: Int,
|
||||||
|
builder: IrSingleStatementBuilder.() -> T
|
||||||
|
) =
|
||||||
|
IrSingleStatementBuilder(context, scope, startOffset, endOffset).builder()
|
||||||
|
|
||||||
fun <T : IrBuilder> T.at(startOffset: Int, endOffset: Int) = apply {
|
fun <T : IrBuilder> T.at(startOffset: Int, endOffset: Int) = apply {
|
||||||
this.startOffset = startOffset
|
this.startOffset = startOffset
|
||||||
this.endOffset = endOffset
|
this.endOffset = endOffset
|
||||||
|
|||||||
+17
-10
@@ -86,17 +86,24 @@ fun IrMemberAccessExpression.removeValueArgument(valueParameterDescriptor: Value
|
|||||||
removeValueArgument(valueParameterDescriptor.index)
|
removeValueArgument(valueParameterDescriptor.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <T : IrMemberAccessExpression> T.mapValueParameters(transform: (ValueParameterDescriptor) -> IrExpression?): T {
|
inline fun <T : IrMemberAccessExpression> T.mapTypeParameters(transform: (TypeParameterDescriptor) -> IrType) : T =
|
||||||
descriptor.valueParameters.forEach {
|
apply {
|
||||||
putValueArgument(it.index, transform(it))
|
descriptor.typeParameters.forEach {
|
||||||
|
putTypeArgument(it.index, transform(it))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun <T : IrMemberAccessExpression> T.mapValueParametersIndexed(transform: (Int, ValueParameterDescriptor) -> IrExpression?): T {
|
inline fun <T : IrMemberAccessExpression> T.mapValueParameters(transform: (ValueParameterDescriptor) -> IrExpression?): T =
|
||||||
descriptor.valueParameters.forEach {
|
apply {
|
||||||
putValueArgument(it.index, transform(it.index, it))
|
descriptor.valueParameters.forEach {
|
||||||
|
putValueArgument(it.index, transform(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <T : IrMemberAccessExpression> T.mapValueParametersIndexed(transform: (Int, ValueParameterDescriptor) -> IrExpression?): T =
|
||||||
|
apply {
|
||||||
|
descriptor.valueParameters.forEach {
|
||||||
|
putValueArgument(it.index, transform(it.index, it))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,19 +31,4 @@ class IrIfThenElseImpl(
|
|||||||
IrWhenBase(startOffset, endOffset, type) {
|
IrWhenBase(startOffset, endOffset, type) {
|
||||||
|
|
||||||
override val branches: MutableList<IrBranch> = SmartList()
|
override val branches: MutableList<IrBranch> = SmartList()
|
||||||
|
|
||||||
constructor(
|
|
||||||
startOffset: Int,
|
|
||||||
endOffset: Int,
|
|
||||||
type: IrType,
|
|
||||||
condition: IrExpression,
|
|
||||||
thenBranch: IrExpression,
|
|
||||||
elseBranch: IrExpression? = null,
|
|
||||||
origin: IrStatementOrigin? = null
|
|
||||||
) : this(startOffset, endOffset, type, origin) {
|
|
||||||
branches.add(IrBranchImpl(startOffset, endOffset, condition, thenBranch))
|
|
||||||
if (elseBranch != null) {
|
|
||||||
branches.add(IrBranchImpl.elseBranch(elseBranch))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -51,7 +51,8 @@ class IrWhenImpl(
|
|||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
type: IrType,
|
type: IrType,
|
||||||
override val origin: IrStatementOrigin? = null
|
override val origin: IrStatementOrigin? = null
|
||||||
) : IrWhenBase(startOffset, endOffset, type) {
|
) :
|
||||||
|
IrWhenBase(startOffset, endOffset, type) {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
startOffset: Int,
|
startOffset: Int,
|
||||||
@@ -71,7 +72,9 @@ open class IrBranchImpl(
|
|||||||
endOffset: Int,
|
endOffset: Int,
|
||||||
override var condition: IrExpression,
|
override var condition: IrExpression,
|
||||||
override var result: IrExpression
|
override var result: IrExpression
|
||||||
) : IrElementBase(startOffset, endOffset), IrBranch {
|
) :
|
||||||
|
IrElementBase(startOffset, endOffset),
|
||||||
|
IrBranch {
|
||||||
|
|
||||||
constructor(condition: IrExpression, result: IrExpression) :
|
constructor(condition: IrExpression, result: IrExpression) :
|
||||||
this(condition.startOffset, condition.endOffset, condition, result)
|
this(condition.startOffset, condition.endOffset, condition, result)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.types
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -25,3 +26,15 @@ val IrType.classifierOrFail: IrClassifierSymbol
|
|||||||
|
|
||||||
val IrType.classifierOrNull: IrClassifierSymbol?
|
val IrType.classifierOrNull: IrClassifierSymbol?
|
||||||
get() = safeAs<IrSimpleType>()?.classifier
|
get() = safeAs<IrSimpleType>()?.classifier
|
||||||
|
|
||||||
|
fun IrType.makeNotNull() =
|
||||||
|
if (this is IrSimpleType && this.hasQuestionMark)
|
||||||
|
IrSimpleTypeImpl(
|
||||||
|
classifier,
|
||||||
|
false,
|
||||||
|
arguments,
|
||||||
|
annotations,
|
||||||
|
Variance.INVARIANT
|
||||||
|
)
|
||||||
|
else
|
||||||
|
this
|
||||||
Reference in New Issue
Block a user