Debugger: Fix line numbers on String literal 'when' condition checks

Before this commit, line numbers were only available on 'when' clause bodies.
So, if a clause condition check didn't succeed, the entirely clause could be ignored.
This commit is contained in:
Yan Zhulanow
2019-07-05 18:23:03 +09:00
parent 3d3bde5483
commit 910133dbfb
4 changed files with 30 additions and 20 deletions
@@ -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);
}
@@ -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()
@@ -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<Integer, List<Pair<String, Label>>> hashCodesToStringAndEntryLabel = new HashMap<>();
private final Map<Integer, List<Entry>> 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<Pair<String, Label>> items = hashCodesToStringAndEntryLabel.get(hashCode);
List<Entry> 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<String, Label> 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;
}
}
}
@@ -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)) {