Move show referring objects to XDebugger

This commit is contained in:
Dmitry Trofimov
2014-08-29 00:31:43 +02:00
parent 648f91c767
commit 404990b8d1
10 changed files with 267 additions and 204 deletions
@@ -0,0 +1,172 @@
/*
* Copyright 2000-2014 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.actions;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.psi.PsiExpression;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
import com.sun.jdi.Field;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
public class JavaReferringObjectsValue extends JavaValue {
private static final long MAX_REFERRING = 100;
private final boolean myIsField;
private JavaReferringObjectsValue(@Nullable JavaValue parent,
@NotNull ValueDescriptorImpl valueDescriptor,
@NotNull EvaluationContextImpl evaluationContext,
NodeManagerImpl nodeManager,
boolean isField) {
super(parent, valueDescriptor, evaluationContext, nodeManager, false);
myIsField = isField;
}
public JavaReferringObjectsValue(@NotNull JavaValue javaValue, boolean isField) {
super(null, javaValue.getDescriptor(), javaValue.getEvaluationContext(), null, false);
myIsField = isField;
}
@Override
public boolean canNavigateToSource() {
return true;
}
@Override
public void computeChildren(@NotNull final XCompositeNode node) {
getEvaluationContext().getDebugProcess().getManagerThread().schedule(
new SuspendContextCommandImpl(getEvaluationContext().getSuspendContext()) {
@Override
public Priority getPriority() {
return Priority.NORMAL;
}
@Override
public void contextAction() throws Exception {
final XValueChildrenList children = new XValueChildrenList();
Value value = getDescriptor().getValue();
List<ObjectReference> references = ((ObjectReference)value).referringObjects(MAX_REFERRING);
int i = 1;
for (final ObjectReference reference : references) {
// try to find field name
Field field = findField(reference, value);
if (field != null) {
ValueDescriptorImpl descriptor = new FieldDescriptorImpl(getProject(), reference, field) {
@Override
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
return reference;
}
};
children.add(new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), null, true));
i++;
}
else {
ValueDescriptorImpl descriptor = new ValueDescriptorImpl(getProject(), reference) {
@Override
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
return reference;
}
@Override
public String getName() {
return "Ref";
}
@Override
public String calcValueName() {
return "Ref";
}
@Override
public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
return null;
}
};
children.add("Referrer " + i++, new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), null, false));
}
}
node.addChildren(children, true);
}
}
);
}
@Override
public void computePresentation(@NotNull final XValueNode node, @NotNull final XValuePlace place) {
if (!myIsField) {
super.computePresentation(node, place);
}
else {
super.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
@Override
public void applyPresentation(@Nullable Icon icon, @NotNull final XValuePresentation valuePresenter, boolean hasChildren) {
node.setPresentation(icon, new XValuePresentation() {
@NotNull
@Override
public String getSeparator() {
return " in ";
}
@Nullable
@Override
public String getType() {
return valuePresenter.getType();
}
@Override
public void renderValue(@NotNull XValueTextRenderer renderer) {
valuePresenter.renderValue(renderer);
}
}, hasChildren);
}
@Override
public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
}
@Override
public boolean isObsolete() {
return false;
}
}, place);
}
}
private static Field findField(ObjectReference reference, Value value) {
for (Field field : reference.referenceType().allFields()) {
if (reference.getValue(field) == value) {
return field;
}
}
return null;
}
}
@@ -1,199 +0,0 @@
/*
* Copyright 2000-2014 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.actions;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.JavaValue;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
import com.intellij.debugger.ui.impl.watch.FieldDescriptorImpl;
import com.intellij.debugger.ui.impl.watch.NodeManagerImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.psi.PsiExpression;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XInspectDialog;
import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
import com.sun.jdi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.List;
/**
* @author egor
*/
public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
private static final long MAX_REFERRING = 100;
@Override
protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
XValue container = node.getValueContainer();
if (container instanceof JavaValue) {
JavaValue javaValue = ((JavaValue)container);
XDebuggerTree tree = XDebuggerTree.getTree(e.getDataContext());
XInspectDialog dialog = new XInspectDialog(tree.getProject(),
tree.getEditorsProvider(),
tree.getSourcePosition(),
nodeName,
new ReferringObjectsValue(javaValue, false),
tree.getValueMarkers());
dialog.setTitle(DebuggerBundle.message("showReferring.dialog.title", nodeName));
dialog.show();
}
}
private static class ReferringObjectsValue extends JavaValue {
private final boolean myIsField;
private ReferringObjectsValue(JavaValue parent,
@NotNull ValueDescriptorImpl valueDescriptor,
@NotNull EvaluationContextImpl evaluationContext,
NodeManagerImpl nodeManager,
boolean isField) {
super(parent, valueDescriptor, evaluationContext, nodeManager, false);
myIsField = isField;
}
public ReferringObjectsValue(JavaValue javaValue, boolean isField) {
super(null, javaValue.getDescriptor(), javaValue.getEvaluationContext(), null, false);
myIsField = isField;
}
@Override
public boolean canNavigateToSource() {
return true;
}
@Override
public void computeChildren(@NotNull final XCompositeNode node) {
getEvaluationContext().getDebugProcess().getManagerThread().schedule(
new SuspendContextCommandImpl(getEvaluationContext().getSuspendContext()) {
@Override
public Priority getPriority() {
return Priority.NORMAL;
}
@Override
public void contextAction() throws Exception {
final XValueChildrenList children = new XValueChildrenList();
Value value = getDescriptor().getValue();
List<ObjectReference> references = ((ObjectReference)value).referringObjects(MAX_REFERRING);
int i = 1;
for (final ObjectReference reference : references) {
// try to find field name
Field field = findField(reference, value);
if (field != null) {
ValueDescriptorImpl descriptor = new FieldDescriptorImpl(getProject(), reference, field) {
@Override
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
return reference;
}
};
children.add(new ReferringObjectsValue(null, descriptor, getEvaluationContext(), null, true));
i++;
}
else {
ValueDescriptorImpl descriptor = new ValueDescriptorImpl(getProject(), reference) {
@Override
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
return reference;
}
@Override
public String getName() {
return "Ref";
}
@Override
public String calcValueName() {
return "Ref";
}
@Override
public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
return null;
}
};
children.add("Referrer " + i++, new ReferringObjectsValue(null, descriptor, getEvaluationContext(), null, false));
}
}
node.addChildren(children, true);
}
}
);
}
@Override
public void computePresentation(@NotNull final XValueNode node, @NotNull final XValuePlace place) {
if (!myIsField) {
super.computePresentation(node, place);
}
else {
super.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
@Override
public void applyPresentation(@Nullable Icon icon, @NotNull final XValuePresentation valuePresenter, boolean hasChildren) {
node.setPresentation(icon, new XValuePresentation() {
@NotNull
@Override
public String getSeparator() {
return " in ";
}
@Nullable
@Override
public String getType() {
return valuePresenter.getType();
}
@Override
public void renderValue(@NotNull XValueTextRenderer renderer) {
valuePresenter.renderValue(renderer);
}
}, hasChildren);
}
@Override
public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
}
@Override
public boolean isObsolete() {
return false;
}
}, place);
}
}
private static Field findField(ObjectReference reference, Value value) {
for (Field field : reference.referenceType().allFields()) {
if (reference.getValue(field) == value) {
return field;
}
}
return null;
}
}
}
@@ -17,6 +17,7 @@ package com.intellij.debugger.engine;
import com.intellij.debugger.DebuggerInvocationUtil;
import com.intellij.debugger.SourcePosition;
import com.intellij.debugger.actions.JavaReferringObjectsValue;
import com.intellij.debugger.actions.JumpToObjectAction;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
@@ -451,4 +452,14 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
public String getValueText() {
return myValueDescriptor.getValueText();
}
@Nullable
@Override
public XReferrersProvider getReferrersProvider() {
return new XReferrersProvider() {
@Override
public XValue getReferringObjectsValue() {
return new JavaReferringObjectsValue(JavaValue.this, false);
}
};
}
}
@@ -124,3 +124,5 @@ setting.sort.alphabetically.label=Sort a&lphabetically
setting.hide.window.label=Hide debug &window on process termination
setting.focus.app.on.breakpoint.label=Focus application on breakpoint
settings.show.window.label=Show &debug window on breakpoint
showReferring.dialog.title=Referring Objects For {0}
@@ -683,6 +683,7 @@
<action id="XDebugger.ToggleSortValues" class="com.intellij.xdebugger.impl.ui.tree.actions.SortValuesToggleAction" icon="AllIcons.ObjectBrowser.Sorted"/>
<action id="Debugger.MarkObject" class="com.intellij.xdebugger.impl.actions.MarkObjectAction"/>
<action id="Debugger.FocusOnBreakpoint" class="com.intellij.xdebugger.impl.actions.FocusOnBreakpointAction"/>
<action id="Debugger.ShowReferring" class="com.intellij.xdebugger.impl.ui.tree.actions.ShowReferringObjectsAction"/>
</group>
<group id="XDebugger.ToolWindow.TopToolbar">
@@ -709,6 +710,7 @@
<group id="XDebugger.ValueGroup" popup="false">
<reference ref="XDebugger.Inspect"/>
<reference ref="Debugger.ShowReferring"/>
<reference ref="Debugger.MarkObject"/>
<reference ref="XDebugger.SetValue"/>
<reference ref="XDebugger.CopyValue"/>
@@ -0,0 +1,23 @@
/*
* Copyright 2000-2014 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.xdebugger.frame;
/**
* @author traff
*/
public interface XReferrersProvider<T extends XValue> {
T getReferringObjectsValue();
}
@@ -87,4 +87,9 @@ public abstract class XValue extends XValueContainer {
public void computeTypeSourcePosition(@NotNull XNavigatable navigatable) {
navigatable.setSourcePosition(null);
}
@Nullable
public XReferrersProvider getReferrersProvider() {
return null;
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2000-2014 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.xdebugger.impl.ui.tree.actions;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.frame.XReferrersProvider;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XInspectDialog;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
/**
* @author egor
*/
public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
@Override
protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
return node.getValueContainer().getReferrersProvider() != null;
}
@Override
protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
XReferrersProvider referrersProvider = node.getValueContainer().getReferrersProvider();
if (referrersProvider != null) {
XDebuggerTree tree = XDebuggerTree.getTree(e.getDataContext());
XInspectDialog dialog = new XInspectDialog(tree.getProject(),
tree.getEditorsProvider(),
tree.getSourcePosition(),
nodeName,
referrersProvider.getReferringObjectsValue(),
tree.getValueMarkers());
dialog.setTitle(XDebuggerBundle.message("showReferring.dialog.title", nodeName));
dialog.show();
}
}
}
@@ -438,5 +438,4 @@ action.kill.process.text=Kill Process
action.kill.process.description=Forcibly terminate debugged application
evaluation.error.unknown.method.return.type=Cannot resolve method return type: {0}
rule.name.group.by.class=Group by class
rule.name.group.by.package=Group by package
showReferring.dialog.title=Referring Objects For {0}
rule.name.group.by.package=Group by package
-3
View File
@@ -162,9 +162,6 @@
<action id="Debugger.ViewText" class="com.intellij.debugger.actions.ViewTextAction">
<add-to-group group-id="XDebugger.ValueGroup" anchor="last"/>
</action>
<action id="Debugger.ShowReferring" class="com.intellij.debugger.actions.ShowReferringObjectsAction">
<add-to-group group-id="XDebugger.ValueGroup" anchor="last"/>
</action>
<action id="Debugger.CopyValue" class="com.intellij.debugger.actions.CopyValueAction"/>
<action id="Debugger.CompareValueWithClipboard" class="com.intellij.debugger.actions.CompareValueWithClipboardAction"/>
<action id="Debugger.CustomizeThreadsView" class="com.intellij.debugger.actions.CustomizeThreadsViewAction">