mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
show values of method arguments even if degug info for local vars is not available (jdk 1.6+ only)
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.impl.descriptors.data;
|
||||
|
||||
import com.intellij.debugger.ui.impl.watch.ArgumentValueDescriptorImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.sun.jdi.Value;
|
||||
|
||||
public class ArgValueData extends DescriptorData<ArgumentValueDescriptorImpl>{
|
||||
private final int myIndex;
|
||||
private final Value myValue;
|
||||
|
||||
public ArgValueData(int index, Value value) {
|
||||
super();
|
||||
myIndex = index;
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
protected ArgumentValueDescriptorImpl createDescriptorImpl(Project project) {
|
||||
return new ArgumentValueDescriptorImpl(project, myIndex, myValue);
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
if(!(object instanceof ArgValueData)) return false;
|
||||
|
||||
return myIndex == ((ArgValueData)object).myIndex;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return myIndex;
|
||||
}
|
||||
|
||||
public DisplayKey<ArgumentValueDescriptorImpl> getDisplayKey() {
|
||||
return new SimpleDisplayKey<ArgumentValueDescriptorImpl>(myIndex);
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,13 @@ import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.jdi.StackFrameProxy;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
|
||||
@@ -248,6 +251,34 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<Value> getArgumentValues() throws EvaluateException {
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread();
|
||||
try {
|
||||
final StackFrame stackFrame = getStackFrame();
|
||||
if (stackFrame != null) {
|
||||
//return stackFrame.getArgumentValues();
|
||||
try {
|
||||
final Method method = StackFrame.class.getMethod("getArgumentValues");
|
||||
//noinspection unchecked
|
||||
return (Collection<Value>)method.invoke(stackFrame, ArrayUtil.EMPTY_OBJECT_ARRAY);
|
||||
}
|
||||
catch (NoSuchMethodException ignored) {
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
throw new EvaluateException("", e.getCause());
|
||||
}
|
||||
catch (IllegalAccessException e) {
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
catch (InvalidStackFrameException e) {
|
||||
clearCaches();
|
||||
return getArgumentValues();
|
||||
}
|
||||
}
|
||||
|
||||
private Map<LocalVariable, Value> getAllValues() throws EvaluateException{
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread();
|
||||
checkValid();
|
||||
|
||||
@@ -51,7 +51,9 @@ import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import com.intellij.util.ui.tree.TreeModelAdapter;
|
||||
import com.sun.jdi.AbsentInformationException;
|
||||
import com.sun.jdi.ObjectCollectedException;
|
||||
import com.sun.jdi.Value;
|
||||
|
||||
import javax.swing.event.TreeModelEvent;
|
||||
import javax.swing.tree.TreeModel;
|
||||
@@ -116,34 +118,54 @@ public class FrameDebuggerTree extends DebuggerTree {
|
||||
super(stackNode);
|
||||
}
|
||||
|
||||
protected void buildVariables(final StackFrameDescriptorImpl stackDescriptor, final EvaluationContextImpl evaluationContext)
|
||||
throws EvaluateException {
|
||||
protected void buildVariables(final StackFrameDescriptorImpl stackDescriptor, final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
final SourcePosition sourcePosition = getDebuggerContext().getSourcePosition();
|
||||
if (sourcePosition == null) {
|
||||
return;
|
||||
}
|
||||
final Map<String, LocalVariableProxyImpl> visibleVariables = getVisibleVariables(stackDescriptor);
|
||||
final Pair<Set<String>, Set<TextWithImports>> usedVars =
|
||||
ApplicationManager.getApplication().runReadAction(new Computable<Pair<Set<String>, Set<TextWithImports>>>() {
|
||||
public Pair<Set<String>, Set<TextWithImports>> compute() {
|
||||
return findReferencedVars(visibleVariables.keySet(), sourcePosition);
|
||||
try {
|
||||
final Map<String, LocalVariableProxyImpl> visibleVariables = getVisibleVariables(stackDescriptor);
|
||||
final Pair<Set<String>, Set<TextWithImports>> usedVars =
|
||||
ApplicationManager.getApplication().runReadAction(new Computable<Pair<Set<String>, Set<TextWithImports>>>() {
|
||||
public Pair<Set<String>, Set<TextWithImports>> compute() {
|
||||
return findReferencedVars(visibleVariables.keySet(), sourcePosition);
|
||||
}
|
||||
});
|
||||
// add locals
|
||||
if (myAutoWatchMode) {
|
||||
for (String var : usedVars.first) {
|
||||
final LocalVariableDescriptorImpl descriptor = myNodeManager.getLocalVariableDescriptor(stackDescriptor, visibleVariables.get(var));
|
||||
myChildren.add(myNodeManager.createNode(descriptor, evaluationContext));
|
||||
}
|
||||
});
|
||||
// add locals
|
||||
if (myAutoWatchMode) {
|
||||
for (String var : usedVars.first) {
|
||||
final LocalVariableDescriptorImpl descriptor = myNodeManager.getLocalVariableDescriptor(stackDescriptor, visibleVariables.get(var));
|
||||
myChildren.add(myNodeManager.createNode(descriptor, evaluationContext));
|
||||
}
|
||||
else {
|
||||
super.buildVariables(stackDescriptor, evaluationContext);
|
||||
}
|
||||
// add expressions
|
||||
final EvaluationContextImpl evalContextCopy = evaluationContext.createEvaluationContext(evaluationContext.getThisObject());
|
||||
evalContextCopy.setAutoLoadClasses(false);
|
||||
for (TextWithImports text : usedVars.second) {
|
||||
myChildren.add(myNodeManager.createNode(myNodeManager.getWatchItemDescriptor(stackDescriptor, text, null), evalContextCopy));
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.buildVariables(stackDescriptor, evaluationContext);
|
||||
}
|
||||
// add expressions
|
||||
final EvaluationContextImpl evalContextCopy = evaluationContext.createEvaluationContext(evaluationContext.getThisObject());
|
||||
evalContextCopy.setAutoLoadClasses(false);
|
||||
for (TextWithImports text : usedVars.second) {
|
||||
myChildren.add(myNodeManager.createNode(myNodeManager.getWatchItemDescriptor(stackDescriptor, text, null), evalContextCopy));
|
||||
catch (EvaluateException e) {
|
||||
if (e.getCause() instanceof AbsentInformationException) {
|
||||
final StackFrameProxyImpl frame = stackDescriptor.getFrameProxy();
|
||||
if (frame == null) {
|
||||
throw e;
|
||||
}
|
||||
final Collection<Value> argValues = frame.getArgumentValues();
|
||||
int index = 0;
|
||||
for (Value argValue : argValues) {
|
||||
final ArgumentValueDescriptorImpl descriptor = myNodeManager.getArgumentValueDescriptor(stackDescriptor, index++, argValue);
|
||||
final DebuggerTreeNodeImpl variableNode = myNodeManager.createNode(descriptor, evaluationContext);
|
||||
myChildren.add(variableNode);
|
||||
}
|
||||
myChildren.add(myNodeManager.createMessageNode(MessageDescriptor.LOCAL_VARIABLES_INFO_UNAVAILABLE));
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl.watch;
|
||||
|
||||
import com.intellij.debugger.DebuggerContext;
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.engine.ContextUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiParameter;
|
||||
import com.intellij.psi.PsiParameterList;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.sun.jdi.PrimitiveValue;
|
||||
import com.sun.jdi.Value;
|
||||
|
||||
public class ArgumentValueDescriptorImpl extends ValueDescriptorImpl{
|
||||
private final int myIndex;
|
||||
private final Value myValue;
|
||||
private String myName;
|
||||
|
||||
public ArgumentValueDescriptorImpl(Project project, int index, Value value) {
|
||||
super(project);
|
||||
myIndex = index;
|
||||
myValue = value;
|
||||
myName = "arg" + String.valueOf(index);
|
||||
setLvalue(true);
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return myValue instanceof PrimitiveValue;
|
||||
}
|
||||
|
||||
public Value calcValue(final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
final SourcePosition position = ContextUtil.getSourcePosition(evaluationContext);
|
||||
if (position != null) {
|
||||
final PsiMethod method = PsiTreeUtil.getParentOfType(position.getElementAt(), PsiMethod.class);
|
||||
if (method != null) {
|
||||
final PsiParameterList params = method.getParameterList();
|
||||
if (myIndex < params.getParametersCount()) {
|
||||
final PsiParameter param = params.getParameters()[myIndex];
|
||||
myName = param.getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return myValue;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public String calcValueName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -538,13 +538,14 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi
|
||||
updateUI(true);
|
||||
}
|
||||
|
||||
protected void buildVariables(final StackFrameDescriptorImpl stackDescriptor, final EvaluationContextImpl evaluationContext)
|
||||
throws EvaluateException {
|
||||
protected void buildVariables(final StackFrameDescriptorImpl stackDescriptor, final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
final StackFrameProxyImpl frame = stackDescriptor.getFrameProxy();
|
||||
for (final LocalVariableProxyImpl local : frame.visibleVariables()) {
|
||||
final LocalVariableDescriptorImpl localVariableDescriptor = myNodeManager.getLocalVariableDescriptor(stackDescriptor, local);
|
||||
final DebuggerTreeNodeImpl variableNode = myNodeManager.createNode(localVariableDescriptor, evaluationContext);
|
||||
myChildren.add(variableNode);
|
||||
if (frame != null) {
|
||||
for (final LocalVariableProxyImpl local : frame.visibleVariables()) {
|
||||
final LocalVariableDescriptorImpl localVariableDescriptor = myNodeManager.getLocalVariableDescriptor(stackDescriptor, local);
|
||||
final DebuggerTreeNodeImpl variableNode = myNodeManager.createNode(localVariableDescriptor, evaluationContext);
|
||||
myChildren.add(variableNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -152,6 +152,10 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory {
|
||||
return getDescriptor(parent, new LocalData((LocalVariableProxyImpl)local));
|
||||
}
|
||||
|
||||
public ArgumentValueDescriptorImpl getArgumentValueDescriptor(NodeDescriptor parent, int index, Value value) {
|
||||
return getDescriptor(parent, new ArgValueData(index, value));
|
||||
}
|
||||
|
||||
public StackFrameDescriptorImpl getStackFrameDescriptor(NodeDescriptorImpl parent, StackFrameProxyImpl frameProxy) {
|
||||
return getDescriptor(parent, new StackFrameData(frameProxy));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user