IDEA-172928 Improve notification that line breakpoints won't work in decompiled file (when there's no debug information)

This commit is contained in:
Egor.Ushakov
2017-05-17 15:46:11 +03:00
parent 469aedb132
commit 36265d4f24
4 changed files with 37 additions and 22 deletions
@@ -553,27 +553,30 @@ public class PositionManagerImpl implements PositionManager, MultiRequestPositio
int rangeBegin = Integer.MAX_VALUE;
int rangeEnd = Integer.MIN_VALUE;
for (Location location : DebuggerUtilsEx.allLineLocations(fromClass)) {
final int lnumber = DebuggerUtilsEx.getLineNumber(location, false);
if (lnumber <= 1) {
// should be a native method, skipping
// sometimes compiler generates location where line number is exactly 1 (e.g. GWT)
// such locations are hardly correspond to real lines in code, so skipping them too
continue;
List<Location> locations = DebuggerUtilsEx.allLineLocations(fromClass);
if (locations != null) {
for (Location location : locations) {
final int lnumber = DebuggerUtilsEx.getLineNumber(location, false);
if (lnumber <= 1) {
// should be a native method, skipping
// sometimes compiler generates location where line number is exactly 1 (e.g. GWT)
// such locations are hardly correspond to real lines in code, so skipping them too
continue;
}
final Method method = DebuggerUtilsEx.getMethod(location);
if (method == null || DebuggerUtils.isSynthetic(method) || method.isBridge()) {
// do not take into account synthetic stuff
continue;
}
int locationLine = lnumber - 1;
PsiFile psiFile = position.getFile().getOriginalFile();
if (psiFile instanceof PsiCompiledFile) {
locationLine = DebuggerUtilsEx.bytecodeToSourceLine(psiFile, locationLine);
if (locationLine < 0) continue;
}
rangeBegin = Math.min(rangeBegin, locationLine);
rangeEnd = Math.max(rangeEnd, locationLine);
}
final Method method = DebuggerUtilsEx.getMethod(location);
if (method == null || DebuggerUtils.isSynthetic(method) || method.isBridge()) {
// do not take into account synthetic stuff
continue;
}
int locationLine = lnumber - 1;
PsiFile psiFile = position.getFile().getOriginalFile();
if (psiFile instanceof PsiCompiledFile) {
locationLine = DebuggerUtilsEx.bytecodeToSourceLine(psiFile, locationLine);
if (locationLine < 0) continue;
}
rangeBegin = Math.min(rangeBegin, locationLine);
rangeEnd = Math.max(rangeEnd, locationLine);
}
final int positionLine = position.getLine();
@@ -600,12 +600,15 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils {
}
}
@NotNull
@Nullable
public static List<Location> allLineLocations(ReferenceType cls) {
try {
return cls.allLineLocations();
}
catch (AbsentInformationException | ObjectCollectedException ignored) {
catch (AbsentInformationException ignored) {
return null;
}
catch (ObjectCollectedException ignored) {
return Collections.emptyList();
}
}
@@ -138,6 +138,14 @@ public class LineBreakpoint<P extends JavaBreakpointProperties> extends Breakpoi
}
}
}
else if (DebuggerUtilsEx.allLineLocations(classType) == null) {
// there's no line info in this class
debugProcess.getRequestsManager()
.setInvalid(this, DebuggerBundle.message("error.invalid.breakpoint.no.line.info", classType.name()));
if (LOG.isDebugEnabled()) {
LOG.debug("No line number info in " + classType.name());
}
}
else {
// there's no executable code in this class
debugProcess.getRequestsManager().setInvalid(this, DebuggerBundle.message(
@@ -391,6 +391,7 @@ label.filed.breakpoint.properties.panel.field.modification=Field &modification
label.group.watch.events=Watch
error.failed.evaluating.breakpoint.condition=Failed to evaluate breakpoint condition\n''{0}''\nReason: {1}
error.invalid.breakpoint.no.executable.code=No executable code found at line {0} in class {1}
error.invalid.breakpoint.no.line.info=Line numbers info is not available in class {0}
error.invalid.breakpoint.bad.line.number=Line number is invalid
line.breakpoint.display.name=Line {0}
line.breakpoint.display.name.with.class.or.method=Line {0,number,#} in {1}