diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java index 4adedd69a776..dd28b21bfe18 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java @@ -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; diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java index b91893b09fbb..8b080134caf5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JvmSmartStepIntoHandler.java @@ -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 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. * diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/PsiMethodListPopupStep.java b/java/debugger/impl/src/com/intellij/debugger/actions/PsiMethodListPopupStep.java index c7c880a09c2a..3e0676a7f0fe 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/PsiMethodListPopupStep.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/PsiMethodListPopupStep.java @@ -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 { private final List myTargets; private final OnChooseRunnable myStepRunnable; - + private final ScopeHighlighter myScopeHighlighter; public interface OnChooseRunnable { void execute(JvmSmartStepIntoHandler.StepTarget stepTarget); } - public PsiMethodListPopupStep(final List targets, final OnChooseRunnable stepRunnable) { + public PsiMethodListPopupStep(Editor editor, final List targets, final OnChooseRunnable stepRunnable) { myTargets = targets; + myScopeHighlighter = new ScopeHighlighter(editor); myStepRunnable = stepRunnable; } + @NotNull + public ScopeHighlighter getScopeHighlighter() { + return myScopeHighlighter; + } + @NotNull public List getValues() { return myTargets; @@ -84,6 +92,7 @@ class PsiMethodListPopupStep implements ListPopupStep