diff --git a/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java b/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java index 3e8ba31b8fb0..53fe18d9bc70 100644 --- a/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/JpsServerManager.java @@ -82,8 +82,10 @@ public class JpsServerManager implements ApplicationComponent{ ApplicationManager.getApplication().executeOnPooledThread(runnable); } }); + private final ProjectManager myProjectManager; - public JpsServerManager(ProjectManager projectManager) { + public JpsServerManager(final ProjectManager projectManager) { + myProjectManager = projectManager; final String systemPath = PathManager.getSystemPath(); File system = new File(systemPath); try { @@ -108,6 +110,40 @@ public class JpsServerManager implements ApplicationComponent{ return ApplicationManager.getApplication().getComponent(JpsServerManager.class); } + public void notifyFilesChanged(Collection paths) { + sendNotification(paths, false); + } + + public void notifyFilesDeleted(Collection paths) { + sendNotification(paths, true); + } + + private void sendNotification(Collection paths, final boolean isDeleted) { + final Client client = myClient; + if (client != null && client.isConnected()) { + final Project[] openProjects = myProjectManager.getOpenProjects(); + if (openProjects.length > 0) { + final Collection changed, deleted; + if (isDeleted) { + changed = Collections.emptyList(); + deleted = paths; + } + else { + changed = paths; + deleted = Collections.emptyList(); + } + for (Project project : openProjects) { + try { + client.sendFSEvent(project.getLocation(), changed, deleted); + } + catch (Exception e) { + LOG.info(e); + } + } + } + } + } + @Nullable public Future submitCompilationTask(final String projectId, final List modules, final boolean rebuild, final JpsServerResponseHandler handler) { final Ref futureRef = new Ref(null); @@ -309,8 +345,6 @@ public class JpsServerManager implements ApplicationComponent{ // commandLine.add((launcherUsed? "-J" : "") + "-D" + CharsetToolkit.FILE_ENCODING_PROPERTY + "=" + CharsetToolkit.getDefaultSystemCharset().name()); //} - - private Process launchServer(int port) throws ExecutionException { final Sdk projectJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk(); final GeneralCommandLine cmdLine = new GeneralCommandLine(); @@ -331,7 +365,7 @@ public class JpsServerManager implements ApplicationComponent{ // debugging cmdLine.addParameter("-XX:+HeapDumpOnOutOfMemoryError"); - //cmdLine.addParameter("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5008"); + cmdLine.addParameter("-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5008"); // javac's VM should use the same default locale that IDEA uses in order for javac to print messages in 'correct' language final String lang = System.getProperty("user.language"); diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java index 96d916ba499c..18b26577017d 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java @@ -18,6 +18,7 @@ package com.intellij.compiler.impl; import com.intellij.ProjectTopics; import com.intellij.compiler.CompilerConfiguration; import com.intellij.compiler.CompilerIOUtil; +import com.intellij.compiler.JpsServerManager; import com.intellij.compiler.make.MakeUtil; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; @@ -1298,9 +1299,13 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { System.out.println(message); } } + + final Set pathsToMark = new HashSet(); + processRecursively(eventFile, true, new FileProcessor() { public void execute(final VirtualFile file) { final String filePath = file.getPath(); + pathsToMark.add(filePath); try { final OutputFileInfo outputInfo = loadOutputInfo(file); if (outputInfo != null) { @@ -1360,6 +1365,10 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } } }); + + if (!pathsToMark.isEmpty()) { + JpsServerManager.getInstance().notifyFilesDeleted(pathsToMark); + } } public void beforeFileMovement(final VirtualFileMoveEvent event) { @@ -1367,10 +1376,14 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } private void markDirtyIfSource(final VirtualFile file) { + final Set pathsToMark = new HashSet(); processRecursively(file, false, new FileProcessor() { public void execute(final VirtualFile file) { final SourceFileInfo srcInfo = file.isValid()? loadSourceInfo(file) : null; if (srcInfo != null) { + + pathsToMark.add(file.getPath()); + for (int projectId : srcInfo.getProjectIds().toArray()) { addSourceForRecompilation(projectId, file, srcInfo); } @@ -1380,9 +1393,13 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } } }); + if (!pathsToMark.isEmpty()) { + JpsServerManager.getInstance().notifyFilesChanged(pathsToMark); + } } private void processNewFile(final VirtualFile file) { + final Set pathsToMark = new HashSet(); ApplicationManager.getApplication().runReadAction(new Runnable() { // need read action to ensure that the project was not disposed during the iteration over the project list public void run() { @@ -1396,6 +1413,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { final TranslatingCompiler[] translators = CompilerManager.getInstance(project).getCompilers(TranslatingCompiler.class); processRecursively(file, false, new FileProcessor() { public void execute(final VirtualFile file) { + pathsToMark.add(file.getPath()); if (isCompilable(file)) { loadInfoAndAddSourceForRecompilation(projectId, file); } @@ -1423,6 +1441,9 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } } }); + if (!pathsToMark.isEmpty()) { + JpsServerManager.getInstance().notifyFilesChanged(pathsToMark); + } } } diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java index 1fa9511d4b14..b91a88f58fde 100644 --- a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java +++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java @@ -15,10 +15,7 @@ */ package com.intellij.compiler.options; -import com.intellij.compiler.CompilerConfiguration; -import com.intellij.compiler.CompilerConfigurationImpl; -import com.intellij.compiler.CompilerWorkspaceConfiguration; -import com.intellij.compiler.MalformedPatternException; +import com.intellij.compiler.*; import com.intellij.compiler.impl.TranslatingCompilerFilesMonitor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.CompilerBundle; @@ -98,6 +95,9 @@ public class CompilerUIConfigurable implements SearchableConfigurable, Configura // this will schedule for compilation all files that might become compilable after resource patterns' changing TranslatingCompilerFilesMonitor.getInstance().scanSourcesForCompilableFiles(myProject); + if (!workspaceConfiguration.USE_COMPILE_SERVER) { + JpsServerManager.getInstance().shutdownServer(); + } } private static void applyResourcePatterns(String extensionString, final CompilerConfigurationImpl configuration) diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/ProtoUtil.java b/jps/jps-builders/src/org/jetbrains/jps/api/ProtoUtil.java index 0a1c2d3d6a87..db78983aeaba 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/ProtoUtil.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/ProtoUtil.java @@ -69,6 +69,14 @@ public class ProtoUtil { return JpsRemoteProto.Message.Request.newBuilder().setRequestType(JpsRemoteProto.Message.Request.Type.RELOAD_PROJECT_COMMAND).setReloadProjectCommand(builder.build()).build(); } + public static JpsRemoteProto.Message.Request createFSEvent(String projectPath, Collection changedPaths, Collection deletedPaths) { + final JpsRemoteProto.Message.Request.FSEvent.Builder builder = JpsRemoteProto.Message.Request.FSEvent.newBuilder(); + builder.setProjectId(projectPath); + builder.addAllChangedPaths(changedPaths); + builder.addAllDeletedPaths(deletedPaths); + return JpsRemoteProto.Message.Request.newBuilder().setRequestType(JpsRemoteProto.Message.Request.Type.FS_EVENT).setFsEvent(builder.build()).build(); + } + public static JpsRemoteProto.Message.Request createSetupRequest(final Map pathVars, List sdkAndLibs) { final JpsRemoteProto.Message.Request.SetupCommand.Builder cmdBuilder = JpsRemoteProto.Message.Request.SetupCommand.newBuilder(); diff --git a/jps/jps-builders/src/org/jetbrains/jps/client/Client.java b/jps/jps-builders/src/org/jetbrains/jps/client/Client.java index 53d5d2e8f50d..a835a34e3fcc 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/client/Client.java +++ b/jps/jps-builders/src/org/jetbrains/jps/client/Client.java @@ -112,6 +112,12 @@ public class Client { return sendRequest(ProtoUtil.createReloadProjectRequest(projectPaths), null); } + @NotNull + public RequestFuture sendFSEvent(String projectPath, Collection changedPaths, Collection deletedPaths) throws Exception { + checkConnected(); + return sendRequest(ProtoUtil.createFSEvent(projectPath, changedPaths, deletedPaths), null); + } + private void checkConnected() throws Exception { if (myState.get() != State.CONNECTED) { throw new Exception("Client not connected"); diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSState.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSState.java index dc5953aab5ac..20bf6bd2b098 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/incremental/FSState.java +++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/FSState.java @@ -25,9 +25,9 @@ public class FSState { public boolean markInitialScanPerformed(Module module, boolean forTests) { final Set map = forTests ? myInitialTestsScanPerformed : myInitialProductionScanPerformed; + return map.add(module); // todo: temp comment - //return map.add(module); - return true; + //return true; } public void beforeNextRoundStart() {