emulated method bpts: set breakpoints in bridge target methods

This commit is contained in:
Egor.Ushakov
2016-11-03 14:17:29 +03:00
parent bc71233ed1
commit 8907ec4031
2 changed files with 27 additions and 4 deletions
@@ -22,6 +22,7 @@ import com.intellij.util.ReflectionUtil;
import com.intellij.util.ThrowableConsumer;
import com.intellij.util.containers.ContainerUtil;
import com.sun.jdi.*;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.*;
@@ -241,10 +242,7 @@ public class MethodBytecodeUtil {
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
ReferenceType cls = ContainerUtil.getFirstItem(clsType.virtualMachine().classesByName(owner));
if (cls != null) {
Method method = ContainerUtil.getFirstItem(cls.methodsByName(name));
if (method != null) {
methodRef.set(method);
}
cls.methodsByName(name).stream().findFirst().ifPresent(methodRef::set);
}
}
});
@@ -252,4 +250,21 @@ public class MethodBytecodeUtil {
}
return methodRef.get();
}
@Nullable
public static Method getBridgeTargetMethod(Method method) {
Ref<Method> methodRef = Ref.create();
if (method.isBridge()) {
visit(method, new MethodVisitor(Opcodes.API_VERSION) {
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
ReferenceType cls = ContainerUtil.getFirstItem(method.virtualMachine().classesByName(owner));
if (cls != null) {
StreamEx.of(cls.methodsByName(name)).without(method).findFirst().ifPresent(methodRef::set);
}
}
});
}
return methodRef.get();
}
}
@@ -156,6 +156,9 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp
Method method = MethodBytecodeUtil.getLambdaMethod(classType);
if (method == null) {
for (Method m : classType.methods()) {
if (!base && m.isAbstract()) {
continue;
}
if (getMethodName().equals(m.name()) && mySignature.getName(debugProcess).equals(m.signature())) {
method = m;
break;
@@ -163,6 +166,11 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp
}
}
if (method != null) {
Method target = MethodBytecodeUtil.getBridgeTargetMethod(method);
if (target != null && !DebuggerUtilsEx.allLineLocations(target).isEmpty()) {
method = target;
}
List<Location> allLineLocations = DebuggerUtilsEx.allLineLocations(method);
if (!allLineLocations.isEmpty()) {
if (isWatchEntry()) {