Use builder API in OperatorExpressionGenerator.
This commit is contained in:
committed by
Dmitry Petrov
parent
600fdf7eee
commit
ed68b3ecd0
@@ -62,6 +62,12 @@ fun IrBuilderWithScope.irIfThenElse(type: KotlinType, condition: IrExpression, t
|
|||||||
fun IrBuilderWithScope.irIfNull(type: KotlinType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
fun IrBuilderWithScope.irIfNull(type: KotlinType, subject: IrExpression, thenPart: IrExpression, elsePart: IrExpression) =
|
||||||
irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart)
|
irIfThenElse(type, irEqualsNull(subject), thenPart, elsePart)
|
||||||
|
|
||||||
|
fun IrBuilderWithScope.irThrowNpe(operator: IrOperator) =
|
||||||
|
IrNullaryPrimitiveImpl(startOffset, endOffset, operator, context.irBuiltIns.throwNpe)
|
||||||
|
|
||||||
|
fun IrBlockBuilder.irThrowNpe() =
|
||||||
|
irThrowNpe(operator ?: IrOperator.EXCLEXCL)
|
||||||
|
|
||||||
fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
|
fun IrBuilderWithScope.irIfThenReturnTrue(condition: IrExpression) =
|
||||||
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnTrue())
|
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, irReturnTrue())
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.psi2ir.builders
|
package org.jetbrains.kotlin.psi2ir.builders
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||||
@@ -109,6 +110,12 @@ fun <T : IrBuilder> T.at(startOffset: Int, endOffset: Int): T {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <T : IrBuilder> T.at(psiElement: PsiElement): T {
|
||||||
|
this.startOffset = psiElement.startOffset
|
||||||
|
this.endOffset = psiElement.endOffset
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
inline fun GeneratorWithScope.irBlock(ktElement: KtElement? = null, operator: IrOperator? = null, resultType: KotlinType? = null,
|
inline fun GeneratorWithScope.irBlock(ktElement: KtElement? = null, operator: IrOperator? = null, resultType: KotlinType? = null,
|
||||||
body: IrBlockBuilder.() -> Unit
|
body: IrBlockBuilder.() -> Unit
|
||||||
): IrExpression =
|
): IrExpression =
|
||||||
|
|||||||
+15
-27
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
|||||||
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.createTemporaryVariableInBlock
|
import org.jetbrains.kotlin.psi2ir.builders.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||||
@@ -109,19 +109,14 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
|
|
||||||
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
|
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
|
||||||
val specialCallForElvis = getResolvedCall(expression)!!
|
val specialCallForElvis = getResolvedCall(expression)!!
|
||||||
val returnType = specialCallForElvis.resultingDescriptor.returnType!!
|
val resultType = specialCallForElvis.resultingDescriptor.returnType!!
|
||||||
val irArgument0 = statementGenerator.generateExpression(expression.left!!)
|
val irArgument0 = statementGenerator.generateExpression(expression.left!!)
|
||||||
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
val irArgument1 = statementGenerator.generateExpression(expression.right!!)
|
||||||
|
|
||||||
val irBlock = IrBlockImpl(expression.startOffset, expression.endOffset, returnType, IrOperator.ELVIS)
|
return irBlock(expression, IrOperator.ELVIS, resultType) {
|
||||||
val irArgument0Value = scope.createTemporaryVariableInBlock(irArgument0, irBlock, "elvis_lhs")
|
val temporary = defineTemporary(irArgument0, "elvis_lhs")
|
||||||
irBlock.addStatement(IrIfThenElseImpl(
|
+irIfNull(resultType, irGet(temporary), irArgument1, irGet(temporary))
|
||||||
expression.startOffset, expression.endOffset, returnType,
|
}
|
||||||
context.equalsNull(expression.startOffset, expression.endOffset, irArgument0Value.load()),
|
|
||||||
irArgument1,
|
|
||||||
irArgument0Value.load()
|
|
||||||
))
|
|
||||||
return irBlock
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateBinaryBooleanOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
private fun generateBinaryBooleanOperator(expression: KtBinaryExpression, irOperator: IrOperator): IrExpression {
|
||||||
@@ -209,29 +204,22 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
|||||||
return IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, irOperator, compareToZeroDescriptor, irCompareToCall)
|
return IrUnaryPrimitiveImpl(expression.startOffset, expression.endOffset, irOperator, compareToZeroDescriptor, irCompareToCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun generateBinaryOperatorAsCall(expression: KtBinaryExpression, irOperator: IrOperator?): IrExpression {
|
|
||||||
val operatorCall = getResolvedCall(expression)!!
|
|
||||||
return CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(operatorCall), irOperator)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private fun generateExclExclOperator(expression: KtPostfixExpression, irOperator: IrOperator): IrExpression {
|
private fun generateExclExclOperator(expression: KtPostfixExpression, irOperator: IrOperator): IrExpression {
|
||||||
val ktArgument = expression.baseExpression!!
|
val ktArgument = expression.baseExpression!!
|
||||||
val irArgument = statementGenerator.generateExpression(ktArgument)
|
val irArgument = statementGenerator.generateExpression(ktArgument)
|
||||||
val ktOperator = expression.operationReference
|
val ktOperator = expression.operationReference
|
||||||
|
|
||||||
val resultType = irArgument.type.makeNotNullable()
|
val resultType = irArgument.type.makeNotNullable()
|
||||||
val irBlock = IrBlockImpl(ktOperator.startOffset, ktOperator.endOffset, resultType, irOperator)
|
|
||||||
val argumentValue = scope.createTemporaryVariableInBlock(irArgument, irBlock, "notnull")
|
|
||||||
val irIfThenElse = IrIfThenElseImpl(ktOperator.startOffset, ktOperator.endOffset, resultType,
|
|
||||||
context.equalsNull(ktOperator.startOffset, ktOperator.endOffset, argumentValue.load()),
|
|
||||||
context.throwNpe(ktOperator.startOffset, ktOperator.endOffset, irOperator),
|
|
||||||
argumentValue.load())
|
|
||||||
|
|
||||||
irBlock.addStatement(irIfThenElse)
|
return irBlock(ktOperator, irOperator, resultType) {
|
||||||
return irBlock
|
val temporary = defineTemporary(irArgument, "notnull")
|
||||||
|
+irIfNull(resultType, irGet(temporary), irThrowNpe(irOperator), irGet(temporary))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateBinaryOperatorAsCall(expression: KtBinaryExpression, irOperator: IrOperator?): IrExpression {
|
||||||
|
val operatorCall = getResolvedCall(expression)!!
|
||||||
|
return CallGenerator(statementGenerator).generateCall(expression, statementGenerator.pregenerateCall(operatorCall), irOperator)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generatePrefixOperatorAsCall(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression {
|
private fun generatePrefixOperatorAsCall(expression: KtPrefixExpression, irOperator: IrOperator): IrExpression {
|
||||||
|
|||||||
Reference in New Issue
Block a user