Search in sources :

Example 1 with SwitchCodegen

use of org.jetbrains.kotlin.codegen.when.SwitchCodegen in project kotlin by JetBrains.

the class ExpressionCodegen method generateWhenExpression.

public StackValue generateWhenExpression(final KtWhenExpression expression, final boolean isStatement) {
    final KtExpression expr = expression.getSubjectExpression();
    final Type subjectType = expressionType(expr);
    final Type resultType = isStatement ? Type.VOID_TYPE : expressionTypeForBranchingOperation(expression);
    return StackValue.operation(resultType, new Function1<InstructionAdapter, Unit>() {

        @Override
        public Unit invoke(InstructionAdapter v) {
            SwitchCodegen switchCodegen = SwitchCodegenUtil.buildAppropriateSwitchCodegenIfPossible(expression, isStatement, CodegenUtil.isExhaustive(bindingContext, expression, isStatement), ExpressionCodegen.this);
            if (switchCodegen != null) {
                switchCodegen.generate();
                return Unit.INSTANCE;
            }
            int subjectLocal = expr != null ? myFrameMap.enterTemp(subjectType) : -1;
            if (subjectLocal != -1) {
                gen(expr, subjectType);
                tempVariables.put(expr, StackValue.local(subjectLocal, subjectType));
                v.store(subjectLocal, subjectType);
            }
            Label end = new Label();
            boolean hasElse = KtPsiUtil.checkWhenExpressionHasSingleElse(expression);
            Label nextCondition = null;
            for (KtWhenEntry whenEntry : expression.getEntries()) {
                if (nextCondition != null) {
                    v.mark(nextCondition);
                }
                nextCondition = new Label();
                FrameMap.Mark mark = myFrameMap.mark();
                Label thisEntry = new Label();
                if (!whenEntry.isElse()) {
                    KtWhenCondition[] conditions = whenEntry.getConditions();
                    for (int i = 0; i < conditions.length; i++) {
                        StackValue conditionValue = generateWhenCondition(expr, subjectType, subjectLocal, conditions[i]);
                        BranchedValue.Companion.condJump(conditionValue, nextCondition, true, v);
                        if (i < conditions.length - 1) {
                            v.goTo(thisEntry);
                            v.mark(nextCondition);
                            nextCondition = new Label();
                        }
                    }
                }
                v.visitLabel(thisEntry);
                gen(whenEntry.getExpression(), resultType);
                mark.dropTo();
                if (!whenEntry.isElse()) {
                    v.goTo(end);
                }
            }
            if (!hasElse && nextCondition != null) {
                v.mark(nextCondition);
                putUnitInstanceOntoStackForNonExhaustiveWhen(expression, isStatement);
            }
            markLineNumber(expression, isStatement);
            v.mark(end);
            myFrameMap.leaveTemp(subjectType);
            tempVariables.remove(expr);
            return null;
        }
    });
}
Also used : IElementType(com.intellij.psi.tree.IElementType) Type(org.jetbrains.org.objectweb.asm.Type) KotlinType(org.jetbrains.kotlin.types.KotlinType) InstructionAdapter(org.jetbrains.org.objectweb.asm.commons.InstructionAdapter) Label(org.jetbrains.org.objectweb.asm.Label) Unit(kotlin.Unit) SwitchCodegen(org.jetbrains.kotlin.codegen.when.SwitchCodegen)

Aggregations

IElementType (com.intellij.psi.tree.IElementType)1 Unit (kotlin.Unit)1 SwitchCodegen (org.jetbrains.kotlin.codegen.when.SwitchCodegen)1 KotlinType (org.jetbrains.kotlin.types.KotlinType)1 Label (org.jetbrains.org.objectweb.asm.Label)1 Type (org.jetbrains.org.objectweb.asm.Type)1 InstructionAdapter (org.jetbrains.org.objectweb.asm.commons.InstructionAdapter)1