'?:' (currently represented as binary expression with operator ELVIS)

This commit is contained in:
Dmitry Petrov
2016-08-17 18:04:34 +03:00
committed by Dmitry Petrov
parent 0d94c3aeb4
commit 8de21aadfa
6 changed files with 76 additions and 3 deletions
@@ -54,7 +54,12 @@ internal val KT_TOKEN_TO_IR_OPERATOR =
KtTokens.EXCLEQEQEQ to IrOperator.EXCLEQEQ,
KtTokens.IN_KEYWORD to IrOperator.IN,
KtTokens.NOT_IN to IrOperator.NOT_IN
KtTokens.NOT_IN to IrOperator.NOT_IN,
KtTokens.ANDAND to IrOperator.ANDAND,
KtTokens.OROR to IrOperator.OROR,
KtTokens.ELVIS to IrOperator.ELVIS
)
internal val AUGMENTED_ASSIGNMENTS =
@@ -74,3 +79,6 @@ internal val IDENTITY_OPERATORS =
internal val IN_OPERATORS =
setOf(IrOperator.IN, IrOperator.NOT_IN)
internal val BINARY_BOOLEAN_OPERATORS =
setOf(IrOperator.ANDAND, IrOperator.OROR)
@@ -44,16 +44,39 @@ class IrOperatorExpressionGenerator(val irStatementGenerator: IrStatementGenerat
return when (irOperator) {
null -> createDummyExpression(expression, ktOperator.toString())
IrOperator.EQ -> generateAssignment(expression)
IrOperator.ELVIS -> generateElvis(expression)
in AUGMENTED_ASSIGNMENTS -> generateAugmentedAssignment(expression, irOperator)
in BINARY_OPERATORS_DESUGARED_TO_CALLS -> generateBinaryOperatorWithConventionalCall(expression, irOperator)
in COMPARISON_OPERATORS -> generateComparisonOperator(expression, irOperator)
in EQUALITY_OPERATORS -> generateEqualityOperator(expression, irOperator)
in IDENTITY_OPERATORS -> generateIdentityOperator(expression, irOperator)
in IN_OPERATORS -> generateInOperator(expression, irOperator)
in BINARY_BOOLEAN_OPERATORS -> generateBinaryBooleanOperator(expression, irOperator)
else -> createDummyExpression(expression, ktOperator.toString())
}
}
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
// TODO desugar '?:' to 'if'?
val specialCallForElvis = getResolvedCall(expression)!!
val returnType = specialCallForElvis.resultingDescriptor.returnType!!
val irArgument0 = irStatementGenerator.generateExpression(expression.left!!).toExpectedType(returnType.makeNullable())
val irArgument1 = irStatementGenerator.generateExpression(expression.right!!).toExpectedType(returnType)
return IrBinaryOperatorExpressionImpl(
expression.startOffset, expression.endOffset, returnType,
IrOperator.ELVIS, null, irArgument0, irArgument1
)
}
private fun generateBinaryBooleanOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
val irArgument0 = irStatementGenerator.generateExpression(expression.left!!).toExpectedType(context.builtIns.booleanType)
val irArgument1 = irStatementGenerator.generateExpression(expression.right!!).toExpectedType(context.builtIns.booleanType)
return IrBinaryOperatorExpressionImpl(
expression.startOffset, expression.endOffset, context.builtIns.booleanType,
irOperator, null, irArgument0, irArgument1
)
}
private fun generateInOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
val operatorCall = getResolvedCall(expression)!!
@@ -102,10 +102,12 @@ class IrStatementGenerator(
override fun visitReturnExpression(expression: KtReturnExpression, data: Nothing?): IrStatement {
val returnTarget = getReturnExpressionTarget(expression)
val irReturnedExpression = expression.returnedExpression?.let {
it.genExpr().toExpectedType(returnTarget.returnType)
}
return IrReturnExpressionImpl(
expression.startOffset, expression.endOffset,
returnTarget,
expression.returnedExpression?.let { it.genExpr().toExpectedType(returnTarget.returnType) }
returnTarget, irReturnedExpression
)
}