summaryrefslogtreecommitdiff
path: root/platform/xdebugger-impl/src/com/intellij
diff options
context:
space:
mode:
Diffstat (limited to 'platform/xdebugger-impl/src/com/intellij')
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java47
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java3
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java7
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java187
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java40
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java43
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java4
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java95
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form14
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java6
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java9
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java47
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java1
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java17
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java26
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java2
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java51
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java11
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java37
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java8
-rw-r--r--platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java66
27 files changed, 615 insertions, 125 deletions
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
index 8ee2f1ee587a..1b0f0ca69a59 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java
@@ -45,6 +45,7 @@ import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.ToolWindowId;
import com.intellij.ui.AppUIUtil;
@@ -96,7 +97,8 @@ public class XDebugSessionImpl implements XDebugSession {
private XSuspendContext mySuspendContext;
private XExecutionStack myCurrentExecutionStack;
private XStackFrame myCurrentStackFrame;
- private XSourcePosition myCurrentPosition;
+ private boolean myIsTopFrame;
+ private XSourcePosition myTopFramePosition;
private final AtomicBoolean myPaused = new AtomicBoolean();
private MyDependentBreakpointListener myDependentBreakpointListener;
private XValueMarkers<?, ?> myValueMarkers;
@@ -255,7 +257,13 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
@Nullable
public XSourcePosition getCurrentPosition() {
- return myCurrentPosition;
+ return myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
+ }
+
+ @Nullable
+ @Override
+ public XSourcePosition getTopFramePosition() {
+ return myTopFramePosition;
}
public XDebugSessionTab init(@NotNull XDebugProcess process, @NotNull XDebugSessionData sessionData, @Nullable RunContentDescriptor contentToReuse) {
@@ -538,8 +546,8 @@ public class XDebugSessionImpl implements XDebugSession {
mySuspendContext = null;
myCurrentExecutionStack = null;
myCurrentStackFrame = null;
- adjustMouseTrackingCounter(myCurrentPosition, -1);
- myCurrentPosition = null;
+ adjustMouseTrackingCounter(myTopFramePosition, -1);
+ myTopFramePosition = null;
myActiveNonLineBreakpoint = null;
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
@@ -559,7 +567,7 @@ public class XDebugSessionImpl implements XDebugSession {
}
private boolean isTopFrameSelected() {
- return myCurrentExecutionStack != null && myCurrentExecutionStack.getTopFrame() == myCurrentStackFrame;
+ return myCurrentExecutionStack != null && myIsTopFrame;
}
@@ -570,7 +578,7 @@ public class XDebugSessionImpl implements XDebugSession {
if (executionStack != null) {
XStackFrame topFrame = executionStack.getTopFrame();
if (topFrame != null) {
- setCurrentStackFrame(executionStack, topFrame);
+ setCurrentStackFrame(executionStack, topFrame, true);
myDebuggerManager.showExecutionPosition();
}
}
@@ -578,17 +586,18 @@ public class XDebugSessionImpl implements XDebugSession {
}
@Override
- public void setCurrentStackFrame(@NotNull final XStackFrame frame) {
- setCurrentStackFrame(myCurrentExecutionStack, frame);
+ public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame) {
+ setCurrentStackFrame(myCurrentExecutionStack, frame, frame == executionStack.getTopFrame());
}
@Override
- public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame) {
+ public void setCurrentStackFrame(@NotNull XExecutionStack executionStack, @NotNull XStackFrame frame, boolean isTopFrame) {
if (mySuspendContext == null) return;
boolean frameChanged = myCurrentStackFrame != frame;
myCurrentExecutionStack = executionStack;
myCurrentStackFrame = frame;
+ myIsTopFrame = isTopFrame;
activateSession();
if (frameChanged) {
@@ -708,7 +717,9 @@ public class XDebugSessionImpl implements XDebugSession {
@Override
public void run() {
if (mySessionTab != null) {
- mySessionTab.toFront(true);
+ if (XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().isShowDebuggerOnBreakpoint()) {
+ mySessionTab.toFront(true);
+ }
mySessionTab.getUi().attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
}
}
@@ -781,14 +792,14 @@ public class XDebugSessionImpl implements XDebugSession {
mySuspendContext = suspendContext;
myCurrentExecutionStack = suspendContext.getActiveExecutionStack();
myCurrentStackFrame = myCurrentExecutionStack != null ? myCurrentExecutionStack.getTopFrame() : null;
- myCurrentPosition = myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
+ myTopFramePosition = myCurrentStackFrame != null ? myCurrentStackFrame.getSourcePosition() : null;
myPaused.set(true);
- if (myCurrentPosition != null) {
- myDebuggerManager.setActiveSession(this, myCurrentPosition, false, getPositionIconRenderer(true));
+ if (myTopFramePosition != null) {
+ myDebuggerManager.setActiveSession(this, myTopFramePosition, false, getPositionIconRenderer(true));
}
- adjustMouseTrackingCounter(myCurrentPosition, 1);
+ adjustMouseTrackingCounter(myTopFramePosition, 1);
if (myShowTabOnSuspend.compareAndSet(true, false)) {
UIUtil.invokeLaterIfNeeded(new Runnable() {
@@ -810,6 +821,7 @@ public class XDebugSessionImpl implements XDebugSession {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
+ if (myProject.isDisposed()) return;
Editor editor = XDebuggerUtilImpl.createEditor(new OpenFileDescriptor(myProject, position.getFile()));
if (editor != null) {
JComponent component = editor.getComponent();
@@ -855,8 +867,8 @@ public class XDebugSessionImpl implements XDebugSession {
mySessionTab.detachFromSession();
}
- adjustMouseTrackingCounter(myCurrentPosition, -1);
- myCurrentPosition = null;
+ adjustMouseTrackingCounter(myTopFramePosition, -1);
+ myTopFramePosition = null;
myCurrentExecutionStack = null;
myCurrentStackFrame = null;
mySuspendContext = null;
@@ -970,6 +982,9 @@ public class XDebugSessionImpl implements XDebugSession {
public void setWatchExpressions(@NotNull XExpression[] watchExpressions) {
mySessionData.setWatchExpressions(watchExpressions);
myDebuggerManager.getWatchesManager().setWatches(getWatchesKey(), watchExpressions);
+ if (Registry.is("debugger.watches.in.variables")) {
+ rebuildViews();
+ }
}
XExpression[] getWatchExpressions() {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
index 6d09b8fd3128..2b84d05011c2 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerSmartStepIntoHandler.java
@@ -47,7 +47,7 @@ public class XDebuggerSmartStepIntoHandler extends XDebuggerSuspendedActionHandl
@Override
protected void perform(@NotNull XDebugSession session, DataContext dataContext) {
final XSmartStepIntoHandler<?> handler = session.getDebugProcess().getSmartStepIntoHandler();
- final XSourcePosition position = session.getCurrentPosition();
+ final XSourcePosition position = session.getTopFramePosition();
if (position == null || handler == null) return;
final FileEditor editor = FileEditorManager.getInstance(session.getProject()).getSelectedEditor(position.getFile());
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
index e2ce9ca7c63d..855abaaad74e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
@@ -36,6 +36,7 @@ import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.DocumentUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.XSourcePosition;
@@ -91,7 +92,7 @@ public class XLineBreakpointImpl<P extends XBreakpointProperties> extends XBreak
RangeHighlighterEx highlighter = myHighlighter;
if (highlighter != null &&
(!highlighter.isValid()
- || highlighter.getStartOffset() >= document.getTextLength()
+ || !DocumentUtil.isValidOffset(highlighter.getStartOffset(), document)
|| !Comparing.equal(highlighter.getTextAttributes(), attributes)
// it seems that this check is not needed - we always update line number from the highlighter
// and highlighter is removed on line and file change anyway
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
index 098b64052284..e88f54f24799 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java
@@ -261,7 +261,7 @@ public class XLineBreakpointManager {
|| mouseEvent.isMetaDown() || mouseEvent.isControlDown()
|| mouseEvent.getButton() != MouseEvent.BUTTON1
|| MarkupEditorFilterFactory.createIsDiffFilter().avaliableIn(editor)
- || e.getArea() != EditorMouseEventArea.LINE_MARKERS_AREA
+ || (e.getArea() != EditorMouseEventArea.LINE_MARKERS_AREA && e.getArea() != EditorMouseEventArea.FOLDING_OUTLINE_AREA)
|| ConsoleViewUtil.isConsoleViewEditor(editor)
||!isFromMyProject(editor)) {
return;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
index 36584d1105d4..de4d45f483bf 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java
@@ -122,6 +122,13 @@ public class XBreakpointActionsPanel<B extends XBreakpointBase<?,?,?>> extends X
}
}
+ JComponent getDefaultFocusComponent() {
+ if (myLogExpressionComboBox != null && myLogExpressionComboBox.getComboBox().isEnabled()) {
+ return myLogExpressionComboBox.getEditorComponent();
+ }
+ return null;
+ }
+
public void dispose() {
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
index 75cbb569ddfd..4e91c27f011d 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java
@@ -180,8 +180,15 @@ public class XLightBreakpointPropertiesPanel<B extends XBreakpointBase<?,?,?>> i
myMainPanel.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent event) {
- if (myConditionComboBox != null) {
- IdeFocusManager.findInstance().requestFocus(myConditionComboBox.getEditorComponent(), false);
+ JComponent compToFocus;
+ if (myConditionComboBox != null && myConditionComboBox.getComboBox().isEnabled()) {
+ compToFocus = myConditionComboBox.getEditorComponent();
+ }
+ else {
+ compToFocus = myActionsPanel.getDefaultFocusComponent();
+ }
+ if (compToFocus != null) {
+ IdeFocusManager.findInstance().requestFocus(compToFocus, false);
}
}
});
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
index 141a56c9b721..be44e2c01d2b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java
@@ -54,6 +54,7 @@ public class CodeFragmentInputComponent extends EvaluationInputComponent {
myMainPanel.add(editorPanel, BorderLayout.CENTER);
}
+ @NotNull
protected XDebuggerEditorBase getInputEditor() {
return myMultilineEditor;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
index c702cae00c6e..3803945f9598 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/EvaluationInputComponent.java
@@ -16,6 +16,7 @@
package com.intellij.xdebugger.impl.evaluate;
import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase;
+import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -33,6 +34,7 @@ public abstract class EvaluationInputComponent {
return myTitle;
}
+ @NotNull
protected abstract XDebuggerEditorBase getInputEditor();
public abstract void addComponent(JPanel contentPanel, JPanel resultPanel);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
index 15a8bf6aed84..45b140ddf8e8 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java
@@ -63,6 +63,7 @@ public class ExpressionInputComponent extends EvaluationInputComponent {
contentPanel.add(hint, BorderLayout.SOUTH);
}
+ @NotNull
protected XDebuggerEditorBase getInputEditor() {
return myExpressionComboBox;
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
index a3aa8ec43fc5..e73564095b21 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java
@@ -15,61 +15,214 @@
*/
package com.intellij.xdebugger.impl.evaluate;
+import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.EditorLinePainter;
import com.intellij.openapi.editor.LineExtensionInfo;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.Gray;
import com.intellij.ui.JBColor;
import com.intellij.ui.SimpleColoredText;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.impl.frame.XDebugView;
import com.intellij.xdebugger.impl.frame.XVariablesView;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueTextRendererImpl;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+import java.util.List;
/**
* @author Konstantin Bulenkov
*/
public class XDebuggerEditorLinePainter extends EditorLinePainter {
+ public static final Key<Map<Variable, VariableValue>> CACHE = Key.create("debug.inline.variables.cache");
@Override
public Collection<LineExtensionInfo> getLineExtensions(@NotNull Project project, @NotNull VirtualFile file, int lineNumber) {
if (!Registry.is("ide.debugger.inline")) {
return null;
}
- Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = project.getUserData(XVariablesView.DEBUG_VARIABLES);
- if (map != null) {
- Set<XValueNodeImpl> values = map.get(Pair.create(file, lineNumber));
- if (values != null && !values.isEmpty()) {
- ArrayList<LineExtensionInfo> result = new ArrayList<LineExtensionInfo>();
- for (XValueNodeImpl value : values) {
- SimpleColoredText text = new SimpleColoredText();
- XValueTextRendererImpl renderer = new XValueTextRendererImpl(text);
- final XValuePresentation presentation = value.getValuePresentation();
- if (presentation == null) continue;
+ final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = project.getUserData(XVariablesView.DEBUG_VARIABLES);
+ final Map<VirtualFile, Long> timestamps = project.getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS);
+ final Document doc = FileDocumentManager.getInstance().getDocument(file);
+
+ if (map == null || timestamps == null || doc == null) {
+ return null;
+ }
+
+ Map<Variable, VariableValue> oldValues = project.getUserData(CACHE);
+ if (oldValues == null) {
+ oldValues = new HashMap<Variable, VariableValue>();
+ project.putUserData(CACHE, oldValues);
+ }
+ final Long timestamp = timestamps.get(file);
+ if (timestamp == null || timestamp < doc.getModificationStamp()) {
+ return null;
+ }
+ Set<XValueNodeImpl> values = map.get(Pair.create(file, lineNumber));
+ if (values != null && !values.isEmpty()) {
+ final int bpLine = getCurrentBreakPointLine(values);
+ ArrayList<LineExtensionInfo> result = new ArrayList<LineExtensionInfo>();
+ for (XValueNodeImpl value : values) {
+ SimpleColoredText text = new SimpleColoredText();
+ XValueTextRendererImpl renderer = new XValueTextRendererImpl(text);
+ final XValuePresentation presentation = value.getValuePresentation();
+ if (presentation == null) continue;
+ try {
if (presentation instanceof XValueCompactPresentation) {
((XValueCompactPresentation)presentation).renderValue(renderer, value);
} else {
presentation.renderValue(renderer);
}
- final Color color = new JBColor(new Color(61, 128, 101), new Color(61, 128, 101));
- result.add(new LineExtensionInfo(" " + value.getName() + ": ", color, null, null, Font.PLAIN));
+ if (StringUtil.isEmpty(text.toString())) {
+ final String type = value.getValuePresentation().getType();
+ if (!StringUtil.isEmpty(type)) {
+ text.append(type, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+ }
+ }
+ } catch (Exception e) {
+ continue;
+ }
+ final Color color = bpLine == lineNumber ? new JBColor(Gray._180, new Color(147, 217, 186)) : getForeground();
+
+ final String name = value.getName();
+ if (StringUtil.isEmpty(text.toString())) {
+ continue;
+ }
+ result.add(new LineExtensionInfo(" " + name + ": ", color, null, null, Font.PLAIN));
+
+ Variable var = new Variable(name, lineNumber);
+ VariableValue variableValue = oldValues.get(var);
+ if (variableValue == null) {
+ variableValue = new VariableValue(text.toString(), null, value.hashCode());
+ oldValues.put(var, variableValue);
+ }
+ if (variableValue.valueNodeHashCode != value.hashCode()) {
+ variableValue.old = variableValue.actual;
+ variableValue.actual = text.toString();
+ variableValue.valueNodeHashCode = value.hashCode();
+ }
+
+ if (!variableValue.isChanged()) {
for (String s : text.getTexts()) {
result.add(new LineExtensionInfo(s, color, null, null, Font.PLAIN));
}
+ } else {
+ variableValue.produceChangedParts(result);
}
- return result;
}
+ return result;
}
return null;
}
+
+ private static int getCurrentBreakPointLine(Set<XValueNodeImpl> values) {
+ try {
+ final XValueNodeImpl node = values.iterator().next();
+ final XDebugSession session = XDebugView.getSession(node.getTree());
+ if (session != null) {
+ final XSourcePosition position = session.getCurrentPosition();
+ if (position != null) {
+ return position.getLine();
+ }
+ }
+ } catch (Exception ignore){}
+ return -1;
+ }
+
+ public static JBColor getForeground() {
+ return new JBColor(new Color(61, 128, 101), new Color(61, 128, 101));
+ }
+
+ public static JBColor getChangedForeground() {
+ return new JBColor(new Color(202, 128, 33), new Color(161, 131, 10));
+ }
+
+ static class Variable {
+ private int lineNumber;
+ private String name;
+
+ public Variable(String name, int lineNumber) {
+ this.lineNumber = lineNumber;
+ this.name = name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ Variable variable = (Variable)o;
+
+ if (lineNumber != variable.lineNumber) return false;
+ if (!name.equals(variable.name)) return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = lineNumber;
+ result = 31 * result + name.hashCode();
+ return result;
+ }
+ }
+
+ static class VariableValue {
+ private String actual;
+ private String old;
+ private int valueNodeHashCode;
+
+ public VariableValue(String actual, String old, int valueNodeHashCode) {
+ this.actual = actual;
+ this.old = old;
+ this.valueNodeHashCode = valueNodeHashCode;
+ }
+
+ public boolean isChanged() {
+ return old != null && !StringUtil.equals(actual, old);
+ }
+
+ public void produceChangedParts(List<LineExtensionInfo> result) {
+ if (isArray(actual) && isArray(old)) {
+ List<String> actualParts = getArrayParts(actual);
+ List<String> oldParts = getArrayParts(old);
+ result.add(new LineExtensionInfo("{", getForeground(), null, null, Font.PLAIN));
+ for (int i = 0; i < actualParts.size(); i++) {
+ if (i < oldParts.size() && StringUtil.equals(actualParts.get(i), oldParts.get(i))) {
+ result.add(new LineExtensionInfo(actualParts.get(i), getForeground(), null, null, Font.PLAIN));
+ } else {
+ result.add(new LineExtensionInfo(actualParts.get(i), getChangedForeground(), null, null, Font.BOLD));
+ }
+ if (i != actualParts.size() - 1) {
+ result.add(new LineExtensionInfo(", ", getForeground(), null, null, Font.PLAIN));
+ }
+ }
+ result.add(new LineExtensionInfo("}", getForeground(), null, null, Font.PLAIN));
+ return;
+ }
+
+ result.add(new LineExtensionInfo(actual, getChangedForeground(), null, null, Font.BOLD));
+ }
+
+ private static boolean isArray(String s) {
+ return s != null && s.startsWith("{") && s.endsWith("}");
+ }
+
+ private static List<String> getArrayParts(String array) {
+ return StringUtil.split(array.substring(1, array.length() - 1), ", ");
+ }
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
index 37da856156ea..74b3b5202dbd 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java
@@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.evaluate;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CustomShortcutSet;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
@@ -79,13 +80,23 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
mySession.addSessionListener(new XDebugSessionAdapter() {
@Override
public void sessionStopped() {
- SwingUtilities.invokeLater(new Runnable() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
close(CANCEL_EXIT_CODE);
}
});
}
+
+ @Override
+ public void stackFrameChanged() {
+ updateSourcePosition();
+ }
+
+ @Override
+ public void sessionPaused() {
+ updateSourcePosition();
+ }
}, myDisposable);
myTreePanel = new XDebuggerTreePanel(session.getProject(), editorsProvider, myDisposable, sourcePosition, XDebuggerActions.EVALUATE_DIALOG_TREE_POPUP_GROUP,
@@ -124,6 +135,15 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
init();
}
+ private void updateSourcePosition() {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ getInputEditor().setSourcePosition(mySession.getCurrentPosition());
+ }
+ });
+ }
+
@Override
protected void doOKAction() {
evaluate();
@@ -138,7 +158,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
super.actionPerformed(e);
if (myMode == EvaluationMode.EXPRESSION && ((e.getModifiers() & InputEvent.CTRL_MASK) != 0)) {
// add to watches
- XExpression expression = myInputComponent.getInputEditor().getExpression();
+ XExpression expression = getInputEditor().getExpression();
if (!XDebuggerUtilImpl.isEmptyExpression(expression)) {
XDebugSessionTab tab = ((XDebugSessionImpl)mySession).getSessionTab();
if (tab != null) {
@@ -179,7 +199,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
public XExpression getExpression() {
- return myInputComponent.getInputEditor().getExpression();
+ return getInputEditor().getExpression();
}
private static String getSwitchButtonText(EvaluationMode mode) {
@@ -205,12 +225,16 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
private void requestFocusInEditor() {
- JComponent preferredFocusedComponent = myInputComponent.getInputEditor().getPreferredFocusedComponent();
+ JComponent preferredFocusedComponent = getInputEditor().getPreferredFocusedComponent();
if (preferredFocusedComponent != null) {
IdeFocusManager.getInstance(mySession.getProject()).requestFocus(preferredFocusedComponent, true);
}
}
+ private XDebuggerEditorBase getInputEditor() {
+ return myInputComponent.getInputEditor();
+ }
+
private EvaluationInputComponent createInputComponent(EvaluationMode mode, XExpression text) {
final Project project = mySession.getProject();
text = XExpressionImpl.changeMode(text, mode);
@@ -223,7 +247,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
private void evaluate() {
- final XDebuggerEditorBase inputEditor = myInputComponent.getInputEditor();
+ final XDebuggerEditorBase inputEditor = getInputEditor();
int offset = -1;
//try to save caret position
@@ -262,7 +286,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
}
public void startEvaluation(@NotNull XDebuggerEvaluator.XEvaluationCallback evaluationCallback) {
- final XDebuggerEditorBase inputEditor = myInputComponent.getInputEditor();
+ final XDebuggerEditorBase inputEditor = getInputEditor();
inputEditor.saveTextInHistory();
XExpression expression = inputEditor.getExpression();
@@ -277,13 +301,13 @@ public class XDebuggerEvaluationDialog extends DialogWrapper {
@Override
public JComponent getPreferredFocusedComponent() {
- return myInputComponent.getInputEditor().getPreferredFocusedComponent();
+ return getInputEditor().getPreferredFocusedComponent();
}
private class SwitchModeAction extends AbstractAction {
@Override
public void actionPerformed(ActionEvent e) {
- XExpression text = myInputComponent.getInputEditor().getExpression();
+ XExpression text = getInputEditor().getExpression();
if (myMode == EvaluationMode.EXPRESSION) {
switchToMode(EvaluationMode.CODE_FRAGMENT, text);
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
index b98440b5d69f..9999ac015b77 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java
@@ -188,10 +188,10 @@ public class XFramesView extends XDebugView {
return toolbar;
}
- private StackFramesListBuilder getOrCreateBuilder(XExecutionStack executionStack) {
+ private StackFramesListBuilder getOrCreateBuilder(XExecutionStack executionStack, XDebugSession session) {
StackFramesListBuilder builder = myBuilders.get(executionStack);
if (builder == null) {
- builder = new StackFramesListBuilder(executionStack);
+ builder = new StackFramesListBuilder(executionStack, session);
myBuilders.put(executionStack, builder);
}
return builder;
@@ -244,7 +244,6 @@ public class XFramesView extends XDebugView {
}
myToolbar.setAddSeparatorFirst(!invisible);
updateFrames(activeExecutionStack, session);
- myListenersEnabled = true;
}
@Override
@@ -270,19 +269,14 @@ public class XFramesView extends XDebugView {
return;
}
if (mySelectedStack != null) {
- getOrCreateBuilder(mySelectedStack).stop();
+ getOrCreateBuilder(mySelectedStack, session).stop();
}
mySelectedStack = executionStack;
if (executionStack != null) {
- StackFramesListBuilder builder = getOrCreateBuilder(executionStack);
+ StackFramesListBuilder builder = getOrCreateBuilder(executionStack, session);
builder.initModel(myFramesList.getModel());
builder.start();
- XStackFrame topFrame = executionStack.getTopFrame();
- if (topFrame != null) {
- myFramesList.setSelectedValue(topFrame, true);
- session.setCurrentStackFrame(executionStack, topFrame);
- }
}
}
@@ -303,7 +297,7 @@ public class XFramesView extends XDebugView {
if (selected instanceof XStackFrame) {
XDebugSession session = getSession(e);
if (session != null) {
- session.setCurrentStackFrame(mySelectedStack, (XStackFrame)selected);
+ session.setCurrentStackFrame(mySelectedStack, (XStackFrame)selected, myFramesList.getSelectedIndex() == 0);
}
}
}
@@ -312,21 +306,15 @@ public class XFramesView extends XDebugView {
private XExecutionStack myExecutionStack;
private final List<XStackFrame> myStackFrames;
private String myErrorMessage;
- private int myNextFrameIndex;
+ private int myNextFrameIndex = 0;
private boolean myRunning;
private boolean myAllFramesLoaded;
+ private final XDebugSession mySession;
- private StackFramesListBuilder(final XExecutionStack executionStack) {
+ private StackFramesListBuilder(final XExecutionStack executionStack, XDebugSession session) {
myExecutionStack = executionStack;
+ mySession = session;
myStackFrames = new ArrayList<XStackFrame>();
- XStackFrame topFrame = executionStack.getTopFrame();
- if (topFrame != null) {
- myStackFrames.add(topFrame);
- myNextFrameIndex = 1;
- }
- else {
- myNextFrameIndex = 0;
- }
}
@Override
@@ -336,6 +324,9 @@ public class XFramesView extends XDebugView {
public void run() {
myStackFrames.addAll(stackFrames);
addFrameListElements(stackFrames, last);
+ if (myNextFrameIndex == 0) {
+ selectTopFrame();
+ }
myNextFrameIndex += stackFrames.size();
myAllFramesLoaded = last;
if (last) {
@@ -399,6 +390,15 @@ public class XFramesView extends XDebugView {
myRunning = false;
}
+ private void selectTopFrame() {
+ if (!myStackFrames.isEmpty() && mySelectedStack != null) {
+ XStackFrame topFrame = myStackFrames.get(0);
+ myFramesList.setSelectedValue(topFrame, true);
+ mySession.setCurrentStackFrame(mySelectedStack, topFrame, true);
+ myListenersEnabled = true;
+ }
+ }
+
@SuppressWarnings("unchecked")
public void initModel(final DefaultListModel model) {
model.removeAllElements();
@@ -411,6 +411,7 @@ public class XFramesView extends XDebugView {
else if (!myAllFramesLoaded) {
model.addElement(null);
}
+ selectTopFrame();
}
}
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
index df43b1147419..ea53645b57e5 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesView.java
@@ -36,7 +36,8 @@ import static com.intellij.xdebugger.impl.ui.tree.nodes.MessageTreeNode.createIn
* @author nik
*/
public class XVariablesView extends XVariablesViewBase {
- public static final Key<Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>> DEBUG_VARIABLES = Key.create("debug.frame");
+ public static final Key<Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>> DEBUG_VARIABLES = Key.create("debug.variables");
+ public static final Key<Map<VirtualFile, Long>> DEBUG_VARIABLES_TIMESTAMPS = Key.create("debug.variables.timestamps");
public XVariablesView(@NotNull XDebugSessionImpl session) {
super(session.getProject(), session.getDebugProcess().getEditorsProvider(), session.getValueMarkers());
@@ -69,6 +70,7 @@ public class XVariablesView extends XVariablesViewBase {
protected void clear() {
XDebuggerTree tree = getTree();
tree.getProject().putUserData(DEBUG_VARIABLES, null);
+ tree.getProject().putUserData(DEBUG_VARIABLES_TIMESTAMPS, null);
tree.setSourcePosition(null);
XDebuggerTreeNode node;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
index ace9938318df..d4bd27c30d9b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XVariablesViewBase.java
@@ -15,20 +15,42 @@
*/
package com.intellij.xdebugger.impl.frame;
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.codeInsight.hint.HintUtil;
import com.intellij.ide.dnd.DnDManager;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.event.SelectionEvent;
+import com.intellij.openapi.editor.event.SelectionListener;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
+import com.intellij.openapi.fileEditor.impl.text.PsiAwareTextEditorImpl;
import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.ui.SimpleColoredText;
import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
+import com.intellij.xdebugger.frame.XFullValueEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.frame.XValuePlace;
+import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeState;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XEvaluationCallbackBase;
import com.intellij.xdebugger.impl.ui.tree.nodes.XStackFrameNode;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodePresentationConfigurator;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,17 +73,84 @@ public abstract class XVariablesViewBase extends XDebugView {
DnDManager.getInstance().registerSource(myDebuggerTreePanel, myDebuggerTreePanel.getTree());
}
- protected void buildTreeAndRestoreState(@NotNull XStackFrame stackFrame) {
+ protected void buildTreeAndRestoreState(@NotNull final XStackFrame stackFrame) {
XDebuggerTree tree = myDebuggerTreePanel.getTree();
- tree.setSourcePosition(stackFrame.getSourcePosition());
+ final XSourcePosition position = stackFrame.getSourcePosition();
+ tree.setSourcePosition(position);
tree.setRoot(new XStackFrameNode(tree, stackFrame), false);
- tree.getProject().putUserData(XVariablesView.DEBUG_VARIABLES, new HashMap<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>());
+ final Project project = tree.getProject();
+ project.putUserData(XVariablesView.DEBUG_VARIABLES, new HashMap<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>>());
+ project.putUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS, new HashMap<VirtualFile, Long>());
Object newEqualityObject = stackFrame.getEqualityObject();
if (myFrameEqualityObject != null && newEqualityObject != null && myFrameEqualityObject.equals(newEqualityObject)
&& myTreeState != null) {
disposeTreeRestorer();
myTreeRestorer = myTreeState.restoreState(tree);
}
+ if (position != null && Registry.is("ide.debugger.inline")) {
+ final VirtualFile file = position.getFile();
+ final FileEditor fileEditor = FileEditorManagerEx.getInstanceEx(project).getSelectedEditor(file);
+ if (fileEditor instanceof PsiAwareTextEditorImpl) {
+ final Editor editor = ((PsiAwareTextEditorImpl)fileEditor).getEditor();
+ final SelectionListener listener = new SelectionListener() {
+ @Override
+ public void selectionChanged(SelectionEvent e) {
+ final String text = editor.getDocument().getText(e.getNewRange());
+ final XDebuggerEvaluator evaluator = stackFrame.getEvaluator();
+ if (evaluator != null && !StringUtil.isEmpty(text)
+ && !(text.contains("exec(") || text.contains("++") || text.contains("--") || text.contains("="))) {
+ evaluator.evaluate(text, new XEvaluationCallbackBase() {
+ @Override
+ public void evaluated(@NotNull XValue result) {
+ result.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
+ @Override
+ public void applyPresentation(@Nullable Icon icon,
+ @NotNull XValuePresentation valuePresenter,
+ boolean hasChildren) {
+ SimpleColoredText text = new SimpleColoredText();
+ XValueNodeImpl.buildText(valuePresenter, text, false);
+ SimpleColoredComponent component = HintUtil.createInformationComponent();
+ text.appendToComponent(component);
+ String str = text.toString();
+ if ("undefined".equals(str) || str.startsWith("Cannot find local variable")
+ || str.startsWith("Invalid expression")) {
+ return; //todo[kb] this is temporary solution
+ }
+ HintManager.getInstance().hideAllHints();
+ HintManager.getInstance().showInformationHint(editor, component);
+ }
+
+ @Override
+ public void setFullValueEvaluator(@NotNull XFullValueEvaluator fullValueEvaluator) {
+ }
+
+ @Override
+ public boolean isObsolete() {
+ return true;
+ }
+ }, XValuePlace.TOOLTIP);
+ }
+
+ @Override
+ public void errorOccurred(@NotNull String errorMessage) {
+ System.out.println(errorMessage);
+ }
+ }, position);
+ }
+ }
+ };
+ editor.getSelectionModel().addSelectionListener(listener);
+ Disposer.register(tree, new Disposable() {
+ @Override
+ public void dispose() {
+ final FileEditor fileEditor = FileEditorManagerEx.getInstanceEx(project).getSelectedEditor(file);
+ if (fileEditor instanceof PsiAwareTextEditorImpl) {
+ ((PsiAwareTextEditorImpl)fileEditor).getEditor().getSelectionModel().removeSelectionListener(listener);
+ }
+ }
+ });
+ }
+ }
}
protected void saveCurrentTreeState(@Nullable XStackFrame stackFrame) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
index 4d1f8e52d24f..1260cb3ff44a 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.form
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.xdebugger.impl.settings.GeneralConfigurableUi">
- <grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+ <grid id="27dc6" binding="rootPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
@@ -10,7 +10,7 @@
<children>
<component id="4b50" class="javax.swing.JCheckBox" binding="hideDebugWindowCheckBox">
<constraints>
- <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text resource-bundle="messages/XDebuggerBundle" key="setting.hide.window.label"/>
@@ -18,7 +18,7 @@
</component>
<vspacer id="8e2ed">
<constraints>
- <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+ <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
</constraints>
</vspacer>
<component id="fc652" class="javax.swing.JCheckBox" binding="focusApplicationOnBreakpointCheckBox" default-binding="true">
@@ -29,6 +29,14 @@
<text resource-bundle="messages/XDebuggerBundle" key="setting.focus.app.on.breakpoint.label"/>
</properties>
</component>
+ <component id="4c3e" class="javax.swing.JCheckBox" binding="myShowDebugWindowOnCheckBox" default-binding="true">
+ <constraints>
+ <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+ </constraints>
+ <properties>
+ <text resource-bundle="messages/XDebuggerBundle" key="settings.show.window.label"/>
+ </properties>
+ </component>
</children>
</grid>
</form>
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
index 273c5490e35d..bab2c88465ad 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/GeneralConfigurableUi.java
@@ -25,23 +25,27 @@ class GeneralConfigurableUi implements ConfigurableUi<XDebuggerGeneralSettings>
private JPanel rootPanel;
private JCheckBox hideDebugWindowCheckBox;
private JCheckBox focusApplicationOnBreakpointCheckBox;
+ private JCheckBox myShowDebugWindowOnCheckBox;
@Override
public void reset(@NotNull XDebuggerGeneralSettings settings) {
focusApplicationOnBreakpointCheckBox.setSelected(Registry.is("debugger.mayBringFrameToFrontOnBreakpoint"));
hideDebugWindowCheckBox.setSelected(settings.isHideDebuggerOnProcessTermination());
+ myShowDebugWindowOnCheckBox.setSelected(settings.isShowDebuggerOnBreakpoint());
}
@Override
public boolean isModified(@NotNull XDebuggerGeneralSettings settings) {
return focusApplicationOnBreakpointCheckBox.isSelected() != Registry.is("debugger.mayBringFrameToFrontOnBreakpoint") ||
- hideDebugWindowCheckBox.isSelected() != settings.isHideDebuggerOnProcessTermination();
+ hideDebugWindowCheckBox.isSelected() != settings.isHideDebuggerOnProcessTermination() ||
+ myShowDebugWindowOnCheckBox.isSelected() != settings.isShowDebuggerOnBreakpoint();
}
@Override
public void apply(@NotNull XDebuggerGeneralSettings settings) {
Registry.get("debugger.mayBringFrameToFrontOnBreakpoint").setValue(focusApplicationOnBreakpointCheckBox.isSelected());
settings.setHideDebuggerOnProcessTermination(hideDebugWindowCheckBox.isSelected());
+ settings.setShowDebuggerOnBreakpoint(myShowDebugWindowOnCheckBox.isSelected());
}
@NotNull
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
index 9720d9517c51..205c1c3948ed 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/settings/XDebuggerGeneralSettings.java
@@ -27,6 +27,7 @@ public class XDebuggerGeneralSettings {
private boolean myUnmuteOnStop = false;
private boolean hideDebuggerOnProcessTermination;
+ private boolean myShowDebuggerOnBreakpoint = true;
@Tag("evaluation-dialog-mode")
public EvaluationMode getEvaluationDialogMode() {
@@ -53,4 +54,12 @@ public class XDebuggerGeneralSettings {
public void setHideDebuggerOnProcessTermination(boolean hideDebuggerOnProcessTermination) {
this.hideDebuggerOnProcessTermination = hideDebuggerOnProcessTermination;
}
+
+ public boolean isShowDebuggerOnBreakpoint() {
+ return myShowDebuggerOnBreakpoint;
+ }
+
+ public void setShowDebuggerOnBreakpoint(boolean showDebuggerOnBreakpoint) {
+ this.myShowDebuggerOnBreakpoint = showDebuggerOnBreakpoint;
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java
new file mode 100644
index 000000000000..7041b24f07fc
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerCopyPastePreprocessor.java
@@ -0,0 +1,47 @@
+/*
+ * 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.xdebugger.impl.ui;
+
+import com.intellij.codeInsight.editorActions.CopyPastePreProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.RawText;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author egor
+ */
+public class DebuggerCopyPastePreprocessor implements CopyPastePreProcessor {
+ public static final Key<Boolean> REMOVE_NEWLINES_ON_PASTE = new Key<Boolean>("REMOVE_NEWLINES_ON_PASTE");
+
+ @Nullable
+ @Override
+ public String preprocessOnCopy(PsiFile file, int[] startOffsets, int[] endOffsets, String text) {
+ return null;
+ }
+
+ @NotNull
+ @Override
+ public String preprocessOnPaste(Project project, PsiFile file, Editor editor, String text, RawText rawText) {
+ if (editor.getUserData(REMOVE_NEWLINES_ON_PASTE) != null) {
+ return text.replace("\n", " ");
+ }
+ return text;
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
index 4c3766f23f5d..1a4505f6d85b 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java
@@ -227,6 +227,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
final Executor debugExecutor = DefaultDebugExecutor.getDebugExecutorInstance();
ExecutionEnvironment environment = getEnvironment();
if (environment != null) {
+ leftToolbar.add(ActionManager.getInstance().getAction(IdeActions.ACTION_RERUN));
List<AnAction> additionalRestartActions = session.getRestartActions();
if (!additionalRestartActions.isEmpty()) {
leftToolbar.addAll(additionalRestartActions);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
index 991036b7f438..61a499ccf4dd 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
@@ -59,7 +59,7 @@ public abstract class XDebuggerEditorBase {
private final XDebuggerEditorsProvider myDebuggerEditorsProvider;
@NotNull private final EvaluationMode myMode;
@Nullable private final String myHistoryId;
- private final XSourcePosition mySourcePosition;
+ @Nullable private XSourcePosition mySourcePosition;
private int myHistoryIndex;
private final JLabel myChooseFactory = new JLabel();
@@ -124,6 +124,13 @@ public abstract class XDebuggerEditorBase {
return panel;
}
+ public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
+ if (mySourcePosition != sourcePosition) {
+ mySourcePosition = sourcePosition;
+ setExpression(getExpression(), false);
+ }
+ }
+
@NotNull
public EvaluationMode getMode() {
return myMode;
@@ -137,10 +144,16 @@ public abstract class XDebuggerEditorBase {
protected abstract void doSetText(XExpression text);
public void setExpression(@Nullable XExpression text) {
+ setExpression(text, true);
+ }
+
+ private void setExpression(@Nullable XExpression text, boolean saveInHistory) {
if (text == null) {
text = getMode() == EvaluationMode.EXPRESSION ? XExpressionImpl.EMPTY_EXPRESSION : XExpressionImpl.EMPTY_CODE_FRAGMENT;
}
- saveTextInHistory(text);
+ if (saveInHistory) {
+ saveTextInHistory(text);
+ }
Language language = text.getLanguage();
if (language == null) {
if (mySourcePosition != null) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
index 051683b875c1..3039d2acda7f 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
@@ -17,9 +17,7 @@ package com.intellij.xdebugger.impl.ui;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.editor.event.DocumentListener;
+import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.EditorComboBoxEditor;
@@ -101,6 +99,11 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
}
super.setItem(createDocument(((XExpression)anObject)));
}
+
+ @Override
+ protected void onEditorCreate(EditorEx editor) {
+ editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
+ }
};
myEditor.getEditorComponent().setFontInheritedFromLAF(false);
myComboBox.setEditor(myEditor);
@@ -110,23 +113,6 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
}
@Override
- protected Document createDocument(XExpression text) {
- Document document = super.createDocument(text);
- document.addDocumentListener(REPLACE_NEWLINES_LISTENER);
- return document;
- }
-
- private static DocumentListener REPLACE_NEWLINES_LISTENER = new DocumentAdapter() {
- @Override
- public void documentChanged(DocumentEvent e) {
- String text = e.getNewFragment().toString();
- if (text.contains("\n")) {
- e.getDocument().replaceString(e.getOffset(), e.getOffset() + e.getNewLength(), text.replace('\n', ' '));
- }
- }
- };
-
- @Override
protected void onHistoryChanged() {
fillComboBox();
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
index aa3445b4b421..3f06418ac8ac 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java
@@ -71,7 +71,7 @@ public class XDebuggerMultilineEditor extends XDebuggerEditorBase {
@Override
public XExpression getExpression() {
- return XExpressionImpl.fromText(myEditorTextField.getText(), EvaluationMode.CODE_FRAGMENT);
+ return getEditorsProvider().createExpression(getProject(), myEditorTextField.getDocument(), myExpression.getLanguage(), EvaluationMode.CODE_FRAGMENT);
}
@Override
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java
new file mode 100644
index 000000000000..4c2962f7f576
--- /dev/null
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/ShowReferringObjectsAction.java
@@ -0,0 +1,51 @@
+/*
+ * 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.xdebugger.impl.ui.tree.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.xdebugger.XDebuggerBundle;
+import com.intellij.xdebugger.frame.XReferrersProvider;
+import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
+import com.intellij.xdebugger.impl.ui.tree.XInspectDialog;
+import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author egor
+ */
+public class ShowReferringObjectsAction extends XDebuggerTreeActionBase {
+
+ @Override
+ protected boolean isEnabled(@NotNull XValueNodeImpl node, @NotNull AnActionEvent e) {
+ return node.getValueContainer().getReferrersProvider() != null;
+ }
+
+ @Override
+ protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) {
+ XReferrersProvider referrersProvider = node.getValueContainer().getReferrersProvider();
+ if (referrersProvider != null) {
+ XDebuggerTree tree = XDebuggerTree.getTree(e.getDataContext());
+ XInspectDialog dialog = new XInspectDialog(tree.getProject(),
+ tree.getEditorsProvider(),
+ tree.getSourcePosition(),
+ nodeName,
+ referrersProvider.getReferringObjectsValue(),
+ tree.getValueMarkers());
+ dialog.setTitle(XDebuggerBundle.message("showReferring.dialog.title", nodeName));
+ dialog.show();
+ }
+ }
+}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
index 7c77bafc6553..211fddae40ea 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java
@@ -23,6 +23,7 @@ import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
import com.intellij.xdebugger.impl.frame.XWatchesView;
+import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import org.jetbrains.annotations.NotNull;
@@ -41,10 +42,7 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase {
if (watchesView != null) {
String expression = node.getValueContainer().getEvaluationExpression();
if (!StringUtil.isEmpty(expression)) {
- XExpressionImpl watchExpression = XExpressionImpl.fromText(expression);
- if (watchExpression != null) {
- watchesView.addWatchExpression(watchExpression, -1, true);
- }
+ watchesView.addWatchExpression(XExpressionImpl.fromText(expression), -1, true);
}
}
}
@@ -55,7 +53,10 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase {
if (view == null && project != null) {
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
if (session != null) {
- return ((XDebugSessionImpl)session).getSessionTab().getWatchesView();
+ XDebugSessionTab tab = ((XDebugSessionImpl)session).getSessionTab();
+ if (tab != null) {
+ return tab.getWatchesView();
+ }
}
}
return view;
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
index fa32ebcc4d75..b7b21560f438 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XStackFrameNode.java
@@ -15,7 +15,16 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XExpression;
+import com.intellij.xdebugger.evaluation.XDebuggerEvaluator;
import com.intellij.xdebugger.frame.XStackFrame;
+import com.intellij.xdebugger.frame.XValue;
+import com.intellij.xdebugger.frame.XValueChildrenList;
+import com.intellij.xdebugger.impl.XDebugSessionImpl;
+import com.intellij.xdebugger.impl.frame.XDebugView;
+import com.intellij.xdebugger.impl.ui.XDebugSessionData;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import org.jetbrains.annotations.NotNull;
@@ -27,4 +36,32 @@ public class XStackFrameNode extends XValueContainerNode<XStackFrame> {
super(tree, null, xStackFrame);
setLeaf(false);
}
+
+ @Override
+ public void startComputingChildren() {
+ if (Registry.is("debugger.watches.in.variables")) {
+ XDebugSession session = XDebugView.getSession(getTree());
+ XDebuggerEvaluator evaluator = getValueContainer().getEvaluator();
+ if (session != null && evaluator != null) {
+ XDebugSessionData data = ((XDebugSessionImpl)session).getSessionData();
+ XExpression[] expressions = data.getWatchExpressions();
+ for (final XExpression expression : expressions) {
+ evaluator.evaluate(expression, new XDebuggerEvaluator.XEvaluationCallback() {
+ @Override
+ public void evaluated(@NotNull XValue result) {
+ XValueChildrenList watches = new XValueChildrenList();
+ watches.add(expression.getExpression(), result);
+ addChildren(watches, false);
+ }
+
+ @Override
+ public void errorOccurred(@NotNull String errorMessage) {
+ // do not add anything
+ }
+ }, getValueContainer().getSourcePosition());
+ }
+ }
+ }
+ super.startComputingChildren();
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
index b9f90fe86b2b..a2fb3d51d253 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueContainerNode.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -15,6 +15,7 @@
*/
package com.intellij.xdebugger.impl.ui.tree.nodes;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.ObjectUtils;
import com.intellij.util.SmartList;
@@ -90,6 +91,11 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
XValueNodeImpl node = new XValueNodeImpl(myTree, XValueContainerNode.this, children.getName(i), children.getValue(i));
myValueChildren.add(node);
newChildren.add(node);
+
+ if (Registry.is("ide.debugger.inline") && "this".equals(node.getName())) { //todo[kb]: try to generify this dirty hack
+ //initialize "this" fields to display in inline view
+ node.getChildren();
+ }
}
myTopGroups = createGroupNodes(children.getTopGroups(), myTopGroups, newChildren);
myBottomGroups = createGroupNodes(children.getBottomGroups(), myBottomGroups, newChildren);
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
index 1f3d4c77e84f..292cca541699 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java
@@ -16,6 +16,8 @@
package com.intellij.xdebugger.impl.ui.tree.nodes;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
@@ -24,9 +26,11 @@ import com.intellij.ui.AppUIUtil;
import com.intellij.ui.ColoredTextContainer;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.NotNullFunction;
+import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.frame.*;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
+import com.intellij.xdebugger.impl.frame.XDebugView;
import com.intellij.xdebugger.impl.frame.XValueMarkers;
import com.intellij.xdebugger.impl.frame.XVariablesView;
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
@@ -120,26 +124,7 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
myValuePresentation = valuePresentation;
myRawValue = XValuePresentationUtil.computeValueText(valuePresentation);
if (Registry.is("ide.debugger.inline")) {
- try {
- getValueContainer().computeSourcePosition(new XNavigatable() {
- @Override
- public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
- Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
- if (map == null || sourcePosition == null) return;
- VirtualFile file = sourcePosition.getFile();
- int line = sourcePosition.getLine();
- Pair<VirtualFile, Integer> key = Pair.create(file, line);
- Set<XValueNodeImpl> presentations = map.get(key);
- if (presentations == null) {
- presentations = new LinkedHashSet<XValueNodeImpl>();
- map.put(key, presentations);
- }
- presentations.add(XValueNodeImpl.this);
- }
- });
- }
- catch (Exception ignore) {
- }
+ updateInlineDebuggerData();
}
updateText();
setLeaf(!hasChildren);
@@ -147,6 +132,39 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
myTree.nodeLoaded(this, myName);
}
+ public void updateInlineDebuggerData() {
+ try {
+ final XDebugSession session = XDebugView.getSession(getTree());
+ if (session != null) {
+ final XSourcePosition position = session.getCurrentPosition();
+ if (position != null) {
+ getValueContainer().computeSourcePosition(new XNearestSourcePosition() {
+ @Override
+ public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
+ final Map<Pair<VirtualFile, Integer>, Set<XValueNodeImpl>> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES);
+ final Map<VirtualFile, Long> timestamps = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS);
+ if (map == null || timestamps == null || sourcePosition == null) return;
+ VirtualFile file = sourcePosition.getFile();
+ final Document doc = FileDocumentManager.getInstance().getDocument(file);
+ if (doc == null) return;
+ int line = sourcePosition.getLine();
+ Pair<VirtualFile, Integer> key = Pair.create(file, line);
+ Set<XValueNodeImpl> presentations = map.get(key);
+ if (presentations == null) {
+ presentations = new LinkedHashSet<XValueNodeImpl>();
+ map.put(key, presentations);
+ timestamps.put(file, doc.getModificationStamp());
+ }
+ presentations.add(XValueNodeImpl.this);
+ }
+ });
+ }
+ }
+ }
+ catch (Exception ignore) {
+ }
+ }
+
@Override
public void setFullValueEvaluator(@NotNull final XFullValueEvaluator fullValueEvaluator) {
AppUIUtil.invokeOnEdt(new Runnable() {
@@ -179,7 +197,13 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
}
public static void buildText(@NotNull XValuePresentation valuePresenter, @NotNull ColoredTextContainer text) {
- XValuePresentationUtil.appendSeparator(text, valuePresenter.getSeparator());
+ buildText(valuePresenter, text, true);
+ }
+
+ public static void buildText(@NotNull XValuePresentation valuePresenter, @NotNull ColoredTextContainer text, boolean appendSeparator) {
+ if (appendSeparator) {
+ XValuePresentationUtil.appendSeparator(text, valuePresenter.getSeparator());
+ }
String type = valuePresenter.getType();
if (type != null) {
text.append("{" + type + "} ", XDebuggerUIConstants.TYPE_ATTRIBUTES);