mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
when debug infor for locals is not available allow evaluation of method arguments by their names
This commit is contained in:
+69
-32
@@ -88,7 +88,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myPosition = position;
|
||||
}
|
||||
|
||||
@Override public void visitCodeFragment(JavaCodeFragment codeFragment) {
|
||||
@Override
|
||||
public void visitCodeFragment(JavaCodeFragment codeFragment) {
|
||||
myVisitedFragments.add(codeFragment);
|
||||
ArrayList<Evaluator> evaluators = new ArrayList<Evaluator>();
|
||||
|
||||
@@ -109,12 +110,14 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myCurrentFragmentEvaluator = oldFragmentEvaluator;
|
||||
}
|
||||
|
||||
@Override public void visitErrorElement(PsiErrorElement element) {
|
||||
@Override
|
||||
public void visitErrorElement(PsiErrorElement element) {
|
||||
throw new EvaluateRuntimeException(EvaluateExceptionUtil
|
||||
.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", element.getText())));
|
||||
}
|
||||
|
||||
@Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
|
||||
@Override
|
||||
public void visitAssignmentExpression(PsiAssignmentExpression expression) {
|
||||
PsiExpression rExpression = expression.getRExpression();
|
||||
if(rExpression == null) throw new EvaluateRuntimeException(EvaluateExceptionUtil
|
||||
.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", expression.getText())));
|
||||
@@ -143,11 +146,13 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new AssignmentEvaluator(lEvaluator, rEvaluator);
|
||||
}
|
||||
|
||||
@Override public void visitStatement(PsiStatement statement) {
|
||||
@Override
|
||||
public void visitStatement(PsiStatement statement) {
|
||||
throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.statement.not.supported", statement.getText())));
|
||||
}
|
||||
|
||||
@Override public void visitBlockStatement(PsiBlockStatement statement) {
|
||||
@Override
|
||||
public void visitBlockStatement(PsiBlockStatement statement) {
|
||||
PsiStatement[] statements = statement.getCodeBlock().getStatements();
|
||||
Evaluator [] evaluators = new Evaluator[statements.length];
|
||||
for (int i = 0; i < statements.length; i++) {
|
||||
@@ -159,7 +164,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new BlockStatementEvaluator(evaluators);
|
||||
}
|
||||
|
||||
@Override public void visitWhileStatement(PsiWhileStatement statement) {
|
||||
@Override
|
||||
public void visitWhileStatement(PsiWhileStatement statement) {
|
||||
PsiStatement body = statement.getBody();
|
||||
if(body == null) return;
|
||||
body.accept(this);
|
||||
@@ -175,7 +181,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new WhileStatementEvaluator(myResult, bodyEvaluator, label);
|
||||
}
|
||||
|
||||
@Override public void visitForStatement(PsiForStatement statement) {
|
||||
@Override
|
||||
public void visitForStatement(PsiForStatement statement) {
|
||||
PsiStatement initializer = statement.getInitialization();
|
||||
Evaluator initializerEvaluator = null;
|
||||
if(initializer != null){
|
||||
@@ -209,7 +216,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new ForStatementEvaluator(initializerEvaluator, conditionEvaluator, updateEvaluator, bodyEvaluator, label);
|
||||
}
|
||||
|
||||
@Override public void visitIfStatement(PsiIfStatement statement) {
|
||||
@Override
|
||||
public void visitIfStatement(PsiIfStatement statement) {
|
||||
PsiStatement thenBranch = statement.getThenBranch();
|
||||
if(thenBranch == null) return;
|
||||
thenBranch.accept(this);
|
||||
@@ -229,27 +237,32 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new IfStatementEvaluator(myResult, thenEvaluator, elseEvaluator);
|
||||
}
|
||||
|
||||
@Override public void visitBreakStatement(PsiBreakStatement statement) {
|
||||
@Override
|
||||
public void visitBreakStatement(PsiBreakStatement statement) {
|
||||
PsiIdentifier labelIdentifier = statement.getLabelIdentifier();
|
||||
myResult = BreakContinueStatementEvaluator.createBreakEvaluator(labelIdentifier != null ? labelIdentifier.getText() : null);
|
||||
}
|
||||
|
||||
@Override public void visitContinueStatement(PsiContinueStatement statement) {
|
||||
@Override
|
||||
public void visitContinueStatement(PsiContinueStatement statement) {
|
||||
PsiIdentifier labelIdentifier = statement.getLabelIdentifier();
|
||||
myResult = BreakContinueStatementEvaluator.createContinueEvaluator(labelIdentifier != null ? labelIdentifier.getText() : null);
|
||||
}
|
||||
|
||||
@Override public void visitExpressionStatement(PsiExpressionStatement statement) {
|
||||
@Override
|
||||
public void visitExpressionStatement(PsiExpressionStatement statement) {
|
||||
statement.getExpression().accept(this);
|
||||
}
|
||||
|
||||
@Override public void visitExpression(PsiExpression expression) {
|
||||
@Override
|
||||
public void visitExpression(PsiExpression expression) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("visitExpression " + expression);
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitBinaryExpression(PsiBinaryExpression expression) {
|
||||
@Override
|
||||
public void visitBinaryExpression(PsiBinaryExpression expression) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("visitBinaryExpression " + expression);
|
||||
}
|
||||
@@ -270,7 +283,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new BinaryExpressionEvaluator(lResult, myResult, opType, type.getCanonicalText());
|
||||
}
|
||||
|
||||
@Override public void visitDeclarationStatement(PsiDeclarationStatement statement) {
|
||||
@Override
|
||||
public void visitDeclarationStatement(PsiDeclarationStatement statement) {
|
||||
List<Evaluator> evaluators = new ArrayList<Evaluator>();
|
||||
|
||||
PsiElement[] declaredElements = statement.getDeclaredElements();
|
||||
@@ -336,7 +350,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitConditionalExpression(PsiConditionalExpression expression) {
|
||||
@Override
|
||||
public void visitConditionalExpression(PsiConditionalExpression expression) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("visitConditionalExpression " + expression);
|
||||
}
|
||||
@@ -368,7 +383,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new ConditionalExpressionEvaluator(conditionEvaluator, thenEvaluator, elseEvaluator);
|
||||
}
|
||||
|
||||
@Override public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("visitReferenceExpression " + expression);
|
||||
}
|
||||
@@ -386,11 +402,19 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
return;
|
||||
}
|
||||
// local variable
|
||||
PsiVariable psiVar = (PsiVariable)element;
|
||||
String localName = psiVar.getName();
|
||||
final PsiVariable psiVar = (PsiVariable)element;
|
||||
final String localName = psiVar.getName();
|
||||
PsiClass variableClass = getContainingClass(psiVar);
|
||||
if (getContextPsiClass() == null || getContextPsiClass().equals(variableClass)) {
|
||||
myResult = new LocalVariableEvaluator(localName, ContextUtil.isJspImplicit(element));
|
||||
final LocalVariableEvaluator localVarEvaluator = new LocalVariableEvaluator(localName, ContextUtil.isJspImplicit(element));
|
||||
if (psiVar instanceof PsiParameter) {
|
||||
final PsiParameter param = (PsiParameter)psiVar;
|
||||
final PsiParameterList paramList = PsiTreeUtil.getParentOfType(param, PsiParameterList.class, true);
|
||||
if (paramList != null) {
|
||||
localVarEvaluator.setParameterIndex(paramList.getParameterIndex(param));
|
||||
}
|
||||
}
|
||||
myResult = localVarEvaluator;
|
||||
return;
|
||||
}
|
||||
// the expression references final var outside the context's class (in some of the outer classes)
|
||||
@@ -451,7 +475,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
objectEvaluator = new ThisEvaluator(iterationCount);
|
||||
}
|
||||
myResult = new FieldEvaluator(objectEvaluator, FieldEvaluator.createClassFilter(fieldClass), psiField.getName());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
//let's guess what this could be
|
||||
PsiElement nameElement = expression.getReferenceNameElement(); // get "b" part
|
||||
String name;
|
||||
@@ -497,7 +522,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitSuperExpression(PsiSuperExpression expression) {
|
||||
@Override
|
||||
public void visitSuperExpression(PsiSuperExpression expression) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("visitSuperExpression " + expression);
|
||||
}
|
||||
@@ -505,7 +531,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new SuperEvaluator(iterationCount);
|
||||
}
|
||||
|
||||
@Override public void visitThisExpression(PsiThisExpression expression) {
|
||||
@Override
|
||||
public void visitThisExpression(PsiThisExpression expression) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("visitThisExpression " + expression);
|
||||
}
|
||||
@@ -535,7 +562,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
return iterationCount;
|
||||
}
|
||||
|
||||
@Override public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
|
||||
@Override
|
||||
public void visitInstanceOfExpression(PsiInstanceOfExpression expression) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("visitInstanceOfExpression " + expression);
|
||||
}
|
||||
@@ -550,7 +578,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new InstanceofEvaluator(operandEvaluator, new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(type)));
|
||||
}
|
||||
|
||||
@Override public void visitParenthesizedExpression(PsiParenthesizedExpression expression) {
|
||||
@Override
|
||||
public void visitParenthesizedExpression(PsiParenthesizedExpression expression) {
|
||||
if (LOG.isDebugEnabled()) {
|
||||
LOG.debug("visitParenthesizedExpression " + expression);
|
||||
}
|
||||
@@ -560,7 +589,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitPostfixExpression(PsiPostfixExpression expression) {
|
||||
@Override
|
||||
public void visitPostfixExpression(PsiPostfixExpression expression) {
|
||||
expression.getOperand().accept(this);
|
||||
PsiType type = expression.getType();
|
||||
if(type == null) {
|
||||
@@ -570,7 +600,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new PostfixOperationEvaluator(myResult, expression.getOperationSign().getTokenType(), type.getCanonicalText());
|
||||
}
|
||||
|
||||
@Override public void visitPrefixExpression(final PsiPrefixExpression expression) {
|
||||
@Override
|
||||
public void visitPrefixExpression(final PsiPrefixExpression expression) {
|
||||
final PsiType type = expression.getType();
|
||||
if(type == null) {
|
||||
throw new EvaluateRuntimeException(
|
||||
@@ -714,7 +745,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new MethodEvaluator(objectEvaluator, contextClass, methodExpr.getReferenceName(), psiMethod != null ? JVMNameUtil.getJVMSignature(psiMethod) : null, argumentEvaluators);
|
||||
}
|
||||
|
||||
@Override public void visitLiteralExpression(PsiLiteralExpression expression) {
|
||||
@Override
|
||||
public void visitLiteralExpression(PsiLiteralExpression expression) {
|
||||
Object value = expression.getValue();
|
||||
if(expression.getParsingError() != null) {
|
||||
throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(expression.getParsingError()));
|
||||
@@ -722,7 +754,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new LiteralEvaluator(value, expression.getType().getCanonicalText());
|
||||
}
|
||||
|
||||
@Override public void visitArrayAccessExpression(PsiArrayAccessExpression expression) {
|
||||
@Override
|
||||
public void visitArrayAccessExpression(PsiArrayAccessExpression expression) {
|
||||
final PsiExpression indexExpression = expression.getIndexExpression();
|
||||
if(indexExpression == null) {
|
||||
throw new EvaluateRuntimeException(EvaluateExceptionUtil
|
||||
@@ -735,13 +768,15 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
myResult = new ArrayAccessEvaluator(arrayEvaluator, indexEvaluator);
|
||||
}
|
||||
|
||||
@Override public void visitTypeCastExpression(PsiTypeCastExpression expression) {
|
||||
@Override
|
||||
public void visitTypeCastExpression(PsiTypeCastExpression expression) {
|
||||
expression.getOperand().accept(this);
|
||||
PsiType castType = expression.getCastType().getType();
|
||||
myResult = new TypeCastEvaluator(myResult, castType.getCanonicalText(), castType instanceof PsiPrimitiveType);
|
||||
}
|
||||
|
||||
@Override public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
|
||||
@Override
|
||||
public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
|
||||
PsiType type = expression.getOperand().getType();
|
||||
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
@@ -753,7 +788,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitNewExpression(PsiNewExpression expression) {
|
||||
@Override
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
PsiType expressionPsiType = expression.getType();
|
||||
if (expressionPsiType instanceof PsiArrayType) {
|
||||
Evaluator dimensionEvaluator = null;
|
||||
@@ -857,7 +893,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
|
||||
@Override
|
||||
public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) {
|
||||
PsiExpression[] initializers = expression.getInitializers();
|
||||
Evaluator[] evaluators = new Evaluator[initializers.length];
|
||||
for (int idx = 0; idx < initializers.length; idx++) {
|
||||
|
||||
+41
-15
@@ -20,6 +20,7 @@
|
||||
*/
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
@@ -28,13 +29,11 @@ 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.debugger.DebuggerBundle;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.sun.jdi.ClassNotLoadedException;
|
||||
import com.sun.jdi.InvalidTypeException;
|
||||
import com.sun.jdi.Type;
|
||||
import com.sun.jdi.Value;
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
class LocalVariableEvaluator implements Evaluator {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.evaluation.expression.LocalVariableEvaluator");
|
||||
@@ -43,12 +42,17 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
private EvaluationContextImpl myContext;
|
||||
private LocalVariableProxyImpl myEvaluatedVariable;
|
||||
private final boolean myIsJspSpecial;
|
||||
private int myParameterIndex = -1;
|
||||
|
||||
public LocalVariableEvaluator(String localVariableName, boolean isJspSpecial) {
|
||||
myLocalVariableName = localVariableName;
|
||||
myIsJspSpecial = isJspSpecial;
|
||||
}
|
||||
|
||||
public void setParameterIndex(int parameterIndex) {
|
||||
myParameterIndex = parameterIndex;
|
||||
}
|
||||
|
||||
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
|
||||
StackFrameProxyImpl frameProxy = context.getFrameProxy();
|
||||
if (frameProxy == null) {
|
||||
@@ -56,18 +60,40 @@ class LocalVariableEvaluator implements Evaluator {
|
||||
}
|
||||
|
||||
try {
|
||||
for(;;) {
|
||||
LocalVariableProxyImpl local = frameProxy.visibleVariableByName(myLocalVariableName);
|
||||
if (local != null) {
|
||||
myEvaluatedVariable = local;
|
||||
myContext = context;
|
||||
return frameProxy.getValue(local);
|
||||
ThreadReferenceProxyImpl threadProxy = null;
|
||||
int lastFrameIndex = -1;
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
LocalVariableProxyImpl local = frameProxy.visibleVariableByName(myLocalVariableName);
|
||||
if (local != null) {
|
||||
myEvaluatedVariable = local;
|
||||
myContext = context;
|
||||
return frameProxy.getValue(local);
|
||||
}
|
||||
}
|
||||
catch (EvaluateException e) {
|
||||
if (!(e.getCause() instanceof AbsentInformationException)) {
|
||||
throw e;
|
||||
}
|
||||
if (myParameterIndex < 0) {
|
||||
throw e;
|
||||
}
|
||||
final List<Value> values = frameProxy.getArgumentValues();
|
||||
if (values.isEmpty() || myParameterIndex >= values.size()) {
|
||||
throw e;
|
||||
}
|
||||
return values.get(myParameterIndex);
|
||||
}
|
||||
|
||||
ThreadReferenceProxyImpl threadProxy = frameProxy.threadProxy();
|
||||
if(myIsJspSpecial && frameProxy.getFrameIndex() < threadProxy.frameCount() - 1) {
|
||||
if(frameProxy.getFrameIndex() < threadProxy.frameCount() - 1) {
|
||||
frameProxy = threadProxy.frame(frameProxy.getFrameIndex() + 1);
|
||||
if (myIsJspSpecial) {
|
||||
if (threadProxy == null /* initialize it lazily */) {
|
||||
threadProxy = frameProxy.threadProxy();
|
||||
lastFrameIndex = threadProxy.frameCount() - 1;
|
||||
}
|
||||
final int currentFrameIndex = frameProxy.getFrameIndex();
|
||||
if (currentFrameIndex < lastFrameIndex) {
|
||||
frameProxy = threadProxy.frame(currentFrameIndex + 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,7 +251,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Value> getArgumentValues() throws EvaluateException {
|
||||
public List<Value> getArgumentValues() throws EvaluateException {
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread();
|
||||
try {
|
||||
final StackFrame stackFrame = getStackFrame();
|
||||
@@ -260,7 +260,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
|
||||
try {
|
||||
final Method method = StackFrame.class.getMethod("getArgumentValues");
|
||||
//noinspection unchecked
|
||||
return (Collection<Value>)method.invoke(stackFrame, ArrayUtil.EMPTY_OBJECT_ARRAY);
|
||||
return (List<Value>)method.invoke(stackFrame, ArrayUtil.EMPTY_OBJECT_ARRAY);
|
||||
}
|
||||
catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user