mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-60234 Automatically unwrap groovy.lang.Reference in the debugger
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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"/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user