mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-175168 On-demand renderers - force on-demand action
This commit is contained in:
@@ -311,20 +311,13 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV
|
||||
|
||||
String value = truncateToMaxLength(myValue);
|
||||
Renderer lastRenderer = myValueDescriptor.getLastRenderer();
|
||||
if (lastRenderer instanceof OnDemandRenderer) {
|
||||
OnDemandRenderer onDemandRenderer = (OnDemandRenderer)lastRenderer;
|
||||
if (OnDemandRenderer.isCalculated(myValueDescriptor)) {
|
||||
lastRenderer = onDemandRenderer.getRenderer();
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastRenderer instanceof CompoundTypeRenderer) {
|
||||
lastRenderer = ((CompoundTypeRenderer)lastRenderer).getLabelRenderer();
|
||||
}
|
||||
if (lastRenderer instanceof ToStringRenderer) {
|
||||
if (!((ToStringRenderer)lastRenderer).isShowValue(myValueDescriptor, myValueDescriptor.getStoredEvaluationContext())) {
|
||||
return; // to avoid empty line for not calculated toStrings
|
||||
}
|
||||
value = StringUtil.wrapWithDoubleQuote(value);
|
||||
}
|
||||
renderer.renderValue(value);
|
||||
|
||||
@@ -610,4 +610,8 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public EvaluationContextImpl getStoredEvaluationContext() {
|
||||
return myStoredEvaluationContext;
|
||||
}
|
||||
}
|
||||
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.actions
|
||||
|
||||
import com.intellij.debugger.settings.NodeRendererSettings
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.actionSystem.ToggleAction
|
||||
import com.intellij.openapi.project.DumbAware
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.xdebugger.XDebuggerManager
|
||||
import com.intellij.xdebugger.impl.XDebugSessionImpl
|
||||
import com.intellij.xdebugger.impl.ui.XDebugSessionData
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
class ForceOnDemandRenderersAction : ToggleAction(), DumbAware {
|
||||
|
||||
override fun isSelected(e: AnActionEvent): Boolean {
|
||||
return RENDERERS_ONDEMAND_FORCED.get(getSessionData(e), false)
|
||||
}
|
||||
|
||||
override fun setSelected(e: AnActionEvent, state: Boolean) {
|
||||
RENDERERS_ONDEMAND_FORCED.set(getSessionData(e), state)
|
||||
NodeRendererSettings.getInstance().fireRenderersChanged()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val RENDERERS_ONDEMAND_FORCED = Key.create<Boolean>("RENDERERS_ONDEMAND_FORCED")
|
||||
|
||||
private fun getSessionData(e: AnActionEvent): XDebugSessionData? {
|
||||
var data = e.getData(XDebugSessionData.DATA_KEY)
|
||||
if (data == null) {
|
||||
val project = e.project
|
||||
if (project != null) {
|
||||
val session = XDebuggerManager.getInstance(project).currentSession
|
||||
if (session != null) {
|
||||
data = (session as XDebugSessionImpl).sessionData
|
||||
}
|
||||
}
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun isForcedOnDemand(session: XDebugSessionImpl): Boolean {
|
||||
return RENDERERS_ONDEMAND_FORCED.get(session.sessionData, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,23 +18,23 @@ package com.intellij.debugger.ui.tree.render;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.DebugProcess;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.FullValueEvaluatorProvider;
|
||||
import com.intellij.debugger.engine.evaluation.*;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContext;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.openapi.util.DefaultJDOMExternalizer;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.xdebugger.frame.XFullValueEvaluator;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class LabelRenderer extends TypeRenderer implements ValueLabelRenderer, FullValueEvaluatorProvider {
|
||||
public class LabelRenderer extends TypeRenderer implements ValueLabelRenderer, OnDemandRenderer {
|
||||
public static final @NonNls String UNIQUE_ID = "LabelRenderer";
|
||||
public boolean myOnDemand;
|
||||
|
||||
@@ -62,7 +62,7 @@ public class LabelRenderer extends TypeRenderer implements ValueLabelRenderer, F
|
||||
public String calcLabel(ValueDescriptor descriptor, EvaluationContext evaluationContext, DescriptorLabelListener labelListener)
|
||||
throws EvaluateException {
|
||||
|
||||
if (myOnDemand && !OnDemandRenderer.isCalculated(descriptor)) {
|
||||
if (!isShowValue(descriptor, evaluationContext)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -92,13 +92,10 @@ public class LabelRenderer extends TypeRenderer implements ValueLabelRenderer, F
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@NotNull
|
||||
@Override
|
||||
public XFullValueEvaluator getFullValueEvaluator(EvaluationContextImpl evaluationContext, ValueDescriptorImpl valueDescriptor) {
|
||||
if (myOnDemand && !OnDemandRenderer.isCalculated(valueDescriptor)) {
|
||||
return OnDemandRenderer.createFullValueEvaluator("… " + getLabelExpression().getText());
|
||||
}
|
||||
return null;
|
||||
public String getLinkText() {
|
||||
return "… " + getLabelExpression().getText();
|
||||
}
|
||||
|
||||
public void readExternal(Element element) throws InvalidDataException {
|
||||
@@ -124,6 +121,11 @@ public class LabelRenderer extends TypeRenderer implements ValueLabelRenderer, F
|
||||
myLabelExpression.setReferenceExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOnDemand(EvaluationContext evaluationContext) {
|
||||
return myOnDemand || OnDemandRenderer.super.isOnDemand(evaluationContext);
|
||||
}
|
||||
|
||||
public boolean isOnDemand() {
|
||||
return myOnDemand;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.FullValueEvaluatorProvider;
|
||||
import com.intellij.debugger.engine.JavaValue;
|
||||
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.ValueDescriptor;
|
||||
import com.intellij.debugger.ui.tree.actions.ForceOnDemandRenderersAction;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.xdebugger.frame.XFullValueEvaluator;
|
||||
import com.intellij.xdebugger.frame.XValuePlace;
|
||||
import com.intellij.xdebugger.impl.XDebugSessionImpl;
|
||||
import com.intellij.xdebugger.impl.ui.tree.nodes.HeadlessValueEvaluationCallback;
|
||||
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
public interface OnDemandRenderer extends FullValueEvaluatorProvider {
|
||||
@Nullable
|
||||
@Override
|
||||
default XFullValueEvaluator getFullValueEvaluator(EvaluationContextImpl evaluationContext,
|
||||
ValueDescriptorImpl valueDescriptor) {
|
||||
if (isOnDemand(evaluationContext) && !isCalculated(valueDescriptor)) {
|
||||
return createFullValueEvaluator(getLinkText());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String getLinkText();
|
||||
|
||||
default boolean isOnDemand(EvaluationContext evaluationContext) {
|
||||
return isOnDemandForced(evaluationContext);
|
||||
}
|
||||
|
||||
default boolean isShowValue(ValueDescriptor valueDescriptor, EvaluationContext evaluationContext) {
|
||||
return !isOnDemand(evaluationContext) || isCalculated(valueDescriptor);
|
||||
}
|
||||
|
||||
static XFullValueEvaluator createFullValueEvaluator(String text) {
|
||||
return new XFullValueEvaluator(text) {
|
||||
@Override
|
||||
public void startEvaluation(@NotNull XFullValueEvaluationCallback callback) {
|
||||
if (callback instanceof HeadlessValueEvaluationCallback) {
|
||||
XValueNodeImpl node = ((HeadlessValueEvaluationCallback)callback).getNode();
|
||||
node.clearFullValueEvaluator();
|
||||
setCalculated(((JavaValue)node.getValueContainer()).getDescriptor());
|
||||
node.getValueContainer().computePresentation(node, XValuePlace.TREE);
|
||||
}
|
||||
callback.evaluated("");
|
||||
}
|
||||
}.setShowValuePopup(false);
|
||||
}
|
||||
|
||||
Key<Boolean> ON_DEMAND_CALCULATED = Key.create("ON_DEMAND_CALCULATED");
|
||||
|
||||
static boolean isCalculated(ValueDescriptor descriptor) {
|
||||
return ON_DEMAND_CALCULATED.get(descriptor, false);
|
||||
}
|
||||
|
||||
static void setCalculated(ValueDescriptor descriptor) {
|
||||
ON_DEMAND_CALCULATED.set(descriptor, true);
|
||||
}
|
||||
|
||||
static boolean isOnDemandForced(EvaluationContext evaluationContext) {
|
||||
return ForceOnDemandRenderersAction.isForcedOnDemand(
|
||||
(XDebugSessionImpl)((DebugProcessImpl)evaluationContext.getDebugProcess()).getXdebugProcess().getSession());
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.DebuggerBundle
|
||||
import com.intellij.debugger.DebuggerContext
|
||||
import com.intellij.debugger.engine.FullValueEvaluatorProvider
|
||||
import com.intellij.debugger.engine.JavaValue
|
||||
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.openapi.util.Key
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.xdebugger.frame.XFullValueEvaluator
|
||||
import com.intellij.xdebugger.frame.XValuePlace
|
||||
import com.intellij.xdebugger.impl.ui.tree.nodes.HeadlessValueEvaluationCallback
|
||||
import com.sun.jdi.Type
|
||||
import com.sun.jdi.Value
|
||||
import javax.swing.Icon
|
||||
|
||||
/**
|
||||
* @author egor
|
||||
*/
|
||||
class OnDemandRenderer(val renderer: NodeRendererImpl) : NodeRendererImpl(), FullValueEvaluatorProvider {
|
||||
init {
|
||||
isEnabled = true
|
||||
}
|
||||
|
||||
@Throws(EvaluateException::class)
|
||||
override fun calcLabel(descriptor: ValueDescriptor, evaluationContext: EvaluationContext, listener: DescriptorLabelListener): String? {
|
||||
if (!isCalculated(descriptor)) {
|
||||
return ""
|
||||
}
|
||||
return renderer.calcLabel(descriptor, evaluationContext, listener)
|
||||
}
|
||||
|
||||
override fun getFullValueEvaluator(evaluationContext: EvaluationContextImpl?, valueDescriptor: ValueDescriptorImpl): XFullValueEvaluator? {
|
||||
if (!isCalculated(valueDescriptor)) {
|
||||
return createFullValueEvaluator(DebuggerBundle.message("message.node.toString"))
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
override fun buildChildren(value: Value?, builder: ChildrenBuilder?, evaluationContext: EvaluationContext?) {
|
||||
renderer.buildChildren(value, builder, evaluationContext)
|
||||
}
|
||||
|
||||
override fun getChildValueExpression(node: DebuggerTreeNode?, context: DebuggerContext?): PsiElement {
|
||||
return renderer.getChildValueExpression(node, context)
|
||||
}
|
||||
|
||||
override fun isExpandable(value: Value?, evaluationContext: EvaluationContext?, parentDescriptor: NodeDescriptor?): Boolean {
|
||||
return renderer.isExpandable(value, evaluationContext, parentDescriptor)
|
||||
}
|
||||
|
||||
override fun calcValueIcon(descriptor: ValueDescriptor?,
|
||||
evaluationContext: EvaluationContext?,
|
||||
listener: DescriptorLabelListener?): Icon? {
|
||||
return renderer.calcValueIcon(descriptor, evaluationContext, listener)
|
||||
}
|
||||
|
||||
override fun isApplicable(type: Type?): Boolean {
|
||||
return renderer.isApplicable(type)
|
||||
}
|
||||
|
||||
override fun getName(): String {
|
||||
return "OnDemand" + renderer.getName()
|
||||
}
|
||||
|
||||
override fun getUniqueId(): String {
|
||||
return "OnDemand" + renderer.getUniqueId()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun createFullValueEvaluator(text: String): XFullValueEvaluator {
|
||||
return object : XFullValueEvaluator(text) {
|
||||
override fun startEvaluation(callback: XFullValueEvaluator.XFullValueEvaluationCallback) {
|
||||
if (callback is HeadlessValueEvaluationCallback) {
|
||||
val node = callback.node
|
||||
node.clearFullValueEvaluator()
|
||||
setCalculated((node.valueContainer as JavaValue).descriptor)
|
||||
node.valueContainer.computePresentation(node, XValuePlace.TREE)
|
||||
}
|
||||
callback.evaluated("")
|
||||
}
|
||||
}.setShowValuePopup(false)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val ON_DEMAND_CALCULATED = Key.create<Boolean>("ON_DEMAND_CALCULATED")
|
||||
|
||||
@JvmStatic
|
||||
fun isCalculated(descriptor: ValueDescriptor): Boolean {
|
||||
return ON_DEMAND_CALCULATED.get(descriptor, false)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setCalculated(descriptor: ValueDescriptor) {
|
||||
ON_DEMAND_CALCULATED.set(descriptor, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -34,10 +34,11 @@ import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
|
||||
import com.sun.jdi.*;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
|
||||
|
||||
public class ToStringRenderer extends NodeRendererImpl {
|
||||
public class ToStringRenderer extends NodeRendererImpl implements OnDemandRenderer {
|
||||
public static final @NonNls String UNIQUE_ID = "ToStringRenderer";
|
||||
|
||||
private boolean USE_CLASS_FILTERS = false;
|
||||
@@ -76,6 +77,11 @@ public class ToStringRenderer extends NodeRendererImpl {
|
||||
@Override
|
||||
public String calcLabel(final ValueDescriptor valueDescriptor, EvaluationContext evaluationContext, final DescriptorLabelListener labelListener)
|
||||
throws EvaluateException {
|
||||
|
||||
if (!isShowValue(valueDescriptor, evaluationContext)) {
|
||||
return "";
|
||||
}
|
||||
|
||||
final Value value = valueDescriptor.getValue();
|
||||
BatchEvaluator.getBatchEvaluator(evaluationContext.getDebugProcess()).invoke(new ToStringCommand(evaluationContext, value) {
|
||||
@Override
|
||||
@@ -96,6 +102,12 @@ public class ToStringRenderer extends NodeRendererImpl {
|
||||
return XDebuggerUIConstants.COLLECTING_DATA_MESSAGE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getLinkText() {
|
||||
return DebuggerBundle.message("message.node.toString");
|
||||
}
|
||||
|
||||
public boolean isUseClassFilters() {
|
||||
return USE_CLASS_FILTERS;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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,13 +16,14 @@
|
||||
package com.intellij.xdebugger.impl.ui;
|
||||
|
||||
import com.intellij.openapi.actionSystem.DataKey;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.xdebugger.XExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class XDebugSessionData {
|
||||
public class XDebugSessionData extends UserDataHolderBase {
|
||||
public static final DataKey<XDebugSessionData> DATA_KEY = DataKey.create("XDebugSessionData");
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -225,6 +225,9 @@
|
||||
|
||||
<action id="Debugger.CreateRenderer" class="com.intellij.debugger.actions.CreateRendererAction" text="Create..."/>
|
||||
<action id="Debugger.AutoRenderer" class="com.intellij.debugger.actions.AutoRendererAction"/>
|
||||
<action id="Debugger.MuteRenderers" class="com.intellij.debugger.ui.tree.actions.ForceOnDemandRenderersAction" text="Force Renderers On-demand">
|
||||
<add-to-group group-id="XDebugger.ValueGroup" anchor="last"/>
|
||||
</action>
|
||||
</group>
|
||||
|
||||
<action class="com.intellij.debugger.memory.action.ShowInstancesByClassAction"
|
||||
|
||||
Reference in New Issue
Block a user