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.add(condition);
conditionValue = generateBlock(statements, false, continueLabel);
conditionValue = generateBlock(statements, false, continueLabel, null);
}
else {
if (body != null) {
@@ -1505,11 +1505,20 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
}
/* 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) {
final Label blockEnd = new Label();
private StackValue generateBlock(
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();
@@ -1563,7 +1572,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return new StackValueWithLeaveTask(answer, new ExtensionFunction0<StackValueWithLeaveTask, Unit>() {
@Override
public Unit invoke(StackValueWithLeaveTask wrapper) {
v.mark(blockEnd);
if (labelBlockEnd == null) {
v.mark(blockEnd);
}
for (Function<StackValue, Void> task : Lists.reverse(leaveTasks)) {
task.fun(wrapper.getStackValue());
}
@@ -320,8 +320,10 @@ public class FunctionCodegen extends ParentCodegenAware {
JetTypeMapper typeMapper = parentCodegen.typeMapper;
Label methodEnd;
if (context.getParentContext() instanceof PackageFacadeContext) {
generatePackageDelegateMethodBody(mv, signature.getAsmMethod(), (PackageFacadeContext) context.getParentContext());
methodEnd = new Label();
}
else {
FrameMap frameMap = createFrameMap(parentCodegen.state, functionDescriptor, signature, isStaticMethod(context.getContextKind(),
@@ -334,11 +336,11 @@ public class FunctionCodegen extends ParentCodegenAware {
if (!JetTypeMapper.isAccessor(functionDescriptor)) {
genNotNullAssertionsForParameters(new InstructionAdapter(mv), parentCodegen.state, functionDescriptor, frameMap);
}
methodEnd = new Label();
context.setMethodEndLabel(methodEnd);
strategy.generateBody(mv, frameMap, signature, context, parentCodegen);
}
Label methodEnd = new Label();
mv.visitLabel(methodEnd);
Type thisType = getThisTypeForFunction(functionDescriptor, context, typeMapper);
@@ -32,6 +32,7 @@ import org.jetbrains.org.objectweb.asm.Type;
public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
private final boolean isInliningLambda;
private Label methodStartLabel;
private Label methodEndLabel;
protected MethodContext(
@NotNull FunctionDescriptor contextDescriptor,
@@ -96,6 +97,15 @@ public class MethodContext extends CodegenContext<CallableMemberDescriptor> {
this.methodStartLabel = methodStartLabel;
}
@Nullable
public Label getMethodEndLabel() {
return methodEndLabel;
}
public void setMethodEndLabel(@NotNull Label methodEndLabel) {
this.methodEndLabel = methodEndLabel;
}
@Override
public String toString() {
return "Method: " + getContextDescriptor();