IDEA-71794 smart step into: provide some visual indication in editor

This commit is contained in:
Eugene Zhuravlev
2013-10-24 15:24:29 +02:00
parent e5208be021
commit 3bb9fb60bd
3 changed files with 57 additions and 8 deletions
@@ -89,7 +89,7 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
@Override
public void visitAnonymousClass(PsiAnonymousClass aClass) {
for (PsiMethod psiMethod : aClass.getMethods()) {
targets.add(new MethodTarget(psiMethod, getCurrentParamName(), true));
targets.add(new MethodTarget(psiMethod, getCurrentParamName(), psiMethod.getBody(), true));
}
}
@@ -104,7 +104,9 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
public void visitCallExpression(final PsiCallExpression expression) {
final PsiMethod psiMethod = expression.resolveMethod();
if (psiMethod != null) {
targets.add(new MethodTarget(psiMethod, null, false));
final PsiElement highlightElement = expression instanceof PsiMethodCallExpression?
((PsiMethodCallExpression)expression).getMethodExpression().getReferenceNameElement() : null;
targets.add(new MethodTarget(psiMethod, null, highlightElement, false));
final PsiExpressionList argList = expression.getArgumentList();
if (argList != null) {
final String methodName = psiMethod.getName();
@@ -143,15 +145,22 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
private static class MethodTarget implements StepTarget {
private final PsiMethod myMethod;
private final PsiElement myHighlightElement;
private final String myLabel;
private final boolean myNeedBreakpointRequest;
private MethodTarget(@NotNull PsiMethod method, String currentParamName, boolean needBreakpointRequest) {
private MethodTarget(@NotNull PsiMethod method, String currentParamName, PsiElement highlightElement, boolean needBreakpointRequest) {
myMethod = method;
myHighlightElement = highlightElement;
myLabel = currentParamName == null? null : currentParamName + ".";
myNeedBreakpointRequest = needBreakpointRequest;
}
@Nullable
public PsiElement getHighlightElement() {
return myHighlightElement;
}
@Nullable
public String getMethodLabel() {
return myLabel;
@@ -18,16 +18,22 @@ package com.intellij.debugger.actions;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.engine.MethodFilter;
import com.intellij.debugger.impl.DebuggerSession;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.ui.popup.ListPopup;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.components.JBList;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.util.Arrays;
import java.util.List;
/**
@@ -49,6 +55,9 @@ public abstract class JvmSmartStepIntoHandler {
@Nullable
String getMethodLabel();
@Nullable
PsiElement getHighlightElement();
boolean needsBreakpointRequest();
boolean equals(Object another);
@@ -66,17 +75,31 @@ public abstract class JvmSmartStepIntoHandler {
public boolean doSmartStep(SourcePosition position, final DebuggerSession session, TextEditor fileEditor) {
final List<StepTarget> targets = findSmartStepTargets(position);
if (!targets.isEmpty()) {
final StepTarget firstTarget = targets.get(0);
if (targets.size() == 1) {
session.stepInto(true, createMethodFilter(targets.get(0)));
session.stepInto(true, createMethodFilter(firstTarget));
}
else {
final PsiMethodListPopupStep popupStep = new PsiMethodListPopupStep(targets, new PsiMethodListPopupStep.OnChooseRunnable() {
final Editor editor = fileEditor.getEditor();
final PsiMethodListPopupStep popupStep = new PsiMethodListPopupStep(editor, targets, new PsiMethodListPopupStep.OnChooseRunnable() {
public void execute(StepTarget chosenTarget) {
session.stepInto(true, createMethodFilter(chosenTarget));
}
});
final ListPopup popup = JBPopupFactory.getInstance().createListPopup(popupStep);
final RelativePoint point = DebuggerUIUtil.calcPopupLocation(fileEditor.getEditor(), position.getLine());
popup.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
popupStep.getScopeHighlighter().dropHighlight();
if (!e.getValueIsAdjusting()) {
final StepTarget selectedTarget = (StepTarget)((JBList)e.getSource()).getSelectedValue();
if (selectedTarget != null) {
highlightTarget(popupStep, selectedTarget);
}
}
}
});
highlightTarget(popupStep, firstTarget);
final RelativePoint point = DebuggerUIUtil.calcPopupLocation(editor, position.getLine());
popup.show(point);
}
return true;
@@ -84,6 +107,13 @@ public abstract class JvmSmartStepIntoHandler {
return false;
}
private static void highlightTarget(PsiMethodListPopupStep popupStep, StepTarget target) {
final PsiElement highlightElement = target.getHighlightElement();
if (highlightElement != null) {
popupStep.getScopeHighlighter().highlight(highlightElement, Arrays.asList(highlightElement));
}
}
/**
* Override in case if your JVMNames slightly different then it can be provided by getJvmSignature method.
*
@@ -15,7 +15,9 @@
*/
package com.intellij.debugger.actions;
import com.intellij.codeInsight.unwrap.ScopeHighlighter;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.popup.*;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiSubstitutor;
@@ -32,17 +34,23 @@ import java.util.List;
class PsiMethodListPopupStep implements ListPopupStep<JvmSmartStepIntoHandler.StepTarget> {
private final List<JvmSmartStepIntoHandler.StepTarget> myTargets;
private final OnChooseRunnable myStepRunnable;
private final ScopeHighlighter myScopeHighlighter;
public interface OnChooseRunnable {
void execute(JvmSmartStepIntoHandler.StepTarget stepTarget);
}
public PsiMethodListPopupStep(final List<JvmSmartStepIntoHandler.StepTarget> targets, final OnChooseRunnable stepRunnable) {
public PsiMethodListPopupStep(Editor editor, final List<JvmSmartStepIntoHandler.StepTarget> targets, final OnChooseRunnable stepRunnable) {
myTargets = targets;
myScopeHighlighter = new ScopeHighlighter(editor);
myStepRunnable = stepRunnable;
}
@NotNull
public ScopeHighlighter getScopeHighlighter() {
return myScopeHighlighter;
}
@NotNull
public List<JvmSmartStepIntoHandler.StepTarget> getValues() {
return myTargets;
@@ -84,6 +92,7 @@ class PsiMethodListPopupStep implements ListPopupStep<JvmSmartStepIntoHandler.St
public PopupStep onChosen(JvmSmartStepIntoHandler.StepTarget selectedValue, final boolean finalChoice) {
if (finalChoice) {
myScopeHighlighter.dropHighlight();
myStepRunnable.execute(selectedValue);
}
return FINAL_CHOICE;
@@ -98,6 +107,7 @@ class PsiMethodListPopupStep implements ListPopupStep<JvmSmartStepIntoHandler.St
}
public void canceled() {
myScopeHighlighter.dropHighlight();
}
public boolean isMnemonicsNavigationEnabled() {