blob: a362e7d7caffffb7da41bab27ce989b931615843 [file] [log] [blame]
/*
* 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) {
if (checkContextNotResumed(node)) return;
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;
}
}