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:
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.when;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.kotlin.psi.KtWhenEntry;
|
||||||
import org.jetbrains.kotlin.psi.KtWhenExpression;
|
import org.jetbrains.kotlin.psi.KtWhenExpression;
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||||
import org.jetbrains.kotlin.resolve.constants.EnumValue;
|
import org.jetbrains.kotlin.resolve.constants.EnumValue;
|
||||||
@@ -58,7 +59,7 @@ public class EnumSwitchCodegen extends SwitchCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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";
|
assert constant instanceof EnumValue : "guaranteed by usage contract";
|
||||||
putTransitionOnce(mapping.getIndexByEntry((EnumValue) constant), entryLabel);
|
putTransitionOnce(mapping.getIndexByEntry((EnumValue) constant), entryLabel);
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.codegen.when;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.kotlin.psi.KtWhenEntry;
|
||||||
import org.jetbrains.kotlin.psi.KtWhenExpression;
|
import org.jetbrains.kotlin.psi.KtWhenExpression;
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||||
import org.jetbrains.org.objectweb.asm.Label;
|
import org.jetbrains.org.objectweb.asm.Label;
|
||||||
@@ -33,7 +34,7 @@ public class IntegralConstantsSwitchCodegen extends SwitchCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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";
|
assert constant.getValue() != null : "constant value should not be null";
|
||||||
int value = (constant.getValue() instanceof Number)
|
int value = (constant.getValue() instanceof Number)
|
||||||
? ((Number) constant.getValue()).intValue()
|
? ((Number) constant.getValue()).intValue()
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.when;
|
package org.jetbrains.kotlin.codegen.when;
|
||||||
|
|
||||||
import com.intellij.openapi.util.Pair;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.kotlin.psi.KtWhenEntry;
|
||||||
import org.jetbrains.kotlin.psi.KtWhenExpression;
|
import org.jetbrains.kotlin.psi.KtWhenExpression;
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||||
import org.jetbrains.kotlin.resolve.constants.StringValue;
|
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 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 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;
|
private int tempVarIndex;
|
||||||
|
|
||||||
public StringSwitchCodegen(
|
public StringSwitchCodegen(
|
||||||
@@ -47,18 +47,16 @@ public class StringSwitchCodegen extends SwitchCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void processConstant(
|
protected void processConstant(@NotNull ConstantValue<?> constant, @NotNull Label entryLabel, @NotNull KtWhenEntry entry) {
|
||||||
@NotNull ConstantValue<?> constant, @NotNull Label entryLabel
|
|
||||||
) {
|
|
||||||
assert constant instanceof StringValue : "guaranteed by usage contract";
|
assert constant instanceof StringValue : "guaranteed by usage contract";
|
||||||
int hashCode = constant.hashCode();
|
int hashCode = constant.hashCode();
|
||||||
|
|
||||||
if (!transitionsTable.containsKey(hashCode)) {
|
if (!transitionsTable.containsKey(hashCode)) {
|
||||||
transitionsTable.put(hashCode, new Label());
|
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
|
@Override
|
||||||
@@ -83,10 +81,10 @@ public class StringSwitchCodegen extends SwitchCodegen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateEntries() {
|
protected void generateEntries() {
|
||||||
for (int hashCode : hashCodesToStringAndEntryLabel.keySet()) {
|
for (int hashCode : hashCodesToEntries.keySet()) {
|
||||||
v.visitLabel(transitionsTable.get(hashCode));
|
v.visitLabel(transitionsTable.get(hashCode));
|
||||||
|
|
||||||
List<Pair<String, Label>> items = hashCodesToStringAndEntryLabel.get(hashCode);
|
List<Entry> items = hashCodesToEntries.get(hashCode);
|
||||||
Label nextLabel = null;
|
Label nextLabel = null;
|
||||||
|
|
||||||
for (int i = 0; i < items.size(); i++) {
|
for (int i = 0; i < items.size(); i++) {
|
||||||
@@ -94,10 +92,11 @@ public class StringSwitchCodegen extends SwitchCodegen {
|
|||||||
v.visitLabel(nextLabel);
|
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.load(tempVarIndex, subjectType);
|
||||||
v.aconst(stringAndEntryLabel.first);
|
v.aconst(entry.value);
|
||||||
v.invokevirtual(
|
v.invokevirtual(
|
||||||
subjectType.getInternalName(),
|
subjectType.getInternalName(),
|
||||||
"equals",
|
"equals",
|
||||||
@@ -113,10 +112,22 @@ public class StringSwitchCodegen extends SwitchCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
v.ifeq(nextLabel);
|
v.ifeq(nextLabel);
|
||||||
v.goTo(stringAndEntryLabel.getSecond());
|
v.goTo(entry.label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.generateEntries();
|
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`
|
package org.jetbrains.kotlin.codegen.`when`
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|
||||||
import org.jetbrains.kotlin.cfg.WhenChecker
|
import org.jetbrains.kotlin.cfg.WhenChecker
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
import org.jetbrains.kotlin.codegen.StackValue
|
||||||
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||||
|
import org.jetbrains.kotlin.psi.KtWhenEntry
|
||||||
import org.jetbrains.kotlin.psi.KtWhenExpression
|
import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
@@ -109,7 +109,7 @@ abstract class SwitchCodegen(
|
|||||||
|
|
||||||
for (constant in switchCodegenProvider.getConstantsFromEntry(entry)) {
|
for (constant in switchCodegenProvider.getConstantsFromEntry(entry)) {
|
||||||
if (constant is NullValue || constant == null) continue
|
if (constant is NullValue || constant == null) continue
|
||||||
processConstant(constant, entryLabel)
|
processConstant(constant, entryLabel, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entry.isElse) {
|
if (entry.isElse) {
|
||||||
@@ -120,10 +120,7 @@ abstract class SwitchCodegen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun processConstant(
|
protected abstract fun processConstant(constant: ConstantValue<*>, entryLabel: Label, entry: KtWhenEntry)
|
||||||
constant: ConstantValue<*>,
|
|
||||||
entryLabel: Label
|
|
||||||
)
|
|
||||||
|
|
||||||
protected fun putTransitionOnce(value: Int, entryLabel: Label) {
|
protected fun putTransitionOnce(value: Int, entryLabel: Label) {
|
||||||
if (!transitionsTable.containsKey(value)) {
|
if (!transitionsTable.containsKey(value)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user