mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-126257 JDK 1.8: Debugger doesn't show variables *outside* lambda - better check for found variable
This commit is contained in:
+3
-1
@@ -628,7 +628,9 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
final String localName = psiVar.getName();
|
||||
PsiClass variableClass = getContainingClass(psiVar);
|
||||
if (getContextPsiClass() == null || getContextPsiClass().equals(variableClass)) {
|
||||
final LocalVariableEvaluator localVarEvaluator = new LocalVariableEvaluator(localName, ContextUtil.isJspImplicit(element));
|
||||
PsiElement method = PsiTreeUtil.getContextOfType(expression, PsiMethod.class, PsiLambdaExpression.class);
|
||||
boolean canScanFrames = method instanceof PsiLambdaExpression || ContextUtil.isJspImplicit(element);
|
||||
LocalVariableEvaluator localVarEvaluator = new LocalVariableEvaluator(localName, canScanFrames);
|
||||
if (psiVar instanceof PsiParameter) {
|
||||
final PsiParameter param = (PsiParameter)psiVar;
|
||||
final PsiParameterList paramList = PsiTreeUtil.getParentOfType(param, PsiParameterList.class, true);
|
||||
|
||||
+43
-22
@@ -21,18 +21,27 @@
|
||||
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;
|
||||
|
||||
@@ -42,12 +51,12 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
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) {
|
||||
@@ -64,23 +73,27 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
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;
|
||||
}
|
||||
@@ -92,7 +105,11 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -101,7 +118,7 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
if (currentFrameIndex < lastFrameIndex) {
|
||||
frameProxy = threadProxy.frame(currentFrameIndex + 1);
|
||||
if (frameProxy != null) {
|
||||
anotherFrame = true;
|
||||
topFrame = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -118,17 +135,6 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -176,6 +182,21 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user