IDEA-42954 Watches are not saved on restart of debug sessions

This commit is contained in:
Egor.Ushakov
2014-05-28 17:39:51 +04:00
parent d174c22e2d
commit 80eba2aaf9
8 changed files with 223 additions and 59 deletions
@@ -913,4 +913,9 @@ public class XDebugSessionImpl implements XDebugSession {
}
}
}
public void setWatchExpressions(@NotNull XExpression[] watchExpressions) {
mySessionData.setWatchExpressions(watchExpressions);
myDebuggerManager.getWatchesManager().setWatches(getSessionName(), watchExpressions);
}
}
@@ -68,6 +68,7 @@ public class XDebuggerManagerImpl extends XDebuggerManager
@NonNls public static final String COMPONENT_NAME = "XDebuggerManager";
private final Project myProject;
private final XBreakpointManagerImpl myBreakpointManager;
private final XDebuggerWatchesManager myWatchesManager;
private final Map<RunContentDescriptor, XDebugSessionData> mySessionData;
private final Map<RunContentDescriptor, XDebugSessionTab> mySessionTabs;
private final Map<ProcessHandler, XDebugSessionImpl> mySessions;
@@ -77,6 +78,7 @@ public class XDebuggerManagerImpl extends XDebuggerManager
public XDebuggerManagerImpl(final Project project, final StartupManager startupManager, MessageBus messageBus) {
myProject = project;
myBreakpointManager = new XBreakpointManagerImpl(project, this, startupManager);
myWatchesManager = new XDebuggerWatchesManager();
mySessionData = new THashMap<RunContentDescriptor, XDebugSessionData>();
mySessionTabs = new THashMap<RunContentDescriptor, XDebugSessionTab>();
mySessions = new LinkedHashMap<ProcessHandler, XDebugSessionImpl>();
@@ -144,6 +146,10 @@ public class XDebuggerManagerImpl extends XDebuggerManager
return myBreakpointManager;
}
public XDebuggerWatchesManager getWatchesManager() {
return myWatchesManager;
}
public Project getProject() {
return myProject;
}
@@ -199,7 +205,7 @@ public class XDebuggerManagerImpl extends XDebuggerManager
XDebugSessionData oldSessionData = contentToReuse != null ? mySessionData.get(contentToReuse) : null;
if (oldSessionData == null) {
oldSessionData = new XDebugSessionData();
oldSessionData = new XDebugSessionData(myWatchesManager.getWatches(session.getSessionName()));
}
// Perform custom configuration of session data for XDebugProcessConfiguratorStarter classes
@@ -310,12 +316,13 @@ public class XDebuggerManagerImpl extends XDebuggerManager
@Override
public XDebuggerState getState() {
return new XDebuggerState(myBreakpointManager.getState());
return new XDebuggerState(myBreakpointManager.getState(), myWatchesManager.getState());
}
@Override
public void loadState(final XDebuggerState state) {
myBreakpointManager.loadState(state.myBreakpointManagerState);
myWatchesManager.loadState(state.myWatchesManagerState);
}
public void showExecutionPosition() {
@@ -325,12 +332,14 @@ public class XDebuggerManagerImpl extends XDebuggerManager
@SuppressWarnings("UnusedDeclaration")
public static class XDebuggerState {
private XBreakpointManagerImpl.BreakpointManagerState myBreakpointManagerState;
private XDebuggerWatchesManager.WatchesManagerState myWatchesManagerState;
public XDebuggerState() {
}
public XDebuggerState(final XBreakpointManagerImpl.BreakpointManagerState breakpointManagerState) {
public XDebuggerState(final XBreakpointManagerImpl.BreakpointManagerState breakpointManagerState, XDebuggerWatchesManager.WatchesManagerState watchesManagerState) {
myBreakpointManagerState = breakpointManagerState;
myWatchesManagerState = watchesManagerState;
}
@Property(surroundWithTag = false)
@@ -341,5 +350,14 @@ public class XDebuggerManagerImpl extends XDebuggerManager
public void setBreakpointManagerState(final XBreakpointManagerImpl.BreakpointManagerState breakpointManagerState) {
myBreakpointManagerState = breakpointManagerState;
}
@Property(surroundWithTag = false)
public XDebuggerWatchesManager.WatchesManagerState getWatchesManagerState() {
return myWatchesManagerState;
}
public void setWatchesManagerState(XDebuggerWatchesManager.WatchesManagerState watchesManagerState) {
myWatchesManagerState = watchesManagerState;
}
}
}
@@ -0,0 +1,117 @@
/*
* 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;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.impl.breakpoints.XExpressionState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* @author egor
*/
public class XDebuggerWatchesManager implements PersistentStateComponent<XDebuggerWatchesManager.WatchesManagerState> {
private final Map<String, XExpression[]> watches = ContainerUtil.newConcurrentMap();
@NotNull
public XExpression[] getWatches(String confName) {
XExpression[] expressions = watches.get(confName);
if (expressions == null) {
return new XExpression[0];
}
return expressions;
}
public void setWatches(String configurationName, XExpression[] expressions) {
if (expressions != null && expressions.length > 0) {
watches.put(configurationName, expressions);
}
else {
watches.remove(configurationName);
}
}
@Nullable
@Override
public WatchesManagerState getState() {
WatchesManagerState state = new WatchesManagerState();
for (Map.Entry<String, XExpression[]> entry : watches.entrySet()) {
state.expressions.add(new ConfigurationState(entry.getKey(), entry.getValue()));
}
return state;
}
@Override
public void loadState(WatchesManagerState state) {
watches.clear();
if (state != null) {
for (ConfigurationState expressionState : state.expressions) {
WatchState[] states = expressionState.myExpressionStates;
XExpression[] expressions = new XExpression[states.length];
for (int i = 0; i < states.length; i++) {
expressions[i] = states[i].toXExpression();
}
watches.put(expressionState.myName, expressions);
}
}
}
@Tag("watches-manager")
public static class WatchesManagerState {
@Property(surroundWithTag = false)
@AbstractCollection(surroundWithTag = false)
public List<ConfigurationState> expressions = new ArrayList<ConfigurationState>();
}
@Tag("configuration")
public static class ConfigurationState {
@Attribute("name")
public String myName;
@Property(surroundWithTag = false)
@AbstractCollection(surroundWithTag = false)
public WatchState[] myExpressionStates;
public ConfigurationState() {
}
public ConfigurationState(String name, XExpression[] expressions) {
this.myName = name;
myExpressionStates = new WatchState[expressions.length];
for (int i = 0; i < expressions.length; i++) {
myExpressionStates[i] = new WatchState(expressions[i]);
}
}
}
@Tag("watch")
public static class WatchState extends XExpressionState {
public WatchState() {}
public WatchState(XExpression expression) {
super(expression);
}
}
}
@@ -15,7 +15,6 @@
*/
package com.intellij.xdebugger.impl.breakpoints;
import com.intellij.lang.Language;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.xmlb.annotations.*;
import com.intellij.xdebugger.XExpression;
@@ -192,7 +191,7 @@ public class BreakpointState<B extends XBreakpoint<P>, P extends XBreakpointProp
}
private Condition(boolean disabled, XExpression expression) {
super(disabled, expression.getExpression(), expression.getLanguage() != null ? expression.getLanguage().getID() : null, expression.getCustomInfo());
super(disabled, expression);
}
@Nullable
@@ -210,7 +209,7 @@ public class BreakpointState<B extends XBreakpoint<P>, P extends XBreakpointProp
}
private LogExpression(boolean disabled, XExpression expression) {
super(disabled, expression.getExpression(), expression.getLanguage() != null ? expression.getLanguage().getID() : null, expression.getCustomInfo());
super(disabled, expression);
}
@Nullable
@@ -221,42 +220,4 @@ public class BreakpointState<B extends XBreakpoint<P>, P extends XBreakpointProp
return new LogExpression(disabled, expression);
}
}
private static class XExpressionState {
@Attribute("disabled")
public boolean myDisabled;
@Attribute("expression")
public String myExpression;
@Attribute("language")
public String myLanguage;
@Attribute("custom")
public String myCustomInfo;
@Text
public String myOldExpression;
public XExpressionState() {
}
public XExpressionState(boolean disabled, @NotNull String expression, String language, String customInfo) {
myDisabled = disabled;
myExpression = expression;
myLanguage = language;
myCustomInfo = customInfo;
}
void checkConverted() {
if (myOldExpression != null) {
myExpression = myOldExpression;
myOldExpression = null;
}
}
public XExpression toXExpression() {
return new XExpressionImpl(myExpression, Language.findLanguageByID(myLanguage), myCustomInfo);
}
}
}
@@ -0,0 +1,71 @@
/*
* 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.breakpoints;
import com.intellij.lang.Language;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Text;
import com.intellij.xdebugger.XExpression;
import org.jetbrains.annotations.NotNull;
/**
* @author egor
*/
public class XExpressionState {
@Attribute("disabled")
public boolean myDisabled;
@Attribute("expression")
public String myExpression;
@Attribute("language")
public String myLanguage;
@Attribute("custom")
public String myCustomInfo;
@Text
public String myOldExpression;
public XExpressionState() {
}
public XExpressionState(boolean disabled, @NotNull String expression, String language, String customInfo) {
myDisabled = disabled;
myExpression = expression;
myLanguage = language;
myCustomInfo = customInfo;
}
public XExpressionState(boolean disabled, XExpression expression) {
this(disabled, expression.getExpression(), expression.getLanguage() != null ? expression.getLanguage().getID() : null, expression.getCustomInfo());
}
public XExpressionState(XExpression expression) {
this(false, expression);
}
void checkConverted() {
if (myOldExpression != null) {
myExpression = myOldExpression;
myOldExpression = null;
}
}
public XExpression toXExpression() {
return new XExpressionImpl(myExpression, Language.findLanguageByID(myLanguage), myCustomInfo);
}
}
@@ -30,14 +30,12 @@ import com.intellij.ui.border.CustomLineBorder;
import com.intellij.util.Alarm;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.frame.XStackFrame;
import com.intellij.xdebugger.impl.XDebugSessionImpl;
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
import com.intellij.xdebugger.impl.ui.XDebugSessionData;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel;
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeRestorer;
@@ -65,14 +63,12 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi
private XDebuggerTreeState myTreeState;
private XDebuggerTreeRestorer myTreeRestorer;
private final WatchesRootNode myRootNode;
@NotNull private final XDebugSession mySession;
private final XDebugSessionData mySessionData;
@NotNull private final XDebugSessionImpl mySession;
private final JPanel myDecoratedPanel;
private final CompositeDisposable myDisposables = new CompositeDisposable();
public XWatchesViewImpl(@NotNull final XDebugSession session, final @NotNull XDebugSessionData sessionData) {
public XWatchesViewImpl(@NotNull final XDebugSessionImpl session) {
mySession = session;
mySessionData = sessionData;
myTreePanel = new XDebuggerTreePanel(session.getProject(), session.getDebugProcess().getEditorsProvider(), this, null,
XDebuggerActions.WATCHES_TREE_POPUP_GROUP, ((XDebugSessionImpl)session).getValueMarkers());
@@ -86,7 +82,7 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi
actionManager.getAction(XDebuggerActions.XEDIT_WATCH).registerCustomShortcutSet(f2Shortcut, tree);
DnDManager.getInstance().registerTarget(this, tree);
myRootNode = new WatchesRootNode(tree, session, this, sessionData.getWatchExpressions());
myRootNode = new WatchesRootNode(tree, session, this, session.getSessionData().getWatchExpressions());
tree.setRoot(myRootNode, false);
final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTreePanel.getTree()).disableUpDownActions();
@@ -295,7 +291,7 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi
watchExpressions.add(child.getExpression());
}
}
mySessionData.setWatchExpressions(watchExpressions.toArray(new XExpression[watchExpressions.size()]));
mySession.setWatchExpressions(watchExpressions.toArray(new XExpression[watchExpressions.size()]));
}
@Override
@@ -16,7 +16,6 @@
package com.intellij.xdebugger.impl.ui;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.util.ArrayUtil;
import com.intellij.xdebugger.XExpression;
import org.jetbrains.annotations.NotNull;
@@ -26,6 +25,7 @@ import org.jetbrains.annotations.NotNull;
public class XDebugSessionData {
public static final DataKey<XDebugSessionData> DATA_KEY = DataKey.create("XDebugSessionData");
@NotNull
private XExpression[] myWatchExpressions;
private boolean myBreakpointsMuted = false;
@@ -33,10 +33,6 @@ public class XDebugSessionData {
myWatchExpressions = watchExpressions;
}
public XDebugSessionData() {
this(new XExpression[0]);
}
public void setWatchExpressions(@NotNull XExpression[] watchExpressions) {
myWatchExpressions = watchExpressions;
}
@@ -90,8 +90,8 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
return result;
}
private Content createWatchesContent(final XDebugSession session, final XDebugSessionData sessionData) {
myWatchesView = new XWatchesViewImpl(session, sessionData);
private Content createWatchesContent(final XDebugSessionImpl session, final XDebugSessionData sessionData) {
myWatchesView = new XWatchesViewImpl(session);
myViews.add(myWatchesView);
Content watchesContent = myUi.createContent(DebuggerContentInfo.WATCHES_CONTENT, myWatchesView.getMainPanel(),
XDebuggerBundle.message("debugger.session.tab.watches.title"), AllIcons.Debugger.Watches, null);