IDEA-60234 Automatically unwrap groovy.lang.Reference in the debugger

This commit is contained in:
peter
2013-10-08 20:29:27 +02:00
parent 0dcb367e7c
commit e1f4afb07e
7 changed files with 139 additions and 13 deletions
@@ -43,6 +43,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -107,11 +108,17 @@ public class NodeRendererSettings implements PersistentStateComponent<Element> {
public static NodeRendererSettings getInstance() {
return ServiceManager.getService(NodeRendererSettings.class);
}
/**
* use {@link com.intellij.debugger.ui.tree.render.NodeRenderer} extension
* @param renderer
*/
@Deprecated
public void addPluginRenderer(NodeRenderer renderer) {
myPluginRenderers.add(renderer);
}
@Deprecated
public void removePluginRenderer(NodeRenderer renderer) {
myPluginRenderers.remove(renderer);
}
@@ -253,15 +260,14 @@ public class NodeRendererSettings implements PersistentStateComponent<Element> {
allRenderers.add(myHexRenderer);
allRenderers.add(myPrimitiveRenderer);
allRenderers.addAll(myPluginRenderers);
Collections.addAll(allRenderers, NodeRenderer.EP_NAME.getExtensions());
myCustomRenderers.iterateRenderers(new InternalIterator<NodeRenderer>() {
public boolean visit(final NodeRenderer renderer) {
allRenderers.add(renderer);
return true;
}
});
for (NodeRenderer myAlternateCollectionRenderer : myAlternateCollectionRenderers) {
allRenderers.add(myAlternateCollectionRenderer);
}
Collections.addAll(allRenderers, myAlternateCollectionRenderers);
allRenderers.add(myColorRenderer);
allRenderers.add(myToStringRenderer);
allRenderers.add(myArrayRenderer);
@@ -29,9 +29,7 @@ import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
import com.intellij.debugger.settings.NodeRendererSettings;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.render.ClassRenderer;
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
import com.intellij.debugger.ui.tree.render.NodeRenderer;
import com.intellij.debugger.ui.tree.render.*;
import com.intellij.debugger.ui.tree.render.Renderer;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
@@ -148,9 +146,7 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
public final void setContext(EvaluationContextImpl evaluationContext) {
DebuggerManagerThreadImpl.assertIsManagerThread();
if (Patches.IBM_JDK_DISABLE_COLLECTION_BUG) {
myStoredEvaluationContext = evaluationContext;
}
myStoredEvaluationContext = evaluationContext;
Value value;
try {
value = calcValue(evaluationContext);
@@ -271,9 +267,12 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
final StringBuilder buf = StringBuilderSpinAllocator.alloc();
try {
final Value value = getValue();
if(isShowIdLabel() && value instanceof ObjectReference) {
final String idLabel = getIdLabel((ObjectReference)value);
if(!label.startsWith(idLabel)) {
if(isShowIdLabel()) {
Renderer lastRenderer = getLastRenderer();
final String idLabel = myStoredEvaluationContext != null && lastRenderer != null ?
((NodeRendererImpl)lastRenderer).getIdLabel(value, myStoredEvaluationContext.getDebugProcess()) :
null;
if(idLabel != null && !label.startsWith(idLabel)) {
buf.append(idLabel);
}
}
@@ -15,7 +15,11 @@
*/
package com.intellij.debugger.ui.tree.render;
import com.intellij.openapi.extensions.ExtensionPointName;
public interface NodeRenderer extends ChildrenRenderer, ValueLabelRenderer {
ExtensionPointName<NodeRenderer> EP_NAME = ExtensionPointName.create("com.intellij.debugger.nodeRenderer");
String getName();
void setName(String text);
@@ -15,13 +15,18 @@
*/
package com.intellij.debugger.ui.tree.render;
import com.intellij.debugger.engine.DebugProcess;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;
import org.jdom.Element;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -81,4 +86,9 @@ public abstract class NodeRendererImpl implements NodeRenderer{
public String toString() {
return getName();
}
@Nullable
public String getIdLabel(Value value, DebugProcess process) {
return value instanceof ObjectReference ? ValueDescriptorImpl.getIdLabel((ObjectReference)value) : null;
}
}
+1
View File
@@ -1442,6 +1442,7 @@
implementation="org.jetbrains.plugins.groovy.debugger.GroovyPositionManagerFactory"/>
<debugger.positionManagerFactory order="after groovyPositionManager"
implementation="org.jetbrains.plugins.groovy.springloaded.SpringLoadedPositionManagerFactory"/>
<debugger.nodeRenderer implementation="org.jetbrains.plugins.groovy.debugger.GroovyRefRenderer"/>
<codeStyle.ReferenceAdjuster language="Groovy" implementationClass="org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.groovy.jarFinder.GroovyFindJarQuickFixProvider"/>
<lang.refactoringSupport.classMembersRefactoringSupport language="Groovy"
@@ -0,0 +1,103 @@
package org.jetbrains.plugins.groovy.debugger;
import com.intellij.debugger.DebuggerContext;
import com.intellij.debugger.engine.DebugProcess;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.DebuggerUtils;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContext;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
import com.intellij.debugger.ui.tree.DebuggerTreeNode;
import com.intellij.debugger.ui.tree.NodeDescriptor;
import com.intellij.debugger.ui.tree.ValueDescriptor;
import com.intellij.debugger.ui.tree.render.ChildrenBuilder;
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
import com.intellij.debugger.ui.tree.render.NodeRenderer;
import com.intellij.debugger.ui.tree.render.NodeRendererImpl;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiExpression;
import com.sun.jdi.*;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
/**
* @author peter
*/
public class GroovyRefRenderer extends NodeRendererImpl {
public GroovyRefRenderer() {
myProperties.setEnabled(true);
myProperties.setName("Groovy Reference");
}
@Override
public String getUniqueId() {
return "GroovyRefRenderer";
}
@Override
public boolean isApplicable(Type type) {
return type instanceof ReferenceType && DebuggerUtils.instanceOf(type, GroovyCommonClassNames.GROOVY_LANG_REFERENCE);
}
@Override
public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) {
ValueDescriptor fieldDescriptor = getWrappedDescriptor(value, evaluationContext.getProject());
getDelegateRenderer(evaluationContext.getDebugProcess(), fieldDescriptor).buildChildren(fieldDescriptor.getValue(), builder, evaluationContext);
}
@Override
public PsiExpression getChildValueExpression(DebuggerTreeNode node, DebuggerContext context) throws EvaluateException {
ValueDescriptor fieldDescriptor = getWrappedDescriptor(((ValueDescriptor)node.getParent().getDescriptor()).getValue(),
context.getProject());
return getDelegateRenderer(context.getDebugProcess(), fieldDescriptor).getChildValueExpression(node, context);
}
@Override
public boolean isExpandable(Value value, EvaluationContext evaluationContext, NodeDescriptor parentDescriptor) {
ValueDescriptor fieldDescriptor = getWrappedDescriptor(value, evaluationContext.getProject());
return getDelegateRenderer(evaluationContext.getDebugProcess(), fieldDescriptor).isExpandable(fieldDescriptor.getValue(),
evaluationContext, fieldDescriptor);
}
@Override
public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener listener)
throws EvaluateException {
ValueDescriptor fieldDescriptor = getWrappedDescriptor(descriptor.getValue(), evaluationContext.getProject());
return getDelegateRenderer(evaluationContext.getDebugProcess(), fieldDescriptor).calcLabel(fieldDescriptor, evaluationContext, listener);
}
private static NodeRenderer getDelegateRenderer(DebugProcess debugProcess, ValueDescriptor fieldDescriptor) {
return ((DebugProcessImpl)debugProcess).getAutoRenderer(fieldDescriptor);
}
private static ValueDescriptor getWrappedDescriptor(Value ref, final Project project) {
final Field field = ((ObjectReference)ref).referenceType().fieldByName("value");
final Value wrapped = ((ObjectReference)ref).getValue(field);
return new ValueDescriptorImpl(project, wrapped) {
@Override
public Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
return wrapped;
}
@Override
public String calcValueName() {
return field.name();
}
@Override
public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
return JavaPsiFacade.getElementFactory(context.getProject()).createExpressionFromText("this." + field.name(), null);
}
};
}
@Nullable
@Override
public String getIdLabel(Value value, DebugProcess process) {
ValueDescriptor fieldDescriptor = getWrappedDescriptor(value, process.getProject());
return ((NodeRendererImpl)getDelegateRenderer(process, fieldDescriptor)).getIdLabel(fieldDescriptor.getValue(), process);
}
}
+3
View File
@@ -99,6 +99,9 @@
<extensionPoint name="debugger.codeFragmentFactory"
interface="com.intellij.debugger.engine.evaluation.CodeFragmentFactory"/>
<extensionPoint name="debugger.nodeRenderer"
interface="com.intellij.debugger.ui.tree.render.NodeRenderer"/>
<extensionPoint name="debugger.breakpointFactory"
interface="com.intellij.debugger.ui.breakpoints.BreakpointFactory"/>