mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
event-based hotswap for compile server
This commit is contained in:
@@ -23,6 +23,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.AbstractProjectComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.OrderEnumerator;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
@@ -67,7 +68,7 @@ public class HotSwapManager extends AbstractProjectComponent {
|
||||
myTimeStamps.put(session, Long.valueOf(tStamp));
|
||||
}
|
||||
|
||||
public Map<String, HotSwapFile> getModifiedClasses(final DebuggerSession session, final HotSwapProgress progress) {
|
||||
public Map<String, HotSwapFile> scanForModifiedClasses(final DebuggerSession session, final HotSwapProgress progress) {
|
||||
DebuggerManagerThreadImpl.assertIsManagerThread();
|
||||
|
||||
final List<File> outputRoots = new ArrayList<File>();
|
||||
@@ -125,7 +126,39 @@ public class HotSwapManager extends AbstractProjectComponent {
|
||||
setTimeStamp(session, newSwapTime);
|
||||
}
|
||||
|
||||
public static Map<DebuggerSession, Map<String, HotSwapFile>> getModifiedClasses(final List<DebuggerSession> sessions, final HotSwapProgress swapProgress) {
|
||||
public static Map<DebuggerSession, Map<String, HotSwapFile>> findModifiedClasses(List<DebuggerSession> sessions, Map<String, List<String>> generatedPaths) {
|
||||
final Map<DebuggerSession, Map<String, HotSwapFile>> result = new java.util.HashMap<DebuggerSession, Map<String, HotSwapFile>>();
|
||||
List<Pair<DebuggerSession, Long>> sessionWithStamps = new ArrayList<Pair<DebuggerSession, Long>>();
|
||||
for (DebuggerSession session : sessions) {
|
||||
sessionWithStamps.add(new Pair<DebuggerSession, Long>(session, getInstance(session.getProject()).getTimeStamp(session)));
|
||||
}
|
||||
for (Map.Entry<String, List<String>> entry : generatedPaths.entrySet()) {
|
||||
final File root = new File(entry.getKey());
|
||||
for (String relativePath : entry.getValue()) {
|
||||
if (SystemInfo.isFileSystemCaseSensitive? StringUtil.endsWith(relativePath, CLASS_EXTENSION) : StringUtil.endsWithIgnoreCase(relativePath, CLASS_EXTENSION)) {
|
||||
final String qualifiedName = relativePath.substring(0, relativePath.length() - CLASS_EXTENSION.length()).replace('/', '.');
|
||||
final HotSwapFile hotswapFile = new HotSwapFile(new File(root, relativePath));
|
||||
final long fileStamp = hotswapFile.file.lastModified();
|
||||
|
||||
for (Pair<DebuggerSession, Long> pair : sessionWithStamps) {
|
||||
final DebuggerSession session = pair.first;
|
||||
if (fileStamp > pair.second) {
|
||||
Map<String, HotSwapFile> container = result.get(session);
|
||||
if (container == null) {
|
||||
container = new java.util.HashMap<String, HotSwapFile>();
|
||||
result.put(session, container);
|
||||
}
|
||||
container.put(qualifiedName, hotswapFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static Map<DebuggerSession, Map<String, HotSwapFile>> scanForModifiedClasses(final List<DebuggerSession> sessions, final HotSwapProgress swapProgress) {
|
||||
final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses = new HashMap<DebuggerSession, Map<String, HotSwapFile>>();
|
||||
|
||||
final MultiProcessCommand scanClassesCommand = new MultiProcessCommand();
|
||||
@@ -141,7 +174,7 @@ public class HotSwapManager extends AbstractProjectComponent {
|
||||
scanClassesCommand.addCommand(debuggerSession.getProcess(), new DebuggerCommandImpl() {
|
||||
protected void action() throws Exception {
|
||||
swapProgress.setDebuggerSession(debuggerSession);
|
||||
final Map<String, HotSwapFile> sessionClasses = getInstance(swapProgress.getProject()).getModifiedClasses(debuggerSession, swapProgress);
|
||||
final Map<String, HotSwapFile> sessionClasses = getInstance(swapProgress.getProject()).scanForModifiedClasses(debuggerSession, swapProgress);
|
||||
if (!sessionClasses.isEmpty()) {
|
||||
modifiedClasses.put(debuggerSession, sessionClasses);
|
||||
}
|
||||
|
||||
@@ -41,12 +41,11 @@ import com.intellij.util.PairFunction;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* User: lex
|
||||
@@ -62,7 +61,21 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
|
||||
public HotSwapUIImpl(final Project project, MessageBus bus) {
|
||||
myProject = project;
|
||||
bus.connect().subscribe(CompilerTopics.COMPILATION_STATUS, new CompilationStatusListener() {
|
||||
|
||||
private final AtomicReference<Map<String, List<String>>> myGeneratedPaths = new AtomicReference<Map<String, List<String>>>(new HashMap<String, List<String>>());
|
||||
|
||||
public void fileGenerated(String outputRoot, String relativePath) {
|
||||
final Map<String, List<String>> map = myGeneratedPaths.get();
|
||||
List<String> paths = map.get(outputRoot);
|
||||
if (paths == null) {
|
||||
paths = new ArrayList<String>();
|
||||
map.put(outputRoot, paths);
|
||||
}
|
||||
paths.add(relativePath);
|
||||
}
|
||||
|
||||
public void compilationFinished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
|
||||
final Map<String, List<String>> generated = myGeneratedPaths.getAndSet(new HashMap<String, List<String>>());
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
@@ -82,7 +95,7 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
|
||||
}
|
||||
}
|
||||
if (!sessions.isEmpty()) {
|
||||
hotSwapSessions(sessions);
|
||||
hotSwapSessions(sessions, generated);
|
||||
}
|
||||
}
|
||||
myPerformHotswapAfterThisCompilation = true;
|
||||
@@ -129,7 +142,7 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
|
||||
return false;
|
||||
}
|
||||
|
||||
private void hotSwapSessions(final List<DebuggerSession> sessions) {
|
||||
private void hotSwapSessions(final List<DebuggerSession> sessions, @Nullable final Map<String, List<String>> generatedPaths) {
|
||||
final boolean shouldAskBeforeHotswap = myAskBeforeHotswap;
|
||||
myAskBeforeHotswap = true;
|
||||
|
||||
@@ -148,7 +161,7 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
|
||||
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
public void run() {
|
||||
final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses = getModifiedClasses(findClassesProgress, sessions);
|
||||
final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses = generatedPaths == null? scanForModifiedClassesWithProgress(sessions, findClassesProgress) : HotSwapManager.findModifiedClasses(sessions, generatedPaths);
|
||||
|
||||
final Application application = ApplicationManager.getApplication();
|
||||
if (modifiedClasses.isEmpty()) {
|
||||
@@ -179,7 +192,7 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
|
||||
@Override
|
||||
public Integer fun(Integer exitCode, JCheckBox cb) {
|
||||
settings.HOTSWAP_HANG_WARNING_ENABLED = !cb.isSelected();
|
||||
return exitCode == DialogWrapper.OK_EXIT_CODE? exitCode : DialogWrapper.CANCEL_EXIT_CODE;
|
||||
return exitCode == DialogWrapper.OK_EXIT_CODE ? exitCode : DialogWrapper.CANCEL_EXIT_CODE;
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -203,6 +216,21 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
|
||||
});
|
||||
}
|
||||
|
||||
private static Map<DebuggerSession, Map<String, HotSwapFile>> scanForModifiedClassesWithProgress(final List<DebuggerSession> sessions, final HotSwapProgressImpl progress) {
|
||||
final Ref<Map<DebuggerSession, Map<String, HotSwapFile>>> result = Ref.create(null);
|
||||
ProgressManager.getInstance().runProcess(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
result.set(HotSwapManager.scanForModifiedClasses(sessions, progress));
|
||||
}
|
||||
finally {
|
||||
progress.finished();
|
||||
}
|
||||
}
|
||||
}, progress.getProgressIndicator());
|
||||
return result.get();
|
||||
}
|
||||
|
||||
private static void reloadModifiedClasses(final Map<DebuggerSession, Map<String, HotSwapFile>> modifiedClasses, final HotSwapProgressImpl progress) {
|
||||
ProgressManager.getInstance().runProcess(new Runnable() {
|
||||
public void run() {
|
||||
@@ -212,18 +240,6 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
|
||||
}, progress.getProgressIndicator());
|
||||
}
|
||||
|
||||
private static Map<DebuggerSession, Map<String, HotSwapFile>> getModifiedClasses(final HotSwapProgressImpl swapProgress, final List<DebuggerSession> sessions) {
|
||||
final Ref<Map<DebuggerSession, Map<String, HotSwapFile>>> modifiedClasses = Ref.create(null);
|
||||
ProgressManager.getInstance().runProcess(new Runnable() {
|
||||
public void run() {
|
||||
modifiedClasses.set(HotSwapManager.getModifiedClasses(sessions, swapProgress));
|
||||
swapProgress.finished();
|
||||
|
||||
}
|
||||
}, swapProgress.getProgressIndicator());
|
||||
return modifiedClasses.get();
|
||||
}
|
||||
|
||||
public void reloadChangedClasses(final DebuggerSession session, boolean compileBeforeHotswap) {
|
||||
dontAskHotswapAfterThisCompilation();
|
||||
if (compileBeforeHotswap) {
|
||||
@@ -233,7 +249,7 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
|
||||
if(session.isAttached()) {
|
||||
final List<DebuggerSession> sessions = new ArrayList<DebuggerSession>(1);
|
||||
sessions.add(session);
|
||||
hotSwapSessions(sessions);
|
||||
hotSwapSessions(sessions, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user