package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.DebuggerBundle;
-import com.intellij.debugger.engine.LambdaMethodFilter;
+import com.intellij.debugger.engine.DebugProcess;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
+import com.intellij.debugger.engine.jdi.StackFrameProxy;
+import com.intellij.debugger.impl.PositionUtil;
+import com.intellij.debugger.impl.SimpleStackFrameContext;
import com.intellij.debugger.jdi.LocalVariableProxyImpl;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.ui.impl.watch.LocalVariableDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiVariable;
import com.sun.jdi.*;
+import org.jetbrains.annotations.Nullable;
import java.util.List;
private final String myLocalVariableName;
private EvaluationContextImpl myContext;
private LocalVariableProxyImpl myEvaluatedVariable;
- private final boolean myIsJspSpecial;
+ private final boolean myCanScanFrames;
private int myParameterIndex = -1;
- public LocalVariableEvaluator(String localVariableName, boolean isJspSpecial) {
+ public LocalVariableEvaluator(String localVariableName, boolean canScanFrames) {
myLocalVariableName = localVariableName;
- myIsJspSpecial = isJspSpecial;
+ myCanScanFrames = canScanFrames;
}
public void setParameterIndex(int parameterIndex) {
try {
ThreadReferenceProxyImpl threadProxy = null;
int lastFrameIndex = -1;
+ PsiVariable variable = null;
- boolean anotherFrame = false;
+ boolean topFrame = true;
while (true) {
try {
LocalVariableProxyImpl local = frameProxy.visibleVariableByName(myLocalVariableName);
if (local != null) {
- myEvaluatedVariable = local;
- myContext = context;
- return frameProxy.getValue(local);
+ if (topFrame ||
+ variable.equals(resolveVariable(frameProxy, myLocalVariableName, context.getProject(), context.getDebugProcess()))) {
+ myEvaluatedVariable = local;
+ myContext = context;
+ return frameProxy.getValue(local);
+ }
}
}
catch (EvaluateException e) {
if (!(e.getCause() instanceof AbsentInformationException)) {
throw e;
}
- if (!anotherFrame) {
+ if (topFrame) {
if (myParameterIndex < 0) {
throw e;
}
}
}
- if (anotherFrame || needToSwitchFrames(frameProxy)) {
+ if (myCanScanFrames) {
+ if (topFrame) {
+ variable = resolveVariable(frameProxy, myLocalVariableName, context.getProject(), context.getDebugProcess());
+ if (variable == null) break;
+ }
if (threadProxy == null /* initialize it lazily */) {
threadProxy = frameProxy.threadProxy();
lastFrameIndex = threadProxy.frameCount() - 1;
if (currentFrameIndex < lastFrameIndex) {
frameProxy = threadProxy.frame(currentFrameIndex + 1);
if (frameProxy != null) {
- anotherFrame = true;
+ topFrame = false;
continue;
}
}
}
}
- private boolean needToSwitchFrames(StackFrameProxyImpl frameProxy) {
- if (myIsJspSpecial) return true;
- try {
- Location location = frameProxy.location();
- if (location == null) return false;
- return LambdaMethodFilter.isLambdaName(location.method().name());
- }
- catch (EvaluateException ignored) {}
- return false;
- }
-
@Override
public Modifier getModifier() {
Modifier modifier = null;
return modifier;
}
+ @Nullable
+ private static PsiVariable resolveVariable(final StackFrameProxy frame,
+ final String name,
+ final Project project,
+ final DebugProcess process) {
+ return ApplicationManager.getApplication().runReadAction(new Computable<PsiVariable>() {
+ @Override
+ public PsiVariable compute() {
+ PsiElement place = PositionUtil.getContextElement(new SimpleStackFrameContext(frame, process));
+ if (place == null) return null;
+ return JavaPsiFacade.getInstance(project).getResolveHelper().resolveReferencedVariable(name, place);
+ }
+ });
+ }
+
@Override
public String toString() {
return myLocalVariableName;