diff options
Diffstat (limited to 'java/compiler/impl/src/com/intellij/compiler')
5 files changed, 186 insertions, 94 deletions
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java index c9e9ce31020a..f57753ef7afc 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java @@ -55,7 +55,7 @@ import java.util.*; public class CompileContextImpl extends UserDataHolderBase implements CompileContextEx { private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileContextImpl"); private final Project myProject; - private final CompilerTask myTask; + private final CompilerTask myBuildSession; private final Map<CompilerMessageCategory, Collection<CompilerMessage>> myMessages = new EnumMap<CompilerMessageCategory, Collection<CompilerMessage>>(CompilerMessageCategory.class); private final boolean myShouldUpdateProblemsView; private CompileScope myCompileScope; @@ -77,7 +77,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon CompileScope compileScope, boolean isMake, boolean isRebuild) { myProject = project; - myTask = compilerSession; + myBuildSession = compilerSession; myCompileScope = compileScope; myMake = isMake; myIsRebuild = isRebuild; @@ -99,6 +99,10 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon myShouldUpdateProblemsView = workspaceConfig.MAKE_PROJECT_ON_SAVE; } + public CompilerTask getBuildSession() { + return myBuildSession; + } + public boolean shouldUpdateProblemsView() { return myShouldUpdateProblemsView; } @@ -154,7 +158,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon myMessages.put(msg.getCategory(), messages); } if (messages.add(msg)) { - myTask.addMessage(msg); + myBuildSession.addMessage(msg); } if (myShouldUpdateProblemsView && msg.getCategory() == CompilerMessageCategory.ERROR) { ProblemsView.SERVICE.getInstance(myProject).addMessage(msg, mySessionId); @@ -200,7 +204,7 @@ public class CompileContextImpl extends UserDataHolderBase implements CompileCon } public ProgressIndicator getProgressIndicator() { - return myTask.getIndicator(); + return myBuildSession.getIndicator(); } public Module getModuleByFile(VirtualFile file) { diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java index 406d16574955..c40edf0f595c 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -28,8 +28,9 @@ import com.intellij.compiler.ModuleCompilerUtil; import com.intellij.compiler.ProblemsView; import com.intellij.compiler.progress.CompilerTask; import com.intellij.compiler.server.BuildManager; -import com.intellij.compiler.server.CustomBuilderMessageHandler; import com.intellij.compiler.server.DefaultMessageHandler; +import com.intellij.notification.Notification; +import com.intellij.notification.NotificationListener; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.compiler.*; import com.intellij.openapi.compiler.ex.CompilerPathsEx; @@ -54,10 +55,7 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.openapi.wm.StatusBar; -import com.intellij.openapi.wm.ToolWindowId; -import com.intellij.openapi.wm.ToolWindowManager; -import com.intellij.openapi.wm.WindowManager; +import com.intellij.openapi.wm.*; import com.intellij.packaging.artifacts.Artifact; import com.intellij.packaging.impl.compiler.ArtifactCompilerUtil; import com.intellij.packaging.impl.compiler.ArtifactsCompiler; @@ -69,6 +67,7 @@ import com.intellij.util.ThrowableRunnable; import com.intellij.util.containers.HashMap; import com.intellij.util.containers.MultiMap; import com.intellij.util.messages.MessageBus; +import com.intellij.util.text.DateFormatUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -80,7 +79,9 @@ import org.jetbrains.jps.api.RequestFuture; import org.jetbrains.jps.model.java.JavaSourceRootType; import javax.swing.*; +import javax.swing.event.HyperlinkEvent; import java.io.File; +import java.lang.ref.WeakReference; import java.util.*; import java.util.concurrent.TimeUnit; @@ -340,13 +341,6 @@ public class CompileDriver { } compileContext.putUserDataIfAbsent(COMPILE_SERVER_BUILD_STATUS, status); break; - case CUSTOM_BUILDER_MESSAGE: - if (event.hasCustomBuilderMessage()) { - CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.CustomBuilderMessage message = event.getCustomBuilderMessage(); - messageBus.syncPublisher(CustomBuilderMessageHandler.TOPIC).messageReceived(message.getBuilderId(), message.getMessageType(), - message.getMessageText()); - } - break; } } }); @@ -510,9 +504,24 @@ public class CompileDriver { if (duration > ONE_MINUTE_MS && CompilerWorkspaceConfiguration.getInstance(myProject).DISPLAY_NOTIFICATION_POPUP) { ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType, statusMessage); } - CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, messageType).notify(myProject); + + final String wrappedMessage = _status != ExitStatus.UP_TO_DATE? "<a href='#'>" + statusMessage + "</a>" : statusMessage; + final Notification notification = CompilerManager.NOTIFICATION_GROUP.createNotification( + "", wrappedMessage, + messageType.toNotificationType(), + new MessagesActivationListener(compileContext) + ); + compileContext.getBuildSession().registerCloseAction(new Runnable() { + @Override + public void run() { + notification.expire(); + } + }); + notification.notify(myProject); + if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) { - compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1); + final String msg = DateFormatUtil.formatDateTime(new Date()) + " - " + statusMessage; + compileContext.addMessage(CompilerMessageCategory.INFORMATION, msg, null, -1, -1); } } } @@ -793,4 +802,28 @@ public class CompileDriver { private void showConfigurationDialog(String moduleNameToSelect, String tabNameToSelect) { ProjectSettingsService.getInstance(myProject).showModuleConfigurationDialog(moduleNameToSelect, tabNameToSelect); } + + private static class MessagesActivationListener extends NotificationListener.Adapter { + private final WeakReference<Project> myProjectRef; + private final Object myContentId; + + public MessagesActivationListener(CompileContextImpl compileContext) { + myProjectRef = new WeakReference<Project>(compileContext.getProject()); + myContentId = compileContext.getBuildSession().getContentId(); + } + + @Override + protected void hyperlinkActivated(@NotNull Notification notification, @NotNull HyperlinkEvent e) { + final Project project = myProjectRef.get(); + if (project != null && !project.isDisposed() && CompilerTask.showCompilerContent(project, myContentId)) { + final ToolWindow tw = ToolWindowManager.getInstance(project).getToolWindow(ToolWindowId.MESSAGES_WINDOW); + if (tw != null) { + tw.activate(null, false); + } + } + else { + notification.expire(); + } + } + } } diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java index f568f2d06364..2f9f023bc52a 100644 --- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java +++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java @@ -22,12 +22,11 @@ package com.intellij.compiler.progress; import com.intellij.compiler.CompilerManagerImpl; -import com.intellij.compiler.CompilerMessageImpl; import com.intellij.compiler.impl.CompilerErrorTreeView; import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel; import com.intellij.ide.errorTreeView.impl.ErrorTreeViewConfiguration; import com.intellij.ide.impl.ProjectUtil; -import com.intellij.openapi.application.Application; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.compiler.*; @@ -42,6 +41,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerListener; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; @@ -120,6 +120,26 @@ public class CompilerTask extends Task.Backgroundable { mySessionId = sessionId; } + @NotNull + public Object getContentId() { + return myContentId; + } + + public void registerCloseAction(final Runnable onClose) { + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { + Disposer.register(myErrorTreeView, new Disposable() { + @Override + public void dispose() { + onClose.run(); + } + }); + return; + } + } + onClose.run(); + } + @Override public String getProcessId() { return "compilation"; @@ -221,13 +241,15 @@ public class CompilerTask extends Task.Backgroundable { private void addIndicatorDelegate() { ProgressIndicator indicator = myIndicator; - if (!(indicator instanceof ProgressIndicatorEx)) return; + if (!(indicator instanceof ProgressIndicatorEx)) { + return; + } ((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() { @Override public void cancel() { super.cancel(); - closeUI(); + selectFirstMessage(); stopAppIconProgress(); } @@ -235,11 +257,26 @@ public class CompilerTask extends Task.Backgroundable { public void stop() { super.stop(); if (!isCanceled()) { - closeUI(); + selectFirstMessage(); } stopAppIconProgress(); } + private void selectFirstMessage() { + if (!isHeadlessMode()) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + synchronized (myMessageViewLock) { + if (myErrorTreeView != null) { + myErrorTreeView.selectFirstMessage(); + } + } + } + }); + } + } + private void stopAppIconProgress() { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override @@ -249,7 +286,8 @@ public class CompilerTask extends Task.Backgroundable { if (myErrorCount > 0) { appIcon.setErrorBadge(myProject, String.valueOf(myErrorCount)); appIcon.requestAttention(myProject, true); - } else if (!myCompilationStartedAutomatically) { + } + else if (!myCompilationStartedAutomatically) { appIcon.setOkBadge(myProject, true); appIcon.requestAttention(myProject, false); } @@ -450,18 +488,22 @@ public class CompilerTask extends Task.Backgroundable { public void showCompilerContent() { synchronized (myMessageViewLock) { if (myErrorTreeView != null) { - final MessageView messageView = MessageView.SERVICE.getInstance(myProject); - Content[] contents = messageView.getContentManager().getContents(); - for (Content content : contents) { - if (CONTENT_ID_KEY.get(content) == myContentId) { - messageView.getContentManager().setSelectedContent(content); - return; - } - } + showCompilerContent(myProject, myContentId); } } } + public static boolean showCompilerContent(final Project project, final Object contentId) { + final MessageView messageView = MessageView.SERVICE.getInstance(project); + for (Content content : messageView.getContentManager().getContents()) { + if (CONTENT_ID_KEY.get(content) == contentId) { + messageView.getContentManager().setSelectedContent(content); + return true; + } + } + return false; + } + private void removeAllContents(Project project, Content notRemove) { if (project.isDisposed()) { return; @@ -488,7 +530,7 @@ public class CompilerTask extends Task.Backgroundable { private void activateMessageView() { synchronized (myMessageViewLock) { - if (myErrorTreeView != null) { + if (myErrorTreeView != null && myProject != null) { final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW); if (tw != null) { tw.activate(null, false); @@ -497,34 +539,6 @@ public class CompilerTask extends Task.Backgroundable { } } - private void closeUI() { - if (isHeadlessMode()) { - return; - } - Window window = getWindow(); - ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MODAL; - final Application application = ApplicationManager.getApplication(); - application.invokeLater(new Runnable() { - @Override - public void run() { - synchronized (myMessageViewLock) { - if (myErrorTreeView != null) { - final boolean shouldRetainView = myErrorCount > 0 || myWarningCount > 0 && !myErrorTreeView.isHideWarnings(); - if (shouldRetainView) { - addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, CompilerBundle.message("statistics.error.count", myErrorCount))); - addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, CompilerBundle.message("statistics.warnings.count", myWarningCount))); - //activateMessageView(); - myErrorTreeView.selectFirstMessage(); - } - else { - removeAllContents(myProject, null); - } - } - } - } - }, modalityState); - } - public Window getWindow(){ return null; } @@ -607,7 +621,7 @@ public class CompilerTask extends Task.Backgroundable { if (event.getContent() == myContent) { synchronized (myMessageViewLock) { if (myErrorTreeView != null) { - myErrorTreeView.dispose(); + Disposer.dispose(myErrorTreeView); myErrorTreeView = null; if (myIndicator.isRunning()) { cancel(); diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index c40135db7c5f..669cf92d37da 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -34,7 +34,9 @@ import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.compiler.CompilationStatusListener; import com.intellij.openapi.compiler.CompileContext; +import com.intellij.openapi.compiler.CompilerTopics; import com.intellij.openapi.components.ApplicationComponent; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.EditorFactory; @@ -64,16 +66,14 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; +import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.VFileEvent; import com.intellij.openapi.vfs.newvfs.impl.FileNameCache; import com.intellij.openapi.wm.IdeFrame; -import com.intellij.util.Alarm; -import com.intellij.util.Function; -import com.intellij.util.PathUtil; -import com.intellij.util.SmartList; +import com.intellij.util.*; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.concurrency.SequentialTaskExecutor; import com.intellij.util.containers.IntArrayList; @@ -1117,6 +1117,44 @@ public class BuildManager implements ApplicationComponent{ scheduleAutoMake(); } }); + conn.subscribe(CompilerTopics.COMPILATION_STATUS, new CompilationStatusListener() { + private final Set<String> myRootsToRefresh = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY); + @Override + public void compilationFinished(boolean aborted, int errors, int warnings, CompileContext compileContext) { + final String[] roots; + synchronized (myRootsToRefresh) { + roots = ArrayUtil.toStringArray(myRootsToRefresh); + myRootsToRefresh.clear(); + } + ApplicationManager.getApplication().executeOnPooledThread(new Runnable() { + @Override + public void run() { + if (project.isDisposed()) { + return; + } + final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + final LocalFileSystem lfs = LocalFileSystem.getInstance(); + final Set<VirtualFile> filesToRefresh = new HashSet<VirtualFile>(); + for (String root : roots) { + final VirtualFile rootFile = lfs.refreshAndFindFileByPath(root); + if (rootFile != null && fileIndex.isInSourceContent(rootFile)) { + filesToRefresh.add(rootFile); + } + } + if (!filesToRefresh.isEmpty()) { + lfs.refreshFiles(filesToRefresh, true, true, null); + } + } + }); + } + + @Override + public void fileGenerated(String outputRoot, String relativePath) { + synchronized (myRootsToRefresh) { + myRootsToRefresh.add(outputRoot); + } + } + }); final String projectPath = getProjectPath(project); Disposer.register(project, new Disposable() { @Override diff --git a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java index 6a8c9740df80..bfde64d4396e 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.openapi.progress.util.ProgressIndicatorUtils; import com.intellij.openapi.progress.util.ReadTask; import com.intellij.openapi.project.DumbService; @@ -40,7 +41,6 @@ import org.jetbrains.jps.api.CmdlineRemoteProto; import org.jetbrains.org.objectweb.asm.Opcodes; import java.util.*; -import java.util.concurrent.atomic.AtomicBoolean; /** * @author Eugene Zhuravlev @@ -66,19 +66,23 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { //noinspection EnumSwitchStatementWhichMissesCases switch (msg.getType()) { case BUILD_EVENT: - handleBuildEvent(sessionId, msg.getBuildEvent()); + final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event = msg.getBuildEvent(); + if (event.getEventType() == CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Type.CUSTOM_BUILDER_MESSAGE && event.hasCustomBuilderMessage()) { + final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.CustomBuilderMessage message = event.getCustomBuilderMessage(); + if (!myProject.isDisposed()) { + myProject.getMessageBus().syncPublisher(CustomBuilderMessageHandler.TOPIC).messageReceived( + message.getBuilderId(), message.getMessageType(), message.getMessageText() + ); + } + } + handleBuildEvent(sessionId, event); break; case COMPILE_MESSAGE: handleCompileMessage(sessionId, msg.getCompileMessage()); break; case CONSTANT_SEARCH_TASK: final CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task = msg.getConstantSearchTask(); - myTaskExecutor.submit(new Runnable() { - @Override - public void run() { - handleConstantSearchTask(channel, sessionId, task); - } - }); + handleConstantSearchTask(channel, sessionId, task); break; } } @@ -88,30 +92,29 @@ public abstract class DefaultMessageHandler implements BuilderMessageHandler { protected abstract void handleBuildEvent(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event); private void handleConstantSearchTask(final Channel channel, final UUID sessionId, final CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task) { - while (true) { - final AtomicBoolean canceled = new AtomicBoolean(false); - DumbService.getInstance(myProject).waitForSmartMode(); - ProgressIndicatorUtils.runWithWriteActionPriority(new ReadTask() { - @Override - public void computeInReadAction(@NotNull ProgressIndicator indicator) { - if (DumbService.isDumb(myProject)) { - canceled.set(true); - return; - } - - doHandleConstantSearchTask(channel, sessionId, task); + ProgressIndicatorUtils.scheduleWithWriteActionPriority(new ProgressIndicatorBase(), myTaskExecutor, new ReadTask() { + @Override + public void computeInReadAction(@NotNull ProgressIndicator indicator) { + if (DumbService.isDumb(myProject)) { + onCanceled(indicator); } - - @Override - public void onCanceled(@NotNull ProgressIndicator indicator) { - canceled.set(true); + else { + doHandleConstantSearchTask(channel, sessionId, task); } - }); - if (!canceled.get()) { - break; } - } + + @Override + public void onCanceled(@NotNull ProgressIndicator indicator) { + DumbService.getInstance(myProject).runWhenSmart(new Runnable() { + @Override + public void run() { + handleConstantSearchTask(channel, sessionId, task); + } + }); + } + }); } + private void doHandleConstantSearchTask(Channel channel, UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task) { final String ownerClassName = task.getOwnerClassName(); final String fieldName = task.getFieldName(); |