Local variables should be visible on return statement in debugger

#KT-6248 Fixed
This commit is contained in:
Natalia Ukhorskaya
2014-12-17 15:56:14 +03:00
parent 311a3a75c8
commit 0dcb5b05b6
3 changed files with 30 additions and 7 deletions
@@ -496,7 +496,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
statements.addAll(doWhileStatements); statements.addAll(doWhileStatements);
statements.add(condition); statements.add(condition);
conditionValue = generateBlock(statements, false, continueLabel); conditionValue = generateBlock(statements, false, continueLabel, null);
} }
else { else {
if (body != null) { if (body != null) {
@@ -1505,11 +1505,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
/* package */ StackValue generateBlock(@NotNull JetBlockExpression expression, boolean isStatement) { /* package */ StackValue generateBlock(@NotNull JetBlockExpression expression, boolean isStatement) {
return generateBlock(expression.getStatements(), isStatement, null); if (expression.getParent() instanceof JetNamedFunction) {
// For functions end of block should be end of function label
return generateBlock(expression.getStatements(), isStatement, null, context.getMethodEndLabel());
}
return generateBlock(expression.getStatements(), isStatement, null, null);
} }
private StackValue generateBlock(List<JetElement> statements, boolean isStatement, Label labelBeforeLastExpression) { private StackValue generateBlock(
final Label blockEnd = new Label(); List<JetElement> statements,
boolean isStatement,
Label labelBeforeLastExpression,
@Nullable final Label labelBlockEnd
) {
final Label blockEnd = labelBlockEnd != null ? labelBlockEnd : new Label();
final List<Function<StackValue, Void>> leaveTasks = Lists.newArrayList(); final List<Function<StackValue, Void>> leaveTasks = Lists.newArrayList();
@@ -1563,7 +1572,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return new StackValueWithLeaveTask(answer, new ExtensionFunction0<StackValueWithLeaveTask, Unit>() { return new StackValueWithLeaveTask(answer, new ExtensionFunction0<StackValueWithLeaveTask, Unit>() {
@Override @Override
public Unit invoke(StackValueWithLeaveTask wrapper) { public Unit invoke(StackValueWithLeaveTask wrapper) {
v.mark(blockEnd); if (labelBlockEnd == null) {
v.mark(blockEnd);
}
for (Function<StackValue, Void> task : Lists.reverse(leaveTasks)) { for (Function<StackValue, Void> task : Lists.reverse(leaveTasks)) {
task.fun(wrapper.getStackValue()); task.fun(wrapper.getStackValue());
} }
@@ -320,8 +320,10 @@ public class FunctionCodegen extends ParentCodegenAware {
JetTypeMapper typeMapper = parentCodegen.typeMapper; JetTypeMapper typeMapper = parentCodegen.typeMapper;
Label methodEnd;
if (context.getParentContext() instanceof PackageFacadeContext) { if (context.getParentContext() instanceof PackageFacadeContext) {
generatePackageDelegateMethodBody(mv, signature.getAsmMethod(), (PackageFacadeContext) context.getParentContext()); generatePackageDelegateMethodBody(mv, signature.getAsmMethod(), (PackageFacadeContext) context.getParentContext());
methodEnd = new Label();
} }
else { else {
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(), FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(),
@@ -334,11 +336,11 @@ public class FunctionCodegen extends ParentCodegenAware {
if (!JetTypeMapper.isAccessor(functionDescriptor)) { if (!JetTypeMapper.isAccessor(functionDescriptor)) {
genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap); genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
} }
methodEnd = new Label();
context.setMethodEndLabel(methodEnd);
strategy.generateBody(mv, frameMap, signature, context, parentCodegen); strategy.generateBody(mv, frameMap, signature, context, parentCodegen);
} }
Label methodEnd = new Label();
mv.visitLabel(methodEnd); mv.visitLabel(methodEnd);
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper); Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
@@ -32,6 +32,7 @@ import org.jetbrains.org.objectweb.asm.Type;
public class MethodContext extends CodegenContext<CallableMemberDescriptor> { public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
private final boolean isInliningLambda; private final boolean isInliningLambda;
private Label methodStartLabel; private Label methodStartLabel;
private Label methodEndLabel;
protected MethodContext( protected MethodContext(
@NotNull FunctionDescriptor contextDescriptor, @NotNull FunctionDescriptor contextDescriptor,
@@ -96,6 +97,15 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
this.methodStartLabel = methodStartLabel; this.methodStartLabel = methodStartLabel;
} }
@Nullable
public Label getMethodEndLabel() {
return methodEndLabel;
}
public void setMethodEndLabel(@NotNull Label methodEndLabel) {
this.methodEndLabel = methodEndLabel;
}
@Override @Override
public String toString() { public String toString() {
return "Method: " + getContextDescriptor(); return "Method: " + getContextDescriptor();