diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/EnumSwitchCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/EnumSwitchCodegen.java index ebde0309f5c..52f247375a7 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/EnumSwitchCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/EnumSwitchCodegen.java @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.when; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.codegen.ExpressionCodegen; +import org.jetbrains.kotlin.psi.KtWhenEntry; import org.jetbrains.kotlin.psi.KtWhenExpression; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.EnumValue; @@ -58,7 +59,7 @@ public class EnumSwitchCodegen extends SwitchCodegen { } @Override - protected void processConstant(@NotNull ConstantValue constant, @NotNull Label entryLabel) { + protected void processConstant(@NotNull ConstantValue constant, @NotNull Label entryLabel, @NotNull KtWhenEntry entry) { assert constant instanceof EnumValue : "guaranteed by usage contract"; putTransitionOnce(mapping.getIndexByEntry((EnumValue) constant), entryLabel); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/IntegralConstantsSwitchCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/IntegralConstantsSwitchCodegen.java index 3ffea59b382..7e997293e90 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/IntegralConstantsSwitchCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/IntegralConstantsSwitchCodegen.java @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.when; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.codegen.ExpressionCodegen; +import org.jetbrains.kotlin.psi.KtWhenEntry; import org.jetbrains.kotlin.psi.KtWhenExpression; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.org.objectweb.asm.Label; @@ -33,7 +34,7 @@ public class IntegralConstantsSwitchCodegen extends SwitchCodegen { } @Override - protected void processConstant(@NotNull ConstantValue constant, @NotNull Label entryLabel) { + protected void processConstant(@NotNull ConstantValue constant, @NotNull Label entryLabel, @NotNull KtWhenEntry entry) { assert constant.getValue() != null : "constant value should not be null"; int value = (constant.getValue() instanceof Number) ? ((Number) constant.getValue()).intValue() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/StringSwitchCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/StringSwitchCodegen.java index 2dcabc6beaf..e17429ab80a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/StringSwitchCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/StringSwitchCodegen.java @@ -16,9 +16,9 @@ package org.jetbrains.kotlin.codegen.when; -import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.codegen.ExpressionCodegen; +import org.jetbrains.kotlin.psi.KtWhenEntry; import org.jetbrains.kotlin.psi.KtWhenExpression; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.StringValue; @@ -34,7 +34,7 @@ public class StringSwitchCodegen extends SwitchCodegen { private static final String HASH_CODE_METHOD_DESC = Type.getMethodDescriptor(Type.INT_TYPE); private static final String EQUALS_METHOD_DESC = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, Type.getType(Object.class)); - private final Map>> hashCodesToStringAndEntryLabel = new HashMap<>(); + private final Map> hashCodesToEntries = new HashMap<>(); private int tempVarIndex; public StringSwitchCodegen( @@ -47,18 +47,16 @@ public class StringSwitchCodegen extends SwitchCodegen { } @Override - protected void processConstant( - @NotNull ConstantValue constant, @NotNull Label entryLabel - ) { + protected void processConstant(@NotNull ConstantValue constant, @NotNull Label entryLabel, @NotNull KtWhenEntry entry) { assert constant instanceof StringValue : "guaranteed by usage contract"; int hashCode = constant.hashCode(); if (!transitionsTable.containsKey(hashCode)) { transitionsTable.put(hashCode, new Label()); - hashCodesToStringAndEntryLabel.put(hashCode, new ArrayList<>()); + hashCodesToEntries.put(hashCode, new ArrayList<>()); } - hashCodesToStringAndEntryLabel.get(hashCode).add(new Pair<>(((StringValue) constant).getValue(), entryLabel)); + hashCodesToEntries.get(hashCode).add(new Entry(((StringValue) constant).getValue(), entryLabel, entry)); } @Override @@ -83,10 +81,10 @@ public class StringSwitchCodegen extends SwitchCodegen { @Override protected void generateEntries() { - for (int hashCode : hashCodesToStringAndEntryLabel.keySet()) { + for (int hashCode : hashCodesToEntries.keySet()) { v.visitLabel(transitionsTable.get(hashCode)); - List> items = hashCodesToStringAndEntryLabel.get(hashCode); + List items = hashCodesToEntries.get(hashCode); Label nextLabel = null; for (int i = 0; i < items.size(); i++) { @@ -94,10 +92,11 @@ public class StringSwitchCodegen extends SwitchCodegen { v.visitLabel(nextLabel); } - Pair stringAndEntryLabel = items.get(i); + Entry entry = items.get(i); + codegen.markLineNumber(entry.entry, false); v.load(tempVarIndex, subjectType); - v.aconst(stringAndEntryLabel.first); + v.aconst(entry.value); v.invokevirtual( subjectType.getInternalName(), "equals", @@ -113,10 +112,22 @@ public class StringSwitchCodegen extends SwitchCodegen { } v.ifeq(nextLabel); - v.goTo(stringAndEntryLabel.getSecond()); + v.goTo(entry.label); } } super.generateEntries(); } + + private static class Entry { + private final String value; + private final Label label; + private final KtWhenEntry entry; + + private Entry(String value, Label label, KtWhenEntry entry) { + this.value = value; + this.label = label; + this.entry = entry; + } + } } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/SwitchCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/SwitchCodegen.kt index 3c59ee77e81..b9b492be80a 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/when/SwitchCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/when/SwitchCodegen.kt @@ -5,11 +5,11 @@ package org.jetbrains.kotlin.codegen.`when` -import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.cfg.WhenChecker import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.descriptors.VariableDescriptor +import org.jetbrains.kotlin.psi.KtWhenEntry import org.jetbrains.kotlin.psi.KtWhenExpression import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.constants.ConstantValue @@ -109,7 +109,7 @@ abstract class SwitchCodegen( for (constant in switchCodegenProvider.getConstantsFromEntry(entry)) { if (constant is NullValue || constant == null) continue - processConstant(constant, entryLabel) + processConstant(constant, entryLabel, entry) } if (entry.isElse) { @@ -120,10 +120,7 @@ abstract class SwitchCodegen( } } - protected abstract fun processConstant( - constant: ConstantValue<*>, - entryLabel: Label - ) + protected abstract fun processConstant(constant: ConstantValue<*>, entryLabel: Label, entry: KtWhenEntry) protected fun putTransitionOnce(value: Int, entryLabel: Label) { if (!transitionsTable.containsKey(value)) {