hotswap: do not 'forget' about changed classes if hotswap was canceled by user

This commit is contained in:
Eugene Zhuravlev
2012-06-21 17:11:44 +02:00
parent 0e0ac3219b
commit 84b283d1af
4 changed files with 57 additions and 22 deletions
@@ -64,10 +64,7 @@ import com.sun.jdi.request.EventRequest;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
public class DebuggerSession implements AbstractDebuggerSession {
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.DebuggerSession");
@@ -195,6 +192,21 @@ public class DebuggerSession implements AbstractDebuggerSession {
return myDebugProcess;
}
private final Map<String, HotSwapFile> myDelayedHotswapFiles = new HashMap<String, HotSwapFile>();
public void addHotswapFiles(Map<String, HotSwapFile> files) {
myDelayedHotswapFiles.putAll(files);
}
@NotNull
public Map<String, HotSwapFile> getHotswapFiles() {
return Collections.unmodifiableMap(myDelayedHotswapFiles);
}
public void clearHotswapFiles() {
myDelayedHotswapFiles.clear();
}
private static class DebuggerSessionState {
final int myState;
final String myDescription;
@@ -35,6 +35,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -154,10 +155,11 @@ public class HotSwapManager extends AbstractProjectComponent {
return project.getComponent(HotSwapManager.class);
}
private void reloadClasses(DebuggerSession session, Map<String, HotSwapFile> classesToReload, HotSwapProgress progress) {
private void reloadClasses(DebuggerSession session, HotSwapProgress progress) {
final long newSwapTime = System.currentTimeMillis();
new ReloadClassesWorker(session, progress).reloadClasses(classesToReload);
new ReloadClassesWorker(session, progress).reloadClasses();
setTimeStamp(session, newSwapTime);
session.clearHotswapFiles();
}
public static Map<DebuggerSession, Map<String, HotSwapFile>> findModifiedClasses(List<DebuggerSession> sessions, Map<String, List<String>> generatedPaths) {
@@ -223,7 +225,7 @@ public class HotSwapManager extends AbstractProjectComponent {
return swapProgress.isCancelled() ? new HashMap<DebuggerSession, Map<String, HotSwapFile>>() : modifiedClasses;
}
public static void reloadModifiedClasses(final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses, final HotSwapProgress reloadClassesProgress) {
public static void reloadModifiedClasses(final Collection<DebuggerSession> sessions, final HotSwapProgress reloadClassesProgress) {
final MultiProcessCommand reloadClassesCommand = new MultiProcessCommand();
reloadClassesProgress.setCancelWorker(new Runnable() {
@@ -232,13 +234,11 @@ public class HotSwapManager extends AbstractProjectComponent {
}
});
for (final DebuggerSession debuggerSession : modifiedClasses.keySet()) {
for (final DebuggerSession debuggerSession : sessions) {
reloadClassesCommand.addCommand(debuggerSession.getProcess(), new DebuggerCommandImpl() {
protected void action() throws Exception {
reloadClassesProgress.setDebuggerSession(debuggerSession);
getInstance(reloadClassesProgress.getProject()).reloadClasses(
debuggerSession, modifiedClasses.get(debuggerSession), reloadClassesProgress
);
getInstance(reloadClassesProgress.getProject()).reloadClasses(debuggerSession, reloadClassesProgress);
}
});
}
@@ -32,7 +32,10 @@ import com.sun.jdi.ReferenceType;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author lex
@@ -87,10 +90,12 @@ class ReloadClassesWorker {
}
}
public void reloadClasses(final Map<String, HotSwapFile> modifiedClasses) {
public void reloadClasses() {
DebuggerManagerThreadImpl.assertIsManagerThread();
if(modifiedClasses == null || modifiedClasses.size() == 0) {
final Map<String, HotSwapFile> modifiedClasses = myDebuggerSession.getHotswapFiles();
if(modifiedClasses.isEmpty()) {
myProgress.addMessage(myDebuggerSession, MessageCategory.INFORMATION, DebuggerBundle.message("status.hotswap.loaded.classes.up.to.date"));
return;
}
@@ -153,17 +153,35 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses = shouldPerformScan?
// todo: rewrite scan from VFS into java.io.File
final Map<DebuggerSession, Map<String, HotSwapFile>> newlyModifiedClasses = shouldPerformScan?
scanForModifiedClassesWithProgress(sessions, findClassesProgress, !isOutOfProcessMode) :
HotSwapManager.findModifiedClasses(sessions, generatedPaths);
final Application application = ApplicationManager.getApplication();
if (modifiedClasses.isEmpty()) {
for (Map.Entry<DebuggerSession, Map<String, HotSwapFile>> entry : newlyModifiedClasses.entrySet()) {
final DebuggerSession session = entry.getKey();
if (shouldPerformScan) {
session.clearHotswapFiles();
}
session.addHotswapFiles(entry.getValue());
}
boolean hasFilesToReload = false;
for (DebuggerSession session : sessions) {
if (!session.getHotswapFiles().isEmpty()) {
hasFilesToReload = true;
break;
}
}
if (!hasFilesToReload) {
final String message = DebuggerBundle.message("status.hotswap.uptodate");
HotSwapProgressImpl.NOTIFICATION_GROUP.createNotification(message, NotificationType.INFORMATION).notify(myProject);
return;
}
final Set<DebuggerSession> sessionsToReload = new HashSet<DebuggerSession>(sessions);
final Application application = ApplicationManager.getApplication();
application.invokeLater(new Runnable() {
public void run() {
if (shouldAskBeforeHotswap && !DebuggerSettings.RUN_HOTSWAP_ALWAYS.equals(runHotswap)) {
@@ -172,7 +190,7 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
if (!dialog.isOK()) {
return;
}
modifiedClasses.keySet().retainAll(dialog.getSessionsToReload());
sessionsToReload.retainAll(dialog.getSessionsToReload());
}
else {
if (shouldDisplayHangWarning) {
@@ -196,11 +214,11 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
}
}
if (!modifiedClasses.isEmpty()) {
if (!sessionsToReload.isEmpty()) {
final HotSwapProgressImpl progress = new HotSwapProgressImpl(myProject);
application.executeOnPooledThread(new Runnable() {
public void run() {
reloadModifiedClasses(modifiedClasses, progress);
reloadModifiedClasses(sessionsToReload, progress);
}
});
}
@@ -225,10 +243,10 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
return result.get();
}
private static void reloadModifiedClasses(final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses, final HotSwapProgressImpl progress) {
private static void reloadModifiedClasses(final Collection<DebuggerSession> sessions, final HotSwapProgressImpl progress) {
ProgressManager.getInstance().runProcess(new Runnable() {
public void run() {
HotSwapManager.reloadModifiedClasses(modifiedClasses, progress);
HotSwapManager.reloadModifiedClasses(sessions, progress);
progress.finished();
}
}, progress.getProgressIndicator());