ensure smart step into methods, whose first statement's line has no executable instructions mapped

This commit is contained in:
Eugene Zhuravlev
2013-11-03 22:13:27 +01:00
parent ad779bf2f9
commit cd139bd5fd
4 changed files with 31 additions and 23 deletions
@@ -28,10 +28,25 @@ import org.jetbrains.annotations.Nullable;
public class AnonymousClassMethodFilter extends BasicStepMethodFilter implements BreakpointStepMethodFilter{
@Nullable
private final SourcePosition myBreakpointPosition;
private final int myLastStatementLine;
public AnonymousClassMethodFilter(PsiMethod psiMethod) {
super(psiMethod);
myBreakpointPosition = calcBreakpointPosition(psiMethod.getBody());
SourcePosition firstStatementPosition = null;
SourcePosition lastStatementPosition = null;
final PsiCodeBlock body = psiMethod.getBody();
if (body != null) {
final PsiStatement[] statements = body.getStatements();
if (statements.length > 0) {
firstStatementPosition = SourcePosition.createFromElement(statements[0]);
if (firstStatementPosition != null) {
final PsiStatement lastStatement = statements[statements.length - 1];
lastStatementPosition = SourcePosition.createFromOffset(firstStatementPosition.getFile(), lastStatement.getTextRange().getEndOffset());
}
}
}
myBreakpointPosition = firstStatementPosition;
myLastStatementLine = lastStatementPosition != null? lastStatementPosition.getLine() : -1;
}
@Nullable
@@ -39,16 +54,7 @@ public class AnonymousClassMethodFilter extends BasicStepMethodFilter implements
return myBreakpointPosition;
}
private static SourcePosition calcBreakpointPosition(final PsiCodeBlock body) {
if (body == null) {
return null;
}
final PsiStatement[] statements = body.getStatements();
if (statements.length == 0) {
return null;
}
final PsiStatement firstStatement = statements[0];
return SourcePosition.createFromElement(firstStatement);
public int getLastStatementLine() {
return myLastStatementLine;
}
}
@@ -25,4 +25,9 @@ import org.jetbrains.annotations.Nullable;
public interface BreakpointStepMethodFilter extends MethodFilter{
@Nullable
SourcePosition getBreakpointPosition();
/**
* @return a zero-based line number of the last lambda statement, or -1 if not available
*/
int getLastStatementLine();
}
@@ -45,11 +45,11 @@ public class LambdaMethodFilter implements BreakpointStepMethodFilter{
final PsiElement body = lambda.getBody();
if (body instanceof PsiCodeBlock) {
final PsiStatement[] statements = ((PsiCodeBlock)body).getStatements();
final int statementCount = statements.length;
if (statementCount > 0) {
if (statements.length > 0) {
firstStatementPosition = SourcePosition.createFromElement(statements[0]);
if (statementCount > 1) {
lastStatementPosition = SourcePosition.createFromElement(statements[statementCount - 1]);
if (firstStatementPosition != null) {
final PsiStatement lastStatement = statements[statements.length - 1];
lastStatementPosition = SourcePosition.createFromOffset(firstStatementPosition.getFile(), lastStatement.getTextRange().getEndOffset());
}
}
}
@@ -69,9 +69,6 @@ public class LambdaMethodFilter implements BreakpointStepMethodFilter{
return myFirstStatementPosition;
}
/**
* @return a zero-based line number of the last lambda statement, or -1 if not available
*/
public int getLastStatementLine() {
return myLastStatementLine;
}
@@ -55,10 +55,10 @@ public class StepIntoBreakpoint extends RunToCursorBreakpoint {
final SourcePosition startPosition = getSourcePosition();
List<Location> locations = positionManager.locationsOfLine(classType, startPosition);
if (locations.isEmpty() && myFilter instanceof LambdaMethodFilter) {
// sometimes first statements are mapped to some weird line number,
// so if lambda spans for more than one lines, try get some locations from these lines
final int lastLine = ((LambdaMethodFilter)myFilter).getLastStatementLine();
if (locations.isEmpty()) {
// sometimes first statements are mapped to some weird line number, or there are no executable instructions at first statement's line
// so if lambda or method body spans for more than one lines, try get some locations from these lines
final int lastLine = myFilter.getLastStatementLine();
if (lastLine >= 0) {
int nextLine = startPosition.getLine() + 1;
while (nextLine <= lastLine && locations.isEmpty()) {