From 3c8f350a73251898468aaeeaccc34f066f91e26f Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 3 Aug 2016 14:46:16 +0300 Subject: [PATCH] allow user renderers for primitive types --- .../actions/CreateRendererAction.java | 7 +- .../intellij/debugger/engine/JavaValue.java | 2 +- .../debugger/impl/DebuggerUtilsImpl.java | 28 +++- .../CompoundRendererConfigurable.java | 18 +-- .../settings/NodeRendererSettings.java | 11 ++ .../settings/UserRenderersConfigurable.java | 4 +- .../watch/UserExpressionDescriptorImpl.java | 29 +--- .../ui/tree/render/CachedEvaluator.java | 30 +--- .../render/CompoundReferenceRenderer.java | 114 ++------------ .../ui/tree/render/CompoundTypeRenderer.java | 145 ++++++++++++++++++ .../render/EnumerationChildrenRenderer.java | 2 +- .../render/ExpressionChildrenRenderer.java | 2 +- .../ui/tree/render/LabelRenderer.java | 6 +- .../ui/tree/render/ReferenceRenderer.java | 53 +------ .../debugger/ui/tree/render/TypeRenderer.java | 78 ++++++++++ 15 files changed, 306 insertions(+), 223 deletions(-) create mode 100644 java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundTypeRenderer.java create mode 100644 java/debugger/impl/src/com/intellij/debugger/ui/tree/render/TypeRenderer.java diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererAction.java index 7449838c7db0..13d59885386d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/CreateRendererAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -22,7 +22,7 @@ import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.settings.UserRenderersConfigurable; -import com.intellij.debugger.ui.tree.render.CompoundReferenceRenderer; +import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.options.ConfigurableBase; @@ -83,8 +83,7 @@ public class CreateRendererAction extends AnAction { }; SingleConfigurableEditor editor = new SingleConfigurableEditor(project, configurable); if (name != null) { - CompoundReferenceRenderer renderer = - NodeRendererSettings.getInstance().createCompoundReferenceRenderer(name, name, null, null); + NodeRenderer renderer = NodeRendererSettings.getInstance().createCompoundTypeRenderer(name, name, null, null); renderer.setEnabled(true); ui.addRenderer(renderer); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index 80cad77b1512..2935c5077802 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -303,7 +303,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV myValueDescriptor.getLastRenderer() instanceof ToStringBasedRenderer) { value = StringUtil.wrapWithDoubleQuote(truncateToMaxLength(myValue)); } - else if (myValueDescriptor.getLastRenderer() instanceof CompoundReferenceRenderer) { + else if (myValueDescriptor.getLastRenderer() instanceof CompoundTypeRenderer) { value = truncateToMaxLength(myValue); } renderer.renderValue(value); diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java index b56d80116d05..252628edd459 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsImpl.java @@ -36,9 +36,10 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.JDOMExternalizerUtil; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiExpression; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiJavaParserFacadeImpl; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.net.NetUtils; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; @@ -138,6 +139,27 @@ public class DebuggerUtilsImpl extends DebuggerUtilsEx{ return PositionUtil.getContextElement(context); } + public static Pair getPsiClassAndType(String className, Project project) { + PsiClass contextClass; + PsiType contextType; + PsiPrimitiveType primitiveType = PsiJavaParserFacadeImpl.getPrimitiveType(className); + if (primitiveType != null) { + contextClass = JavaPsiFacade.getInstance(project).findClass(primitiveType.getBoxedTypeName(), GlobalSearchScope.allScope(project)); + contextType = primitiveType; + } + else { + contextClass = findClass(className, project, GlobalSearchScope.allScope(project)); + if (contextClass != null) { + contextClass = (PsiClass)contextClass.getNavigationElement(); + } + if (contextClass instanceof PsiCompiledElement) { + contextClass = (PsiClass)((PsiCompiledElement)contextClass).getMirror(); + } + contextType = getType(className, project); + } + return Pair.create(contextClass, contextType); + } + @Override public PsiClass chooseClassDialog(String title, Project project) { TreeClassChooser dialog = TreeClassChooserFactory.getInstance(project).createAllProjectScopeChooser(title); diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java index f7b132069849..b74de6b5d444 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java @@ -52,8 +52,8 @@ import java.util.ArrayList; import java.util.List; class CompoundRendererConfigurable extends JPanel { - private CompoundReferenceRenderer myRenderer; - private CompoundReferenceRenderer myOriginalRenderer; + private CompoundTypeRenderer myRenderer; + private CompoundTypeRenderer myOriginalRenderer; private Project myProject; private final ClassNameEditorWithBrowseButton myClassNameField; private final JRadioButton myRbDefaultLabel; @@ -187,9 +187,9 @@ class CompoundRendererConfigurable extends JPanel { } public void setRenderer(NodeRenderer renderer) { - if (renderer instanceof CompoundReferenceRenderer) { - myRenderer = (CompoundReferenceRenderer)renderer; - myOriginalRenderer = (CompoundReferenceRenderer)renderer.clone(); + if (renderer instanceof CompoundTypeRenderer) { + myRenderer = (CompoundTypeRenderer)renderer; + myOriginalRenderer = (CompoundTypeRenderer)renderer.clone(); } else { myRenderer = myOriginalRenderer = null; @@ -197,7 +197,7 @@ class CompoundRendererConfigurable extends JPanel { reset(); } - public CompoundReferenceRenderer getRenderer() { + public CompoundTypeRenderer getRenderer() { return myRenderer; } @@ -300,7 +300,7 @@ class CompoundRendererConfigurable extends JPanel { if (myRenderer == null) { return false; } - final CompoundReferenceRenderer cloned = (CompoundReferenceRenderer)myRenderer.clone(); + final CompoundTypeRenderer cloned = (CompoundTypeRenderer)myRenderer.clone(); flushDataTo(cloned); return !DebuggerUtilsEx.externalizableEqual(cloned, myOriginalRenderer); } @@ -311,10 +311,10 @@ class CompoundRendererConfigurable extends JPanel { } flushDataTo(myRenderer); // update the renderer to compare with in order to find out whether we've been modified since last apply - myOriginalRenderer = (CompoundReferenceRenderer)myRenderer.clone(); + myOriginalRenderer = (CompoundTypeRenderer)myRenderer.clone(); } - private void flushDataTo(final CompoundReferenceRenderer renderer) { // label + private void flushDataTo(final CompoundTypeRenderer renderer) { // label LabelRenderer labelRenderer = null; renderer.setShowType(myShowTypeCheckBox.isSelected()); if (myRbExpressionLabel.isSelected()) { diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java index 6a9e6459e5b6..28281e790403 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java @@ -328,9 +328,20 @@ public class NodeRendererSettings implements PersistentStateComponent { else if(rendererId.equals(CompoundNodeRenderer.UNIQUE_ID) || rendererId.equals(REFERENCE_RENDERER)) { return createCompoundReferenceRenderer("unnamed", CommonClassNames.JAVA_LANG_OBJECT, null, null); } + else if (rendererId.equals(CompoundTypeRenderer.UNIQUE_ID)) { + return createCompoundTypeRenderer("unnamed", CommonClassNames.JAVA_LANG_OBJECT, null, null); + } return null; } + public CompoundTypeRenderer createCompoundTypeRenderer( + @NonNls final String rendererName, @NonNls final String className, final ValueLabelRenderer labelRenderer, final ChildrenRenderer childrenRenderer + ) { + CompoundTypeRenderer renderer = new CompoundTypeRenderer(this, rendererName, labelRenderer, childrenRenderer); + renderer.setClassName(className); + return renderer; + } + public CompoundReferenceRenderer createCompoundReferenceRenderer( @NonNls final String rendererName, @NonNls final String className, final ValueLabelRenderer labelRenderer, final ChildrenRenderer childrenRenderer ) { diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java index 2b48c8c0caa1..8f54aa21ea37 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/UserRenderersConfigurable.java @@ -16,7 +16,7 @@ package com.intellij.debugger.settings; import com.intellij.debugger.DebuggerBundle; -import com.intellij.debugger.ui.tree.render.CompoundNodeRenderer; +import com.intellij.debugger.ui.tree.render.CompoundTypeRenderer; import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.ide.util.ElementsChooser; import com.intellij.openapi.Disposable; @@ -209,7 +209,7 @@ public final class UserRenderersConfigurable extends JPanel implements Configura @Override public void run(AnActionButton button) { - final NodeRenderer renderer = (NodeRenderer)NodeRendererSettings.getInstance().createRenderer(CompoundNodeRenderer.UNIQUE_ID); + NodeRenderer renderer = (NodeRenderer)NodeRendererSettings.getInstance().createRenderer(CompoundTypeRenderer.UNIQUE_ID); renderer.setEnabled(true); addRenderer(renderer); SwingUtilities.invokeLater(myNameField::requestFocus); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java index e2d4a317cf68..bdb10992aff6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -21,19 +21,19 @@ package com.intellij.debugger.ui.impl.watch; import com.intellij.debugger.DebuggerBundle; -import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.StackFrameContext; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.impl.DebuggerUtilsImpl; import com.intellij.debugger.ui.tree.UserExpressionDescriptor; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiCodeFragment; -import com.sun.jdi.ObjectReference; +import com.intellij.psi.PsiType; import com.sun.jdi.Type; -import com.sun.jdi.Value; import org.jetbrains.annotations.Nullable; public class UserExpressionDescriptorImpl extends EvaluationDescriptor implements UserExpressionDescriptor{ @@ -60,24 +60,11 @@ public class UserExpressionDescriptorImpl extends EvaluationDescriptor implement } protected PsiCodeFragment getEvaluationCode(final StackFrameContext context) throws EvaluateException { - Value value = myParentDescriptor.getValue(); - - if(value instanceof ObjectReference) { - final String typeName = value.type().name(); - - final PsiClass psiClass = DebuggerUtils.findClass(myTypeName, myProject, context.getDebugProcess().getSearchScope()); - - if (psiClass == null) { - throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.type.name", typeName)); - } - - return createCodeFragment(psiClass); - } - else { - throw EvaluateExceptionUtil.createEvaluateException( - DebuggerBundle.message("evaluation.error.objref.expected", myParentDescriptor.getName()) - ); + Pair psiClassAndType = DebuggerUtilsImpl.getPsiClassAndType(myTypeName, myProject); + if (psiClassAndType.first == null) { + throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.type.name", myTypeName)); } + return createCodeFragment(psiClassAndType.first); } public ValueDescriptorImpl getParentDescriptor() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CachedEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CachedEvaluator.java index fc3100126dfc..24e458e61ad5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CachedEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CachedEvaluator.java @@ -18,9 +18,10 @@ package com.intellij.debugger.ui.tree.render; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.evaluation.*; import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; +import com.intellij.debugger.impl.DebuggerUtilsImpl; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; import com.intellij.psi.*; -import com.intellij.psi.impl.PsiJavaParserFacadeImpl; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.reference.SoftReference; import org.jetbrains.annotations.Nullable; @@ -66,31 +67,14 @@ public abstract class CachedEvaluator { protected Cache initEvaluatorAndChildrenExpression(final Project project) { final Cache cache = new Cache(); try { - String className = getClassName(); - PsiClass contextClass; - PsiType contextType; - PsiPrimitiveType primitiveType = PsiJavaParserFacadeImpl.getPrimitiveType(className); - if (primitiveType != null) { - contextClass = JavaPsiFacade.getInstance(project).findClass(primitiveType.getBoxedTypeName(), GlobalSearchScope.allScope(project)); - contextType = primitiveType; - } - else { - contextClass = DebuggerUtils.findClass(className, project, GlobalSearchScope.allScope(project)); - if (contextClass != null) { - contextClass = (PsiClass)contextClass.getNavigationElement(); - } - if (contextClass instanceof PsiCompiledElement) { - contextClass = (PsiClass)((PsiCompiledElement)contextClass).getMirror(); - } - if (contextClass == null) { - throw EvaluateExceptionUtil.CANNOT_FIND_SOURCE_CLASS; - } - contextType = DebuggerUtils.getType(className, project); + Pair psiClassAndType = DebuggerUtilsImpl.getPsiClassAndType(getClassName(), project); + if (psiClassAndType.first == null) { + throw EvaluateExceptionUtil.CANNOT_FIND_SOURCE_CLASS; } cache.myPsiChildrenExpression = null; - JavaCodeFragment codeFragment = myDefaultFragmentFactory.createCodeFragment(myReferenceExpression, contextClass, project); + JavaCodeFragment codeFragment = myDefaultFragmentFactory.createCodeFragment(myReferenceExpression, psiClassAndType.first, project); codeFragment.forceResolveScope(GlobalSearchScope.allScope(project)); - codeFragment.setThisType(contextType); + codeFragment.setThisType(psiClassAndType.second); DebuggerUtils.checkSyntax(codeFragment); cache.myPsiChildrenExpression = codeFragment instanceof PsiExpressionCodeFragment ? ((PsiExpressionCodeFragment)codeFragment).getExpression() : null; cache.myEvaluator = myDefaultFragmentFactory.getEvaluatorBuilder().build(codeFragment, null); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java index 76976c36c7d4..597db0460a40 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundReferenceRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -15,118 +15,22 @@ */ package com.intellij.debugger.ui.tree.render; -import com.intellij.debugger.DebuggerContext; -import com.intellij.debugger.engine.DebugProcess; -import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.settings.NodeRendererSettings; -import com.intellij.debugger.ui.tree.DebuggerTreeNode; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.psi.CommonClassNames; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementFactory; -import com.intellij.psi.search.GlobalSearchScope; import com.sun.jdi.ReferenceType; import com.sun.jdi.Type; -import org.jetbrains.annotations.NotNull; -public class CompoundReferenceRenderer extends CompoundNodeRenderer{ - protected static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.CompoundReferenceRenderer"); - - public CompoundReferenceRenderer(final NodeRendererSettings rendererSettings, String name, ValueLabelRenderer labelRenderer, ChildrenRenderer childrenRenderer) { +public class CompoundReferenceRenderer extends CompoundTypeRenderer { + public CompoundReferenceRenderer(NodeRendererSettings rendererSettings, + String name, + ValueLabelRenderer labelRenderer, + ChildrenRenderer childrenRenderer) { super(rendererSettings, name, labelRenderer, childrenRenderer); - myProperties.setClassName(CommonClassNames.JAVA_LANG_OBJECT); - LOG.assertTrue(labelRenderer == null || labelRenderer instanceof ReferenceRenderer); - LOG.assertTrue(childrenRenderer == null || childrenRenderer instanceof ReferenceRenderer); } - public void setLabelRenderer(ValueLabelRenderer labelRenderer) { - final ValueLabelRenderer prevRenderer = getLabelRenderer(); - super.setLabelRenderer(myRendererSettings.isBase(labelRenderer) ? null : labelRenderer); - final ValueLabelRenderer currentRenderer = getLabelRenderer(); - if (prevRenderer != currentRenderer) { - if (currentRenderer instanceof ReferenceRenderer) { - ((ReferenceRenderer)currentRenderer).setClassName(getClassName()); - } - } - } - - public void setChildrenRenderer(ChildrenRenderer childrenRenderer) { - final ChildrenRenderer prevRenderer = getChildrenRenderer(); - super.setChildrenRenderer(myRendererSettings.isBase(childrenRenderer) ? null : childrenRenderer); - final ChildrenRenderer currentRenderer = getChildrenRenderer(); - if (prevRenderer != currentRenderer) { - if (currentRenderer instanceof ReferenceRenderer) { - ((ReferenceRenderer)currentRenderer).setClassName(getClassName()); - } - } - } - - public ChildrenRenderer getChildrenRenderer() { - final ChildrenRenderer childrenRenderer = super.getChildrenRenderer(); - return childrenRenderer != null ? childrenRenderer : getDefaultRenderer(); - } - - private NodeRenderer getDefaultRenderer() { - return getClassName().endsWith("]") ? myRendererSettings.getArrayRenderer() : myRendererSettings.getClassRenderer(); - } - - public ValueLabelRenderer getLabelRenderer() { - final ValueLabelRenderer labelRenderer = super.getLabelRenderer(); - return labelRenderer != null ? labelRenderer : getDefaultRenderer(); - } - - private ChildrenRenderer getRawChildrenRenderer() { - NodeRenderer classRenderer = getDefaultRenderer(); - final ChildrenRenderer originalRenderer = super.getChildrenRenderer(); - return originalRenderer == classRenderer ? null : originalRenderer; - } - - private ValueLabelRenderer getRawLabelRenderer() { - NodeRenderer classRenderer = getDefaultRenderer(); - final ValueLabelRenderer originalRenderer = super.getLabelRenderer(); - return originalRenderer == classRenderer ? null : originalRenderer; - } - - public boolean isApplicable(Type type) { - if(type == null || !(type instanceof ReferenceType) || !DebuggerUtils.instanceOf(type, getClassName())) { - return false; + if (type instanceof ReferenceType) { + return super.isApplicable(type); } - return super.isApplicable(type); - } - - public void setClassName(@NotNull String name) { - myProperties.setClassName(name); - if(getRawLabelRenderer() != null) { - final ValueLabelRenderer originalLabelRenderer = super.getLabelRenderer(); - if (originalLabelRenderer instanceof ReferenceRenderer) { - ((ReferenceRenderer)originalLabelRenderer).setClassName(name); - } - } - - if(getRawChildrenRenderer() != null) { - final ChildrenRenderer originalChildrenRenderer = super.getChildrenRenderer(); - if (originalChildrenRenderer instanceof ReferenceRenderer) { - ((ReferenceRenderer)originalChildrenRenderer).setClassName(name); - } - } - } - - public @NotNull String getClassName() { - return myProperties.getClassName(); - } - - protected final PsiElement getContext(Project project, DebuggerContext context) { - DebugProcess process = context.getDebugProcess(); - GlobalSearchScope scope = process != null ? process.getSearchScope() : GlobalSearchScope.allScope(project); - return DebuggerUtils.findClass(getClassName(), project, scope); - } - - protected final PsiElement getChildValueExpression(String text, DebuggerTreeNode node, DebuggerContext context) { - Project project = node.getProject(); - PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); - return elementFactory.createExpressionFromText(text, getContext(project, context)); + return false; } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundTypeRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundTypeRenderer.java new file mode 100644 index 000000000000..4707d20e5f10 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/CompoundTypeRenderer.java @@ -0,0 +1,145 @@ +/* + * Copyright 2000-2016 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.tree.render; + +import com.intellij.debugger.DebuggerContext; +import com.intellij.debugger.engine.DebugProcess; +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.settings.NodeRendererSettings; +import com.intellij.debugger.ui.tree.DebuggerTreeNode; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.project.Project; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiJavaParserFacadeImpl; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.TypeConversionUtil; +import com.sun.jdi.Type; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +public class CompoundTypeRenderer extends CompoundNodeRenderer { + public static final @NonNls String UNIQUE_ID = "CompoundTypeRenderer"; + protected static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.CompoundReferenceRenderer"); + + public CompoundTypeRenderer(NodeRendererSettings rendererSettings, + String name, + ValueLabelRenderer labelRenderer, + ChildrenRenderer childrenRenderer) { + super(rendererSettings, name, labelRenderer, childrenRenderer); + myProperties.setClassName(CommonClassNames.JAVA_LANG_OBJECT); + LOG.assertTrue(labelRenderer == null || labelRenderer instanceof TypeRenderer); + LOG.assertTrue(childrenRenderer == null || childrenRenderer instanceof TypeRenderer); + } + + public void setLabelRenderer(ValueLabelRenderer labelRenderer) { + final ValueLabelRenderer prevRenderer = getLabelRenderer(); + super.setLabelRenderer(myRendererSettings.isBase(labelRenderer) ? null : labelRenderer); + final ValueLabelRenderer currentRenderer = getLabelRenderer(); + if (prevRenderer != currentRenderer) { + if (currentRenderer instanceof TypeRenderer) { + ((TypeRenderer)currentRenderer).setClassName(getClassName()); + } + } + } + + public void setChildrenRenderer(ChildrenRenderer childrenRenderer) { + final ChildrenRenderer prevRenderer = getChildrenRenderer(); + super.setChildrenRenderer(myRendererSettings.isBase(childrenRenderer) ? null : childrenRenderer); + final ChildrenRenderer currentRenderer = getChildrenRenderer(); + if (prevRenderer != currentRenderer) { + if (currentRenderer instanceof TypeRenderer) { + ((TypeRenderer)currentRenderer).setClassName(getClassName()); + } + } + } + + public ChildrenRenderer getChildrenRenderer() { + final ChildrenRenderer childrenRenderer = super.getChildrenRenderer(); + return childrenRenderer != null ? childrenRenderer : getDefaultRenderer(); + } + + private NodeRenderer getDefaultRenderer() { + String name = getClassName(); + if (TypeConversionUtil.isPrimitive(name)) { + return myRendererSettings.getPrimitiveRenderer(); + } + return name.endsWith("]") ? myRendererSettings.getArrayRenderer() : myRendererSettings.getClassRenderer(); + } + + public ValueLabelRenderer getLabelRenderer() { + final ValueLabelRenderer labelRenderer = super.getLabelRenderer(); + return labelRenderer != null ? labelRenderer : getDefaultRenderer(); + } + + private ChildrenRenderer getRawChildrenRenderer() { + NodeRenderer classRenderer = getDefaultRenderer(); + final ChildrenRenderer originalRenderer = super.getChildrenRenderer(); + return originalRenderer == classRenderer ? null : originalRenderer; + } + + private ValueLabelRenderer getRawLabelRenderer() { + NodeRenderer classRenderer = getDefaultRenderer(); + final ValueLabelRenderer originalRenderer = super.getLabelRenderer(); + return originalRenderer == classRenderer ? null : originalRenderer; + } + + public boolean isApplicable(Type type) { + if (DebuggerUtils.instanceOf(type, getClassName())) { + return super.isApplicable(type); + } + return false; + } + + @Override + public String getUniqueId() { + return UNIQUE_ID; + } + + public void setClassName(@NotNull String name) { + myProperties.setClassName(name); + if (getRawLabelRenderer() != null) { + final ValueLabelRenderer originalLabelRenderer = super.getLabelRenderer(); + if (originalLabelRenderer instanceof TypeRenderer) { + ((TypeRenderer)originalLabelRenderer).setClassName(name); + } + } + + if (getRawChildrenRenderer() != null) { + final ChildrenRenderer originalChildrenRenderer = super.getChildrenRenderer(); + if (originalChildrenRenderer instanceof TypeRenderer) { + ((TypeRenderer)originalChildrenRenderer).setClassName(name); + } + } + } + + public + @NotNull + String getClassName() { + return myProperties.getClassName(); + } + + protected final PsiElement getContext(Project project, DebuggerContext context) { + DebugProcess process = context.getDebugProcess(); + GlobalSearchScope scope = process != null ? process.getSearchScope() : GlobalSearchScope.allScope(project); + return DebuggerUtils.findClass(getClassName(), project, scope); + } + + protected final PsiElement getChildValueExpression(String text, DebuggerTreeNode node, DebuggerContext context) { + Project project = node.getProject(); + PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory(); + return elementFactory.createExpressionFromText(text, getContext(project, context)); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java index 2067fbeb70e7..ad09d9693c3b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/EnumerationChildrenRenderer.java @@ -41,7 +41,7 @@ import java.util.List; * Date: Dec 19, 2003 * Time: 1:25:15 PM */ -public final class EnumerationChildrenRenderer extends ReferenceRenderer implements ChildrenRenderer{ +public final class EnumerationChildrenRenderer extends TypeRenderer implements ChildrenRenderer{ public static final @NonNls String UNIQUE_ID = "EnumerationChildrenRenderer"; private boolean myAppendDefaultChildren; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java index c5e56b25a183..3276f351611a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ExpressionChildrenRenderer.java @@ -50,7 +50,7 @@ import java.util.List; * Date: Sep 17, 2003 * Time: 2:04:00 PM */ -public class ExpressionChildrenRenderer extends ReferenceRenderer implements ChildrenRenderer { +public class ExpressionChildrenRenderer extends TypeRenderer implements ChildrenRenderer { public static final @NonNls String UNIQUE_ID = "ExpressionChildrenRenderer"; private static final Key EXPRESSION_VALUE = new Key<>("EXPRESSION_VALUE"); private static final Key LAST_CHILDREN_RENDERER = new Key<>("LAST_CHILDREN_RENDERER"); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java index 4e14423ce57b..86b105b48df5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/LabelRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -28,7 +28,6 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.DefaultJDOMExternalizer; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; -import com.sun.jdi.PrimitiveValue; import com.sun.jdi.Value; import org.jdom.Element; import org.jetbrains.annotations.NonNls; @@ -40,7 +39,7 @@ import javax.swing.*; * Date: Sep 20, 2003 * Time: 10:27:12 PM */ -public class LabelRenderer extends ReferenceRenderer implements ValueLabelRenderer{ +public class LabelRenderer extends TypeRenderer implements ValueLabelRenderer{ public static final @NonNls String UNIQUE_ID = "LabelRenderer"; private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.impl.watch.render.ClassLabelRenderer"); @@ -69,7 +68,6 @@ public class LabelRenderer extends ReferenceRenderer implements ValueLabelRender throws EvaluateException { final Value value = descriptor.getValue(); - LOG.assertTrue(!(value instanceof PrimitiveValue)); String result; final DebugProcess debugProcess = evaluationContext.getDebugProcess(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java index 4ac38e184c6b..18928dc90f77 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ReferenceRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2016 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. @@ -16,64 +16,19 @@ package com.intellij.debugger.ui.tree.render; import com.intellij.debugger.engine.DebuggerUtils; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; -import com.intellij.psi.CommonClassNames; import com.sun.jdi.ReferenceType; import com.sun.jdi.Type; -import org.jdom.Element; import org.jetbrains.annotations.NotNull; -public abstract class ReferenceRenderer implements Renderer { - private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.ReferenceRenderer"); - protected BasicRendererProperties myProperties = new BasicRendererProperties(); - +public abstract class ReferenceRenderer extends TypeRenderer { protected ReferenceRenderer() { - this(CommonClassNames.JAVA_LANG_OBJECT); } protected ReferenceRenderer(@NotNull String className) { - myProperties.setClassName(className); - } - - public String getClassName() { - return myProperties.getClassName(); - } - - public void setClassName(String className) { - myProperties.setClassName(className); - } - - public Renderer clone() { - try { - final ReferenceRenderer cloned = (ReferenceRenderer)super.clone(); - cloned.myProperties = myProperties.clone(); - return cloned; - } - catch (CloneNotSupportedException e) { - LOG.error(e); - } - return null; + super(className); } public boolean isApplicable(Type type) { - return type != null && type instanceof ReferenceType && DebuggerUtils.instanceOf(type, getClassName()); - } - - public void writeExternal(Element element) throws WriteExternalException { - myProperties.writeExternal(element); - } - - public void readExternal(Element element) throws InvalidDataException { - myProperties.readExternal(element); - } - - protected CachedEvaluator createCachedEvaluator() { - return new CachedEvaluator() { - protected String getClassName() { - return ReferenceRenderer.this.getClassName(); - } - }; + return type instanceof ReferenceType && DebuggerUtils.instanceOf(type, getClassName()); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/TypeRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/TypeRenderer.java new file mode 100644 index 000000000000..cdde150690c7 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/TypeRenderer.java @@ -0,0 +1,78 @@ +/* + * Copyright 2000-2016 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.tree.render; + +import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.psi.CommonClassNames; +import com.sun.jdi.Type; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; + +public abstract class TypeRenderer implements Renderer { + private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.tree.render.ReferenceRenderer"); + protected BasicRendererProperties myProperties = new BasicRendererProperties(); + + protected TypeRenderer() { + this(CommonClassNames.JAVA_LANG_OBJECT); + } + + protected TypeRenderer(@NotNull String className) { + myProperties.setClassName(className); + } + + public String getClassName() { + return myProperties.getClassName(); + } + + public void setClassName(String className) { + myProperties.setClassName(className); + } + + public Renderer clone() { + try { + final TypeRenderer cloned = (TypeRenderer)super.clone(); + cloned.myProperties = myProperties.clone(); + return cloned; + } + catch (CloneNotSupportedException e) { + LOG.error(e); + } + return null; + } + + public boolean isApplicable(Type type) { + return DebuggerUtils.instanceOf(type, getClassName()); + } + + public void writeExternal(Element element) throws WriteExternalException { + myProperties.writeExternal(element); + } + + public void readExternal(Element element) throws InvalidDataException { + myProperties.readExternal(element); + } + + protected CachedEvaluator createCachedEvaluator() { + return new CachedEvaluator() { + protected String getClassName() { + return TypeRenderer.this.getClassName(); + } + }; + } +}