integrate hotswap with automake mode
authorEugene Zhuravlev <jeka@intellij.com>
Mon, 30 Jan 2012 20:51:52 +0000 (21:51 +0100)
committerEugene Zhuravlev <jeka@intellij.com>
Mon, 30 Jan 2012 20:54:56 +0000 (21:54 +0100)
java/compiler/impl/src/com/intellij/compiler/CompileServerManager.java
java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerAdapter.java [new file with mode: 0644]
java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java
java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerListener.java
java/debugger/impl/src/com/intellij/debugger/impl/HotSwapManager.java
java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java

index 9e0e25ca9c94efeac34831ffe1b41c3756d547dd..05aaeb88f46d7b5f790f63e3f2604bab71660c8a 100644 (file)
@@ -27,7 +27,9 @@ import com.intellij.notification.Notification;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.PathMacros;
 import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.compiler.CompilationStatusListener;
 import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.compiler.CompilerTopics;
 import com.intellij.openapi.components.ApplicationComponent;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
@@ -666,18 +668,25 @@ public class CompileServerManager implements ApplicationComponent{
 
     @Override
     public boolean handleBuildEvent(JpsRemoteProto.Message.Response.BuildEvent event) {
-      final JpsRemoteProto.Message.Response.BuildEvent.Type type = event.getEventType();
-      if (type == JpsRemoteProto.Message.Response.BuildEvent.Type.FILES_GENERATED) {
-        for (JpsRemoteProto.Message.Response.BuildEvent.GeneratedFile gf : event.getGeneratedFilesList()) {
-        }
-      }
-      if (type == JpsRemoteProto.Message.Response.BuildEvent.Type.BUILD_COMPLETED) {
-        if (event.hasCompletionStatus()) {
-          myBuildStatus = event.getCompletionStatus();
-        }
-        return true;
+      switch (event.getEventType()) {
+        case BUILD_COMPLETED:
+          if (event.hasCompletionStatus()) {
+            myBuildStatus = event.getCompletionStatus();
+          }
+          return true;
+
+        case FILES_GENERATED:
+          final CompilationStatusListener publisher = myProject.getMessageBus().syncPublisher(CompilerTopics.COMPILATION_STATUS);
+          for (JpsRemoteProto.Message.Response.BuildEvent.GeneratedFile generatedFile : event.getGeneratedFilesList()) {
+            final String root = FileUtil.toSystemIndependentName(generatedFile.getOutputRoot());
+            final String relativePath = FileUtil.toSystemIndependentName(generatedFile.getRelativePath());
+            publisher.fileGenerated(root, relativePath);
+          }
+          return false;
+
+        default:
+          return false;
       }
-      return false;
     }
 
     @Override
index 7cf748d5bf3c8082dfd15c5b49fa9cf6ca5be3a4..b4d2692efc09a83d3135bf3695dc3c021ca351e7 100644 (file)
@@ -467,7 +467,7 @@ public class CompileDriver {
         final JpsRemoteProto.Message.Response.BuildEvent.Type eventType = event.getEventType();
         switch (eventType) {
           case BUILD_STARTED:
-            compileContext.getProgressIndicator().setText("Compilation started");
+            //compileContext.getProgressIndicator().setText("Compilation started");
             break;
           case FILES_GENERATED:
             final List<JpsRemoteProto.Message.Response.BuildEvent.GeneratedFile> generated = event.getGeneratedFilesList();
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerAdapter.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerAdapter.java
new file mode 100644 (file)
index 0000000..6fe296e
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2012 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.debugger.impl;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 1/30/12
+ */
+public class DebuggerManagerAdapter implements DebuggerManagerListener{
+  @Override
+  public void sessionCreated(DebuggerSession session) {
+  }
+
+  @Override
+  public void sessionAttached(DebuggerSession session) {
+  }
+
+  @Override
+  public void sessionDetached(DebuggerSession session) {
+  }
+
+  @Override
+  public void sessionRemoved(DebuggerSession session) {
+  }
+}
index db6febbfe4103ce347e3f18e75e54ef65388f73a..ab009da131392c60d0b8efc05d2da4cd00b683f3 100644 (file)
@@ -88,8 +88,13 @@ public class DebuggerManagerImpl extends DebuggerManagerEx {
       if(myDebuggerStateManager.myDebuggerSession == session) {
         myDebuggerStateManager.fireStateChanged(newContext, event);
       }
-
-      if(event == DebuggerSession.EVENT_DISPOSE) {
+      if (event == DebuggerSession.EVENT_ATTACHED) {
+        myDispatcher.getMulticaster().sessionAttached(session);
+      }
+      else if (event == DebuggerSession.EVENT_DETACHED) {
+        myDispatcher.getMulticaster().sessionDetached(session);
+      }
+      else if(event == DebuggerSession.EVENT_DISPOSE) {
         dispose(session);
         if(myDebuggerStateManager.myDebuggerSession == session) {
           myDebuggerStateManager.setState(DebuggerContextImpl.EMPTY_CONTEXT, DebuggerSession.STATE_DISPOSED, DebuggerSession.EVENT_DISPOSE, null);
index 61f7acb1273d78d6b4651d0b0694b3c38afdae65..ff4261fb8339b72d8a8498d6e9334c10ceea8549 100644 (file)
  */
 package com.intellij.debugger.impl;
 
-import com.intellij.debugger.impl.DebuggerSession;
-
 import java.util.EventListener;
 
 public interface DebuggerManagerListener extends EventListener{
   void sessionCreated(DebuggerSession session);
+  void sessionAttached(DebuggerSession session);
+  void sessionDetached(DebuggerSession session);
   void sessionRemoved(DebuggerSession session);
 }
index 9483a6668db2c05f5df9b1a4eb95f16d8d0a5e86..b7cd3f9ef9a1733f92c2c9ea661a5e78db540d58 100644 (file)
@@ -44,7 +44,7 @@ public class HotSwapManager extends AbstractProjectComponent {
 
   public HotSwapManager(Project project, DebuggerManagerEx manager) {
     super(project);
-    manager.addDebuggerManagerListener(new DebuggerManagerListener() {
+    manager.addDebuggerManagerListener(new DebuggerManagerAdapter() {
       public void sessionCreated(DebuggerSession session) {
         myTimeStamps.put(session, Long.valueOf(System.currentTimeMillis()));
       }
index ff744dbad2d4d6be2bd84f1d0844c0aca2064313..8bba2718311068732aa44e19b4eb176d5b7b4d33 100644 (file)
@@ -18,7 +18,9 @@ package com.intellij.debugger.ui;
 import com.intellij.CommonBundle;
 import com.intellij.compiler.CompilerWorkspaceConfiguration;
 import com.intellij.debugger.DebuggerBundle;
+import com.intellij.debugger.DebuggerManager;
 import com.intellij.debugger.DebuggerManagerEx;
+import com.intellij.debugger.impl.DebuggerManagerAdapter;
 import com.intellij.debugger.impl.DebuggerSession;
 import com.intellij.debugger.impl.HotSwapFile;
 import com.intellij.debugger.impl.HotSwapManager;
@@ -36,11 +38,13 @@ import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Ref;
 import com.intellij.psi.PsiDocumentManager;
 import com.intellij.util.PairFunction;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.messages.MessageBus;
+import com.intellij.util.messages.MessageBusConnection;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -59,47 +63,31 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
   private final Project myProject;
   private boolean myPerformHotswapAfterThisCompilation = true;
 
-  public HotSwapUIImpl(final Project project, MessageBus bus) {
+  public HotSwapUIImpl(final Project project, final MessageBus bus, DebuggerManager debugManager) {
     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>>());
+    ((DebuggerManagerEx)debugManager).addDebuggerManagerListener(new DebuggerManagerAdapter() {
+      private MessageBusConnection myConn = null;
+      private int mySessionCount = 0;
 
-      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);
+      @Override
+      public void sessionAttached(DebuggerSession session) {
+        if (mySessionCount++ == 0) {
+          myConn = bus.connect();
+          myConn.subscribe(CompilerTopics.COMPILATION_STATUS, new MyCompilationStatusListener());
         }
-        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;
-        }
-
-        if (errors == 0 && !aborted && myPerformHotswapAfterThisCompilation) {
-          for (HotSwapVetoableListener listener : myListeners) {
-            if (!listener.shouldHotSwap(compileContext)) {
-              return;
-            }
-          }
-
-          final List<DebuggerSession> sessions = new ArrayList<DebuggerSession>();
-          Collection<DebuggerSession> debuggerSessions = DebuggerManagerEx.getInstanceEx(myProject).getSessions();
-          for (final DebuggerSession debuggerSession : debuggerSessions) {
-            if (debuggerSession.isAttached() && debuggerSession.getProcess().canRedefineClasses()) {
-              sessions.add(debuggerSession);
-            }
-          }
-          if (!sessions.isEmpty()) {
-            hotSwapSessions(sessions, generated);
+      @Override
+      public void sessionDetached(DebuggerSession session) {
+        mySessionCount = Math.max(0, mySessionCount - 1);
+        if (mySessionCount == 0) {
+          final MessageBusConnection conn = myConn;
+          if (conn != null) {
+            Disposer.dispose(conn);
+            myConn = null;
           }
         }
-        myPerformHotswapAfterThisCompilation = true;
       }
     });
   }
@@ -253,9 +241,7 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
     }
     else {
       if(session.isAttached()) {
-        final List<DebuggerSession> sessions = new ArrayList<DebuggerSession>(1);
-        sessions.add(session);
-        hotSwapSessions(sessions, null);
+        hotSwapSessions(Collections.singletonList(session), null);
       }
     }
   }
@@ -267,4 +253,47 @@ public class HotSwapUIImpl extends HotSwapUI implements ProjectComponent{
   public void dontAskHotswapAfterThisCompilation() {
     myAskBeforeHotswap = false;
   }
+
+  private class MyCompilationStatusListener implements 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;
+      }
+
+      if (errors == 0 && !aborted && myPerformHotswapAfterThisCompilation) {
+        for (HotSwapVetoableListener listener : myListeners) {
+          if (!listener.shouldHotSwap(compileContext)) {
+            return;
+          }
+        }
+
+        final List<DebuggerSession> sessions = new ArrayList<DebuggerSession>();
+        Collection<DebuggerSession> debuggerSessions = DebuggerManagerEx.getInstanceEx(myProject).getSessions();
+        for (final DebuggerSession debuggerSession : debuggerSessions) {
+          if (debuggerSession.isAttached() && debuggerSession.getProcess().canRedefineClasses()) {
+            sessions.add(debuggerSession);
+          }
+        }
+        if (!sessions.isEmpty()) {
+          hotSwapSessions(sessions, generated);
+        }
+      }
+      myPerformHotswapAfterThisCompilation = true;
+    }
+  }
 }