From c0a7c5286ab594b134ca2201b8090a854916b643 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 27 Oct 2014 09:24:19 +0100 Subject: [PATCH 01/55] new View Mode action breaks Ctrl+~,UP pattern for accessing LaFs --- platform/platform-resources/src/idea/PlatformActions.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index f989604a8c65..014c6306a701 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -583,8 +583,8 @@ - + From 3b2dabf77479acb3a66e57451905a0d4f32471a8 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 23 Oct 2014 00:08:48 +0200 Subject: [PATCH 02/55] 'preload build process' optimization, initial (off in registry by default). --- .../compiler/server/BuildManager.java | 280 ++++++++++++------ .../server/BuildMessageDispatcher.java | 69 ++++- .../server/BuilderMessageHandler.java | 18 ++ ...per.java => DelegatingMessageHandler.java} | 15 +- .../PreloadedProcessMessageHandler.java | 48 +++ .../org/jetbrains/jps/cmdline/BuildMain.java | 72 ++++- .../jetbrains/jps/cmdline/BuildRunner.java | 16 +- .../jetbrains/jps/cmdline/BuildSession.java | 99 +++++-- .../jetbrains/jps/cmdline/PreloadedData.java | 71 +++++ .../org/jetbrains/jps/build/Standalone.java | 3 +- .../util/resources/misc/registry.properties | 3 + 11 files changed, 539 insertions(+), 155 deletions(-) rename java/compiler/impl/src/com/intellij/compiler/server/{MessageHandlerWrapper.java => DelegatingMessageHandler.java} (59%) create mode 100644 java/compiler/impl/src/com/intellij/compiler/server/PreloadedProcessMessageHandler.java create mode 100644 jps/jps-builders/src/org/jetbrains/jps/cmdline/PreloadedData.java 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 bc31490a54b6..23dc33a9b627 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -58,10 +58,7 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl; import com.intellij.openapi.roots.*; import com.intellij.openapi.startup.StartupManager; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.ShutDownTracker; -import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; @@ -103,8 +100,7 @@ import org.jetbrains.jps.cmdline.ClasspathBootstrap; import org.jetbrains.jps.incremental.Utils; import org.jetbrains.jps.model.serialization.JpsGlobalLoader; -import javax.tools.JavaCompiler; -import javax.tools.ToolProvider; +import javax.tools.*; import java.awt.*; import java.io.File; import java.io.IOException; @@ -154,6 +150,8 @@ public class BuildManager implements ApplicationComponent{ private final Map myAutomakeFutures = Collections.synchronizedMap(new HashMap()); private final Map myBuildsInProgress = Collections.synchronizedMap(new HashMap()); + private final Map, OSProcessHandler>> myPreloadedBuilds = + Collections.synchronizedMap(new HashMap, OSProcessHandler>>()); private final BuildProcessClasspathManager myClasspathManager = new BuildProcessClasspathManager(); private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE); private final Map myProjectDataMap = Collections.synchronizedMap(new HashMap()); @@ -385,6 +383,8 @@ public class BuildManager implements ApplicationComponent{ } public void clearState(Project project) { + cancelPreloadedBuilds(project); + final String projectPath = getProjectPath(project); synchronized (myProjectDataMap) { final ProjectData data = myProjectDataMap.get(projectPath); @@ -540,6 +540,15 @@ public class BuildManager implements ApplicationComponent{ return futures; } + private String cancelPreloadedBuilds(Project project) { + final String projectPath = getProjectPath(project); + final Pair, OSProcessHandler> pair = myPreloadedBuilds.remove(projectPath); + if (pair != null) { + myMessageDispatcher.cancelSession(pair.first.getRequestID()); + } + return projectPath; + } + @Nullable public RequestFuture scheduleBuild( final Project project, final boolean isRebuild, final boolean isMake, @@ -548,53 +557,34 @@ public class BuildManager implements ApplicationComponent{ final Map userData, final DefaultMessageHandler messageHandler) { final String projectPath = getProjectPath(project); - final UUID sessionId = UUID.randomUUID(); - final boolean isAutomake = messageHandler instanceof AutoMakeMessageHandler; - final BuilderMessageHandler handler = new MessageHandlerWrapper(messageHandler) { - @Override - public void buildStarted(UUID sessionId) { - super.buildStarted(sessionId); - try { - ApplicationManager.getApplication().getMessageBus().syncPublisher(BuildManagerListener.TOPIC).buildStarted(project, sessionId, isAutomake); - } - catch (Throwable e) { - LOG.error(e); - } - } - @Override - public void sessionTerminated(UUID sessionId) { - try { - super.sessionTerminated(sessionId); - } - finally { - try { - ApplicationManager.getApplication().getMessageBus().syncPublisher(BuildManagerListener.TOPIC).buildFinished(project, sessionId, isAutomake); - } - catch (Throwable e) { - LOG.error(e); - } - } - } - }; - // ensure server is listening - if (myListenPort < 0) { - try { - synchronized (this) { - if (myListenPort < 0) { - myListenPort = startListening(); - } - } - } - catch (Exception e) { - handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null)); - handler.sessionTerminated(sessionId); - return null; - } + final Pair, OSProcessHandler> preloaded = myPreloadedBuilds.get(projectPath); + final RequestFuture preloadedFuture = preloaded != null? preloaded.first : null; + final boolean usingPreloadedProcess = preloadedFuture != null && myMessageDispatcher.acquirePreloadedSessionIfReady(preloadedFuture.getRequestID()); + + final UUID sessionId; + final BuilderMessageHandler handler = new NotifyingMessageHandler(project, messageHandler, messageHandler instanceof AutoMakeMessageHandler); + if (usingPreloadedProcess) { + LOG.info("Using preloaded build process to compile " + projectPath); + sessionId = preloadedFuture.getRequestID(); + preloadedFuture.getMessageHandler().setDelegateHandler(handler); + myPreloadedBuilds.remove(projectPath); + } + else { + sessionId = UUID.randomUUID(); + } + + try { + ensureListening(); + } + catch (Exception e) { + handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null)); + handler.sessionTerminated(sessionId); + return null; } try { - final RequestFuture future = new RequestFuture(handler, sessionId, new RequestFuture.CancelAction() { + final RequestFuture future = usingPreloadedProcess? preloadedFuture : new RequestFuture(handler, sessionId, new RequestFuture.CancelAction() { @Override public void cancel(RequestFuture future) throws Exception { myMessageDispatcher.cancelSession(future.getRequestID()); @@ -605,16 +595,15 @@ public class BuildManager implements ApplicationComponent{ runCommand(new Runnable() { @Override public void run() { - if (future.isCancelled() || project.isDisposed()) { + if (!usingPreloadedProcess && (future.isCancelled() || project.isDisposed())) { + // in case of preloaded process the process was already running, so the handler will be notified upon process termination handler.sessionTerminated(sessionId); future.setDone(); return; } final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = - CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.newBuilder() - .setGlobalOptionsPath(PathManager.getOptionsPath()) - .build(); + CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.newBuilder().setGlobalOptionsPath(PathManager.getOptionsPath()).build(); CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges; final SequentialTaskExecutor projectTaskQueue; synchronized (myProjectDataMap) { @@ -646,21 +635,11 @@ public class BuildManager implements ApplicationComponent{ params = CmdlineProtoUtil.createUpToDateCheckRequest(projectPath, scopes, paths, userData, globals, currentFSChanges); } else { - params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, isMake ? Collections.emptyList() : paths, - userData, globals, currentFSChanges); + params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, isMake ? Collections.emptyList() : paths, userData, globals, currentFSChanges); + } + if (!usingPreloadedProcess) { + myMessageDispatcher.registerBuildMessageHandler(future, params); } - - myMessageDispatcher.registerBuildMessageHandler(sessionId, new MessageHandlerWrapper(handler) { - @Override - public void sessionTerminated(UUID sessionId) { - try { - super.sessionTerminated(sessionId); - } - finally { - future.setDone(); - } - } - }, params); try { projectTaskQueue.submit(new Runnable() { @@ -669,33 +648,46 @@ public class BuildManager implements ApplicationComponent{ Throwable execFailure = null; try { if (project.isDisposed()) { - return; + if (usingPreloadedProcess) { + future.cancel(true); + } + else { + return; + } } myBuildsInProgress.put(projectPath, future); - final OSProcessHandler processHandler = launchBuildProcess(project, myListenPort, sessionId); - final StringBuilder stdErrOutput = new StringBuilder(); - processHandler.addProcessListener(new ProcessAdapter() { - @Override - public void onTextAvailable(ProcessEvent event, Key outputType) { - // re-translate builder's output to idea.log - final String text = event.getText(); - if (!StringUtil.isEmptyOrSpaces(text)) { - LOG.info("BUILDER_PROCESS [" + outputType.toString() + "]: " + text.trim()); - if (stdErrOutput.length() < 1024 && ProcessOutputTypes.STDERR.equals(outputType)) { - stdErrOutput.append(text); + final OSProcessHandler processHandler; + final StringBuilder errorsOnLaunch = new StringBuilder(); + if (usingPreloadedProcess) { + myMessageDispatcher.sendBuildParameters(future.getRequestID(), params); + processHandler = preloaded.second; + } + else { + processHandler = launchBuildProcess(project, myListenPort, sessionId, false); + processHandler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + if (ProcessOutputTypes.STDERR.equals(outputType)) { + if (errorsOnLaunch.length() < 1024) { + final String text = event.getText(); + if (!StringUtil.isEmptyOrSpaces(text)) { + errorsOnLaunch.append(text); + } + } } } - } - }); - processHandler.startNotify(); + }); + processHandler.startNotify(); + } + final boolean terminated = processHandler.waitFor(); if (terminated) { final int exitValue = processHandler.getProcess().exitValue(); if (exitValue != 0) { final StringBuilder msg = new StringBuilder(); msg.append("Abnormal build process termination: "); - if (stdErrOutput.length() > 0) { - msg.append("\n").append(stdErrOutput); + if (errorsOnLaunch.length() > 0) { + msg.append("\n").append(errorsOnLaunch); } else { msg.append("unknown error"); @@ -723,6 +715,17 @@ public class BuildManager implements ApplicationComponent{ unregistered.sessionTerminated(sessionId); } } + + if (Registry.is("compiler.process.preload") && !myPreloadedBuilds.containsKey(projectPath) && !project.isDisposed()) { + try { + final Pair, OSProcessHandler> pair = launchPreloadedBuildProcess(project); + myPreloadedBuilds.put(projectPath, pair); + } + catch (Exception e) { + LOG.info("Error pre-loading build process for project " + projectPath, e); + } + } + } } }); @@ -747,6 +750,16 @@ public class BuildManager implements ApplicationComponent{ return null; } + private void ensureListening() throws Exception { + if (myListenPort < 0) { + synchronized (this) { + if (myListenPort < 0) { + myListenPort = startListening(); + } + } + } + } + @Override public void initComponent() { } @@ -762,7 +775,40 @@ public class BuildManager implements ApplicationComponent{ return "com.intellij.compiler.server.BuildManager"; } - private OSProcessHandler launchBuildProcess(Project project, final int port, final UUID sessionId) throws ExecutionException { + private Pair, OSProcessHandler> launchPreloadedBuildProcess(final Project project) throws Exception { + ensureListening(); + + final RequestFuture future = new RequestFuture(new PreloadedProcessMessageHandler(project), UUID.randomUUID(), new RequestFuture.CancelAction() { + @Override + public void cancel(RequestFuture future) throws Exception { + myMessageDispatcher.cancelSession(future.getRequestID()); + } + }); + myMessageDispatcher.registerBuildMessageHandler(future, null); + try { + final OSProcessHandler processHandler = launchBuildProcess(project, myListenPort, future.getRequestID(), true); + processHandler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + if (ProcessOutputTypes.STDERR.equals(outputType)) { + final String text = event.getText(); + if (!StringUtil.isEmptyOrSpaces(text)) { + LOG.info("PRELOADED_BUILD_PROCESS: " + text); + } + } + } + }); + + processHandler.startNotify(); + return Pair.create(future, processHandler); + } + catch (ExecutionException e) { + myMessageDispatcher.unregisterBuildMessageHandler(future.getRequestID()); + throw e; + } + } + + private OSProcessHandler launchBuildProcess(Project project, final int port, final UUID sessionId, boolean requestProjectPreload) throws ExecutionException { final String compilerPath; final String vmExecutablePath; JavaSdkVersion sdkVersion = null; @@ -863,6 +909,11 @@ public class BuildManager implements ApplicationComponent{ } cmdLine.addParameter("-Djdt.compiler.useSingleThread=true"); // always run eclipse compiler in single-threaded mode + if (requestProjectPreload) { + cmdLine.addParameter("-Dpreload.project.path=" + FileUtil.toCanonicalPath(getProjectPath(project))); + cmdLine.addParameter("-Dpreload.config.path=" + FileUtil.toCanonicalPath(PathManager.getOptionsPath())); + } + final String shouldGenerateIndex = System.getProperty(GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION); if (shouldGenerateIndex != null) { cmdLine.addParameter("-D"+ GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION +"=" + shouldGenerateIndex); @@ -961,12 +1012,24 @@ public class BuildManager implements ApplicationComponent{ final Process process = cmdLine.createProcess(); - return new OSProcessHandler(process, null, mySystemCharset) { + final OSProcessHandler processHandler = new OSProcessHandler(process, null, mySystemCharset) { @Override protected boolean shouldDestroyProcessRecursively() { return true; } }; + processHandler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + // re-translate builder's output to idea.log + final String text = event.getText(); + if (!StringUtil.isEmptyOrSpaces(text)) { + LOG.info("BUILDER_PROCESS [" + outputType.toString() + "]: " + text.trim()); + } + } + }); + + return processHandler; } public File getBuildSystemDirectory() { @@ -1086,6 +1149,50 @@ public class BuildManager implements ApplicationComponent{ } } + private static class NotifyingMessageHandler extends DelegatingMessageHandler { + private final Project myProject; + private final BuilderMessageHandler myDelegateHandler; + private boolean myIsAutomake; + + public NotifyingMessageHandler(@NotNull Project project, @NotNull BuilderMessageHandler delegateHandler, final boolean isAutomake) { + myProject = project; + myDelegateHandler = delegateHandler; + myIsAutomake = isAutomake; + } + + @Override + protected BuilderMessageHandler getDelegateHandler() { + return myDelegateHandler; + } + + @Override + public void buildStarted(UUID sessionId) { + super.buildStarted(sessionId); + try { + ApplicationManager + .getApplication().getMessageBus().syncPublisher(BuildManagerListener.TOPIC).buildStarted(myProject, sessionId, myIsAutomake); + } + catch (Throwable e) { + LOG.error(e); + } + } + + @Override + public void sessionTerminated(UUID sessionId) { + try { + super.sessionTerminated(sessionId); + } + finally { + try { + ApplicationManager.getApplication().getMessageBus().syncPublisher(BuildManagerListener.TOPIC).buildFinished(myProject, sessionId, myIsAutomake); + } + catch (Throwable e) { + LOG.error(e); + } + } + } + } + private class ProjectWatcher extends ProjectManagerAdapter { private final Map myConnections = new HashMap(); @@ -1169,6 +1276,7 @@ public class BuildManager implements ApplicationComponent{ @Override public void projectClosing(Project project) { + cancelPreloadedBuilds(project); for (RequestFuture future : cancelAutoMakeTasks(project)) { future.waitFor(500, TimeUnit.MILLISECONDS); } diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java index d324a620155b..7ee922211e57 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java @@ -21,10 +21,12 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandlerContext; import io.netty.util.AttributeKey; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.io.SimpleChannelInboundHandlerAdapter; import org.jetbrains.jps.api.CmdlineProtoUtil; import org.jetbrains.jps.api.CmdlineRemoteProto; +import org.jetbrains.jps.api.RequestFuture; import java.util.Map; import java.util.Set; @@ -41,19 +43,34 @@ class BuildMessageDispatcher extends SimpleChannelInboundHandlerAdapter SESSION_DATA = AttributeKey.valueOf("BuildMessageDispatcher.sessionData"); - private final Map myMessageHandlers = new ConcurrentHashMap(16, 0.75f, 1); + private final Map mySessionDescriptors = new ConcurrentHashMap(16, 0.75f, 1); private final Set myCanceledSessions = new ConcurrentHashSet(); - public void registerBuildMessageHandler(UUID sessionId, - BuilderMessageHandler handler, - CmdlineRemoteProto.Message.ControllerMessage params) { - myMessageHandlers.put(sessionId, new SessionData(sessionId, handler, params)); + public void registerBuildMessageHandler(@NotNull final RequestFuture future, @Nullable CmdlineRemoteProto.Message.ControllerMessage params) { + final BuilderMessageHandler wrappedHandler = new DelegatingMessageHandler() { + @Override + protected BuilderMessageHandler getDelegateHandler() { + return future.getMessageHandler(); + } + + @Override + public void sessionTerminated(UUID sessionId) { + try { + super.sessionTerminated(sessionId); + } + finally { + future.setDone(); + } + } + }; + final UUID sessionId = future.getRequestID(); + mySessionDescriptors.put(sessionId, new SessionData(sessionId, wrappedHandler, params)); } @Nullable public BuilderMessageHandler unregisterBuildMessageHandler(UUID sessionId) { myCanceledSessions.remove(sessionId); - final SessionData data = myMessageHandlers.remove(sessionId); + final SessionData data = mySessionDescriptors.remove(sessionId); return data != null? data.handler : null; } @@ -74,11 +91,26 @@ class BuildMessageDispatcher extends SimpleChannelInboundHandlerAdapter myFilePaths; - private final Map myBuilderParams; + private List myFilePaths = Collections.emptyList(); + private Map myBuilderParams = Collections.emptyMap(); private boolean myForceCleanCaches; - public BuildRunner(JpsModelLoader modelLoader, List filePaths, Map builderParams) { + public BuildRunner(JpsModelLoader modelLoader) { myModelLoader = modelLoader; - myFilePaths = filePaths; - myBuilderParams = builderParams; + } + + public void setFilePaths(List filePaths) { + myFilePaths = filePaths != null? filePaths : Collections.emptyList(); + } + + public void setBuilderParams(Map builderParams) { + myBuilderParams = builderParams != null? builderParams : Collections.emptyMap(); } public ProjectDescriptor load(MessageHandler msgHandler, File dataStorageRoot, BuildFSState fsState) throws IOException { diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java index 9dd87443eae0..0fc6039dfb90 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildSession.java @@ -25,6 +25,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.concurrency.SequentialTaskExecutor; import com.intellij.util.io.DataOutputStream; import io.netty.channel.Channel; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.TimingLog; import org.jetbrains.jps.api.*; @@ -57,9 +58,11 @@ import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage */ final class BuildSession implements Runnable, CanceledStatus { private static final Logger LOG = Logger.getInstance("#org.jetbrains.jps.cmdline.BuildSession"); - private static final String FS_STATE_FILE = "fs_state.dat"; + public static final String FS_STATE_FILE = "fs_state.dat"; private final UUID mySessionId; private final Channel myChannel; + @Nullable + private final PreloadedData myPreloadedData; private volatile boolean myCanceled = false; private final String myProjectPath; @Nullable @@ -70,6 +73,7 @@ final class BuildSession implements Runnable, CanceledStatus { private volatile ProjectDescriptor myProjectDescriptor; private final Map, ConstantSearchFuture> mySearchTasks = Collections.synchronizedMap(new HashMap, ConstantSearchFuture>()); private final ConstantSearch myConstantSearch = new ConstantSearch(); + @NotNull private final BuildRunner myBuildRunner; private final boolean myForceModelLoading; private final BuildType myBuildType; @@ -78,24 +82,31 @@ final class BuildSession implements Runnable, CanceledStatus { BuildSession(UUID sessionId, Channel channel, CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage params, - @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent delta) { + @Nullable CmdlineRemoteProto.Message.ControllerMessage.FSEvent delta, @Nullable PreloadedData preloaded) { mySessionId = sessionId; myChannel = channel; - + myPreloadedData = preloaded; + final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = params.getGlobalSettings(); myProjectPath = FileUtil.toCanonicalPath(params.getProjectId()); String globalOptionsPath = FileUtil.toCanonicalPath(globals.getGlobalOptionsPath()); myBuildType = convertCompileType(params.getBuildType()); myScopes = params.getScopeList(); List filePaths = params.getFilePathList(); - Map builderParams = new HashMap(); + final Map builderParams = new HashMap(); for (CmdlineRemoteProto.Message.KeyValuePair pair : params.getBuilderParameterList()) { builderParams.put(pair.getKey(), pair.getValue()); } myInitialFSDelta = delta; - JpsModelLoaderImpl loader = new JpsModelLoaderImpl(myProjectPath, globalOptionsPath, null); - myForceModelLoading = Boolean.parseBoolean(builderParams.get(BuildParametersKeys.FORCE_MODEL_LOADING)); - myBuildRunner = new BuildRunner(loader, filePaths, builderParams); + if (preloaded == null || preloaded.getRunner() == null) { + myBuildRunner = new BuildRunner(new JpsModelLoaderImpl(myProjectPath, globalOptionsPath, null)); + } + else { + myBuildRunner = preloaded.getRunner(); + } + myBuildRunner.setFilePaths(filePaths); + myBuildRunner.setBuilderParams(builderParams); + myForceModelLoading = (preloaded != null && preloaded.getProjectDescriptor() != null) || Boolean.parseBoolean(builderParams.get(BuildParametersKeys.FORCE_MODEL_LOADING)); } @Override @@ -185,8 +196,9 @@ final class BuildSession implements Runnable, CanceledStatus { // invoked the very first time for this project myBuildRunner.setForceCleanCaches(true); } - - final DataInputStream fsStateStream = createFSDataStream(dataStorageRoot); + final ProjectDescriptor preloadedProject = myPreloadedData != null? myPreloadedData.getProjectDescriptor() : null; + final DataInputStream fsStateStream = + preloadedProject != null || myInitialFSDelta == null /*this will force FS rescan*/? null : createFSDataStream(dataStorageRoot, myInitialFSDelta.getOrdinal()); if (fsStateStream != null) { // optimization: check whether we can skip the build @@ -198,27 +210,56 @@ final class BuildSession implements Runnable, CanceledStatus { } } - final BuildFSState fsState = new BuildFSState(false); + final BuildFSState fsState = preloadedProject != null? preloadedProject.fsState : new BuildFSState(false); try { - final ProjectDescriptor pd = myBuildRunner.load(msgHandler, dataStorageRoot, fsState); - TimingLog.LOG.debug("Project descriptor loaded"); - myProjectDescriptor = pd; - if (fsStateStream != null) { - try { - try { - fsState.load(fsStateStream, pd.getModel(), pd.getBuildRootIndex()); - applyFSEvent(pd, myInitialFSDelta, false); - TimingLog.LOG.debug("FS Delta loaded"); - } - finally { - fsStateStream.close(); + final ProjectDescriptor pd; + if (preloadedProject != null) { + pd = preloadedProject; + final List preloadMessages = myPreloadedData.getLoadMessages(); + if (!preloadMessages.isEmpty()) { + // replay preload-time messages, so that they are delivered to the IDE + for (BuildMessage message : preloadMessages) { + msgHandler.processMessage(message); } } - catch (Throwable e) { - LOG.error(e); - fsState.clearAll(); + if (myInitialFSDelta == null || myPreloadedData.getFsEventOrdinal() + 1L != myInitialFSDelta.getOrdinal()) { + // FS rescan was forced + fsState.clearAll(); + } + else { + // apply events to already loaded state + try { + applyFSEvent(pd, myInitialFSDelta, false); + } + catch (Throwable e) { + LOG.error(e); + fsState.clearAll(); + } } } + else { + // standard case + pd = myBuildRunner.load(msgHandler, dataStorageRoot, fsState); + TimingLog.LOG.debug("Project descriptor loaded"); + if (fsStateStream != null) { + try { + try { + fsState.load(fsStateStream, pd.getModel(), pd.getBuildRootIndex()); + applyFSEvent(pd, myInitialFSDelta, false); + TimingLog.LOG.debug("FS Delta loaded"); + } + finally { + fsStateStream.close(); + } + } + catch (Throwable e) { + LOG.error(e); + fsState.clearAll(); + } + } + } + myProjectDescriptor = pd; + myLastEventOrdinal = myInitialFSDelta != null? myInitialFSDelta.getOrdinal() : 0L; // free memory @@ -469,11 +510,7 @@ final class BuildSession implements Runnable, CanceledStatus { } @Nullable - private DataInputStream createFSDataStream(File dataStorageRoot) { - if (myInitialFSDelta == null) { - // this will force FS rescan - return null; - } + private static DataInputStream createFSDataStream(File dataStorageRoot, final long currentEventOrdinal) { try { final File file = new File(dataStorageRoot, FS_STATE_FILE); byte[] bytes; @@ -490,7 +527,7 @@ final class BuildSession implements Runnable, CanceledStatus { return null; } final long savedOrdinal = in.readLong(); - if (savedOrdinal + 1L != myInitialFSDelta.getOrdinal()) { + if (savedOrdinal + 1L != currentEventOrdinal) { return null; } return in; diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/PreloadedData.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/PreloadedData.java new file mode 100644 index 000000000000..bf5ece5d6fdd --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/PreloadedData.java @@ -0,0 +1,71 @@ +/* + * Copyright 2000-2014 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 org.jetbrains.jps.cmdline; + +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jps.incremental.messages.BuildMessage; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Eugene Zhuravlev + * Date: 22-Oct-14 + */ +public class PreloadedData { + @Nullable + private BuildRunner runner; + @Nullable + private ProjectDescriptor projectDescriptor; + + private final List loadMessages = new ArrayList(); + + private long fsEventOrdinal; + + @Nullable + public BuildRunner getRunner() { + return runner; + } + + public void setRunner(@Nullable BuildRunner runner) { + this.runner = runner; + } + + @Nullable + public ProjectDescriptor getProjectDescriptor() { + return projectDescriptor; + } + + public void setProjectDescriptor(@Nullable ProjectDescriptor projectDescriptor) { + this.projectDescriptor = projectDescriptor; + } + + public long getFsEventOrdinal() { + return fsEventOrdinal; + } + + public void setFsEventOrdinal(long fsEventOrdinal) { + this.fsEventOrdinal = fsEventOrdinal; + } + + public List getLoadMessages() { + return loadMessages; + } + + public void addMessage(BuildMessage msg) { + loadMessages.add(msg); + } +} diff --git a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java index 979fd78703f1..7b7d425f1a09 100644 --- a/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java +++ b/jps/standalone-builder/src/org/jetbrains/jps/build/Standalone.java @@ -193,8 +193,7 @@ public class Standalone { public static void runBuild(JpsModelLoader loader, File dataStorageRoot, MessageHandler messageHandler, List scopes, boolean includeDependenciesToScope) throws Exception { - final BuildRunner buildRunner = new BuildRunner(loader, Collections.emptyList(), Collections.emptyMap() - ); + final BuildRunner buildRunner = new BuildRunner(loader); ProjectDescriptor descriptor = buildRunner.load(messageHandler, dataStorageRoot, new BuildFSState(true)); try { buildRunner.runBuild(descriptor, CanceledStatus.NULL, null, messageHandler, BuildType.BUILD, scopes, includeDependenciesToScope); diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index e5be37cd7b30..5c559a09fb55 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -198,6 +198,9 @@ compiler.process.use.memory.temp.cache=true compiler.process.use.memory.temp.cache.description=Store temporary data in memory for faster compilation;\ requires larger heap size for the build process. If parallel build is enabled, the option is ignored and temp data is always stored in memory. +compiler.process.preload=false +compiler.process.preload.description=After build finishes, the IDE will pre-load and leave waiting in memory the build process for the next compilation. This will save time for process start and project model loading (may be noticeable for big projects).\ + compiler.process.debug.port=-1 compiler.automake.trigger.delay=300 From a2595d6960aaf06e853acf2b1dcf4939d7d7186d Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 27 Oct 2014 10:20:32 +0100 Subject: [PATCH 03/55] once preloaded process has been started, it should be used by the next compile session (incomplete) --- .../intellij/compiler/impl/CompileDriver.java | 9 +- .../compiler/server/BuildManager.java | 68 ++++++++++----- .../server/BuildMessageDispatcher.java | 83 +++++++++++-------- 3 files changed, 97 insertions(+), 63 deletions(-) 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 a35a03630ad9..d4a69206c3ba 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -71,9 +71,9 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; +import org.jetbrains.jps.api.BasicFuture; import org.jetbrains.jps.api.CmdlineProtoUtil; import org.jetbrains.jps.api.CmdlineRemoteProto; -import org.jetbrains.jps.api.RequestFuture; import org.jetbrains.jps.model.java.JavaSourceRootType; import javax.swing.*; @@ -138,7 +138,7 @@ public class CompileDriver { return; } try { - final RequestFuture future = compileInExternalProcess(compileContext, true); + final BasicFuture future = compileInExternalProcess(compileContext, true); if (future != null) { while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { @@ -194,7 +194,7 @@ public class CompileDriver { } @Nullable - private RequestFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, final boolean onlyCheckUpToDate) + private BasicFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, final boolean onlyCheckUpToDate) throws Exception { final CompileScope scope = compileContext.getCompileScope(); final Collection paths = CompileScopeUtil.fetchFiles(compileContext); @@ -400,7 +400,7 @@ public class CompileDriver { return; } - final RequestFuture future = compileInExternalProcess(compileContext, false); + final BasicFuture future = compileInExternalProcess(compileContext, false); if (future != null) { while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { @@ -646,7 +646,6 @@ public class CompileDriver { final Module[] scopeModules = scope.getAffectedModules(); final List modulesWithoutOutputPathSpecified = new ArrayList(); final List modulesWithoutJdkAssigned = new ArrayList(); - final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject); final CompilerManager compilerManager = CompilerManager.getInstance(myProject); for (final Module module : scopeModules) { if (!compilerManager.isValidationEnabled(module)) { 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 23dc33a9b627..2c5b378d96ea 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -148,7 +148,7 @@ public class BuildManager implements ApplicationComponent{ private final File mySystemDirectory; private final ProjectManager myProjectManager; - private final Map myAutomakeFutures = Collections.synchronizedMap(new HashMap()); + private final Map myAutomakeFutures = Collections.synchronizedMap(new HashMap()); private final Map myBuildsInProgress = Collections.synchronizedMap(new HashMap()); private final Map, OSProcessHandler>> myPreloadedBuilds = Collections.synchronizedMap(new HashMap, OSProcessHandler>>()); @@ -447,7 +447,7 @@ public class BuildManager implements ApplicationComponent{ } final List scopes = CmdlineProtoUtil.createAllModulesScopes(false); final AutoMakeMessageHandler handler = new AutoMakeMessageHandler(project); - final RequestFuture future = scheduleBuild( + final BasicFuture future = scheduleBuild( project, false, true, false, scopes, Collections.emptyList(), Collections.emptyMap(), handler ); if (future != null) { @@ -526,12 +526,12 @@ public class BuildManager implements ApplicationComponent{ return false; } - public Collection cancelAutoMakeTasks(Project project) { - final Collection futures = new SmartList(); + public Collection cancelAutoMakeTasks(Project project) { + final Collection futures = new SmartList(); synchronized (myAutomakeFutures) { - for (Map.Entry entry : myAutomakeFutures.entrySet()) { + for (Map.Entry entry : myAutomakeFutures.entrySet()) { if (entry.getValue().equals(project)) { - final RequestFuture future = entry.getKey(); + final BasicFuture future = entry.getKey(); future.cancel(false); futures.add(future); } @@ -540,17 +540,30 @@ public class BuildManager implements ApplicationComponent{ return futures; } - private String cancelPreloadedBuilds(Project project) { + private void cancelPreloadedBuilds(Project project) { final String projectPath = getProjectPath(project); final Pair, OSProcessHandler> pair = myPreloadedBuilds.remove(projectPath); if (pair != null) { - myMessageDispatcher.cancelSession(pair.first.getRequestID()); + final RequestFuture future = pair.first; + myMessageDispatcher.cancelSession(future.getRequestID()); + runCommand(new Runnable() { + @Override + public void run() { + // waiting for preloaded process from project's task queue guarantees no build is started for this project + // until this one gracefully exits and closes all its storages + getProjectData(projectPath).taskQueue.submit(new Runnable() { + @Override + public void run() { + future.waitFor(); + } + }); + } + }); } - return projectPath; } @Nullable - public RequestFuture scheduleBuild( + public BasicFuture scheduleBuild( final Project project, final boolean isRebuild, final boolean isMake, final boolean onlyCheckUpToDate, final List scopes, final Collection paths, @@ -558,9 +571,9 @@ public class BuildManager implements ApplicationComponent{ final String projectPath = getProjectPath(project); - final Pair, OSProcessHandler> preloaded = myPreloadedBuilds.get(projectPath); + final Pair, OSProcessHandler> preloaded = myPreloadedBuilds.remove(projectPath); final RequestFuture preloadedFuture = preloaded != null? preloaded.first : null; - final boolean usingPreloadedProcess = preloadedFuture != null && myMessageDispatcher.acquirePreloadedSessionIfReady(preloadedFuture.getRequestID()); + final boolean usingPreloadedProcess = preloadedFuture != null; final UUID sessionId; final BuilderMessageHandler handler = new NotifyingMessageHandler(project, messageHandler, messageHandler instanceof AutoMakeMessageHandler); @@ -568,7 +581,6 @@ public class BuildManager implements ApplicationComponent{ LOG.info("Using preloaded build process to compile " + projectPath); sessionId = preloadedFuture.getRequestID(); preloadedFuture.getMessageHandler().setDelegateHandler(handler); - myPreloadedBuilds.remove(projectPath); } else { sessionId = UUID.randomUUID(); @@ -607,11 +619,7 @@ public class BuildManager implements ApplicationComponent{ CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges; final SequentialTaskExecutor projectTaskQueue; synchronized (myProjectDataMap) { - ProjectData data = myProjectDataMap.get(projectPath); - if (data == null) { - data = new ProjectData(new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE)); - myProjectDataMap.put(projectPath, data); - } + final ProjectData data = getProjectData(projectPath); if (isRebuild) { data.dropChanges(); } @@ -659,7 +667,10 @@ public class BuildManager implements ApplicationComponent{ final OSProcessHandler processHandler; final StringBuilder errorsOnLaunch = new StringBuilder(); if (usingPreloadedProcess) { - myMessageDispatcher.sendBuildParameters(future.getRequestID(), params); + final boolean paramsSent = myMessageDispatcher.sendBuildParameters(future.getRequestID(), params); + if (!paramsSent) { + myMessageDispatcher.cancelSession(future.getRequestID()); + } processHandler = preloaded.second; } else { @@ -716,7 +727,7 @@ public class BuildManager implements ApplicationComponent{ } } - if (Registry.is("compiler.process.preload") && !myPreloadedBuilds.containsKey(projectPath) && !project.isDisposed()) { + if (Registry.is("compiler.process.preload") && !project.isDisposed()) { try { final Pair, OSProcessHandler> pair = launchPreloadedBuildProcess(project); myPreloadedBuilds.put(projectPath, pair); @@ -750,6 +761,18 @@ public class BuildManager implements ApplicationComponent{ return null; } + @NotNull + private ProjectData getProjectData(String projectPath) { + synchronized (myProjectDataMap) { + ProjectData data = myProjectDataMap.get(projectPath); + if (data == null) { + data = new ProjectData(new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE)); + myProjectDataMap.put(projectPath, data); + } + return data; + } + } + private void ensureListening() throws Exception { if (myListenPort < 0) { synchronized (this) { @@ -1277,7 +1300,7 @@ public class BuildManager implements ApplicationComponent{ @Override public void projectClosing(Project project) { cancelPreloadedBuilds(project); - for (RequestFuture future : cancelAutoMakeTasks(project)) { + for (BasicFuture future : cancelAutoMakeTasks(project)) { future.waitFor(500, TimeUnit.MILLISECONDS); } } @@ -1293,13 +1316,14 @@ public class BuildManager implements ApplicationComponent{ } private static class ProjectData { + @NotNull final SequentialTaskExecutor taskQueue; private final Set myChanged = new THashSet(); private final Set myDeleted = new THashSet(); private long myNextEventOrdinal = 0L; private boolean myNeedRescan = true; - private ProjectData(SequentialTaskExecutor taskQueue) { + private ProjectData(@NotNull SequentialTaskExecutor taskQueue) { this.taskQueue = taskQueue; } diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java index 7ee922211e57..59c19f0ad7fe 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java @@ -95,20 +95,30 @@ class BuildMessageDispatcher extends SimpleChannelInboundHandlerAdapter Date: Mon, 27 Oct 2014 11:00:33 +0100 Subject: [PATCH 04/55] inline debugger: better fg colors for execution line --- .../impl/evaluate/XDebuggerEditorLinePainter.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java index cce3eac58098..a71b6ec5de7a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEditorLinePainter.java @@ -26,7 +26,10 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.ui.*; +import com.intellij.ui.ColorUtil; +import com.intellij.ui.JBColor; +import com.intellij.ui.SimpleColoredText; +import com.intellij.ui.SimpleTextAttributes; import com.intellij.util.NotNullProducer; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XSourcePosition; @@ -95,7 +98,7 @@ public class XDebuggerEditorLinePainter extends EditorLinePainter { catch (Exception e) { continue; } - final Color color = bpLine == lineNumber ? new JBColor(Gray._180, new Color(147, 217, 186)) : getForeground(); + final Color color = bpLine == lineNumber ? new JBColor(new Color(0, 255, 86), new Color(255, 235, 9)) : getForeground(); final String name = value.getName(); if (StringUtil.isEmpty(text.toString())) { From 78986b3fa807a7f03c0214497ab31e7a55d1d4a9 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 27 Oct 2014 11:03:27 +0100 Subject: [PATCH 05/55] Inline debugger: better fg colors for Darcula --- platform/util/resources/misc/registry.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 5c559a09fb55..7d9390c705e3 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -47,11 +47,11 @@ ide.debugger.inline=true ide.debugger.inline.description=Enables variables view in editor ide.debugger.inline.fg.color=134,134,134 ide.debugger.inline.fg.color.description=Inline values foreground -ide.debugger.inline.dark.fg.color=61,128,101 +ide.debugger.inline.dark.fg.color=62,179,151 ide.debugger.inline.dark.fg.color.description=Inline values foreground for dark editor scheme ide.debugger.inline.fg.modified.color=202,128,33 ide.debugger.inline.fg.modified.color.description=Inline modified values foreground -ide.debugger.inline.dark.fg.modified.color=161,131,10 +ide.debugger.inline.dark.fg.modified.color=202,126,3 ide.debugger.inline.dark.fg.modified.color.description=Inline modified values foreground for dark editor scheme ide.debugMode.description=Record additional information to make bug reports more informative. From 18de0b042cb574d6c5c085f585dbdc33ef6f1d5c Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 27 Oct 2014 11:04:31 +0100 Subject: [PATCH 06/55] inline debugger: show values at declaration and at nearest to execution point lines --- .../xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java index 7020c9a5cf84..6f911b28cd68 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/XValueNodeImpl.java @@ -160,10 +160,11 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu }; if (getValueContainer().computeInlineDebuggerData(callback) == ThreeState.UNSURE) { - getValueContainer().computeSourcePosition(new XNearestSourcePosition() { + class ValueDeclaration implements XNavigatable { @Override public void setSourcePosition(@Nullable XSourcePosition sourcePosition) { - final Map, Set> map = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES); + final Map, Set> map = + myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES); final Map timestamps = myTree.getProject().getUserData(XVariablesView.DEBUG_VARIABLES_TIMESTAMPS); if (map == null || timestamps == null || sourcePosition == null) return; VirtualFile file = sourcePosition.getFile(); @@ -172,7 +173,10 @@ public class XValueNodeImpl extends XValueContainerNode implements XValu int line = sourcePosition.getLine(); callback.computed(file, doc, line); } - }); + } + class NearestValuePosition extends ValueDeclaration implements XNearestSourcePosition {} + getValueContainer().computeSourcePosition(new ValueDeclaration()); + getValueContainer().computeSourcePosition(new NearestValuePosition()); } } } From e3faaf04429a1d8a0f3b6c4e136d76f68e2fc04e Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Mon, 27 Oct 2014 13:36:39 +0300 Subject: [PATCH 07/55] PY-13297 Move caret on the line after inserted comment with encoding declaration Append empty line if inserted comment is on the last line in document. --- .../quickfix/AddEncodingQuickFix.java | 35 +++++++++++++++---- .../inspections/AddEncodingInEmptyFile.py | 1 + .../AddEncodingInEmptyFile_after.py | 2 ++ .../testData/inspections/AddEncoding_after.py | 2 +- .../com/jetbrains/python/PyQuickFixTest.java | 9 ++++- 5 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 python/testData/inspections/AddEncodingInEmptyFile.py create mode 100644 python/testData/inspections/AddEncodingInEmptyFile_after.py diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddEncodingQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddEncodingQuickFix.java index 8b65e34ad3ca..82f61cfb1b57 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddEncodingQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddEncodingQuickFix.java @@ -17,8 +17,15 @@ package com.jetbrains.python.inspections.quickfix; import com.intellij.codeInspection.LocalQuickFix; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.LogicalPosition; +import com.intellij.openapi.fileEditor.FileEditor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.jetbrains.python.PyBundle; @@ -32,13 +39,13 @@ import org.jetbrains.annotations.NotNull; * add missing encoding declaration * # -*- coding: -*- * to the source file - * + *

* User: catherine */ public class AddEncodingQuickFix implements LocalQuickFix { - private String myDefaultEncoding; - private int myEncodingFormatIndex; + private final String myDefaultEncoding; + private final int myEncodingFormatIndex; public AddEncodingQuickFix(String defaultEncoding, int encodingFormatIndex) { myDefaultEncoding = defaultEncoding; @@ -57,14 +64,28 @@ public class AddEncodingQuickFix implements LocalQuickFix { } public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) { - PsiFile file = descriptor.getPsiElement().getContainingFile(); + final PsiElement element = descriptor.getPsiElement(); + final PsiFile file = element.getContainingFile(); if (file == null) return; PsiElement firstLine = file.getFirstChild(); if (firstLine instanceof PsiComment && firstLine.getText().startsWith("#!")) { firstLine = firstLine.getNextSibling(); } - PsiComment encodingLine = PyElementGenerator.getInstance(project).createFromText(LanguageLevel.forElement(file), PsiComment.class, - String.format(PyEncodingUtil.ENCODING_FORMAT_PATTERN[myEncodingFormatIndex], myDefaultEncoding)); - file.addBefore(encodingLine, firstLine); + final String commentText = String.format(PyEncodingUtil.ENCODING_FORMAT_PATTERN[myEncodingFormatIndex], myDefaultEncoding); + final PyElementGenerator elementGenerator = PyElementGenerator.getInstance(project); + PsiComment encodingComment = elementGenerator.createFromText(LanguageLevel.forElement(file), PsiComment.class, commentText); + encodingComment = (PsiComment)file.addBefore(encodingComment, firstLine); + + final FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(element.getContainingFile().getVirtualFile()); + if (fileEditor instanceof TextEditor) { + final Editor editor = ((TextEditor)fileEditor).getEditor(); + final Document document = editor.getDocument(); + final int insertedLineNumber = document.getLineNumber(encodingComment.getTextOffset()); + if (insertedLineNumber == document.getLineCount() - 1) { + PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document); + document.insertString(document.getLineEndOffset(insertedLineNumber), "\n"); + } + editor.getCaretModel().moveToLogicalPosition(new LogicalPosition(insertedLineNumber + 1, 0)); + } } } diff --git a/python/testData/inspections/AddEncodingInEmptyFile.py b/python/testData/inspections/AddEncodingInEmptyFile.py new file mode 100644 index 000000000000..376db9193fc4 --- /dev/null +++ b/python/testData/inspections/AddEncodingInEmptyFile.py @@ -0,0 +1 @@ + diff --git a/python/testData/inspections/AddEncodingInEmptyFile_after.py b/python/testData/inspections/AddEncodingInEmptyFile_after.py new file mode 100644 index 000000000000..76ea4ea7c759 --- /dev/null +++ b/python/testData/inspections/AddEncodingInEmptyFile_after.py @@ -0,0 +1,2 @@ +# coding=utf-8 + \ No newline at end of file diff --git a/python/testData/inspections/AddEncoding_after.py b/python/testData/inspections/AddEncoding_after.py index ef08f90863b7..974d8ff7f054 100644 --- a/python/testData/inspections/AddEncoding_after.py +++ b/python/testData/inspections/AddEncoding_after.py @@ -1,2 +1,2 @@ # coding=utf-8 -c = "string" +c = "string" diff --git a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java index e49b0eaee6c8..c7e8d138aa83 100644 --- a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java +++ b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java @@ -349,11 +349,18 @@ public class PyQuickFixTest extends PyTestCase { PyBundle.message("QFIX.add.super"), true, true); } - public void testAddEncoding() { //PY-491 + //PY-491, PY-13297 + public void testAddEncoding() { doInspectionTest("AddEncoding.py", PyMandatoryEncodingInspection.class, PyBundle.message("QFIX.add.encoding"), true, true); } + // PY-13297 + public void testAddEncodingInEmptyFile() { + doInspectionTest("AddEncodingInEmptyFile.py", PyMandatoryEncodingInspection.class, + PyBundle.message("QFIX.add.encoding"), true, true); + } + public void testRemoveDecorator() { //PY-3348 doInspectionTest("RemoveDecorator.py", PyDecoratorInspection.class, PyBundle.message("QFIX.remove.decorator"), true, true); From f79ce8cc9ee16660f59afc6e601fe9769ef63432 Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 27 Oct 2014 14:10:57 +0400 Subject: [PATCH 08/55] IDEA-106103 XML editor: Allow highlighting of different namespace nodes in different colors: XSLT color page --- .../src/META-INF/XmlPlugin.xml | 2 +- .../intellij/lang/xpath/xslt/XsltSupport.java | 4 ++ .../xpath/xslt/validation/XsltColorPage.java | 61 +++++++++++++++++++ .../xslt/validation/XsltNSColorProvider.java | 37 +++++++++++ .../xpath/xpath-view/src/META-INF/plugin.xml | 3 + 5 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltColorPage.java create mode 100644 plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltNSColorProvider.java diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index 64f737ce376b..00f42a06cd93 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -116,8 +116,8 @@ - + diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/XsltSupport.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/XsltSupport.java index 3a412bf3ca8c..68c031cea400 100644 --- a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/XsltSupport.java +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/XsltSupport.java @@ -15,6 +15,8 @@ */ package org.intellij.lang.xpath.xslt; +import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; @@ -47,6 +49,8 @@ public class XsltSupport { public static final String XSLT_NS = "http://www.w3.org/1999/XSL/Transform"; public static final String PLUGIN_EXTENSIONS_NS = "urn:idea:xslt-plugin#extensions"; public static final Key> FORCE_XSLT_KEY = Key.create("FORCE_XSLT"); + public static final TextAttributesKey XSLT_DIRECTIVE = + TextAttributesKey.createTextAttributesKey("XSLT_DIRECTIVE", DefaultLanguageHighlighterColors.TEMPLATE_LANGUAGE_COLOR); private static final Map XPATH_ATTR_MAP = new THashMap(10); private static final Map> XPATH_AVT_MAP = new THashMap>(10); diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltColorPage.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltColorPage.java new file mode 100644 index 000000000000..e4f7f43057f0 --- /dev/null +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltColorPage.java @@ -0,0 +1,61 @@ +/* + * Copyright 2000-2014 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 org.intellij.lang.xpath.xslt.validation; + +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.options.colors.AttributesDescriptor; +import com.intellij.openapi.options.colors.pages.XMLColorsPage; +import org.intellij.lang.xpath.xslt.XsltSupport; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.Map; + +/** + * @author Dmitry Avdeev + */ +public class XsltColorPage extends XMLColorsPage { + @NotNull + @Override + public String getDisplayName() { + return "XSLT"; + } + + @NotNull + @Override + public AttributesDescriptor[] getAttributeDescriptors() { + return new AttributesDescriptor[] { new AttributesDescriptor("XSLT directive", XsltSupport.XSLT_DIRECTIVE)}; + } + + @NotNull + @Override + public String getDemoText() { + return "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + " \n" + + ""; + } + + @Override + public Map getAdditionalHighlightingTagToDescriptorMap() { + return Collections.singletonMap("xsl", XsltSupport.XSLT_DIRECTIVE); + } +} diff --git a/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltNSColorProvider.java b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltNSColorProvider.java new file mode 100644 index 000000000000..6687c71e70c2 --- /dev/null +++ b/plugins/xpath/xpath-lang/src/org/intellij/lang/xpath/xslt/validation/XsltNSColorProvider.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2014 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 org.intellij.lang.xpath.xslt.validation; + +import com.intellij.codeInsight.daemon.impl.analysis.XmlNSColorProvider; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.psi.xml.XmlElement; +import com.intellij.psi.xml.XmlTag; +import org.intellij.lang.xpath.xslt.XsltSupport; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dmitry Avdeev + */ +public class XsltNSColorProvider implements XmlNSColorProvider { + + @Nullable + @Override + public TextAttributesKey getKeyForNamespace(String namespace, XmlElement context) { + if (!(context instanceof XmlTag)) return null; + if (XsltSupport.XSLT_NS.equals(((XmlTag)context).getNamespace())) return XsltSupport.XSLT_DIRECTIVE; + return null; + } +} diff --git a/plugins/xpath/xpath-view/src/META-INF/plugin.xml b/plugins/xpath/xpath-view/src/META-INF/plugin.xml index 840cccb76aca..0be80ec48645 100644 --- a/plugins/xpath/xpath-view/src/META-INF/plugin.xml +++ b/plugins/xpath/xpath-view/src/META-INF/plugin.xml @@ -145,6 +145,9 @@ + + + From 986a786650469d1181f4a005fe450a5123c1ee7d Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Mon, 27 Oct 2014 14:58:48 +0400 Subject: [PATCH 09/55] DSGN-869 New icons for task management --- .../tasks/tasks-core/src/icons/TasksIcons.java | 10 +++++----- plugins/tasks/tasks-core/src/icons/asana.png | Bin 737 -> 325 bytes plugins/tasks/tasks-core/src/icons/asana@2x.png | Bin 0 -> 594 bytes plugins/tasks/tasks-core/src/icons/assembla.png | Bin 635 -> 358 bytes .../tasks/tasks-core/src/icons/assembla@2x.png | Bin 0 -> 802 bytes plugins/tasks/tasks-core/src/icons/autoMode.png | Bin 397 -> 398 bytes .../tasks/tasks-core/src/icons/autoMode@2x.png | Bin 0 -> 866 bytes plugins/tasks/tasks-core/src/icons/bug.png | Bin 568 -> 471 bytes plugins/tasks/tasks-core/src/icons/bug@2x.png | Bin 0 -> 1210 bytes .../tasks/tasks-core/src/icons/bug@2x_dark.png | Bin 0 -> 1290 bytes plugins/tasks/tasks-core/src/icons/bug_dark.png | Bin 0 -> 470 bytes plugins/tasks/tasks-core/src/icons/bugzilla.png | Bin 766 -> 775 bytes .../tasks/tasks-core/src/icons/bugzilla@2x.png | Bin 0 -> 1909 bytes .../tasks/tasks-core/src/icons/exception.png | Bin 611 -> 426 bytes .../tasks/tasks-core/src/icons/exception@2x.png | Bin 0 -> 862 bytes plugins/tasks/tasks-core/src/icons/feature.png | Bin 649 -> 472 bytes .../tasks/tasks-core/src/icons/feature@2x.png | Bin 0 -> 965 bytes plugins/tasks/tasks-core/src/icons/fogbugz.png | Bin 804 -> 546 bytes .../tasks/tasks-core/src/icons/fogbugz@2x.png | Bin 0 -> 1219 bytes plugins/tasks/tasks-core/src/icons/github.png | Bin 397 -> 469 bytes .../tasks/tasks-core/src/icons/github@2x.png | Bin 0 -> 1020 bytes .../tasks-core/src/icons/github@2x_dark.png | Bin 0 -> 1275 bytes .../tasks/tasks-core/src/icons/github_dark.png | Bin 0 -> 600 bytes plugins/tasks/tasks-core/src/icons/gitlab.png | Bin 628 -> 518 bytes .../tasks/tasks-core/src/icons/gitlab@2x.png | Bin 0 -> 1161 bytes plugins/tasks/tasks-core/src/icons/jira.png | Bin 665 -> 326 bytes plugins/tasks/tasks-core/src/icons/jira@2x.png | Bin 0 -> 645 bytes .../tasks/tasks-core/src/icons/jira@2x_dark.png | Bin 0 -> 636 bytes .../tasks/tasks-core/src/icons/jira_dark.png | Bin 0 -> 326 bytes .../tasks/tasks-core/src/icons/lighthouse.gif | Bin 664 -> 0 bytes .../tasks/tasks-core/src/icons/lighthouse.png | Bin 0 -> 847 bytes .../tasks-core/src/icons/lighthouse@2x.png | Bin 0 -> 2322 bytes plugins/tasks/tasks-core/src/icons/mantis.png | Bin 843 -> 732 bytes .../tasks/tasks-core/src/icons/mantis@2x.png | Bin 0 -> 2045 bytes plugins/tasks/tasks-core/src/icons/other.png | Bin 423 -> 141 bytes plugins/tasks/tasks-core/src/icons/other@2x.png | Bin 0 -> 183 bytes plugins/tasks/tasks-core/src/icons/pivotal.png | Bin 567 -> 289 bytes .../tasks/tasks-core/src/icons/pivotal/bug.png | Bin 735 -> 471 bytes .../tasks-core/src/icons/pivotal/bug@2x.png | Bin 0 -> 1210 bytes .../src/icons/pivotal/bug@2x_dark.png | Bin 0 -> 1290 bytes .../tasks-core/src/icons/pivotal/bug_dark.png | Bin 0 -> 470 bytes .../tasks-core/src/icons/pivotal/chore.png | Bin 416 -> 232 bytes .../tasks-core/src/icons/pivotal/chore@2x.png | Bin 0 -> 303 bytes .../tasks-core/src/icons/pivotal/feature.png | Bin 382 -> 472 bytes .../tasks-core/src/icons/pivotal/feature@2x.png | Bin 0 -> 965 bytes .../tasks-core/src/icons/pivotal/release.png | Bin 514 -> 501 bytes .../tasks-core/src/icons/pivotal/release@2x.png | Bin 0 -> 1069 bytes .../src/icons/pivotal/release@2x_dark.png | Bin 0 -> 1132 bytes .../src/icons/pivotal/release_dark.png | Bin 0 -> 520 bytes .../tasks/tasks-core/src/icons/pivotal@2x.png | Bin 0 -> 518 bytes plugins/tasks/tasks-core/src/icons/redmine.png | Bin 381 -> 308 bytes .../tasks/tasks-core/src/icons/redmine@2x.png | Bin 0 -> 639 bytes .../tasks/tasks-core/src/icons/savedContext.png | Bin 510 -> 205 bytes .../tasks-core/src/icons/savedContext@2x.png | Bin 0 -> 278 bytes plugins/tasks/tasks-core/src/icons/sprintly.png | Bin 685 -> 775 bytes .../tasks/tasks-core/src/icons/sprintly@2x.png | Bin 0 -> 2210 bytes .../tasks/tasks-core/src/icons/startTimer.png | Bin 537 -> 643 bytes .../tasks-core/src/icons/startTimer@2x.png | Bin 0 -> 1483 bytes .../tasks/tasks-core/src/icons/stopTimer.png | Bin 393 -> 515 bytes .../tasks/tasks-core/src/icons/stopTimer@2x.png | Bin 0 -> 1141 bytes plugins/tasks/tasks-core/src/icons/trac.png | Bin 727 -> 328 bytes plugins/tasks/tasks-core/src/icons/trac@2x.png | Bin 0 -> 643 bytes plugins/tasks/tasks-core/src/icons/trello.png | Bin 390 -> 205 bytes .../tasks/tasks-core/src/icons/trello@2x.png | Bin 0 -> 283 bytes plugins/tasks/tasks-core/src/icons/unknown.png | Bin 452 -> 168 bytes .../tasks/tasks-core/src/icons/unknown@2x.png | Bin 0 -> 315 bytes plugins/tasks/tasks-core/src/icons/youtrack.png | Bin 334 -> 554 bytes .../tasks/tasks-core/src/icons/youtrack@2x.png | Bin 0 -> 1120 bytes 68 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 plugins/tasks/tasks-core/src/icons/asana@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/assembla@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/autoMode@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/bug@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/bug@2x_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/bug_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/bugzilla@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/exception@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/feature@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/fogbugz@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/github@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/github@2x_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/github_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/gitlab@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/jira@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/jira@2x_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/jira_dark.png delete mode 100644 plugins/tasks/tasks-core/src/icons/lighthouse.gif create mode 100644 plugins/tasks/tasks-core/src/icons/lighthouse.png create mode 100644 plugins/tasks/tasks-core/src/icons/lighthouse@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/mantis@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/other@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal/bug@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal/bug@2x_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal/bug_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal/chore@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal/feature@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal/release@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal/release@2x_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal/release_dark.png create mode 100644 plugins/tasks/tasks-core/src/icons/pivotal@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/redmine@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/savedContext@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/sprintly@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/startTimer@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/stopTimer@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/trac@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/trello@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/unknown@2x.png create mode 100644 plugins/tasks/tasks-core/src/icons/youtrack@2x.png diff --git a/plugins/tasks/tasks-core/src/icons/TasksIcons.java b/plugins/tasks/tasks-core/src/icons/TasksIcons.java index 68a2e24608ea..0beca234c217 100644 --- a/plugins/tasks/tasks-core/src/icons/TasksIcons.java +++ b/plugins/tasks/tasks-core/src/icons/TasksIcons.java @@ -40,15 +40,15 @@ public class TasksIcons { public static final Icon Github = load("/icons/github.png"); // 16x16 public static final Icon Gitlab = load("/icons/gitlab.png"); // 16x16 public static final Icon Jira = load("/icons/jira.png"); // 16x16 - public static final Icon Lighthouse = load("/icons/lighthouse.gif"); // 16x16 + public static final Icon Lighthouse = load("/icons/lighthouse.png"); // 16x16 public static final Icon Mantis = load("/icons/mantis.png"); // 16x16 public static final Icon Other = load("/icons/other.png"); // 16x16 public static class Pivotal { - public static final Icon Bug = load("/icons/pivotal/bug.png"); // 14x14 - public static final Icon Chore = load("/icons/pivotal/chore.png"); // 14x14 - public static final Icon Feature = load("/icons/pivotal/feature.png"); // 14x14 - public static final Icon Release = load("/icons/pivotal/release.png"); // 14x14 + public static final Icon Bug = load("/icons/pivotal/bug.png"); // 16x16 + public static final Icon Chore = load("/icons/pivotal/chore.png"); // 16x16 + public static final Icon Feature = load("/icons/pivotal/feature.png"); // 16x16 + public static final Icon Release = load("/icons/pivotal/release.png"); // 16x16 } public static final Icon Pivotal = load("/icons/pivotal.png"); // 16x16 diff --git a/plugins/tasks/tasks-core/src/icons/asana.png b/plugins/tasks/tasks-core/src/icons/asana.png index 25cea963476622af16df96939796061006fcc1fd..2d2958fc7f7384bd625d14b417f44aab9a5e07bf 100644 GIT binary patch delta 309 zcmV-50m}a21;ql88Gi-<001BJ|6u?C0Srk*K~#9!t=OJ~3p`kTsNP1*gPIv@yZAbmCa~1sr1` zAAZ1=wMw`^TzYZ>p7H7q=*gAkabQ@d=-0sp_y3f5L??~(!jNnR6Xbd=)mi1fc z%av8}D4i%zfG+LrKugJ6&=2MdTg=hKnH1e|bzq10GX?Pn08TKDo^HBa00000NkvXX Hu0mjfbRCnQ delta 724 zcmV;_0xSK+0^tRa8Gix*005AYXf^-<00DDSM?wIu&K&6g000SaNLh0L01FcU01FcV z0GgZ_00007bV*G`2i*l04jeA;*tLR?671E4=e+N8dtKbwA3=npQ<798&NBo6a%AaMSYs}Tj)I^dK+f7$_nza{Uia;J!AdalPdA{*J5J5I&3lli&Qu5I<- zIpd8C%{(tQ#KN@S=nwJO(2q0n%wdux_ z_V(`h$-ilueGVP-rJ1GFmR6M>wF3aif~Q6^efHDj!7;l<8FJMRwo=ZQd(A7Qzpzwn zE-!uadv)W{Oag(>ru4%?&*0_EklR@{kOT+-7AgyOpZ>RY zs=T&!>VMs{zDi0!GOIHM=Um4*Q4nCHQX3>nC_MTRO;$3JCMf{kiS)nzGvAw-0|?N^ zP`Y&C<+wB9m)q4xuNSKW-;2(ZRhvhX^xz0T4D(;(94Ja+44vpceY5xZ-RZ3%e?D=i zi&P+asD>X~F*<2VHG_zQHe^Z4LFTqz<@NXaH%)ib{b%*wxSc06sT;Vyn6GSfuC8`Q zRsQ;6(~p$I$A6DN5*d~fMrS4hApQr#3}^SO{%CXn00007MhQ!y(JE<0m=(1N@o*g&nhM(x4fpVFNDU z7G(PM!zy^84q`RtF&!Wi=HQJMGwL2jAl^=Z8VH(PnDf&g@i}kRLgp800Se%eO|}bz z&;Uh{L-N1_?evKxHZA}OW&^AX6P$uu>zk^Gf*yDh<``xH${+yeP{jje3j=Q;)x_eW zR$-oF7T^SA;^zU{g@HpB7gr>+Pay`_7Xk!$fG#>}%4f*85ujctKrtMG4@!;nfEh8g z2Oe|+gxrKiMS=?|pcCe)1JsVBtpMS4l0ZN1(@bCa(G!b9q8Ma^?TA&iLAW>(JXa(@;^+2skm9~M?!imrd zaG=)%ORWE$HjbpE(*p-uJ#Z!rsl z?uDuUn`dSJZK5zZzxH$~$PqGYHwJQK@KzL~fc?J}8Rs3JP zHS~XcO*450fJLIQcX7)9#u+)}834kdL;^}UX-#z`8}J8NBDucde{@9~Jic+|2TC&2 eFO9XK_Daqzkr`3KbZ|8nuZg1`OcF%`NCjW4urzH{;!K`TM;$(>hHs@k?I& z^}YB1z2!@#EgdmSe_KlzAl_kZyR?4wwnHqN;op$(MW+Qo=bYL@SuRRi26)vpdj>hbw%a?>+%&JaSj$+~Hzgb)*tNR0jT^&0{k68 zj!YqPWgfrR)_)ifzB~uHSFaes9WqC#SfXYu(W&Gx|GtR)%kOx#w2J3%m*G@%<`Q$} z5>v(!>0{f0VQlZth*uaxeeWbTwvBRS^};O94!!0(`6wobjaP7o%vW%>4>5pd;?}yy zpk10_(WYRQyP>09oZ*-(a=dDWHKb+0)~*CUC6VpHG=E-vEMoEV4>-DR!`6|-*X3VW z_)rwFl-YioHD!RSGsa8tiZQBM;#@Isz5uB?329#f(QC8p+t3>0>eN1I$^e>$h&AoQ z&<391Uq>5wike_jw4Y=#14wLi5l2|I!MiW3@Q6x#qLacV;8rsDw(=8imWrH1 zxuwEo09;vh>mXO^zxoXJwxke_u-O6$oVz*4vFesVY&P@D04qe=dmZ+G@&B-zZNCw7 xTErEA5`?~~McN5Hm0=0?S##C}SUdS&{~s0fG#0pUwpRcE002ovPDHLkV1jhTEcO5Z diff --git a/plugins/tasks/tasks-core/src/icons/assembla@2x.png b/plugins/tasks/tasks-core/src/icons/assembla@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9b2e1daa0276dbffe94071f99c5b9a492dc8ccfc GIT binary patch literal 802 zcmV+-1Ks?IP)CMBCs)6H!rA01&W|5%A9d zgeqzRML0#cMPQv``qvtPo&c_{bv9^8aaZwg)PXj>oNIt z2g;h1$gfr--cafbfZG#**9ozDEBc3zp`|w#vkSra_UzO(%O?>suqH7yyy?0hiZP3&QJBhv{}R!f_Kv5$KhVED};&Va2&AuRw2 zuC_f1=4&dhfEcY!S^!#{MEH3+gu7c|eTK9E?y`Qr1 zdVD|keMvJw5u>v~Q>o{%L}-FquA~4IT8EC$0-cYe*o-35T+#wiB#ADVY%an*QI4jX zEa?G$H>WG&a1xnW)r&H{=eGas@1;SH-gmQxs9Y95uvm)8Q|-sp>o?Qd7J g=?%G>{kON{pB9+uWQo#4R{#J207*qoM6N<$g2@$f%m4rY literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/autoMode.png b/plugins/tasks/tasks-core/src/icons/autoMode.png index 9355db4b2de6ade4c4aaa23145cd3bbc2da88c35..8b4cf8c4b6cf64b88320fb281239d4eac165a0a4 100644 GIT binary patch delta 371 zcmV-(0gV2Q1C9fbB!5*&L_t(|+NG0APQm~XhK(!TcmQ4Us0At_mS>@8X+Q$@^jO==NPSDsHI<2YBGSms7wK@7q25Ff%U?ZQ|OLwD_gD#O%98t8=pXestD z>vvJ;1%FnZWo+k18fYtC7+T>WR-3^OO7I28?m%;KF)uR41nx6$o?!Kl}h0Y zmF2t}#vEH-JYwWh1HR!9BA{xUFcrK{#Iegfv4KlWfP2`7vwyV>vgGd(*|nrLO;1TS zpxbe9j|X5o{g8G7WF-jVl1n08)(o z$jWsT2Hu}lXKR_6kp>GDFO0455KGPAE5ZAMV|SptK~r3X zzP>(SLGbppWp`4UpWqHu1t)X@2W^#oRu`O>i7!!kW{0N4R24a!{9nKE9h z!oAzC$}?a&4%wbdrfts=V{d_WTEas`B2NOA5i3EXPL0!(6ihUz;(JYQ7~24{Fp8AL z7;qh`1Oa*VdJ4j=29{}CO8~Kn+Ro|v@*)pF*1h+RTh_2la(tisMuWUsjcmu6VVv(` z*A=}dD@J1AgqEDc6BV#gBM;IzzITe7#yZqm!(~Tr=@%n;;CDkQ#=wR}j+RA(s8(T6 ztA)RJQ0>$|VnCh@@Xk!If$s1cHFCiSyfVcMzJru4BxOYaWO_hKNy&iF8@O#zr5XT4 zU3ZDYO>+(ZuLJnxux&WB2l_<{!ZgSZJaV-pHAv!AE~f@1no*<9fjoz+9thSms0#pI zy-K$0oaF}J#HFR?>Lsf*0|_)AHY6Z3+axRS$(g9>PY#I|6ldEPR;Qcg<^Z&oG8sA) zfG~q;86Zc1F7e5%*wYMS{QSd<^M5>y^41_H=PkxH2s;I%J<>Hei#j3e2Y_XpP%i7% zD?Rs--16NW#c1|JYwKfS2BbQow&X&usz+$$`|svo#C^{L1D+Q@&I8B8r^NaK>8{II zyxhIIG5A0-gb7k(6=RL*2atTZ0DurT+?66(i^E7oNFE=Cxd3uJ zFth~kl~mV2`JPT19dt;95y>RU1(4|hU41SCiXOvgcam<@i4VfGYS6FI_if=4b6_BV zZ@7LFls^-lF6rc=gQ|tdoE?A516!Dqb4esV$8A)NNV+k>e3Un~3U+}!ik}PR(F16^ zBEnee#Nx0^Ni2FDQ}DeY-vcLf`~;)T!f0A_o#>Zy>x*;=>#WOQA8PG9`0U&`>k>2iSWBk{hO9*;;J|XBg5WhYbA9!VVOyKF$ zkv^$-4LBR?H}P_M`2U*)3IFeurv6`2kn#U+dD{Qm#mWD#Wq(J{IG+$G4$_pIoV+O` zBjYcKh8u7;+9&c_R@DD{<>~())#d(w(vbfjs2EJ&ugF*mWV-|LYY+|6jNyVy$stGY z0c{0oT3(X#|4Drw7(cAe`hO!Q)(j|q7$gU!F}-jgF7W%w?3n+j^5RkOvGj=l7vclB zfQo-W4fu@J1%GE!!@gcAO#FYf2o;~pi1>dd(hFq3PrL?PPY*wEzc>l(g(Z1u{~wej zgYivZxSR=dw%khB$cXMO^-v`D341+Y>%8dMfF2ZwDR%V6=-arIJLw=5)1&eX)Nz0)_c1E0000?m)$M?s@i}#c*Aw&Z(h}KCzze{w5wF9(GpVp@F78k^U~};U0Ew z`HsG2;hxsjkyhD37R~W4?b+U$ei|nB@%J6np4e&p?_cg8-4>kMAD%rmCVzIKw@y~& z{K62eqEPJ?H`7*o!8S9wu3WDkC!xtM^0T}I=V$9Lv=>^m{nBD{p~X((Yr{m>?Z3W$ z-_^}W?`(+_-Qy{Cz)SR!hr(4ag&Y2MHv;u;d8#;g7CyAoc;sT};9L5{PV42iC0{nJ z{O_Fn-z(#PQTPAq>Hj+x{O?=l6W;uP;)?(4cK+Xf_^z|cEoCuzV328*1o;8Oj6qpL z+te&RIj_2|W9p1qv*)Z{yLRKI&0Dtb+`W6x(UXs!JbC`<^XH$x{xH=!169xUba4!k zxSX8e!p!5q!t#hmpdr>_PW#M8VUGOWb@C;^Slb^e5{ACZRn#JTiwArf)KO@NJGn b3gTe~DWM4f4>I4L diff --git a/plugins/tasks/tasks-core/src/icons/bug@2x.png b/plugins/tasks/tasks-core/src/icons/bug@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2fc69150f98f346cc4804b7f42abab03fc625254 GIT binary patch literal 1210 zcmV;r1V#IaP) zVjAj|U}|DCYE5drV!@@$E;nf@%U%H4wWOLD(+3R?&FB9tXK~ofE=w2EhhNT|Z)VQ_ ze=alUd|5=4buU@Ds1Ss;cmVW+{4}0j#d-|%fD!OBcpW^M(AWpyJMgfA&?De;{yrn` zZVc?@0vEs~FboVbk>_~hZzvde3w+4m9RjwyF_4If3-0ChE#Olg+bMhQX>ficrXZ2+ zT&zbHE99~Lve+5$+GZHY(hGw3grEt2D->Vw2t@;fg6eO#P;|$$%pw?mUnp5PE@(z2 zp*%bOo+L>rShgMq@_~(|Aq!GPq{35o0NN^=cZ>7T>}< zRT&#VBTo%$Rnxx8l9PA>v>OFQ{dI9+>><`6l%55!bt~3JJHLoqpRp^ zb&wO{tc=GZovvWJUD^TBMP`n}t{>#R-@T>*Penn&1m-)~Ttf@5I3Qq;^^%p*4p&O% z+r>7B*<|8z%xNz|pF!O_Z8y^VagieEy72ce9B71lWbunbs z(L{CGeGpqxFtC*N2n3pIZ%5do>uy{Z;g{-Z)S%vyv4K#V)gSF}F0XvBY7z3765%!r zjc8SmK`g3ZAe#0R_(lD@b1k(rk57;xUxe|P5;L|+@(G3eGhT#KmWtePqnYOL88UjE zR&t^dR>osW_$56v(3SCL$bLj2d)3!-jYlXIy$&n6m@$;B9uN&Qs#7h#Z4@3?_z~ss zp?@eX1AeP^XV_VNYZjYJGFGNW5@YoszMKhT3Aqm*=#xY-5BFv{d0cD;oJ@N+42p(5 zvySRN0V(m3&4Q^BVf7*6h{f(_mrV_g7xX%?H^su{ZfB`~s%=W>l7PI}VEa zU17U%08lyv@B{l5Tes)X^E6nLM^_4ReKG^v!D%p+)^;2xVAb6p77gYZu`(FOFsCAf zbud#WU@A)g87VI~Go(JSE#nhW96=D=r;OT}VXM9uLj5-y41f6>40mwN_ydf6QLB%h zH|Z|IM9xN^3AX}o!iiVlhtgfL7(0-Pn{gU?+GYLF7yDLz2{tP1jjjYPN4f@&XwwEBbNMlGA&| Ye|zs)5^k8ChyVZp07*qoM6N<$f;3PqtN;K2 literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/bug@2x_dark.png b/plugins/tasks/tasks-core/src/icons/bug@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6d02836719e9a80e4fc2c18852f6cf061f5eb6fd GIT binary patch literal 1290 zcmV+l1@-!gP)!Lr&2Dl9@7WL;y1(%Uc86YU*$sZKok$P}`%t zei_JdT2E;SVg=koo%Qi-VrqMyXFGx%+H?Vg-j6@u1TLUb$>p6l48aNwyHj90T zAh&W4IAwW1#BASp5g+m^Wjc|7e3!i7FHcPg%(Io8gU~?(tXRzu?rMa={bp!1urT>^*MKds`S7uIC7vI4X@HTaN2Dw0m$OHvUl;u9{R!IK5SXU0d=6$f- zVSoraxQvdXn9w=PvYZIMJ<{FOg=1tR%am*?z-znyOS}XQsVL1Q&mX_2l|caCdgV0} zL^>^;06v5JO<*B2fMwJc?zH$%d~oc39QXP`=nAjUrP1^Cegv;c!s55cU z?*s&#Nm{^gg(NiAAP1LO4K7O!*o;~*qX1Hpc03#ysIywxLpW$eKmf6|@uEMzfOC~a zSIJ;5Q}w#AYb(H0T}+PXYXSnUB|QTe^?!#uacgxqu8Uw>JxnPiTT&L_Z`B4?tR&#f z95)A{IWB=#4Y*}_Bo$v45D-QzNiBi5LEgJe_I`_oV=V}gs7;7Py%OAIVv?r66%g=E z(laoxDa%^IBQ?}i%h7MD2ManUWz;5wS0_gSxrcF3RzQGyUAe$-RGnUGtbs)Io3z}l zkdm|)^$M7($p7ujCN_2%Nc~OO@s-*x%dLsPfzJM8YrmFZ4w^YAZf=BA;x=m(g~5qSq7=;#OpR9;5c<~7O^6a$2d7n zznszq1l)F@%G3Wps>}WVq#^%5&_!VSenrMo zphkBfehs2QnlW5(DLLfmJ)o^1P0LGi{y(YD1LKF)S^sb3#F_yW9|q$8P#V(<2jT+1 zpUjT=e=08?1s_X~_eqi%{{ojEMhdBE3Kc{KRX( z_4M!q_luLjURaWs_WwaiG8o?khRc~ScUyv9xEvoCa5p#h|9xN#z%aVgtWG$ ze&dy_n4NdhBcI&Oi2MztUtdoQzOp|f?%gpjTl@)$*rZIG%tQ$W0M`L**dpk#^8f$< M07*qoM6N<$f-kG!X#fBK literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/bugzilla.png b/plugins/tasks/tasks-core/src/icons/bugzilla.png index b06da57f512e72d9489c04e5386c21cbce3aa4b8..7dc4666337d28f036a240e2f0b5917a97692e9da 100644 GIT binary patch delta 752 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 literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/exception.png b/plugins/tasks/tasks-core/src/icons/exception.png index 3edaf7ab9785581055475a5fbaa74a30f98e92d1..02ce6b16d34899701987234cc1e7648d5bb79905 100644 GIT binary patch delta 401 zcmV;C0dD@|1gZm&BYy#LNklG4AaLzf&n*?4Z&vs z0~QPtmjdGJFhg(}u(#8h0Ue{e23d|M1CR_#1Yx2L*i`Q&d7;Jd-_;J?|H$}Ko8JGO z4X)D(yP(Bo^^GYe|L@E(`+sMy8JNB?%lzN|Zm%MOF4$1#!+(CJ&-Ux>1=j!XFS7yT zTZ@oXjgJ3sEp+^UWsc*Yy}dz~Hr9EW5DtSD=iBF| zx%|I6&lQZX0P)3{F8`1BI{n|*X#aOpmDAzXeo z;dSfmOwT{3r+>NsKQ_Vb|GsvY{~M~^W|I_+yC%i#KRMO=|A{GH|MzxzFI`pX#YmC? zTiXNf9qRY~zrWXe^ZGhZW~^a=1GmhXIX!h#z5B22T|w8^*SfLc3`AT8%UA_x7+M`NrSHZ& z*e?e_gL_!`pMq>zGszTHqzei-UV-yg9O3wPbYGlel6`*_u&SAoYLYIfSf$}q{-+=( zXqcQyG$pOp0^07nq??qgI*Ou>0_D-Oj~h6y1aaZ!M8Zv+{A=j4 zh=!pfG!rfPI>@#yf~sQRyz3zrK5-~}T9G_Uu+U8qwSN(Wj}e59x4?gdV61&R?zLG7 zWCOW%4VuyT?a|a+5^sBV!{15ZbL>Sn$E(9_79)sMFuy99yiZlJ$Vp(T%y1WcwDJq* zA!u?HZqLNm@xvB^O3k1_(IoywL@FzzGUtQ;XbWaXuhXz(er;R7H${b81%hO3d?b;| z*qZDh$V4V)VQ4A@dd63DQ!w?XU|?{1+17uTYrQmbG;xbnodK}E3zU1Y8-CGF$ Zmmfb*@12dFT~Yu5002ovPDHLkV1h{#8SwxB diff --git a/plugins/tasks/tasks-core/src/icons/exception@2x.png b/plugins/tasks/tasks-core/src/icons/exception@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1d1607adb7f18b48ff796753ff25da075dd5c44e GIT binary patch literal 862 zcmV-k1EKthP)vP->1pb`q#J5($6cJ0X*pBz zMpH4Tb8Xt(m^z(VXh`)ERA7;4qQ5qwSmP{qhaNs}fA;^Lo&Wj&{{#RacvGv@5GK@( zfX8<(4?+|I{6@qoV9#GftO9QPiwHG<5FqdIH}N838Q_uU8xgAjfBy3TLoGEZzQ5yd zTr>l6yhSa*j3#}bD?JN=vZHZ(&r$mQhy>_`8M#i;IasPW53T^rRbSd25h2$j_79lK ziEAs;i?G&`0PkA=?X@yxYpQ`uir6a{ddN&%kRS2Mw(LcoS0U}?yJi7G0L zpcEJqkf1L=efL>DWumh%gBf(da3ylu)PUTw$~od$WoEx!#a(f7Ylc&?g{+u8^jP$XQ^PWgni#vg2o(dAYCTJj^QR8m)?~4V#h!-ewgXn31u; zRL_FpN|sJ1U>}IuVWd&Z^Q_I8JJx0n_?nh+hsSDp2cvo#cFT%u%uQ^V!8m`h$hf8n z3Fk=Ek7HfsjUI!T4HhZ)kC%_RHiLw7EGGAX&XOzk7qy6cQr13GBim(=u#bnb4+P`m z?+Zvz3G#Kk4slP+g2~3r&*Ng&sZe*qU>NrU8mkHhN~vI|W58rR`&*~HqBxwbI2di7 z08Kd`8!DrN`>8j(uu@^Thfy#pJ(Fo4TpQI_(6@V}MUO(c6XFVL0T!kk^%d02K*r+U o)$s&6xr(29NLQ40HPG?D02*LtfLLj1slVuv zPKP)5<{113VIcc0NDL$gQUg*8)Z-2}V0pQ3!r?~q|EHS_{(qlnH2QzC&Gi4(DJK8# z&VyhO8zcsj1F1OzRJ**wHxI=NyE=TAU7T$B|MC>G|5v7(|GzQQ;{UC=mS7BGgTz2` zAT_%>{r0b}@?}IZU{kXn*U?Enx3A2!{eN{9c6s8fzeKYxUJSG1>k5 z#pw?JvEh?b+<*V??C^`g8w>lpTyLD7?DYT46ij@m*X{qBY7a@A1}rXc7Tw+I{O|Y# z*Z;>SV&eUsF8`O8xccHWU}>R4^v+i2|A+eAfY|;2!9EW#2C)zKyZztY?(%;{iDMH^ z1D2OK&f3xH`hQ=y`{&&qZXmV^5E}#8GeKfI+uZ)IDmZuAjMIRXrS@yKG&rVjs&nK; pPjx^so~?~eX{*caF%6&u0|0H@IKjfLOcekC002ovPDHLkV1lZ^=hFZH delta 625 zcmV-%0*?LI1BnHYBYy%=NklQrO%g@uCR2H3)<1YF?L) zl`S$z+Cq~^sURsLa1!Lmn^{pr;5Pdp(ZCg~b+ty4WVRNY%(dk{a^LUAwtwfmu?XJR zE;{hzTpXU?bDsY>G5|8lz=*>yiN*enqBC6FPLNUd9X86Ub$_zI1uS1i6^6o7 zw;-D4@c7kyRnjUgAlF^Z^8%?Hk7Sldf?%8Y^ao?#3!EEzI4>!n^PU+T6X@!<;`jwC z482ygpB#d&>wg;bCJUm896C*wfTW&MO%Xu~iPy6v>5TvP|H}m}3Jk6t00peUj*kj~H zA|zCnuYf5R(Y~O=Hdh0*PK{n9$T20HzH}FKseO$IGJip^9FNa|2#Tcm;9MK(T`IIp zHe=^Ktx_x~mJlT~)1~rkK!ay1{Dm*b@M#?J9m0B7Ew(r|!yR@*JE{?9kR^h-U|zU- zoA&^evkGjQ-G~-540Y2=$fs%`e_4ZC z=Q`}M?P>;J=3$?Dm(bjl5Tx@Z;S*&FJPC}!sSiddCgiBMsj%aABjUL@dB%$H4@82& z5yxVuX*fjDn=PS7lW&r~@W;~r`>mCxTWU=BoTbq63QNx<1^>%0KcnDazqAe200000 LNkvXXu0mjf~D2NIy5PB-;p_}(4%6Yc4i>YgKGpM&7L)2tC2A6oCD+b3rcrL z3^=ulZR{1{?7RBCFzt#AfU%e4NNxLHH_&ocX&5ud!lXS4rkrzNj5(|=)xcVJ3ANFw zNeOSvN!t{})}~YP9o;(Fr-|BVm~_O#`{p??#vInL2YZ9(Q4_Us$D#%rvs3DtvJU~H zi2}cN7x=V$z^mB{1LU_y69awPIPerCz%xTUyseK3Ed3eGVGVl%y<`SwQ3JJ56SZ*% z+2vSZz^P4J({e`s;P$y>7%Gg0M@3Qd7|}(+)6!^oX^De34a9_fKA6KA_F!-DJZhpg z*)dLbty}aF^pvJ=_L$VuLuMJgsEMDCg)Fe{gV(lwWLd(ZU=4e)H+UX3iS|ryS^Caj zzJ$J-jF_QoM`lKCG`y6BFGdS5sj0nt&HLOEhNKO2tlo zA0nfCgRfdK@x&^I=T?dnIODHTfY*HZ_>#Vaj7eVn*h0foi;xpI<2B2n_eyHSk__~e zBo7Z)iD0CL<_u#v1a0SKa^42)S)%n_Mf8`!3L1v1#hhWvrO=Wq(eXEsEllgt3BhNg z;h|Z~8K#Ve);#(iZv!_@QdRB}5%?-3;HwNq3f_w302nWr7&QW zeTQWXGHStTAvvsl?+eTrq|i}BgFP!r&e=diX5!Ji7lqJYPM)Pfg0LRFg!=8D4bp?X z-)5lm5)Fry&ZoADfin;vt5vr00000NkvXXu0mjfi!{wB literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/fogbugz.png b/plugins/tasks/tasks-core/src/icons/fogbugz.png index 70c2d7ffef5829afd90add6c70b8bd4dba4c1fb5..1b1f086720ae86c33e1a635eda960ede261ee431 100644 GIT binary patch delta 532 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 literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/github.png b/plugins/tasks/tasks-core/src/icons/github.png index b2f329a2756c9b3a46f5ac2faca8801a3929e4e3..1cd6d256b56cc0bda22c6781eb59c605850df8f1 100644 GIT binary patch delta 454 zcmV;%0XhDS1JwhN8Gi-<001BJ|6u?C0h~!hK~#9!rBl6X0znY=A@oiBc>onbtDM!f zqBcH)7N#&*+9=A2K7zH1V6GBv5>1hCDFh*CPE@!QYKkv2%bl!xNeU0XV|Hie+u8YM zJpeqnK>YlEzYH(ofiNZPZA|SwuN><}pb$P&snn3Z*=n`=Vt=sBd+f7gTnX-i!Qe-? z+kKzU=ddj642EG~Fc=sd!?BkHT$(u=jb7XBHbS8gip3&Ytrj#*Lq4AeC8F2sVLTqc z1p)z+;(ao~J(c*#C)H{-(ApKvW>ZwdvD_1x;EC_a&R8r4Isu79Lf8zpxq^5+E(kc5 z8!Hp+x7+Q3oqt?D_2H@q{eEBg*xqb5tjxicKv5K!rYTBxlG$Fb*GMLlV$I6Xp5=N4 zUDr{qRz-qCu-om>Xf)92bmS{MUp0|r5?x;|m#Ek42#3RnMx!W~%aEnDXX31hK9+_h zs#GdaRTYs)ZqJR>;M1&07*qoM6N<$f}Y9MFaQ7m delta 381 zcmV-@0fPS31C0Za8Gi%-006c6H|hWY0aQsuK~yMHWBAX23a6!YmHc8t@X@4ShzPx9 z`g=nSr-BcBMrW1oK9l&scSG$H4;BR=CGYtDGxQa3d|wj;SFj|?VZYtMwu-!oCrm2Z zb0(iLQn}6WSLnTq>IEyXI?4ca z)(1YepB~%)Gw5BEditNCtAye2vM{I>VJjK_E{WRX#PBz1E=)mB0mI)_Ay5UkRMc*Q zj90jSP2)d<&SjVh8+_o73|Y@o5L)>w|QLB z^4QMs_nZNGz%hWF#q@Vk%pn`QgA9LfsbEpC&rahy$O@LRvPsU!Yz-&?ht00000NkvXXu0mjfy^*z% diff --git a/plugins/tasks/tasks-core/src/icons/github@2x.png b/plugins/tasks/tasks-core/src/icons/github@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1f02f43021eea7b2b9b9849c0885e6c752949bc2 GIT binary patch literal 1020 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 delta 604 zcmV-i0;Bzg1oQ-uBYy%rNklg^MXlz0y-o-F$q7oO5?)?j;BvX36VAfnFw{FcXf~TjBofGE zGGNt81vl5%_*E$2vr2_(wTkIu(@ zhiEj4j~g3sI8LEZC@>n0cx?La4nCg`ED#9raSR3n-hb}%^Rp1_z^AP(q|<5m{eEaQ z8rW<$PA+vd91cO#^LRY399XSZ9^7uXC9){ECkTZS6G-HQeCpU_GI5`YB+=}%*{q~I znut=V#E12DDM7#A=Y=%8yHY|XGTrTVq19?p5p+S7>5K@ZB|eQbvnRyRltdhx*ElT- zhzN=!AXQbPMHY+2pb@yB_s?V4JXmbq>-EB7HcNaEM>IAOJg*P7tTyqROeS$^w{s0p q^|$_3Hm~>P0D9{mK`d{9$^HSBTaKp$QNT9<0000mE)3 diff --git a/plugins/tasks/tasks-core/src/icons/gitlab@2x.png b/plugins/tasks/tasks-core/src/icons/gitlab@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..011d5d6bcc61f25308b9896ea907ac40cf689250 GIT binary patch literal 1161 zcmV;41a|w0P)6;mHn za7lC&hjAW6QNvNuao=aYzTaW)Fi!W*jJ6TCf&pF@sJLlWZbs{3CzX_-R1f&O7 zSJzvNK}HP2*--^N_des11M{vjUNgEGcjX8?%*e=~?(S}ij*ed8|B;L{HWXg*^78tW zo107g+@UlV?->#C@$s8|eSHKQuq8*prL?q^v|2449UW0^Z7s2Z&;0(Hg`&rd0yj6e z(TIqM1C>fekmBNE^7ZxA@>mrkfN{yR=0;#(;Fr$MPBI#ew6L&1X=!O7;37xha!yW; zad>!GOomKNO;Jot%r_p34G9U+R#sNh#KZ*c?(UMc93CE$TCJw?@^T6e4%YLUw{dZC zdKi@i+bZ+(3|j{lV{0_QmZ)w8p+!uZzK z7X7T?L}3`Q#qpql4V!g5Lxo}M0Yq^B|5(a}MPiHXEPi=)Tx@7XOx zJn0D*@UIzuetuL~SV*IzqvAM~1aZ>e-%r`u*~p+{I{f|p@f&5608))3cql(V|JY(n za5hjyMFqi4k|1c2ihRV1>#D1(u@Q}Ry|5iQK zIRa-HIS3XIKoNngtgKK$L4in1YXjrs}(9n=zJU>5gb_rqw0m{8WxCSL!NJG&d!c`9X5df$P_j{!p1My zs{_vLw;31&^SQY>*_;PCbVC3&UQXb9=viN1C+;)5tox2bHzM?Fu3!dqIP?NJ5>U=9 znUa!{Xm4-thjEaC{}Fh|0`!>^UCDUCo2;xX(PojuQcPG1{3->krQqaHH8ECHR0QMi zPIV{bg&8QTAc1D0*XtF_FpQ3jjEK{aN;b+j>!@R#JN2cM7iZ#_H#av$TB6BdXOokY z!aZ;W`hHhemmrEc8yg#xl9B@BAFR9Iscyxr86CjocVkRI~ zhpEG5fD;h^1LA{F{#qcu3&gTOJQ;}p192Wc1Ehd>JrHLhxd?`Rpe{1TWx#SE_6K57 zESh0h0Ej(+co{YWjzXRI1L|ZysPjQM28bnq_zP6cX>11gL4PGdcn=V>LS3~5h}nU7 z6Ow!ct}vL7q-Y5cvp_?C3X=F*e1XUY#JiCcZwC1niGKnX#rVxflTXf&Hps2?1dM0000OjWDhxlf7PA8BucJ$a0z3VI%Z95LO@AnFFrkHBc6+?IOV1=^6(Uz#!R$`UL3N`UWQ7uB*?!!7rbkzw17Xz4 zf-PBiUf+y*V<%>>NdZ}$1nr9k@V~8#IdHg!u|4w|NW@;u-<*l=?*q_0d5hHC5)2NF zB36DLWQiP+JJo2n^#8dEx_4g@y6G@TqykY%XD~cA34hO&7xGhDkmU-HRR>Y{s4h5( zQk>T4FlTKlwQ~S*$~;y&vUDFvw2Bhl61@kM6DeB&f^0^zQpsMH#c+sEy8;I-?aZ@e zW+w`maC^X=D~4<}$7Ijjn1SjK=Ag?#1OXJ>e?uFl84C4nreIcVGWKK_iJAW=frVy2 zA~74Gw0aUk*KOb~u+lD!KZ2@8^WQB5f;XP(F?W4BNce8leeOhCw+$gw0f|!K#MQF@ zD@f0Oz%C0fj*h!oOK&}N86<265|3UFYVja~N`o0{%}d&C1~$e#?}xFi7mw*2G__j9 b83^DP`fN>Jw#lU800000NkvXXu0mjf((E47 diff --git a/plugins/tasks/tasks-core/src/icons/jira@2x.png b/plugins/tasks/tasks-core/src/icons/jira@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3825b73930ffa01092c22409574448a6c34cd3a7 GIT binary patch literal 645 zcmV;00($+4P)$aunWzSZAfw&K)eTt9|3U>5VJtV z6VdeihlU7Q4oF8cD20f4mIdPXNO}%Xng$$!xCV%=Nl2h_KwJvMNkGg&ssl=(DV%}I z*Z_!&iE+SZXwV%8;z}U)0AgV>ECgjsDs{{DT+=?8K6Y9sn^LlHs6ye+CV2 zMapuZ1bG9CIfsaGKr9xGAY6dtfZ15&_aezB;V>hM7zcoSdLN7CFVL(9Q*#ta?lurh zK;@)?_zf2QFMybv*jx~R!w1)am>;SJL>~s?b5KiR@qPk_-V{=^;X)h+oj@x0nb6{W zBMv<~fS8d~2Y@WOh{M1GNFf1>lGQlWf{JA^atk6EAijsgU{K1J1Y#a&4#1}719~M! zPD!W&E$^{e@ES*g{SPfqY^YHkgRmkH-@;)LHvA5V&8gKMfMH>@tcMGO3N3AFHb{^$ zsA5?~zyW5|ZV@447HD>wipK$<1j$Sb2LuE0TWAFXa>PVDjwq+L0|bEhCDib*K^<;EBVBen@JJ zpsi+fHSyGNKqnT1k77}WEh^?v!vWi|7+i)$T?!U;hpFL!HE4$ZfhIt7bvn>$cQ+Dl fB-sHYu6GOoM4k6_0YL#W00000NkvXXu0mjfws8XZ literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/jira@2x_dark.png b/plugins/tasks/tasks-core/src/icons/jira@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..33cda03b2b276db88db66f34292e64504352c4a0 GIT binary patch literal 636 zcmV-?0)zdDP)y{`DJkqs)9}@lEaaN9F}tbRP*#+z6lP(88J7}? zB9RPHMrLDjEyR@Z`k#8fdODrM`@Y{1W%28)bDqopJ?DAOIiJU}EYD-&d2#|O>O1X{ z1Ac*jpdWCz$DlM-#{>pf0BGGS`k+QK1+eTHugCYoG_nhe`_Egw1Hd)1)2n!Kotme zDxi@n++&zb&|pWv87f84Pjjz{f8}?}eEwFPxP}=uljn5Ad;8cJ}vZ@I<%~ry(3am`xVF znq`}hCIoy{1fEmaskWlWgn%(c;AVxLS7A46Lcov|^qLA#wo9jLcY@LGSirOUcYF)% W&%vaRQa@b)0000tncrp<`4ESTw`101$fs@iJ@%9ECdZ2h_=aQ0Iei z3=m5I@fWC?)7T8~gGz$%9w26gx@rp$vjg!aB>4zjVK5&_(GnnLfrkDRB=NQQ0+9`f zcOxm@4Dv4${{$?G@udS!s4f4|@O~iXBa{wc8074UXa?9ItHEagGY}sK;%Ff5K{DVD z5OWY?Kr~dtUm$h^;-yH2WD{e+W~ky1Kr8~pJV5*sDI5qIa2=|64U*UdXo5P3(*SZY Y0L^wVK@5`(ivR!s07*qoM6N<$f=8Nq9RL6T literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/lighthouse.gif b/plugins/tasks/tasks-core/src/icons/lighthouse.gif deleted file mode 100644 index e12b528031e664e897c804633632d7ae103560ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 664 zcmV;J0%!e4Nk%w1VGsZi0OkMyf5Gsg(dmiB@}<)0qR{7n!ti{)?tQ%LdAjL#yzQ~x z_O0CYsoV9Z)aq5Q?MjrzhsN`R!|{K>?tZ@Pe7@~^z3zCu?@XA?bhP5G-u9~6^QYMJ zsnzP8&E-p%$$r1?dcN&-v*Aag`J8Qf4Sp>#PhG-_IthVtJv*Jn97F4@P@P(u=SF`c0-1d6D@UGqUfW7E|z3PF!>43iK zr`GL)zw3g*@Px$iPN?RE#qxo|@PNSWbG74$!Rb=2@1)V^aIoO3-Swc)=YzlLdb{UJ zr|hWM?@pV~s@U&(x#v@`@JOWRcD3Pmwd8lWQA^8LV00000EC2ui z01yBW000N|fGa2{EGsD~e2IxHBRp$D3|$Nx8zwm?3@0*68X6vaCIuAxhZ`R%2=vh7!H-uxejfM%>$R+&Kma?>31VOX diff --git a/plugins/tasks/tasks-core/src/icons/lighthouse.png b/plugins/tasks/tasks-core/src/icons/lighthouse.png new file mode 100644 index 0000000000000000000000000000000000000000..bb6dc364a52eab2a41b45bad4cde7129ee122117 GIT binary patch literal 847 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 literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/mantis.png b/plugins/tasks/tasks-core/src/icons/mantis.png index d180cfa545c797813c91f1ef283b9b99c4d39640..7e783936ba3e1f2849d0903f554fb719b3fbc7da 100644 GIT binary patch delta 709 zcmV;$0y_Q62HXXZBYy&;Nklg6y0|(FS$_5Tt)Zvy9d?2nfPV~bT%VP4`Y_Mmrp=1~ z>-VYtpR-Hq|Jftl|F$0KuK>xv`Se~OaHZAzwjDm_uo`gXxX#_lJ?j6@oZ|i;yH@-E z%j?Ylr*!N7U$a^FE=az4cUynu9<~2P>okAC4LEfDlqt-BHQRi5_cyTq|9PF^f8q?) z|F6z6{GZp$`hS1Y=DbChAK%bU*r@lbe5>03^357Q;Rd8^(EeMrsbt~%&mVbSynii} zw>WmE#$=QKj9s?>^`{#B51AW#80d8Vj1BPz>h`JqFWs#6zh#H>b+`fLn+!fw0i6}I z+V$4)J7-P){Q1L}yS8B(OO@4skygi#GY>aToOfbXYJciREpRlauGRcM|5(jbxB+vI zRtkL~zKHvDi%@mhA#alIhWp4~T2a=nxzhG(kI;R`* z69eyxP4IgC@byz^3^FCVchSl!+F r?`7HCjfMr!6ILCx|)ZUy>5DG>V`^PKlPQ`DNoGf)$d}YG1|oKfkwTB5__3xk){Tt~$e~?gA6bcN1*3E? zb7Ii3-KZ4h$rqRg&LHNekP}FNv`{&Y@qUM^`@iY1rm1MIG7}Sn+XWJL=Hf!dWLjIM zR#K##(9R}7-FzdNV1-Js>wuNUeX6jlePU|jCC=wT-`A)8V6Z;~`ul=`YCHGOzXe30q=t79VN_=g7#}Na5DIlkyYB_gr-ytjyZ(i3Du> zuCO5Dr+@He6tsAH!8n=?%3SqjDz+?s{jR$c}4hK<5hP zQ7$}&`H`I(a=06BBo-M#t|JGKK%}1-?(Y8s)Bews95M?d00000NkvXXu0mjf(GHWa diff --git a/plugins/tasks/tasks-core/src/icons/mantis@2x.png b/plugins/tasks/tasks-core/src/icons/mantis@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..211bd8bbcf839918466e99af49cd23e2085d7d80 GIT binary patch literal 2045 zcmV9sKsK-nO0iIagK#RKoUp*K}ZTJ)&&)0k%~Ai1C-5~v2Z{JWKaYYB9MSA z0U=?RE$n3r1goN;AmW0ul%gyG0o0Kt0q*=S6b}`((CM6+bLO7&&cD6;?sva;?|t{j z008@M4(xvh0FpaB4?j6o#`LjGa?G<#w5jnaKE}4M8uTZYDj@4gkl+k_+F*zZr; ze(!#7$A;G$uS;?}oN9TwXW-FC*fM2B0Fdw+OU(8q@4q!NKKed-?i(JIM%T(VfvE-8 zvSm;>yaro=tQY{2kg`a>J#n@I=OkK_OPZ$8K9<_4&M*`PWrds=9v@rvOZqn-v=O@c zdX;_^fRctXV~=$GZc?-kxE2uM^d%LrNGE|gmjpre%HWZyJ;*GKbb6D%psi7FBgPH?^A zU$=%y?4Q23DnejYAf+by__6_9yH&Ppq*;1S+=+p>8-u!P1@N!J4dV+12ngVpwGk#e z=D&#^U{H|vA!OGVSTA0qw5iTihf9SMbp-IQB!G9eS;Mjc)YaJJin|nmm$esqZ%e^U zF9reGe+2hRB79w}0apd9VWuC0M3w@KcG<%8Jq(;#UzIFMLm7IEWvfetI?kFhc$W~s zHJv=RYyg?ro9~KyujSq>TOQive_0fYYgQlO~#0hH&^LDY_c zEyMcKf_`LqipP#zEeT^jr35%pr2=kQYBS3Qa6I0sT7*+XJ+8`Zj1hU~Yu!tst5B|=PtqgxSY4p7E)@3@<;oojB(oLbx zp}<2%k>@Vy^8mar?rvHFz^9A=zI+0h^T=QvW8Qe>?oG|bAnMy1$;#meS}`UaFxKaQ zh0y?G{B)0x)j`J3_^k~(XztYX^gG)UY;K}J^~E#h9|9HdDpm#W(s?kEW!~{i036FF zicpXsx{#t?qVCl3%rGzU%*@M^@cG0GIXkv*gfxRbi$&nZPZ`Y{4>1JW1WnP%_?SGJ zcanGBcW0g!1k@5>H&YXiRuSPaM_rPJC>VKH3N4oa@GIEajB?cHCzQUms<1nc4Ey68 ziaHId6vFd+zE~3o{vV`A!`w8*5G4et4jw8na~r1)e=e1FVZQ z!M=18m?vq@r)~!61%5KFUIO4kZAdUO?4GSAscz^Vp*@T%Q&?LcWq)6`^W~XP?37E( zqQEz-fS`^?J&H$Cy;G4Pb|u5#G}fWkvXBI)a9w(!Nze9NZ7}6(fmsF_4wY;I|NLWV zuRROey6>y{en*%^!Q#XvN`eM$hkp%0LZL2)I%{>_BLT1D?mBU>9U)wAX5Be`a4gq= zAbbt;D3i{0Yy;SsyctxYbU_=>FbA$1@2$sicYp7vUIi2(^89Fl8XU>ikkGb;K@q#< zlE=}OIN%0|Y(3Cm=zu>jB5+|r{opUJ8s|_T5V3}Xb!PfT$uqXVhxkxRFo4fkhA-NC zyEgt}KfrIP-u~A@;-m*2Fy?8Rusu}^^fRbH45mLm$RUX(^_;H?Xm8!J{MZY6LB(Mq z3l+~LeMh?%)2<0)(Lolk7jjG^U{$0#FS{YhzrwSy<}C%5~zYpqi)$N{I$=F!FB< zvuLVtAwW--e)E#j9|!wBJ(fce2Gpp`eH-T=x-HJNR0^*XQh2%^Nc7BEaYvLX$lGI- zXz)}cRS!PF_x3&9i+4h4;%yA)9QU-n*ANrQwc!Dab*{ACP~}vnS=n6h=3tTZIcdCD ztqx7oJz;FxNj0 zi=xB3A)im7PUzq2358F`SGlGKhsmC$Pa}_T&p_%N9WJ#s>Ap$FFvgKD9Zs8ztXXLR0CFgrWD_`l%) b_V4&#H_j7NG4yqz00000NkvXXu0mjf@~hS2 literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/other.png b/plugins/tasks/tasks-core/src/icons/other.png index fb5256180562f4357a5622c4ad8322eb4f15163d..17988437e5203a1d8e727f404de8493743e519bd 100644 GIT binary patch delta 113 zcmV-%0FM8s1C0TYBWeItNkl+PfG`6I2Hb=h zg4Y0;Eyx%uCk4dUL57fP034HS0J=eRG2lNIJn90vxd4b6@L-}0Ac$#W0J#_d9zv1f Tl)33$00000NkvXXu0mjf#LOz| delta 398 zcmV;90df9~0jC3yBYy#INkln`E!ycg_i`2%8hZ;)B!7_s^M`2!P0c_|l|IFjm&$;R45-Ai!q06IjIN@dGw?)1bm7R(~uMwEHfn(Q{B!ZB)B9 z_D{38&bAQSzGRZ+nF5yD&>T)pbx@&V>2oTObr%;m`9QK7E}(Wf;CmghZ>a*oOAv#LU34Jr4COI3Q4GH_F?#|EP)1scRQD9!f zJ*N=nHQ%>f`hI!4w&1#kw|BITykNVbZTEnK#et(?j*cFK^Z~XFj5!aMOM3*S7BXyS hIZ)1UZ!cd2W9o7@wGzGW7C@IUc)I$ztaD0e0syziMZo|7 literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/pivotal.png b/plugins/tasks/tasks-core/src/icons/pivotal.png index 1ae1042485d468fbbedd9d5b30eff6e89b0a9b31..7dcd1252a30a5133d67ba3b3e7a9d367072cdaaa 100644 GIT binary patch delta 273 zcmV+s0q*{{1fc?u8Gi-<001BJ|6u?C0O(0XK~#9!ty4J?fyAr5@qZEMpiU)^c)HIDynL7G9+2Dvy|;<>9@`h>`oc%DI20B6t81 X2_FcC+eza9015yANkvXXu0mjfwr_a4 delta 553 zcmV+^0@nSZ0=EQ^8Gi!+001a04^sdD0WwfbR7Hrw<^KHq{{H^CJWHw)B&N~p!&zqf z{Qdj<{p|Jnjl|}v)9koAO4jQ3`ttLP#OD0>__EjTn9At<{r>y&^!57u_xkGS&O^!n=b`hTw>GOr>t?)Lky*6pw) zG_WK!&*${9B{iJP>7C5!xjRah$>^8K=$p*x`1}3R==Ii)my^fm*z5M$?DzZh^{CS9 zo6G6im!I00p#1sy#9L>@UTT!c=f+`ek;mt*9xuXIW2@Bc`t$Vc_4}^Y?fdoiuOKnq zpr_sK_vE#@&VT0g`S9`i{Qdgy@r}ji+U)k)?DwtJ?Z;(s%jEOS<@Edf{`>v@&E@p` z_xI(tyXCgL=DWb>yus+d#QppG=)lG3!N#c(ZZ-e_0KiE^K~#8NRn60m1W^zM;5ur1 zY}?k_w$1l{h3z@n&Sbu;%3lI5+MT9nVelmE8#x%1$A4u7xOQK{=;8`t@nw_uLr;@4 zLDPiKNU}Dcv8AKIF?Cf}UXynK$|-&;P_FoaM{#JDzIW-r4U~64?HMgEApRJ0gMG3H z0t^}lsr99m>s$Q3L%GWD{3smyBCGsu{lt1!0YC|f*3T9p_g`z`Llj)Yb00>AAK}Z# rZQ#s|o+6C}a{8VLo^XdTC(g@1B~ch%4|Wt`00000NkvXXu0mjfPcmK? diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/bug.png b/plugins/tasks/tasks-core/src/icons/pivotal/bug.png index fb5bdeb8edcc316ae138676ed81be275fab5463a..412b67006dc2277271510330c077e7e6293fc752 100644 GIT binary patch literal 471 zcmV;|0Vw{7P)C=%usdx=I8|ydma(ejxn*|B~@06zgUs90q|89BO|J%jM z|F307&p4kDC=Sw;oSeKVBO~K4h=v<*HrglhT2|Emd*$i>AJyglf6|cuAE+2i->=A6 z3S_$j@oNwb(v0DPOUWTe?*VNEXdd(hFq3PrL?P zPY*wEzc>l(g(Z1u{~wejgYivZxSR=dw%khB$cXMO^-v`D341+Y>%8dMfF2ZwD zR%V6=-arIJ zT4Q65adBE&TL1t6dtF^lO-xfXINxJyM@>qjK};SgDPv+`ZEkNI92`npS&4IVF+)W= zJ31U396BB&vN1uBVr3^eH(Xv`N-8a}EVH97zQ z06IWFPfbq4lZ^kgr~9OuzL}7bfP3(;q|A?rZES0EZEN&YVBm3et$26km5=jydGvO6 z^sb`quA}Lvox_ia!j+DAUt*D8W9w#a|9yb-XKe3XW8aL4{HC4kotA-dZ{Vq);+T=w zo|WUVq={Kx z_>crQD@g?2e*gdgiAh93R0tgf!7WMy004l|?>S`1f@rph2!ds02n+rMgC{VUy@MxM zwR;EK94rijK`g=$40;g}^gUHo4g5+~)yBY&R6_u?3+`5@GuXp;G};;3zQ;ZnY{BE# zpF`Jdf``u>xitsAKXQBkV7<-_fLGp)PXNz&GjRr%yhu}*c*08R+|?Ww=^yh;8EEcA R_{RVM002ovPDHLkV1mqwI9mV! diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/bug@2x.png b/plugins/tasks/tasks-core/src/icons/pivotal/bug@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2fc69150f98f346cc4804b7f42abab03fc625254 GIT binary patch literal 1210 zcmV;r1V#IaP) zVjAj|U}|DCYE5drV!@@$E;nf@%U%H4wWOLD(+3R?&FB9tXK~ofE=w2EhhNT|Z)VQ_ ze=alUd|5=4buU@Ds1Ss;cmVW+{4}0j#d-|%fD!OBcpW^M(AWpyJMgfA&?De;{yrn` zZVc?@0vEs~FboVbk>_~hZzvde3w+4m9RjwyF_4If3-0ChE#Olg+bMhQX>ficrXZ2+ zT&zbHE99~Lve+5$+GZHY(hGw3grEt2D->Vw2t@;fg6eO#P;|$$%pw?mUnp5PE@(z2 zp*%bOo+L>rShgMq@_~(|Aq!GPq{35o0NN^=cZ>7T>}< zRT&#VBTo%$Rnxx8l9PA>v>OFQ{dI9+>><`6l%55!bt~3JJHLoqpRp^ zb&wO{tc=GZovvWJUD^TBMP`n}t{>#R-@T>*Penn&1m-)~Ttf@5I3Qq;^^%p*4p&O% z+r>7B*<|8z%xNz|pF!O_Z8y^VagieEy72ce9B71lWbunbs z(L{CGeGpqxFtC*N2n3pIZ%5do>uy{Z;g{-Z)S%vyv4K#V)gSF}F0XvBY7z3765%!r zjc8SmK`g3ZAe#0R_(lD@b1k(rk57;xUxe|P5;L|+@(G3eGhT#KmWtePqnYOL88UjE zR&t^dR>osW_$56v(3SCL$bLj2d)3!-jYlXIy$&n6m@$;B9uN&Qs#7h#Z4@3?_z~ss zp?@eX1AeP^XV_VNYZjYJGFGNW5@YoszMKhT3Aqm*=#xY-5BFv{d0cD;oJ@N+42p(5 zvySRN0V(m3&4Q^BVf7*6h{f(_mrV_g7xX%?H^su{ZfB`~s%=W>l7PI}VEa zU17U%08lyv@B{l5Tes)X^E6nLM^_4ReKG^v!D%p+)^;2xVAb6p77gYZu`(FOFsCAf zbud#WU@A)g87VI~Go(JSE#nhW96=D=r;OT}VXM9uLj5-y41f6>40mwN_ydf6QLB%h zH|Z|IM9xN^3AX}o!iiVlhtgfL7(0-Pn{gU?+GYLF7yDLz2{tP1jjjYPN4f@&XwwEBbNMlGA&| Ye|zs)5^k8ChyVZp07*qoM6N<$f;3PqtN;K2 literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/bug@2x_dark.png b/plugins/tasks/tasks-core/src/icons/pivotal/bug@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..6d02836719e9a80e4fc2c18852f6cf061f5eb6fd GIT binary patch literal 1290 zcmV+l1@-!gP)!Lr&2Dl9@7WL;y1(%Uc86YU*$sZKok$P}`%t zei_JdT2E;SVg=koo%Qi-VrqMyXFGx%+H?Vg-j6@u1TLUb$>p6l48aNwyHj90T zAh&W4IAwW1#BASp5g+m^Wjc|7e3!i7FHcPg%(Io8gU~?(tXRzu?rMa={bp!1urT>^*MKds`S7uIC7vI4X@HTaN2Dw0m$OHvUl;u9{R!IK5SXU0d=6$f- zVSoraxQvdXn9w=PvYZIMJ<{FOg=1tR%am*?z-znyOS}XQsVL1Q&mX_2l|caCdgV0} zL^>^;06v5JO<*B2fMwJc?zH$%d~oc39QXP`=nAjUrP1^Cegv;c!s55cU z?*s&#Nm{^gg(NiAAP1LO4K7O!*o;~*qX1Hpc03#ysIywxLpW$eKmf6|@uEMzfOC~a zSIJ;5Q}w#AYb(H0T}+PXYXSnUB|QTe^?!#uacgxqu8Uw>JxnPiTT&L_Z`B4?tR&#f z95)A{IWB=#4Y*}_Bo$v45D-QzNiBi5LEgJe_I`_oV=V}gs7;7Py%OAIVv?r66%g=E z(laoxDa%^IBQ?}i%h7MD2ManUWz;5wS0_gSxrcF3RzQGyUAe$-RGnUGtbs)Io3z}l zkdm|)^$M7($p7ujCN_2%Nc~OO@s-*x%dLsPfzJM8YrmFZ4w^YAZf=BA;x=m(g~5qSq7=;#OpR9;5c<~7O^6a$2d7n zznszq1l)F@%G3Wps>}WVq#^%5&_!VSenrMo zphkBfehs2QnlW5(DLLfmJ)o^1P0LGi{y(YD1LKF)S^sb3#F_yW9|q$8P#V(<2jT+1 zpUjT=e=08?1s_X~_eqi%{{ojEMhdBE3Kc{KRX( z_4M!q_luLjURaWs_WwaiG8o?khRc~ScUyv9xEvoCa5p#h|9xN#z%aVgtWG$ ze&dy_n4NdhBcI&Oi2MztUtdoQzOp|f?%gpjTl@)$*rZIG%tQ$W0M`L**dpk#^8f$< M07*qoM6N<$f-kG!X#fBK literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/chore.png b/plugins/tasks/tasks-core/src/icons/pivotal/chore.png index bfe2e63909e14b0ebf860c4b43c7b5d2d27bcbd7..7479b84eb0dfb155e9a206ed2d05af374baaeca4 100644 GIT binary patch literal 232 zcmVP)?j&e)f-@K?Fex`M(ep9p|N0Rfj;81spEO8=F-QXqQkR;84g-}M in z-7AA}6vt1Yc1OzPE|skb7iv$DEH%-*Olm7__L$d+G(;>+Ay(#fmNxP-;d%0UVM#0P zV)+N$Q;J%`T3%*fzX!?p+?>~AyL5_7do+Xv*lz9DL6&X5>y9sD5Sm>|lVZ}VFU{VgjpcU<|G87|BtuA3Z3vXN$?9p1Hd|tbxXAX0000< KMNUMnLSTXsLcON| diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/chore@2x.png b/plugins/tasks/tasks-core/src/icons/pivotal/chore@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f4406c39f0a6980ce299aad58f856cdd0e7ca611 GIT binary patch literal 303 zcmV+~0nq-5P)k;1g@RXuBiapOE3ogCE!AQC8svwzyKJyO?U>~82}^3AOqBqzzsV7u&_@Q6 zYasb8GLRT<6B_?YO&rOTKMn16C|wue_%r%DfER78Ck=D1GBW@G002ovPDHLkV1j-% Bbk6_) literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/feature.png b/plugins/tasks/tasks-core/src/icons/pivotal/feature.png index a68335907b15bda97f70f825c45a2ae0324a6e05..26793add948f8012355c3de8d6c9f6466a9b85ef 100644 GIT binary patch literal 472 zcmV;}0Vn>6P)NklfLLj1slVuvPKP)5<{113VIcc0NDL$gQUg*8)Z-2} zV0pQ3!r?~q|EHS_{-08t+5P*)=??#~;geI`|L^SZi@+NT`@39koSy9T z|I8Fje5lv$|C(wKNt^~OE^rpz-Rk`B_ypJg$0uUq{hcoVmzTKu;xu4sp+oe}R_FhR z`rLrn{r|x}4=@I?5BIzM-`(!=e?^I76HWt`mpIPa(dzntU$^_`-5qWqwh0g$1KBe{ zVmsU1{;w)`+KkhHm8JG;wlp}VZ>n?TMNf4=F`liBPHC&l?J*6Y1OotV+&IC)txOdF O0000HM5&JtCBLbmnqk@FWk5@t(7ylnkcZBG_jgFzN9+1o;26DJK(=Nw3;>2urA`f zG{UAi;lDc8wKc@5KFqK^#HcsRt~t@OJJYc;*0V9%yFJ>yL)*MSBc_l$UyALLF~&#?aD#!%tPtLI_k$f=)*Vb$UaKRQQ80i02p*q zPE!B?5D-8>KtNz%fPjFYprEk8z|hd(@bJP!5#Im+0DnnDK~xAG1;J5H#2^#^z+oeMID2a=T_< zM}DT4)^dni;_D}Stk+(0E@i%d%RFp(t@Zoy846-9%s@fC60VBE7VCZ(Z?T=w_X>6I c5fK33A9L~~(ITs7F#rGn07*qoM6N<$f(BZ!+5i9m diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/feature@2x.png b/plugins/tasks/tasks-core/src/icons/pivotal/feature@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..66f44bd2ad51c9c5cc0ed478e39205cfa1d8091f GIT binary patch literal 965 zcmV;$13LVPP)~D2NIy5PB-;p_}(4%6Yc4i>YgKGpM&7L)2tC2A6oCD+b3rcrL z3^=ulZR{1{?7RBCFzt#AfU%e4NNxLHH_&ocX&5ud!lXS4rkrzNj5(|=)xcVJ3ANFw zNeOSvN!t{})}~YP9o;(Fr-|BVm~_O#`{p??#vInL2YZ9(Q4_Us$D#%rvs3DtvJU~H zi2}cN7x=V$z^mB{1LU_y69awPIPerCz%xTUyseK3Ed3eGVGVl%y<`SwQ3JJ56SZ*% z+2vSZz^P4J({e`s;P$y>7%Gg0M@3Qd7|}(+)6!^oX^De34a9_fKA6KA_F!-DJZhpg z*)dLbty}aF^pvJ=_L$VuLuMJgsEMDCg)Fe{gV(lwWLd(ZU=4e)H+UX3iS|ryS^Caj zzJ$J-jF_QoM`lKCG`y6BFGdS5sj0nt&HLOEhNKO2tlo zA0nfCgRfdK@x&^I=T?dnIODHTfY*HZ_>#Vaj7eVn*h0foi;xpI<2B2n_eyHSk__~e zBo7Z)iD0CL<_u#v1a0SKa^42)S)%n_Mf8`!3L1v1#hhWvrO=Wq(eXEsEllgt3BhNg z;h|Z~8K#Ve);#(iZv!_@QdRB}5%?-3;HwNq3f_w302nWr7&QW zeTQWXGHStTAvvsl?+eTrq|i}BgFP!r&e=diX5!Ji7lqJYPM)Pfg0LRFg!=8D4bp?X z-)5lm5)Fry&ZoADfin;vt5vr00000NkvXXu0mjfi!{wB literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/release.png b/plugins/tasks/tasks-core/src/icons/pivotal/release.png index 10e71b0a54a3ea865533086710560188291284cf..fd41786c4d44e4d38840ca5274f4988871d2e256 100644 GIT binary patch literal 501 zcmVV2hE}Tul}ZKdcKegd zl?ntwfOflmi|dki2dmXe1F8Mp%6KXHL+kF*~Tk;Bt^Mgj&@Nf6rfhC(b(Z| zP$BY$%!mcY$O`gIUgCK^gS){kYzmiL*%_&F87JR=kpz4eoidlkfkAGt1udkdpH~S rdcD3RHAvUU#BV>(V4UUO1f%c)j#>(mvNOP?00000NkvXXu0mjf4yxG) literal 514 zcmV+d0{#7oP)bN=ZX%kl^4Dp_rv$kS5y`F6|TRpGInj+%y^uEHxYsQ79C|t~0W^G*T~Y zm!@eS7!kEv4WrQr^Z8tw2ZI3|4u{x1AqV6Wxss-II_>27j&xl|I2=YIkwCdz#&|r& zLAMLTG?B~Yu>Nulx~_>Lm(u9>`_o>p_lIE^2!%r6vsgs2SVTUbM<5WuE(^UbY{N24 zu~w7DNF=i3@pyhSE~3#WQmGW&Za0_&U3ToW+o;#;*ve+1sp_45M#gKAI7mFjl8i# zcD?1zmX-fYee&n9(@%22A%~S`$TqUuFGf94o~fnr58JKNqb9?ynE(I)07*qoM6N<$ Ef))Yt5C8xG diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/release@2x.png b/plugins/tasks/tasks-core/src/icons/pivotal/release@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2365649df2a4437b7c334d3b8451e98ea04d1bd7 GIT binary patch literal 1069 zcmV+|1k(G7P);e^EaLz8_#d5??b`NIvjU(1)54gW;o86ki{Lkb~ui zL5$&GlZu$BDfwe6K1Ri7n)~^~m@c7>Z47~f4loU%-Qxm18rp}j@ zl|5~3ZQc662)tqf&CSj4O(qk0d3kXtC?X=_XJ%%mIXO9b-@hcV3s`{rC#R;SmV$$W zN#ueIKR>_a`1p8RXlUq#e?cIEjU*){S#36(#&~sgHJQz3G8&E2b9i|8KtMpi4UD&} z7l9Y7*kZACQDk&);oB&xC6&0m^F9q@kdOc9VN{Wk%OGidVGz5?rP6RmiEFT{qmvV!j z@vi#4^H|#t+;&A^Gce7r8XX<2H5d$(kdQzP4Gn~FP=9~F#?`!grLo!BSt=?jB9v=~ zY!2QziM7kXepdvp2*uA4>tUrKghV=OoZU)!XJ@Aqf#Km{`6#lts;a6!VEhPptLGRN z3dP~Mxw&2H-Ev0H%*;?@V} z{_G%t^S-DgFgQ495k$|rB5+J7XiR>|a1WETdoi0+~rqN7Nw*99@q;9>DIfu&_*!DZ+TCD*_&(^7X8f n@ileD=YUggA>j6Z$L_>0>jAX}vTe?000000NkvXXu0mjfo&@9Q literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/pivotal/release@2x_dark.png b/plugins/tasks/tasks-core/src/icons/pivotal/release@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..f14f527c048b98d41f881bbb8d7b9178320a1610 GIT binary patch literal 1132 zcmV-y1e5!TP)L zBcw)J-=Bk`k!1VAU?fT^Z09t0o7-#0`(n$FXZPKE?|Yu-+_6)4d;p#|{ci!$DBx0P=(`Ic zA#dyJ>!-`h%OAp+<^K}U)!5jm+-GIgk(HJ88O5kjRaMmm-@X9teKi3$n|CU%;c zwKX&}%+dm2C%(gu%mBvVcN}1wrUhI^qOh>A59fr!KAIeH(#xyIV%M(rD-jVND=RC% zkU*6IcqDa~ET9>Q4jwx6A}uX#j3%$HuAbg*Y}~RPO=ShK4OZ zzP_&^5XUhn{rvrVX>!~Fxm-R?ljr2*jEh8~n%df01sQt=*v&}*kksN!JO_s^rl&ZD zDQRqC(yAJB_wabd^gihPc?Hht>FYQ92LwEXIH`y6_gn<%VnCIZl}$0p5uPVb^dJEk z{23DyGhk(H-H~wP#xP9|4$PWcShUgaoj!A>2Ihvj2sn#IVq;?m)d{$H>(*ankcP7Y zPtTq^si~ik7{{bi={WPf{QUenn9JZI;4vC;admx(XKig`^IT;FV*x#<1!QMu{~@#7 zySGCu77qx8LIpEMKpYk_S2h6~06!`!D!yZyVPIjSqV zOeUL*kB=X+wX^HQ-`+kxa#%Y7Sj#5B2aR64etn4V?mmYsJUsm4)wsApRm7vXJ(ia3 zH2D!n$1Y|zKpJ<$^F1zUh?Puv+|8{!At7Oi5m-vBd`MzqYT6nU6r{MFm^i}pK1wX^ zS5prVd^Q2=0a$Q`q4w{Cv!0|4NON;1m}JqA1$lXS69K1Ay}@(FF)Utc$ftv`Lg=s;r^LaVMmh8F(~zGc${9_V2Go0TFNuG6mT4c%8IJVPGIu zKTO+=Yyw<}k(_y|V*~&LY`UnZs0}LRUolczS~{n4rl+Tu!Q2xrw_zGFbd2SSUJY;q z$eG?t)Kt#8y1G76S?3jiMn?hY(Ygh+S9ryyKze>f0Z@uZRfPxP=;ZW>G%31l0_=zv z4;I;IV$%^!y!~Bx{QUfS$@bT9X-JZZfRjsXxv>r7LH&5Dx|9IkYy$A50TSgpn)>@i y8q|YadO|$^7l8X3Bwuh>yi${YJ{KflIq?fa@imZDq#Q2*0000Ya8_qJ}``g+r*O$&hH3iu3AJ%0T7 zEkA$%>nm5T{Jd=W@=uCNN@tXmmCx+iv*#Dc&@EfGyacj$0@?Q13@BT;aN#0NnstAimq%+xy_)!Gph>o135S+`01y$N(E#+sh!04Gj&?=FOY; ze$L#vbAaNR=mz8iaqrQiN1uZcnVs2U<6_}V90L*rH71+jO!o+mMmSm94M}c zZU87+obe=Eg?;<>OS)g538-Ha_Ef#R8kQ09RqXMPL=D8T?r?wnmeT`xoc0000< KMNUMnLSTZ159!nZ literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/pivotal@2x.png b/plugins/tasks/tasks-core/src/icons/pivotal@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f1afcaa3bcdbe94e24f1c91b3672597c62884fcb GIT binary patch literal 518 zcmV+h0{Q)kP)S5bo26sGxTd3yO+wpr~)4FCZwW2SvfZr?B2s^zKE`n=zqAduV8F1>4f3Rg1#7 zUm%dIX*NmI#?r$FVRz@7FFUh4vk4+f#EHbe5wLxor%s|f1svZN=<=yTQn602dV@+I z-zM_x8)KNmn#cu!^gdUk>emk$4R2u0UCs~+@h#v)dN==4^LH?wCVnaoM!7bAZ#A0Q^0l?b)?m-_9*yxA@ax zKN(F0T&Wdj%;jhAZTAQVZ0%g&77BPMI^(Bp9t3x8?EpWefVFJ|0{v^cz$@AL3*-1p8B5$iv! z?Hh3FNgqP!;R_C4aR|TXz^r<)hc2G*2vHAuX5+whU|K$Zfq$qZZcs#Q>3o2lKLeAy zL>?)0&{};|&PtkHqWNoJd>h}z6yLaadtqc1?JN*91H;nU2}IT02FTJ&y=yb@UN{Zo z3Jn~&4Uh%3lR?A`yyc>82tKjzb?@XK+I=pF delta 355 zcmV-p0i6D{0{sGzBYy!zNklbnJW<8siCyUI_ z%@z|9guX+h{k2NM4X~GM!b>qN<4;r5UJp`?b~G1tHS^vFiwy~k!NRvEq5PHzO|9c8 zXW(2x?i!wDv{*@!?lKqd6J(@Y74Oo{Hwrf}r9(wT2AQS1%}BMmSSOBYO?IT%bggT@ z>ow$C7?Lg&k6ik2wvpV0!-5X`GP;EEe!ut}T=k5Jocdg2@Uf>W85FPgGmvJdO}|Zi zXtC7KK$?7;{sLWNQ$fj4h$q|o1}m{%@d^KbeE}W&g~;}f2w4CC002ovPDHLkV1ntT BqlEwf diff --git a/plugins/tasks/tasks-core/src/icons/redmine@2x.png b/plugins/tasks/tasks-core/src/icons/redmine@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..55ae4db6476c127aae6ee3c362db5bed0c16e591 GIT binary patch literal 639 zcmV-_0)YLAP)7{~Eh@z9|kV1X4P6(!Lj`f-U&Dhg>y$vi|51f?h=i)2#t>);;{WQT}Ku#?*{ zyLl>t4iUskMpV>7*k*_rD#7NDukVRxWte%sGuEXJb9lk*_j$e_KFh-HI>s31UviQH zNrC^Sz|4*2<*0y*$H?O+<}ik5=)tzXDlmP$Im#OBL>db)77Mbo58MB!z|^&qHgy<9 z0c+60Z)A$7=2C)J;-&sjcW`lwA2PlgzFnQ%fPy^;*0$l9C zH;mvl@^a=X`<^?o1tu;x`lT=gqsYqq_pU#T*Ecb*+pou61cO)Diw(%)wr^*N_O3W@#Ur`9N3y)kd)5Mlu5`%@ z7%_`ptVGJUv&8no27NM9MHOJ)A{lwf z^s=kf0w3MOo_@5UMqXEAt30cs3NWw0CV8%r>;dcw6?or%s0zlXfB|fVV-r4eO!BWdDUcK> ZSp;PIc24EiDPjNs002ovPDHLkV1i|cBCP-b literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/savedContext.png b/plugins/tasks/tasks-core/src/icons/savedContext.png index 84b5f8910735ad69aee47bcd57de0627e1cb2a7d..4eecb92bb1361499c5cb9c704930e37bf544c783 100644 GIT binary patch delta 188 zcmV;t07L)&1I+=D8Gi-<001BJ|6u?C0F+5YK~#9!t&zbEfFKM-JBJfF3=?p10xq5z z#XXFZaIAbn4I+r5hZhKZUJDR26R_5DgULgJoTC?lEtT8}r~uXn&nl80K}uaP&I{Fe zB+yzT%sIxGBZE0WwkSxEa1x64sZs^{#^$l5H+i@b1u*=_}anc4IT?x q{4a>8Uj=e^p(Y5Fu8{r2X>SLPU1;TJAOj`<0000iFU8_*OpX=I{F2=l9|4`Q7RF-0Aq%-g&O`sncb=kEIE?fK;G`J}SObbq4U==bOG`t|tz*yQ)?@%ypB*Wl~; z^!WVN;`ZwB`kj;8oRQn~_x#e~_2=;V^Y{GF-}UD1`ttVt&D`_l?fGbX!(ef;@%8-h z_4{{jxVWhQ@_+I9ti0BvvBcZw_uc6CM&ZTL0000GbW%=J0NMZm-QXe^INU7s)7bU& zlV7n;0001?NkluB2Rd9({7P&F-Kr3RUME`T84 zE=iSYt=>?YE?80vIE4^&dwl?Jb`T&KjVCrtXJ42vmcNVDdIR7m4BOovKv|Xz45zaS lpmDikh%n3}if&^B@dhBa79oD)7c>9>002ovPDHLkV1l>xB&z@b diff --git a/plugins/tasks/tasks-core/src/icons/savedContext@2x.png b/plugins/tasks/tasks-core/src/icons/savedContext@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1c03eaad1a36e38be8557ae6794a74338723408e GIT binary patch literal 278 zcmV+x0qOpUP)@C$7R5D{ovYpm?y zf>_~y`Je-UMT`QxIm9TyokQ#eKwA0Yxdw=wJ0YyKnl1@xD4(oQB zMs#6epW0GD$zGO=>65u{Y9z|M{sYuY#swu}S$(BsV)M1m2!qv%HRmdv8%}&%UP8yD z3AKIdaA601vsQWtP)Df6owDkNJ~hnqKY;CDNQbu&5BrhW8U!QXE(| zhzK$WELgGLau1G%i*Ubq4xjN0m_!sva`5|p^YIO2g6E1jm)D zaJRLA2?od{i^cglsOVul(aywqK$T>Can0=lvI($J7JiEvuGUs;4)kN!Xz zFeF_z!G9v?_d+zJb@KpHl2`9O8-YCrA-x`+E((EZ6LJ~7BZCOc7{QWrEEWb>AC#6^ zly#3uctE*WcA}_RmFP^ zGqA1Mu;ExC#aV*gX@lH63(>Ham}L*EdlUkp^Z-Ce06FE7l#1!oMP2gt%LAH)TZ5_) s5p#V=vsBux=q9lXa+`&R|AnLI9~2hwQpyK_N&o-=07*qoM6N<$f?%Izd;kCd delta 672 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 N07*qoLAqe7yoRH=xyH0;~J zu$Hw2E!!|`eKW(p6w-kbhBl2c0*00pj_16*H+c+iW-u{Tl3y~sd(Qv<@4e^Vcb^#m znEjWS{cj9BeE85P1qB6%kaXlXM2kG(&~nexxfnA&JdtMPCE@dZ8^B;6qz?g}qM{-w zFE59RiVF6(u#JoL5p=%JJ?{~k*kj+6G=nHk8)$bi||S%XlFTrOvG z^g1T~LIMmL&}y|T+%yeQQcX<_jE|4A!bDb9)>eIe{iEgO<;j(m6*WP>H5$$0-Me?! z_&Ca;T)ocyjMe~(v0!69CDqo}!qn6hOixeK=r)&@mgbt9n-|WXKfihZ{(U9JGWt*q z#ZnIC(vooo+VqQaj{zJBUvN7#g=1r5tOyFOV}~?S=H9(~s<^ngrzotU|HZg);lf6G zdiqn!rP|<@V@FV!;s&r2YLJs-DyYfHNg6$kT#aoEPiAK3?#^GdN89?~E!(&P+e7&FjCL4$*X>|VzyT*S^8 zF|xC>S7{dTFwz)`AxML?hK7cC1Kq|9Xz5f_sZ=a@z)au>88L8OC&@rkQc?;QX(T?A zaD0gj@NuNU>v1Qh)|i1ORIy5>k_D4h2xEw}w6qO0k!qXc1$H^!JE0}9ZSqk?9Ja+H zMO>VU*W-4>6O#t++_}So)2GHmg)s!iFOdPq>w(~u|1LOO^8@Frfsekpk$DN*B}h7I z^znN8F~Bat$jAuG#KgoT?q$XhD5}1A@nWKG$@)A zQ6nC;Zjs)8mVhln+P73RxNaI0U`!zKZF(Pqeocgc_IU8Bj{=vnGhlzsAMA7eHWHASICb0P5{0Mx|&@pK^9LWy? z>s%l3xO#g2vMeVPwbKxZ$%BaA^9qH6g<+Uk+(wKMB*$^oez!i>@eY}2i3Rss2{@IU z0-LLTV0p!B>ts$;%h!3|ylKz?PPy(VZf|dg{{DV4v56I|#x}+Pl4G^!z^DDgJ$Sdq zf=5FX9IXrmJ1kVoAHBfhd-w6Tv)tT84d7^XFQbx@683#S^?*j!sNfj!KZ#4tS@3L& z6{qzB@Mwwwim@*~0ajR`7C*ReAINgeHUG}_m0bp~Qd!Wzb^e{u)6)aJy}e{)6HmxF zY-jY4I9G>(drOQ_jx|MtOML_!DL)N|^Zdc$%5gBya$SDwl1qrr02UpK@Ipd&zT3BN zvqlIsvWCmDh`VG0W0gpxqcjxUnxaf|BNAL1&Vggqdtg%-1P6ceS~0)u7N#?RqB^ki z*Lf4g#l?UZ5q3#LNVTsx1xFhr_KkDH*=;O*002ovPDHLkV1mJh%r^i4 literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/stopTimer.png b/plugins/tasks/tasks-core/src/icons/stopTimer.png index dfeccbaf4b8235bf3c66e77098fa0bc50f0a75fd..54502704d26b44acf0d2b337b36b1845cecb2649 100644 GIT binary patch delta 500 zcmV+6j#q0I{hjDXk5g5!MGV<*A`#-7e$J9TGsK^yEGJk9^ig;vMhHN$qwOS48 z^?I+RnEFwFMX0SH6T=4Akw^rp)vBTEI`4EkD(76GmSXCUMx!+N4VfA)VLB8Ffyd+d zayT6C&1Una-EK28Hk%DpRW&G&@`nvVsZolYBtLP5hiSs$x@x(UyhheAj*-vf6z9Bl^NWdkn`&*$?hnk_bu*PwH; zCxkS!!5H1dKp+6ISPT-01SFG5>3-i1PiI>~Nc-(Aa6Fxz`t}k$o@@vq&GOf4yxUxW qhl3R%r1cDbqqa5&`tGt2(!K$xc&-ulwAAVV0000hz$m z-GKlA0F_BZK~#8NP0mLG!ypVrK^X%f!oAnj-pl(;T4NUBYzI)tsBp3xA4##P4i;7c_Y2U4iGKn$q(Oaet>U7B1846UUqfEVon3P8zcy=Op2ni5E1jIn( zS}p}nTP}sR&}j>m7Giu5#&F4m<@cSOb8_g_93HgEFKN$S-`d~ad+ohXD@3H?zog=S zW8nDsxFoHut#1Mk_zh&hg+@ku=Fws*a(EkzfY;2=|Fr=G-v;wQblTh7rKhJydV71- z@8&iw_O_|>Q|>BIq>oPMlBYk~+ zx(RB2Hg&G^Yf%H)Y}Nn)uY)Cuy1Tn&etupek%)M`UWrDdMPZE3=TkK~9h1MoyG0FT zG8q+Zn*0hlhtD!tcpsGPS$Ad!oltLv2py@06?o zBvV1-PZSLf4$AiSw(RWeaCB$;`}?txk&$>^UESHi!9f7AN-m6HEH%_}$utAMR%41PM>kAxEkt5{aPQZhwiyN&YTGLqo$0kH_Ob1;|R@7E2? zlroUvsTK?dRdB#;VT4K{u&!YmsIIO)N0A1K#W9DTPdhO)r3_rKVgrGI3dBL66vORy zzo3cE&dyYcxS*a-+YJ|G4XmxLsbKm-I8>BkAbuYPT=n(!PW-kN0y*v?mx~~`3!0j; zOR&1SsU2n{yXoLW`~o3{Ql6X-QUAR=9j6eiSa3?=k1hVy z7n1&=-V)Rr22lAbFz`&j6J}>;Wo~YcM$T|T#?Y?hV2eMgl5}I8C8#wFpy*W0FC={D zo0^(ZjSv_)!Lp>VOSTXj0H5qVzAp#g*I0sD!vK;Rpz}9$6CE8Lf)^2WNebZF{qmmd ze_L${Y7GOJ;%lJuSIsY_JSB&Rhh<`7LZ+vubzHI9&m{Hqp(Us_3}EjUL@Ufi^9yEM zTO02H;)*%%O6uzemY}w*0h5upz&F~7nFW`iHu}gWNq3bcs5Ku%mWVj+NTS|u32JZr z-!AgtV@bF^w*<8}Hn3Cmp**ks)DqO**ub{^1Bp8;EkW%+Vv}K#$N_=k00000NkvXX Hu0mjfIe;AT literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/trac.png b/plugins/tasks/tasks-core/src/icons/trac.png index 2275f30a11d0c2f16d16085f66875485670f37ed..dc10451e2dbcefac736a8cb895a832ee7ecea8f3 100644 GIT binary patch delta 302 zcmV+}0nz@~1;_%BBYy!8NklFt9H9{^%;ba7k;a9}ZD4iM`T zYrs+Z*C&PUR48>(SB5dQ;WCx0MLg34{jX25-r$v~U} z#7~h7U;|=ZD0?^5fG^k#04ZDm#C_1v2Z=F41JV=9-v~8eH#P&fpiTuT=!9yhLGn@^ zG)($|SR0!GEI|Afs`wGqfGtP{z{14~Uo?6H@e3fH55z`5{2k4J|In0)H!rY2!(bnh zrjtNC7l_+{SSOy40Wf?Ji0=Zi2ewRxVF0-p0OF4@z4l!a761SM07*qoM6N<$f{EXG A-v9sr delta 704 zcmV;x0zdu80@nqQBYy&(Nklv zmbLJU5JIAd+}{b7qo7{sJ^sDAGGeh92Ph7W5XZBkQEAz61_Ce!rKlPsueV4 z5}*xxbp{Ey3h9dV=fMhZ80sL9I|DwR0Y0R_$#t3V^g)#ZF4ywBCA_%BPAMvN!n0}M z?P)r;*9oyzuYW&|0l%*T^QJOc>WE6%7SX4L2?m3*8*)b@S#}GY@71Kvf}e|&$kls| zZNQH@ur?_~nP&8U415uCyS=HDw$`$2BE3Z2CNFeQR)1CtRJ4FkPl0dBp|%79ZsPzP zgIs^&0MR;@%YSeE_`a%J8|`6-#G`iCOZ|FvXd;kVVZz z=V2lC#D6wI{NtkE4`URV8rBv1b%mPoeuyYTHZ(7io4dju0RHzltAQFM7 z72MehzSaUhk13INADEm3z6@#5Zv7>-8z+E=@W8p+J3<%`o70dHkuqEN+ImOZ*{P4} zfw?Mh`WP{?PjR=dCe|E_1zWp-{&w)|Q6d@e$T>{pd7QgSpb)F!sW~?~ZXCSS> mg{+V_q!!h-ZQ7}o6Zr>KPr}ZrRItYY0000AsbNw`rY6m17D7#p^g>bC zj0GFTG-a5@M2WDV$QZ8gso$+%r+eNz=ehor#iw5P{O<33-nqZ~JLg)qZCiJVb?*e0 z0@bDrfI$$Y6Mqu|e}N4e?@C~n1bV#|5KEe)ku(i_1;t(ql!J5N50f++lz~?u$xDG+ zTH56h3FE;$#R>L7p;rP4U=#F(NZ86IclZP1yeh(EFiIl*E{UgI1O%^HOaQb*Dlj7@ z{w9qtDFnt?%m~;5k4y!s6v_EB9#_Q7vY0u#_S{sUN0Iysi|JIvd}1-B;Jwo+O$7QC z$xlEk#S|-I%2_Yz01H$LMgkRzro@hfoahq7GKqB1OsnQxd+YZ2bOeSdxP&Fkr+#nl+5%Ml4s@Uf;iI3W`c<+CJ1~%q*5vb7>NCX$s&EKU{ zkNCalGRYe@{+a4UT%Qs?*=MfEo^fkH*hCDn+tVoyP?>0XeiNWR7d>O%Ah!2#$3 z8IkUWKg0C+cVPq^j%Y=V1q#59l&p)!o`7GP0)qNTx8pS0@kBxHvE`gJm|WbOece-W z5}lC5@0SLXpHd(3^jJQnsQe(EgkFFm`qwcx@m;VYO}VLb z3{q=|Y``TFG{f*kWCOs0JFh+efAPtCycnbgrXIt9tIt0EH|yF3SJ1lS>i^z7H{g7b z97qjb1CX6rv-#5h_MO*I#OQB8_wMU(zG){JUU>ca2MVUW0X68cK(Ybo8b~sLl7vJ~ qQof9AfH4qXAwe@ptufpHN-zNTpV&*_={Z^e0000_37KYFF%0Xi90W9R4ipsDFtZ&nxRmTn8HQamkv2SU^>GsWM+BTo*+IkK{!#^OLh^*nyUli;AVj!S`DZ9ZMRLhnuJ$CcQ zuRmXZ{QmY6ioX8*1xMe22B0s2X|+(07zmN6)nYuL3XfVb3g?h zEQjF=Y!0|iM+aQT<^Ys9zxwRs|JR>?Pz8g`LUX`xYz{zCL@mo<7~OoL9pF4^Kh|Kh z?%nhM-kUG~AH4nY-v-FWrpA5B0m>bKFD|b>`vAuH)Qmb{)B(fa0idjC-n|>EyyJv@ zw08i_3!+g6j5+{UWn|R@tc+fNro96OygD9H4jAwz*?>1n2fSHMua3!XTpbhiuGw!Y hTKbz{*KEZ0jsYeCee{GTRD}Ql002ovPDHLkV1gi;coF~r literal 0 HcmV?d00001 diff --git a/plugins/tasks/tasks-core/src/icons/unknown.png b/plugins/tasks/tasks-core/src/icons/unknown.png index 609fd60936e64abdf985ff5e4a80f94189a45f59..04c30c9facae970d3927510d6629e4202372a0ae 100644 GIT binary patch delta 141 zcmV;80CNAt1E>LzBYyyINklUZ|(U v0Jvsy4fs!PAW|F)1Ly)`Fl`JV7Xtu29FFn$Fwy1!00003e+qdf%2oksqGAJS_S_SRW zKM_O=g{VygAzh3JyLibo~s1;3%9%=sb;TLxtPt7iRf*Ok?(Q}zMKM@+2g2B(2B)GKamD-b;%Fi6lgQQeZ0(%DR1frN1!_d;`3B V9vK1%DRuw=002ovPDHLkV1oZo!$trA diff --git a/plugins/tasks/tasks-core/src/icons/unknown@2x.png b/plugins/tasks/tasks-core/src/icons/unknown@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1e84ca4569a1c53aafc016ffc83aea2f64baa9 GIT binary patch literal 315 zcmV-B0mS}^P)4A@fy#2}&F z`BVmYHXdP0o`?uoQwN9#xs}6jP@xP+!$A%gZ=goK2ZqYS$lD5t zKn9|=0v7TLb`YlyNNOuMXX6A$aDuVCjvxOWe<-kkK>P#36F|*+z#a8)NXgMk5w!pS N002ovPDHLkV1l($hwuNU9-sf)d)@#4 zoy!CCLf-QmkKbQG3P>Gf1K6Nx;D64PLmz+r_;&99;eU*mzySR7e~HxZ|3`CQeE;#| zeAJh&f-tI-XB8PWyBpMm%Q)FzmwA5dH4pnNv;q>OBcKa|Y}#0Jm|#swAg e!kU>V!4&|`u!XNCI0ZBS0000Pq9*^pYX9ZHc7w9Ecsh54v;Y79OJAt}<-z~&+H`@kRA#D@pU;+_ zyJK^%aelG?syQx3ptg{4hLE>LTBc88siv&IbAhreM4viQqkleBq!j!s9{>OVmq|oH zRCr!xk5`TaK?p+)l|$z|apV23xTtGO8fh%?^S}l`N59j*77*be{5)F~qiPL=pqHvz zg<$^$ymcWs>rX--@Y^t_l$*`N5U7P6hKZT4jYTU!!OhcM>yER75)cs*Yd~`fh;N`+ zGI!NdLYphUgf|*l+vKwL8-xXGJq)+U2%Mxy`WHH9OnL5e1PKsQ-~W>O11+})vfWKx QI{*Lx07*qoM6N<$f*a|R?EnA( diff --git a/plugins/tasks/tasks-core/src/icons/youtrack@2x.png b/plugins/tasks/tasks-core/src/icons/youtrack@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6ba3829c6ff692a617c648efc781896ba171d10c GIT binary patch literal 1120 zcmV-m1fTnfP)9i_=qPi4EzkfQVDCu@>;$68?*d>5Nz?(D1H=GYzyct`Hy|4b2gZ;!PRR-2fagFT;7%J7ieUnl0QKbhxtzc{5||741NJ{4 z!SfNA3S{DC6cd<0HQwY+jw3`synlw zqD(9?%k_-Xa*^4<$)`xw0N!o}cH~bq<@y#$?6vtQd5Q(y9N_Yxo^C<9=+DUQ$m3&T z(~2qt1Ty4`a3R|$?ADuFpHXry4Z7M5`H(!>ifmN{IELep2G<4CAFivxQUVw01_6o` zuJXIJ&_}?SQ=*BPgp?7R(S?XDsO0=8N&;ra?exsV%VOgPfmzrsCGd_8-g-9M?327f zUl<)3>TDqzl!zXkS^Qf9F9(^0z$57nM&P!TfSC?HlUQK%CQh5%fD*^s^vcoPte_;H z0-LY6kIa|*Hw&cB^os9M`s|8KDS;N9s-Bd5^$MtZakz7JWT5E7MjPYbED%4)!M6*K ze_O-E>7)c~bg(k5sFD@PjtUSJC|3?80t20VyO6k7CMGUlN}!AmKB#*A-7AnVwh?#k zjO&3mhMx0D9(?rZ?;23g@Gil+(@z_j*fc4DR62Os;dF=7n`_2 zl+IdjihO3Z+8tW&OynK=>Pe>R$stv5H;mef@=uo|SCePtUurCctHK}u6e(5>&_zr@ zAy(mQA~NhcL*0A17f}|xwD7D6^r54Qe5;VaJ}UT?(Dwi?D8-dr6Mi|FEKLP`Qe14w zFFzT!MQ58u24DroQBT@qLIV7LeF!WE9CBYdu*U9y{VAMG9DcUU29}a*{H^FOB(M?) z1_G&%htfarSyn|x-xIhDY>+ELEoqnsOarRhk(47JwU5YkQCrRhcm~b_)2Zaue`jDK5!wN42UY{41WroVsDn$VwhAmDBOcz) mV;kl;nX#p^OYq;Gj(-8n3JgF@>8qyz0000 Date: Fri, 24 Oct 2014 14:33:23 +0200 Subject: [PATCH 10/55] cleanup ConfigImportHelper --- .../application/ConfigImportHelper.java | 72 +++++++++---------- .../src/messages/ApplicationBundle.properties | 1 - 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java index 068cb4b7e0f2..ade61f35e6e4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -17,11 +17,13 @@ package com.intellij.openapi.application; import com.intellij.ide.plugins.IdeaPluginDescriptorImpl; import com.intellij.ide.plugins.PluginManager; +import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.AppUIUtil; import com.intellij.util.PlatformUtils; +import com.intellij.util.ReflectionUtil; import com.intellij.util.ThreeState; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -30,8 +32,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; import java.io.*; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.List; import java.util.PropertyResourceBundle; @@ -65,10 +65,13 @@ public class ConfigImportHelper { AppUIUtil.updateWindowIcon(dialog); dialog.setVisible(true); if (dialog.isImportEnabled()) { - File instHome = dialog.getSelectedFile(); - oldConfigDir = getOldConfigDir(instHome, settings); - if (!validateOldConfigDir(instHome, oldConfigDir, settings)) continue; + File installationHome = dialog.getSelectedFile(); + oldConfigDir = getOldConfigDir(installationHome, settings); + if (!validateOldConfigDir(installationHome, oldConfigDir, settings)) { + continue; + } + assert oldConfigDir != null; doImport(newConfigPath, oldConfigDir); settings.importFinished(newConfigPath); System.setProperty(CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY, Boolean.TRUE.toString()); @@ -81,26 +84,16 @@ public class ConfigImportHelper { private static ConfigImportSettings getConfigImportSettings() { try { - Class customProviderClass = - Class.forName("com.intellij.openapi.application." + PlatformUtils.getPlatformPrefix() + "ConfigImportSettings"); - if (customProviderClass != null) { - if (ConfigImportSettings.class.isAssignableFrom(customProviderClass)) { - Constructor constructor = customProviderClass.getDeclaredConstructor(); - if (constructor != null) { - return (ConfigImportSettings)constructor.newInstance(); - } - } + @SuppressWarnings("unchecked") + Class customProviderClass = + (Class)Class.forName("com.intellij.openapi.application." + PlatformUtils.getPlatformPrefix() + "ConfigImportSettings"); + if (ConfigImportSettings.class.isAssignableFrom(customProviderClass)) { + return ReflectionUtil.newInstance(customProviderClass); } } catch (ClassNotFoundException ignored) { } - catch (NoSuchMethodException ignored) { - } - catch (InvocationTargetException ignored) { - } - catch (InstantiationException ignored) { - } - catch (IllegalAccessException ignored) { + catch (RuntimeException ignored) { } return new ConfigImportSettings(); } @@ -108,7 +101,7 @@ public class ConfigImportHelper { @Nullable private static File findOldConfigDir(String newConfigPath, @Nullable String customPathSelector) { final File configDir = new File(newConfigPath); - final File selectorDir = CONFIG_RELATED_PATH.length() == 0 ? configDir : configDir.getParentFile(); + final File selectorDir = CONFIG_RELATED_PATH.isEmpty() ? configDir : configDir.getParentFile(); final File parent = selectorDir.getParentFile(); if (parent == null || !parent.exists()) return null; File maxFile = null; @@ -119,7 +112,7 @@ public class ConfigImportHelper { final String customPrefix = customPathSelector != null ? getPrefixFromSelector(customPathSelector) : null; for (File file : parent.listFiles(new FilenameFilter() { @Override - public boolean accept(File file, String name) { + public boolean accept(@NotNull File file, @NotNull String name) { return StringUtil.startsWithIgnoreCase(name, prefix) || customPrefix != null && StringUtil.startsWithIgnoreCase(name, customPrefix); } @@ -139,9 +132,9 @@ public class ConfigImportHelper { return (SystemInfo.isMac ? "" : ".") + selector.replaceAll("\\d", ""); } - public static void doImport(final String newConfigPath, final File oldConfigDir) { + private static void doImport(@NotNull String newConfigPath, @NotNull File oldConfigDir) { try { - xcopy(oldConfigDir, new File(newConfigPath)); + copy(oldConfigDir, new File(newConfigPath)); } catch (IOException e) { JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), @@ -150,14 +143,12 @@ public class ConfigImportHelper { } } - public static boolean validateOldConfigDir(final File instHome, final File oldConfigDir, ConfigImportSettings settings) { + private static boolean validateOldConfigDir(@Nullable File installationHome, @Nullable File oldConfigDir, @NotNull ConfigImportSettings settings) { if (oldConfigDir == null) { - final String message = !instHome.equals(oldConfigDir) ? - ApplicationBundle.message("error.invalid.installation.home", instHome.getAbsolutePath(), - settings.getProductName(ThreeState.YES)) : - ApplicationBundle.message("error.invalid.config.folder", instHome.getAbsolutePath(), - settings.getProductName(ThreeState.YES)); - JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), message); + if (installationHome != null) { + JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), + ApplicationBundle.message("error.invalid.installation.home", installationHome.getAbsolutePath(), settings.getProductName(ThreeState.YES))); + } return false; } @@ -171,7 +162,7 @@ public class ConfigImportHelper { return true; } - public static void xcopy(File src, File dest) throws IOException { + private static void copy(@NotNull File src, @NotNull File dest) throws IOException { src = src.getCanonicalFile(); dest = dest.getCanonicalFile(); if (!src.isDirectory()) { @@ -190,13 +181,13 @@ public class ConfigImportHelper { File plugins = new File(dest, PLUGINS_PATH); if (plugins.exists()) { final ArrayList descriptors = new ArrayList(); - PluginManager.loadDescriptors(plugins.getPath(), descriptors, null, 0); + PluginManagerCore.loadDescriptors(plugins.getPath(), descriptors, null, 0); final ArrayList oldPlugins = new ArrayList(); for (IdeaPluginDescriptorImpl descriptor : descriptors) { oldPlugins.add(descriptor.getPluginId().getIdString()); } if (!oldPlugins.isEmpty()) { - PluginManager.savePluginsList(oldPlugins, false, new File(dest, PluginManager.INSTALLED_TXT)); + PluginManagerCore.savePluginsList(oldPlugins, false, new File(dest, PluginManager.INSTALLED_TXT)); } FileUtil.delete(plugins); } @@ -208,8 +199,11 @@ public class ConfigImportHelper { } @Nullable - public static File getOldConfigDir(File oldInstallHome, ConfigImportSettings settings) { - if (oldInstallHome == null) return null; + public static File getOldConfigDir(@Nullable File oldInstallHome, ConfigImportSettings settings) { + if (oldInstallHome == null) { + return null; + } + // check if it's already config dir if (new File(oldInstallHome, OPTIONS_XML).exists()) { return oldInstallHome; @@ -299,8 +293,8 @@ public class ConfigImportHelper { @NotNull final String propertyName) { if (file.getName().endsWith(".properties")) { try { - InputStream fis = new BufferedInputStream(new FileInputStream(file)); PropertyResourceBundle bundle; + InputStream fis = new BufferedInputStream(new FileInputStream(file)); try { bundle = new PropertyResourceBundle(fis); } @@ -374,7 +368,7 @@ public class ConfigImportHelper { @Nullable private static String getContent(File file) { try { - StringBuffer content = new StringBuffer(); + StringBuilder content = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file))); try { do { diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 6162300942a0..b02ba924695f 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -1,5 +1,4 @@ error.invalid.installation.home=Unable to import settings. ''{0}'' doesn''t appear to be valid {1} installation home. -error.invalid.config.folder=Unable to import settings. ''{0}'' doesn''t appear to be valid {1} config folder. error.no.settings.path=Unable to import settings. {0} does not exist. title.settings.import.failed=Settings Import Failed error.unable.to.import.settings=Unable to import settings. {0} From 6c49f93f01a02502ebea4ff9869e5a9d5b0ad7ce Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 24 Oct 2014 14:35:07 +0200 Subject: [PATCH 11/55] =?UTF-8?q?we=20don't=20need=20to=20remove=20plugin?= =?UTF-8?q?=5Fui.xml=20anymore=20=E2=80=94=20installed=20plugin=20list=20i?= =?UTF-8?q?s=20not=20stored?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/intellij/openapi/application/ConfigImportHelper.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java index ade61f35e6e4..0a1a1a37b4fe 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -191,11 +191,6 @@ public class ConfigImportHelper { } FileUtil.delete(plugins); } - - File pluginsSettings = new File(new File(dest, "options"), "plugin_ui.xml"); - if (pluginsSettings.exists()) { - FileUtil.delete(pluginsSettings); - } } @Nullable From fdb024452db5b3bab7daafebca30de9581da194a Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 27 Oct 2014 12:06:32 +0100 Subject: [PATCH 12/55] IDEA-131750 Fail to start after update from WebStorm 8 to WebStorm 9 (problem with TFS plugin) --- .../ide/plugins/PluginManagerCore.java | 15 +++- .../application/ConfigImportHelper.java | 68 +++++++++++++------ 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java index d80d36822eb1..c4681c4d77e9 100644 --- a/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java +++ b/platform/core-impl/src/com/intellij/ide/plugins/PluginManagerCore.java @@ -30,7 +30,10 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.StreamUtil; import com.intellij.openapi.util.io.ZipFileCache; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.util.*; +import com.intellij.util.ArrayUtil; +import com.intellij.util.Function; +import com.intellij.util.PlatformUtilsCore; +import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.intellij.util.execution.ParametersListUtil; @@ -166,7 +169,7 @@ public class PluginManagerCore { return app != null && app.isUnitTestMode(); } - public static void savePluginsList(Collection ids, boolean append, File plugins) throws IOException { + public static void savePluginsList(@NotNull Collection ids, boolean append, @NotNull File plugins) throws IOException { if (!plugins.isFile()) { FileUtil.ensureCanCreateFile(plugins); } @@ -700,7 +703,13 @@ public class PluginManagerCore { List result, @Nullable StartupProgress progress, int pluginsCount) { - final File pluginsHome = new File(pluginsPath); + loadDescriptors(new File(pluginsPath), result, progress, pluginsCount); + } + + public static void loadDescriptors(@NotNull File pluginsHome, + List result, + @Nullable StartupProgress progress, + int pluginsCount) { final File[] files = pluginsHome.listFiles(); if (files != null) { int i = result.size(); diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java index 0a1a1a37b4fe..d33010f3703f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -24,6 +24,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.AppUIUtil; import com.intellij.util.PlatformUtils; import com.intellij.util.ReflectionUtil; +import com.intellij.util.SmartList; import com.intellij.util.ThreeState; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -55,10 +56,11 @@ public class ConfigImportHelper { private ConfigImportHelper() { } - public static void importConfigsTo(String newConfigPath) { + public static void importConfigsTo(@NotNull String newConfigPath) { ConfigImportSettings settings = getConfigImportSettings(); - File oldConfigDir = findOldConfigDir(newConfigPath, settings.getCustomPathsSelector()); + File newConfigDir = new File(newConfigPath); + File oldConfigDir = findOldConfigDir(newConfigDir, settings.getCustomPathsSelector()); do { ImportOldConfigsPanel dialog = new ImportOldConfigsPanel(oldConfigDir, settings); dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL); @@ -72,7 +74,7 @@ public class ConfigImportHelper { } assert oldConfigDir != null; - doImport(newConfigPath, oldConfigDir); + doImport(newConfigDir, oldConfigDir); settings.importFinished(newConfigPath); System.setProperty(CONFIG_IMPORTED_IN_CURRENT_SESSION_KEY, Boolean.TRUE.toString()); } @@ -82,6 +84,7 @@ public class ConfigImportHelper { while (true); } + @NotNull private static ConfigImportSettings getConfigImportSettings() { try { @SuppressWarnings("unchecked") @@ -99,11 +102,12 @@ public class ConfigImportHelper { } @Nullable - private static File findOldConfigDir(String newConfigPath, @Nullable String customPathSelector) { - final File configDir = new File(newConfigPath); + private static File findOldConfigDir(@NotNull File configDir, @Nullable String customPathSelector) { final File selectorDir = CONFIG_RELATED_PATH.isEmpty() ? configDir : configDir.getParentFile(); final File parent = selectorDir.getParentFile(); - if (parent == null || !parent.exists()) return null; + if (parent == null || !parent.exists()) { + return null; + } File maxFile = null; long lastModified = 0; final String selector = PathManager.getPathsSelector() != null ? PathManager.getPathsSelector() : selectorDir.getName(); @@ -117,9 +121,12 @@ public class ConfigImportHelper { customPrefix != null && StringUtil.startsWithIgnoreCase(name, customPrefix); } })) { - final File options = new File(file, CONFIG_RELATED_PATH + OPTIONS_XML); - if (!options.exists()) continue; - final long modified = options.lastModified(); + File options = new File(file, CONFIG_RELATED_PATH + OPTIONS_XML); + if (!options.exists()) { + continue; + } + + long modified = options.lastModified(); if (modified > lastModified) { lastModified = modified; maxFile = file; @@ -132,9 +139,9 @@ public class ConfigImportHelper { return (SystemInfo.isMac ? "" : ".") + selector.replaceAll("\\d", ""); } - private static void doImport(@NotNull String newConfigPath, @NotNull File oldConfigDir) { + private static void doImport(@NotNull File newConfigDir, @NotNull File oldConfigDir) { try { - copy(oldConfigDir, new File(newConfigPath)); + copy(oldConfigDir, newConfigDir); } catch (IOException e) { JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), @@ -175,21 +182,44 @@ public class ConfigImportHelper { return; } - FileUtil.copyDir(src, dest); + FileUtil.ensureExists(dest); - // Delete plugins just imported. They're most probably incompatible with newer idea version. - File plugins = new File(dest, PLUGINS_PATH); + File[] childFiles = src.listFiles(new FilenameFilter() { + @Override + public boolean accept(@NotNull File dir, @NotNull String name) { + // Don't copy plugins just imported. They're most probably incompatible with newer idea version. + return !StringUtil.startsWithChar(name, '.') && !name.equals(PLUGINS_PATH) && !name.equals(PLUGINS_PATH); + } + }); + + if (childFiles == null || childFiles.length == 0) { + return; + } + + for (File from : childFiles) { + File to = new File(dest, from.getName()); + if (from.isDirectory()) { + FileUtil.copyDir(from, to, false); + } + else { + FileUtil.copy(from, to); + } + } + + File plugins = new File(src, PLUGINS_PATH); if (plugins.exists()) { - final ArrayList descriptors = new ArrayList(); - PluginManagerCore.loadDescriptors(plugins.getPath(), descriptors, null, 0); - final ArrayList oldPlugins = new ArrayList(); + List descriptors = new SmartList(); + PluginManagerCore.loadDescriptors(plugins, descriptors, null, 0); + List oldPlugins = new SmartList(); for (IdeaPluginDescriptorImpl descriptor : descriptors) { - oldPlugins.add(descriptor.getPluginId().getIdString()); + // check isBundled also - probably plugin is bundled in new IDE version + if (descriptor.isEnabled() && !descriptor.isBundled()) { + oldPlugins.add(descriptor.getPluginId().getIdString()); + } } if (!oldPlugins.isEmpty()) { PluginManagerCore.savePluginsList(oldPlugins, false, new File(dest, PluginManager.INSTALLED_TXT)); } - FileUtil.delete(plugins); } } From 0854b89902697de2dc58ccf303ad32ba2da3942b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 27 Oct 2014 12:30:56 +0100 Subject: [PATCH 13/55] IDEA-CR-802 fix "same conditions?" --- .../com/intellij/openapi/application/ConfigImportHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java index d33010f3703f..b376ad8c324d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ConfigImportHelper.java @@ -188,7 +188,7 @@ public class ConfigImportHelper { @Override public boolean accept(@NotNull File dir, @NotNull String name) { // Don't copy plugins just imported. They're most probably incompatible with newer idea version. - return !StringUtil.startsWithChar(name, '.') && !name.equals(PLUGINS_PATH) && !name.equals(PLUGINS_PATH); + return !StringUtil.startsWithChar(name, '.') && !name.equals(PLUGINS_PATH); } }); From 54c0fcfc7f19f61c66821b69c135d2c20a5345dc Mon Sep 17 00:00:00 2001 From: Liana Bakradze Date: Mon, 27 Oct 2014 15:00:37 +0300 Subject: [PATCH 14/55] fixed test result printer for python3 --- .../fileTemplates/internal/test_helper.py.ft | 4 ++-- .../resources/courses/introduction_course.zip | Bin 95611 -> 95611 bytes 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft b/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft index 9d1842742845..313b9150c467 100644 --- a/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft +++ b/python/edu/course-creator/resources/fileTemplates/internal/test_helper.py.ft @@ -46,9 +46,9 @@ def check_importable_path(path): try: import_file(path) except: - failed("File contains syntax errors", test_file_importable.func_name) + failed("File contains syntax errors", test_file_importable.__name__) return - passed(test_file_importable.func_name) + passed(test_file_importable.__name__) def import_file(path): diff --git a/python/edu/learn-python/resources/courses/introduction_course.zip b/python/edu/learn-python/resources/courses/introduction_course.zip index 07ad882088c1aa378ce7a8069cb3fd4390d0cfc2..c44ce1790f94592e46e606b8ab75ae6afe7525e2 100644 GIT binary patch delta 18838 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 Date: Mon, 27 Oct 2014 13:12:59 +0100 Subject: [PATCH 15/55] Remove print. --- python/helpers/pydev/pydev_ipython/matplotlibtools.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/helpers/pydev/pydev_ipython/matplotlibtools.py b/python/helpers/pydev/pydev_ipython/matplotlibtools.py index 2b9f1e72209e..075c43781ab3 100644 --- a/python/helpers/pydev/pydev_ipython/matplotlibtools.py +++ b/python/helpers/pydev/pydev_ipython/matplotlibtools.py @@ -49,7 +49,6 @@ def patch_use(interpreter): """ Patch matplotlib function 'use' """ matplotlib = sys.modules['matplotlib'] def patched_use(*args, **kwargs): - print "patched use!" matplotlib.real_use(*args, **kwargs) gui, backend = find_gui_and_backend() interpreter.enableGui(gui) From aba1adbc056257747689e3f35caf7b27a068e723 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 24 Oct 2014 16:48:54 +0400 Subject: [PATCH 16/55] check for dumb #IDEA-128914 fixed --- .../xml/util/documentation/HtmlDocumentationProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java b/xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java index 271fd5b6ff3d..1b416f37b92d 100644 --- a/xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java +++ b/xml/impl/src/com/intellij/xml/util/documentation/HtmlDocumentationProvider.java @@ -19,6 +19,7 @@ import com.intellij.lang.Language; import com.intellij.lang.LanguageDocumentation; import com.intellij.lang.documentation.DocumentationProvider; import com.intellij.lang.documentation.DocumentationUtil; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; @@ -273,7 +274,7 @@ public class HtmlDocumentationProvider implements DocumentationProvider { if (result== null && styleProvider !=null) { result = styleProvider.getDocumentationElementForLink(psiManager, link, context); } - if (result== null && ourScriptProvider !=null) { + if (result== null && ourScriptProvider != null && !DumbService.isDumb(psiManager.getProject())) { result = ourScriptProvider.getDocumentationElementForLink(psiManager, link,context); } return result; From a5918f4d10fb9f3a52f6eeb1bb9069234f598ed8 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Mon, 27 Oct 2014 13:33:04 +0100 Subject: [PATCH 17/55] Project View: sort directories by type as well (e.g. OS X bundles .app, .framework) + readability improved --- .../ide/projectView/impl/nodes/PsiDirectoryNode.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java index ec0b9dd8b6c6..7447fa3006c5 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/PsiDirectoryNode.java @@ -321,9 +321,13 @@ public class PsiDirectoryNode extends BasePsiNode implements Navig @Override public Comparable getTypeSortKey() { VirtualFile file = getVirtualFile(); - if (file == null) return null; - String extension = file.getExtension(); - return extension == null ? null : new PsiFileNode.ExtensionSortKey(extension); + if (file != null) { + String extension = file.getExtension(); + if (extension != null) { + return new PsiFileNode.ExtensionSortKey(extension); + } + } + return null; } @Override From 2679d398a1ebe8f4b0cd4e553f24e16c28ccadde Mon Sep 17 00:00:00 2001 From: "Vladimir.Orlov" Date: Mon, 27 Oct 2014 15:39:43 +0300 Subject: [PATCH 18/55] added ability to get patches for custom-jdk-bundled mac installations. --- .../intellij/openapi/updateSettings/impl/UpdateChecker.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index 6e879427859a..1d8fa160a1e2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -764,7 +764,11 @@ public final class UpdateChecker { String fromBuildNumber = patch.getFromBuild().asStringWithoutProductCode(); String toBuildNumber = newVersion.getNumber().asStringWithoutProductCode(); - String bundledJdk = "jdk-bundled".equals(System.getProperty("idea.java.redist")) ? "-jdk-bundled" : ""; + String jdkMacRedist = System.getProperty("idea.java.redist"); + String bundledJdk = ""; + if (jdkMacRedist.lastIndexOf("jdk-bundled") >= 0 ){ + bundledJdk = "jdk-bundled".equals(jdkMacRedist) ? "-jdk-bundled" : "-custom-jdk-bundled"; + } String fileName = productCode + "-" + fromBuildNumber + "-" + toBuildNumber + "-patch" + bundledJdk + osSuffix + ".jar"; From 0c75cdaf419f27d8442b3df156fd06ce8cdc343e Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Mon, 27 Oct 2014 14:07:12 +0400 Subject: [PATCH 19/55] annotation added --- .../org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java index 038c1c24121f..d4d40d791bed 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/provider/update/HgUpdateEnvironment.java @@ -35,7 +35,7 @@ import java.util.List; public class HgUpdateEnvironment implements UpdateEnvironment { private final Project project; - private final HgUpdateConfigurationSettings updateConfiguration; + @NotNull private final HgUpdateConfigurationSettings updateConfiguration; public HgUpdateEnvironment(Project project) { this.project = project; @@ -89,7 +89,7 @@ public class HgUpdateEnvironment implements UpdateEnvironment { private final HgUpdateConfigurationSettings updateConfiguration; protected HgUpdateDialog updateDialog; - public UpdateConfigurable(HgUpdateConfigurationSettings updateConfiguration) { + public UpdateConfigurable(@NotNull HgUpdateConfigurationSettings updateConfiguration) { this.updateConfiguration = updateConfiguration; } From 4e3741467901fdd3cbfe5874616fd6030aed88d8 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Mon, 27 Oct 2014 16:28:49 +0300 Subject: [PATCH 20/55] IDEA-129421 "Rerun failed tests" ignores pinned status of the tab --- .../com/intellij/execution/ui/RunContentManagerImpl.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java index c9dae095522c..b7f56a69f887 100644 --- a/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/ui/RunContentManagerImpl.java @@ -38,6 +38,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.project.ProjectManager; import com.intellij.openapi.project.ProjectManagerListener; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.util.Key; @@ -421,7 +422,11 @@ public class RunContentManagerImpl implements RunContentManager, Disposable { } //Stage two: try to get content from descriptor itself final Content attachedContent = descriptor.getAttachedContent(); - if (attachedContent != null && attachedContent.isValid() && contentManager.getIndexOfContent(attachedContent) != -1) { + + if (attachedContent != null + && attachedContent.isValid() + && contentManager.getIndexOfContent(attachedContent) != -1 + && (Comparing.equal(descriptor.getDisplayName(), attachedContent.getDisplayName()) || !attachedContent.isPinned())) { content = attachedContent; } } From ed706f730cc43cacaef974ff30f285c9f9484b0a Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Mon, 27 Oct 2014 16:48:53 +0300 Subject: [PATCH 21/55] rename some files like in PyDev debugger --- .../pkgutil_old.py => _pydev_imps/_pydev_pkgutil_old.py} | 0 .../pluginbase.py => _pydev_imps/_pydev_pluginbase.py} | 4 ++-- .../uuid_old.py => _pydev_imps/_pydev_uuid_old.py} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename python/helpers/pydev/{third_party/pkgutil_old.py => _pydev_imps/_pydev_pkgutil_old.py} (100%) rename python/helpers/pydev/{third_party/pluginbase.py => _pydev_imps/_pydev_pluginbase.py} (99%) rename python/helpers/pydev/{third_party/uuid_old.py => _pydev_imps/_pydev_uuid_old.py} (100%) diff --git a/python/helpers/pydev/third_party/pkgutil_old.py b/python/helpers/pydev/_pydev_imps/_pydev_pkgutil_old.py similarity index 100% rename from python/helpers/pydev/third_party/pkgutil_old.py rename to python/helpers/pydev/_pydev_imps/_pydev_pkgutil_old.py diff --git a/python/helpers/pydev/third_party/pluginbase.py b/python/helpers/pydev/_pydev_imps/_pydev_pluginbase.py similarity index 99% rename from python/helpers/pydev/third_party/pluginbase.py rename to python/helpers/pydev/_pydev_imps/_pydev_pluginbase.py index 18bd50524fc2..ed4203fb6f89 100644 --- a/python/helpers/pydev/third_party/pluginbase.py +++ b/python/helpers/pydev/_pydev_imps/_pydev_pluginbase.py @@ -16,14 +16,14 @@ from pydevd_constants import IS_PY24, IS_PY3K, IS_JYTHON if IS_PY24: - from third_party.uuid_old import uuid4 + from _pydev_imps._pydev_uuid_old import uuid4 else: from uuid import uuid4 if IS_PY3K: import pkgutil else: - import pkgutil_old as pkgutil + from _pydev_imps import _pydev_pkgutil_old as pkgutil import errno try: diff --git a/python/helpers/pydev/third_party/uuid_old.py b/python/helpers/pydev/_pydev_imps/_pydev_uuid_old.py similarity index 100% rename from python/helpers/pydev/third_party/uuid_old.py rename to python/helpers/pydev/_pydev_imps/_pydev_uuid_old.py From 50812e342612a422a7c08eca80fe8e4f052a5504 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 24 Oct 2014 14:39:39 +0200 Subject: [PATCH 22/55] light duplicate profile --- .../dupLocator/LightDuplicateProfile.java | 30 +++++++++++++ .../dupLocator/index/DuplicatesIndex.java | 43 ++++++++++++------- 2 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 platform/duplicates-analysis/src/com/intellij/dupLocator/LightDuplicateProfile.java diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/LightDuplicateProfile.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/LightDuplicateProfile.java new file mode 100644 index 000000000000..9f2c2a7c7d95 --- /dev/null +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/LightDuplicateProfile.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2014 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.dupLocator; + +import com.intellij.lang.LighterASTNode; +import com.intellij.psi.PsiFile; + +/** + * Created by Maxim.Mossienko on 10/1/2014. + */ +public interface LightDuplicateProfile { + void process(PsiFile file, Callback callback); + + interface Callback { + void process(LighterASTNode node, int hash); + } +} diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java index 55367ae4a19d..2f7962e3d87e 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java @@ -18,15 +18,17 @@ package com.intellij.dupLocator.index; import com.intellij.dupLocator.DuplicatesProfile; import com.intellij.dupLocator.DuplocateVisitor; import com.intellij.dupLocator.DuplocatorState; +import com.intellij.dupLocator.LightDuplicateProfile; import com.intellij.dupLocator.treeHash.FragmentsCollector; import com.intellij.dupLocator.util.PsiFragment; import com.intellij.lang.Language; +import com.intellij.lang.LighterASTNode; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.LanguageFileType; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiFile; import com.intellij.util.SystemProperties; import com.intellij.util.indexing.*; import com.intellij.util.io.DataExternalizer; @@ -52,6 +54,7 @@ import java.util.Map; public class DuplicatesIndex extends FileBasedIndexExtension implements PsiDependentIndex { static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.duplicates.online.calculation", isEnabledByDefault()); + static boolean ourEnabledLightProfiles = false; private static boolean isEnabledByDefault() { Application application = ApplicationManager.getApplication(); @@ -59,7 +62,7 @@ public class DuplicatesIndex extends FileBasedIndexExtension NAME = ID.create("DuplicatesIndex"); - private static final int myBaseVersion = 10; + private static final int myBaseVersion = 11; private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() { @Override @@ -107,21 +110,31 @@ public class DuplicatesIndex extends FileBasedIndexExtension map(@NotNull final FileContent inputData) { - return ApplicationManager.getApplication().runReadAction(new Computable>() { - @Override - public Map compute() { - FileType type = inputData.getFileType(); + FileType type = inputData.getFileType(); - DuplicatesProfile profile = findDuplicatesProfile(type); - if (profile == null) return Collections.emptyMap(); + DuplicatesProfile profile = findDuplicatesProfile(type); + if (profile == null) return Collections.emptyMap(); - MyFragmentsCollector collector = new MyFragmentsCollector(profile, ((LanguageFileType)type).getLanguage()); - DuplocateVisitor visitor = profile.createVisitor(collector, true); - visitor.visitNode(((FileContentImpl)inputData).getPsiFileAccountingForUnsavedDocument()); + PsiFile psiFile = ((FileContentImpl)inputData).getPsiFileAccountingForUnsavedDocument(); - return collector.getMap(); - } - }); + if (profile instanceof LightDuplicateProfile && ourEnabledLightProfiles) { + final THashMap result = new THashMap(); + ((LightDuplicateProfile)profile).process(psiFile, new LightDuplicateProfile.Callback() { + @Override + public void process(LighterASTNode node, int hash) { + TIntArrayList list = result.get(hash); + if (list == null) { result.put(hash, list = new TIntArrayList(1)); } + list.add(node.getStartOffset()); + } + }); + return result; + } + MyFragmentsCollector collector = new MyFragmentsCollector(profile, ((LanguageFileType)type).getLanguage()); + DuplocateVisitor visitor = profile.createVisitor(collector, true); + + visitor.visitNode(psiFile); + + return collector.getMap(); } }; @@ -135,7 +148,7 @@ public class DuplicatesIndex extends FileBasedIndexExtension Date: Fri, 24 Oct 2014 14:39:59 +0200 Subject: [PATCH 23/55] notnull --- platform/core-api/src/com/intellij/lang/LighterAST.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/core-api/src/com/intellij/lang/LighterAST.java b/platform/core-api/src/com/intellij/lang/LighterAST.java index 71305c5937be..af01fcb7d7f1 100644 --- a/platform/core-api/src/com/intellij/lang/LighterAST.java +++ b/platform/core-api/src/com/intellij/lang/LighterAST.java @@ -47,7 +47,7 @@ public abstract class LighterAST { @NotNull public abstract List getChildren(@NotNull final LighterASTNode parent); - public static @Nullable LighterAST getLighterASTFromFileAST(@NotNull FileASTNode node, @NotNull Language language) { + public static @NotNull LighterAST getLighterASTFromFileAST(@NotNull FileASTNode node, @NotNull Language language) { final IFileElementType contentType = LanguageParserDefinitions.INSTANCE.forLanguage(language).getFileNodeType(); assert contentType instanceof ILightStubFileElementType; From 92d34a326c21bda021fb5cd57b0375105075ea01 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Fri, 24 Oct 2014 14:41:29 +0200 Subject: [PATCH 24/55] IDEA-131853 Duplicate navigates to same place --- .../src/com/intellij/dupLocator/index/DuplicatesIndex.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java index 2f7962e3d87e..98145cda3c3b 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java @@ -62,7 +62,7 @@ public class DuplicatesIndex extends FileBasedIndexExtension NAME = ID.create("DuplicatesIndex"); - private static final int myBaseVersion = 11; + private static final int myBaseVersion = 12; private final FileBasedIndex.InputFilter myInputFilter = new FileBasedIndex.InputFilter() { @Override From 95a046771133aa8c8143be325c942e79e82dbb6e Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 27 Oct 2014 14:18:57 +0100 Subject: [PATCH 25/55] better api for lighter ast + caching --- .../intellij/lang/FCTSBackedLighterAST.java | 2 +- .../src/com/intellij/lang/FileASTNode.java | 4 +++ .../src/com/intellij/lang/LighterAST.java | 17 --------- .../intellij/psi/stubs/LightStubBuilder.java | 2 +- .../psi/impl/source/tree/FileElement.java | 36 +++++++++++++++++-- .../source/tree/LazyParseableElement.java | 8 +++-- 6 files changed, 46 insertions(+), 23 deletions(-) diff --git a/platform/core-api/src/com/intellij/lang/FCTSBackedLighterAST.java b/platform/core-api/src/com/intellij/lang/FCTSBackedLighterAST.java index b393f8d37707..2df20519e18d 100644 --- a/platform/core-api/src/com/intellij/lang/FCTSBackedLighterAST.java +++ b/platform/core-api/src/com/intellij/lang/FCTSBackedLighterAST.java @@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -class FCTSBackedLighterAST extends LighterAST { +public class FCTSBackedLighterAST extends LighterAST { private final FlyweightCapableTreeStructure myTreeStructure; public FCTSBackedLighterAST(final CharTable charTable, final FlyweightCapableTreeStructure treeStructure) { diff --git a/platform/core-api/src/com/intellij/lang/FileASTNode.java b/platform/core-api/src/com/intellij/lang/FileASTNode.java index 136530822a23..193e2421ebd1 100644 --- a/platform/core-api/src/com/intellij/lang/FileASTNode.java +++ b/platform/core-api/src/com/intellij/lang/FileASTNode.java @@ -17,6 +17,7 @@ package com.intellij.lang; import com.intellij.util.CharTable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * Top-level node in AST, corresponds to PsiFile. @@ -28,4 +29,7 @@ public interface FileASTNode extends ASTNode { CharTable getCharTable(); boolean isParsed(); + + @Nullable + LighterAST getLighterAST(); } diff --git a/platform/core-api/src/com/intellij/lang/LighterAST.java b/platform/core-api/src/com/intellij/lang/LighterAST.java index af01fcb7d7f1..de2c44aa1299 100644 --- a/platform/core-api/src/com/intellij/lang/LighterAST.java +++ b/platform/core-api/src/com/intellij/lang/LighterAST.java @@ -15,8 +15,6 @@ */ package com.intellij.lang; -import com.intellij.psi.tree.IFileElementType; -import com.intellij.psi.tree.ILightStubFileElementType; import com.intellij.util.CharTable; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -46,19 +44,4 @@ public abstract class LighterAST { @NotNull public abstract List getChildren(@NotNull final LighterASTNode parent); - - public static @NotNull LighterAST getLighterASTFromFileAST(@NotNull FileASTNode node, @NotNull Language language) { - final IFileElementType contentType = LanguageParserDefinitions.INSTANCE.forLanguage(language).getFileNodeType(); - assert contentType instanceof ILightStubFileElementType; - - final LighterAST tree; - if (!node.isParsed()) { - final ILightStubFileElementType type = (ILightStubFileElementType)contentType; - tree = new FCTSBackedLighterAST(node.getCharTable(), type.parseContentsLight(node)); - } - else { - tree = new TreeBackedLighterAST(node); - } - return tree; - } } \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/psi/stubs/LightStubBuilder.java b/platform/core-api/src/com/intellij/psi/stubs/LightStubBuilder.java index 102288e1a9a0..e9dec24fca2c 100644 --- a/platform/core-api/src/com/intellij/psi/stubs/LightStubBuilder.java +++ b/platform/core-api/src/com/intellij/psi/stubs/LightStubBuilder.java @@ -47,7 +47,7 @@ public class LightStubBuilder implements StubBuilder { LOG.error("File is not of ILightStubFileElementType: " + contentType + ", " + file); return null; } - final LighterAST tree = LighterAST.getLighterASTFromFileAST(file.getNode(), language); + final LighterAST tree = file.getNode().getLighterAST(); if (tree == null) return null; final StubElement rootStub = createStubForFile(file, tree); diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java index d3071ddbca7d..a2348eabbe97 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/FileElement.java @@ -16,16 +16,19 @@ package com.intellij.psi.impl.source.tree; -import com.intellij.lang.ASTNode; -import com.intellij.lang.FileASTNode; +import com.intellij.lang.*; import com.intellij.openapi.util.Getter; +import com.intellij.openapi.util.Key; import com.intellij.psi.PsiElement; import com.intellij.psi.impl.PsiManagerEx; import com.intellij.psi.impl.source.CharTableImpl; import com.intellij.psi.impl.source.PsiFileImpl; import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.IFileElementType; +import com.intellij.psi.tree.ILightStubFileElementType; import com.intellij.util.CharTable; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class FileElement extends LazyParseableElement implements FileASTNode, Getter { private volatile CharTable myCharTable = new CharTableImpl(); @@ -47,6 +50,35 @@ public class FileElement extends LazyParseableElement implements FileASTNode, Ge return myCharTable; } + private static final Key ourTreeKey = Key.create("lighter.key"); + + @Nullable + @Override + public LighterAST getLighterAST() { + final IFileElementType contentType = (IFileElementType)getElementType(); + assert contentType instanceof ILightStubFileElementType; + + LighterAST tree; + if (!isParsed()) { + tree = getUserData(ourTreeKey); + if (tree == null) { + final ILightStubFileElementType type = (ILightStubFileElementType)contentType; + tree = new FCTSBackedLighterAST(getCharTable(), type.parseContentsLight(this)); + putUserData(ourTreeKey, tree); + } + } + else { + tree = new TreeBackedLighterAST(this); + } + return tree; + } + + @Override + protected void resetCachesOnParsedStateUpdate() { + putUserData(ourTreeKey, null); + super.resetCachesOnParsedStateUpdate(); + } + public FileElement(IElementType type, CharSequence text) { super(type, text); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LazyParseableElement.java b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LazyParseableElement.java index ebc699aaf181..85a28f195282 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/tree/LazyParseableElement.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/tree/LazyParseableElement.java @@ -181,8 +181,8 @@ public class LazyParseableElement extends CompositeElement { if (rawFirstChild() != null) { LOG.error("Reentrant parsing?"); } - - myText = null; + + resetCachesOnParsedStateUpdate(); if (parsedNode == null) return; super.rawAddChildrenWithoutNotifications((TreeElement)parsedNode); @@ -199,6 +199,10 @@ public class LazyParseableElement extends CompositeElement { } } + protected void resetCachesOnParsedStateUpdate() { + myText = null; + } + @Override public void rawAddChildrenWithoutNotifications(@NotNull TreeElement first) { if (myText() != null) { From 49eee8d05d4ffb064c1ee6dd0ddd813538da3260 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 27 Oct 2014 14:25:42 +0100 Subject: [PATCH 26/55] light duplicate profile, step 2 --- .../src/com/intellij/dupLocator/LightDuplicateProfile.java | 3 ++- .../src/com/intellij/dupLocator/index/DuplicatesIndex.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/LightDuplicateProfile.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/LightDuplicateProfile.java index 9f2c2a7c7d95..c3011c11454e 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/LightDuplicateProfile.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/LightDuplicateProfile.java @@ -15,6 +15,7 @@ */ package com.intellij.dupLocator; +import com.intellij.lang.LighterAST; import com.intellij.lang.LighterASTNode; import com.intellij.psi.PsiFile; @@ -25,6 +26,6 @@ public interface LightDuplicateProfile { void process(PsiFile file, Callback callback); interface Callback { - void process(LighterASTNode node, int hash); + void process(LighterAST ast, LighterASTNode node, int hash); } } diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java index 98145cda3c3b..b3e94c465e70 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java @@ -22,6 +22,7 @@ import com.intellij.dupLocator.LightDuplicateProfile; import com.intellij.dupLocator.treeHash.FragmentsCollector; import com.intellij.dupLocator.util.PsiFragment; import com.intellij.lang.Language; +import com.intellij.lang.LighterAST; import com.intellij.lang.LighterASTNode; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -121,7 +122,7 @@ public class DuplicatesIndex extends FileBasedIndexExtension result = new THashMap(); ((LightDuplicateProfile)profile).process(psiFile, new LightDuplicateProfile.Callback() { @Override - public void process(LighterASTNode node, int hash) { + public void process(LighterAST ast, LighterASTNode node, int hash) { TIntArrayList list = result.get(hash); if (list == null) { result.put(hash, list = new TIntArrayList(1)); } list.add(node.getStartOffset()); From 85630605e156e729efc51d8ecee56b15ffe45894 Mon Sep 17 00:00:00 2001 From: Alexander Zolotov Date: Mon, 27 Oct 2014 16:53:46 +0300 Subject: [PATCH 27/55] Emmet support in JSX Harmony (WEB-13885, WEB-13951) --- .../intellij/codeInsight/template/emmet/XmlEmmetParser.java | 6 +++++- .../template/emmet/generators/ZenCodingGenerator.java | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java index 01ddc3ca563f..57dc97700a74 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/XmlEmmetParser.java @@ -313,7 +313,7 @@ public class XmlEmmetParser extends EmmetParser { } if (token == ZenCodingTokens.DOT || token == ZenCodingTokens.SHARP) { - final String name = token == ZenCodingTokens.DOT ? CLASS : ID; + final String name = getAttributeName(token); advance(); token = getToken(); final String value = getAttributeValueByToken(token); @@ -326,6 +326,10 @@ public class XmlEmmetParser extends EmmetParser { return null; } + protected String getAttributeName(ZenCodingToken delimiterToken) { + return delimiterToken == ZenCodingTokens.DOT ? CLASS : ID; + } + @Nullable private List> parseAttributeList() { final List> result = new ArrayList>(); diff --git a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java index b15df8b5da2e..846eb867d844 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java +++ b/xml/impl/src/com/intellij/codeInsight/template/emmet/generators/ZenCodingGenerator.java @@ -61,8 +61,8 @@ public abstract class ZenCodingGenerator { public static List getInstances() { List generators = new ArrayList(); - generators.add(XmlZenCodingGeneratorImpl.INSTANCE); Collections.addAll(generators, EP_NAME.getExtensions()); + generators.add(XmlZenCodingGeneratorImpl.INSTANCE); return generators; } From b0ad9c3ae9c61d35cd47b8fceac7e8eeeeec0d77 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 27 Oct 2014 15:31:05 +0100 Subject: [PATCH 28/55] fix PyCharm welcome --- .../openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java index 2994fede233a..ff94a4d5391f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/welcomeScreen/NewWelcomeScreen.java @@ -28,7 +28,6 @@ import com.intellij.openapi.updateSettings.impl.UpdateChecker; import com.intellij.openapi.updateSettings.impl.UpdateSettings; import com.intellij.openapi.util.DimensionService; import com.intellij.openapi.util.IconLoader; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.wm.WelcomeScreen; import com.intellij.ui.ScreenUtil; import com.intellij.ui.components.labels.LinkLabel; @@ -150,7 +149,7 @@ public class NewWelcomeScreen extends JPanel implements WelcomeScreen { } public static boolean isNewWelcomeScreen(@NotNull AnActionEvent e) { - return e.getPlace() == ActionPlaces.WELCOME_SCREEN && Registry.is("ide.new.welcome.screen"); + return e.getPlace() == ActionPlaces.WELCOME_SCREEN && FlatWelcomeFrameProvider.isAvailable(); } private static class WelcomeScreenGroup extends DefaultActionGroup { From 80683d965def8564ecdcf01a3d5634dda896bc55 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Mon, 27 Oct 2014 15:12:55 +0100 Subject: [PATCH 29/55] rollback fg color for inline debugger under Darcula (cherry picked from commit fbb5649599f225c3a4812474949473a35a9499b2) --- platform/util/resources/misc/registry.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 7d9390c705e3..d9f47ad0209a 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -47,7 +47,7 @@ ide.debugger.inline=true ide.debugger.inline.description=Enables variables view in editor ide.debugger.inline.fg.color=134,134,134 ide.debugger.inline.fg.color.description=Inline values foreground -ide.debugger.inline.dark.fg.color=62,179,151 +ide.debugger.inline.dark.fg.color=61,128,101 ide.debugger.inline.dark.fg.color.description=Inline values foreground for dark editor scheme ide.debugger.inline.fg.modified.color=202,128,33 ide.debugger.inline.fg.modified.color.description=Inline modified values foreground From a6e35cfd57a15fa66adff75643d26f9f1a15880d Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 27 Oct 2014 12:14:28 +0100 Subject: [PATCH 30/55] calculate void/value lambda compatibility based on valid, non-modified lambda expression --- .../refactoring/util/RefactoringUtil.java | 38 +++++++++++-------- ...utInLambdaBodyVoidValueConflict.after.java | 20 ++++++++++ .../PutInLambdaBodyVoidValueConflict.java | 17 +++++++++ .../refactoring/IntroduceVariableTest.java | 4 ++ 4 files changed, 63 insertions(+), 16 deletions(-) create mode 100644 java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoidValueConflict.after.java create mode 100644 java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoidValueConflict.java diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java index 004599135fee..d181d3c49351 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java +++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java @@ -870,32 +870,38 @@ public class RefactoringUtil { JavaCodeStyleManager.getInstance(declaration.getProject()).shortenClassReferences(declaration); if (loopBodyCopy != null) codeBlock.add(loopBodyCopy); } else if (container instanceof PsiLambdaExpression) { - final PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)container; - final PsiElement lambdaExpressionBody = lambdaExpression.getBody(); - LOG.assertTrue(lambdaExpressionBody != null); + PsiLambdaExpression lambdaExpression = (PsiLambdaExpression)container; + final PsiElement invalidBody = lambdaExpression.getBody(); + if (invalidBody == null) return declaration; final PsiLambdaExpression expressionFromText = (PsiLambdaExpression)elementFactory - .createExpressionFromText(lambdaExpression.getParameterList().getText() + " -> {}", lambdaExpression); + .createExpressionFromText(lambdaExpression.getParameterList().getText() + " -> {}", lambdaExpression.getParent()); PsiCodeBlock newBody = (PsiCodeBlock)expressionFromText.getBody(); LOG.assertTrue(newBody != null); newBody.add(declaration); - PsiStatement lastBodyStatement = elementFactory.createStatementFromText("a;", lambdaExpression); - ((PsiExpressionStatement)lastBodyStatement).getExpression().replace(lambdaExpressionBody); + lambdaExpression = + (PsiLambdaExpression)lambdaExpression.replace(elementFactory.createExpressionFromText( + lambdaExpression.getParameterList().getText() + " -> " + invalidBody.getText(), lambdaExpression)); + + final PsiElement lambdaExpressionBody = lambdaExpression.getBody(); + LOG.assertTrue(lambdaExpressionBody != null); + final PsiStatement lastBodyStatement; + if (LambdaUtil.getFunctionalInterfaceReturnType(lambdaExpression) == PsiType.VOID) { + lastBodyStatement = elementFactory.createStatementFromText("a;", lambdaExpression); + ((PsiExpressionStatement)lastBodyStatement).getExpression().replace(lambdaExpressionBody); + } + else { + lastBodyStatement = elementFactory.createStatementFromText("return a;", lambdaExpression); + final PsiExpression returnValue = ((PsiReturnStatement)lastBodyStatement).getReturnValue(); + LOG.assertTrue(returnValue != null); + returnValue.replace(lambdaExpressionBody); + } newBody.add(lastBodyStatement); - PsiLambdaExpression copy = (PsiLambdaExpression)lambdaExpression.replace(expressionFromText); + final PsiLambdaExpression copy = (PsiLambdaExpression)lambdaExpression.replace(expressionFromText); newBody = (PsiCodeBlock)copy.getBody(); LOG.assertTrue(newBody != null); - - if (LambdaUtil.getFunctionalInterfaceReturnType(copy) != PsiType.VOID) { - PsiExpressionStatement lastStatement = (PsiExpressionStatement)newBody.getStatements()[1]; - PsiReturnStatement returnStatement = (PsiReturnStatement)elementFactory.createStatementFromText("return a;", copy); - final PsiExpression returnValue = returnStatement.getReturnValue(); - LOG.assertTrue(returnValue != null); - returnValue.replace(lastStatement.getExpression()); - lastStatement.replace(returnStatement); - } declaration = newBody.getStatements()[0]; declaration = (PsiStatement)JavaCodeStyleManager.getInstance(declaration.getProject()).shortenClassReferences(declaration); } diff --git a/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoidValueConflict.after.java b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoidValueConflict.after.java new file mode 100644 index 000000000000..6315c2590032 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoidValueConflict.after.java @@ -0,0 +1,20 @@ +class Foo { + interface I { + T m(Object op); + } + + interface J { + void m(T o); + } + + + void f(J r) {} + void f(I r) {} + + { + f((a) -> { + int c = 1; + return c; + }); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoidValueConflict.java b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoidValueConflict.java new file mode 100644 index 000000000000..bdea215a08a4 --- /dev/null +++ b/java/java-tests/testData/refactoring/introduceVariable/PutInLambdaBodyVoidValueConflict.java @@ -0,0 +1,17 @@ +class Foo { + interface I { + T m(Object op); + } + + interface J { + void m(T o); + } + + + void f(J r) {} + void f(I r) {} + + { + f((a) -> 1); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java index 29f792330bbf..2e2a6cc488a3 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceVariableTest.java @@ -441,6 +441,10 @@ public class IntroduceVariableTest extends LightCodeInsightTestCase { doTest(new MockIntroduceVariableHandler("c", false, false, false, "int")); } + public void testPutInLambdaBodyVoidValueConflict() { + doTest(new MockIntroduceVariableHandler("c", false, false, false, "int")); + } + public void testNormalizeDeclarations() { doTest(new MockIntroduceVariableHandler("i3", false, false, false, "int")); } From e473a2ed4d2cec4fb387ba749caaeac41fffa899 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 27 Oct 2014 13:26:33 +0100 Subject: [PATCH 31/55] missed writable checks --- .../codeInspection/AnonymousCanBeLambdaInspection.java | 2 ++ .../AnonymousCanBeMethodReferenceInspection.java | 2 ++ .../codeInspection/ExplicitTypeCanBeDiamondInspection.java | 5 ++++- .../codeInspection/LambdaCanBeMethodReferenceInspection.java | 2 ++ .../PossibleHeapPollutionVarargsInspection.java | 2 ++ .../codeInspection/RedundantLambdaCodeBlockInspection.java | 2 ++ 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java index 39098b51d8f8..88df46359853 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeLambdaInspection.java @@ -17,6 +17,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.AnnotationUtil; import com.intellij.codeInsight.ChangeContextUtil; +import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil; import com.intellij.codeInsight.intention.HighPriorityAction; @@ -208,6 +209,7 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); if (element instanceof PsiNewExpression) { + if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return; final PsiAnonymousClass anonymousClass = ((PsiNewExpression)element).getAnonymousClass(); LOG.assertTrue(anonymousClass != null); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java index 2f9f4f883648..fb3c6183889f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnonymousCanBeMethodReferenceInspection.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection; +import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -115,6 +116,7 @@ public class AnonymousCanBeMethodReferenceInspection extends BaseJavaBatchLocalI public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); if (element instanceof PsiNewExpression) { + if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return; final PsiAnonymousClass anonymousClass = ((PsiNewExpression)element).getAnonymousClass(); if (anonymousClass == null) return; final PsiMethod[] methods = anonymousClass.getMethods(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java index 08bb3413f313..b39171e76b89 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection; +import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.openapi.diagnostic.Logger; @@ -94,7 +95,9 @@ public class ExplicitTypeCanBeDiamondInspection extends BaseJavaBatchLocalInspec @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - PsiDiamondTypeUtil.replaceExplicitWithDiamond(descriptor.getPsiElement()); + final PsiElement element = descriptor.getPsiElement(); + if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return; + PsiDiamondTypeUtil.replaceExplicitWithDiamond(element); } } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java index b8c3908d392c..8b9d7f76917e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/LambdaCanBeMethodReferenceInspection.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection; +import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -390,6 +391,7 @@ public class LambdaCanBeMethodReferenceInspection extends BaseJavaBatchLocalInsp @Override public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); + if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return; final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class); if (lambdaExpression == null) return; final PsiType functionalInterfaceType = lambdaExpression.getFunctionalInterfaceType(); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java index d4812f0bced7..d464e9cc45a4 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java @@ -16,6 +16,7 @@ package com.intellij.codeInspection; import com.intellij.codeInsight.AnnotationUtil; +import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil; import com.intellij.codeInsight.intention.AddAnnotationPsiFix; @@ -133,6 +134,7 @@ public class PossibleHeapPollutionVarargsInspection extends BaseJavaBatchLocalIn public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement psiElement = descriptor.getPsiElement(); if (psiElement instanceof PsiIdentifier) { + if (!FileModificationService.getInstance().preparePsiElementForWrite(psiElement)) return; final PsiMethod psiMethod = (PsiMethod)psiElement.getParent(); psiMethod.getModifierList().setModifierProperty(PsiModifier.FINAL, true); new AddAnnotationPsiFix("java.lang.SafeVarargs", psiMethod, PsiNameValuePair.EMPTY_ARRAY).applyFix(project, descriptor); diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java index 7a96ab1cc8bc..38bd06bba509 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java @@ -15,6 +15,7 @@ */ package com.intellij.codeInspection; +import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.GroupNames; import com.intellij.codeInsight.intention.HighPriorityAction; import com.intellij.openapi.diagnostic.Logger; @@ -158,6 +159,7 @@ public class RedundantLambdaCodeBlockInspection extends BaseJavaBatchLocalInspec public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { final PsiElement element = descriptor.getPsiElement(); if (element != null) { + if (!FileModificationService.getInstance().preparePsiElementForWrite(element)) return; final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class); if (lambdaExpression != null) { final PsiElement body = lambdaExpression.getBody(); From f2257025fad4526761a6541c07f7fab11e8f0f3a Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 27 Oct 2014 15:29:10 +0100 Subject: [PATCH 32/55] extract light method object: create class initializer if there is no place to put initializer (IDEA-131912) --- .../ExtractLightMethodObjectHandler.java | 24 +++++++-- .../OnClosingBrace.java | 10 ++++ .../OnClosingBraceLocalClass.java | 12 +++++ .../OnEmptyMethod.java | 7 +++ .../OnFieldInitialization.java | 7 +++ .../OnSuperConstructorCall.java | 9 ++++ .../ExtractMethodObject4DebuggerTest.java | 50 +++++++++++++++++++ 7 files changed, 115 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnClosingBrace.java create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnClosingBraceLocalClass.java create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnEmptyMethod.java create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnFieldInitialization.java create mode 100644 java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnSuperConstructorCall.java diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java index 968b537bb71d..c008f7f7a609 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java +++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractLightMethodObjectHandler.java @@ -92,12 +92,28 @@ public class ExtractLightMethodObjectHandler { final TextRange range = originalContext.getTextRange(); final PsiElement originalAnchor = CodeInsightUtil.findElementInRange(copy, range.getStartOffset(), range.getEndOffset(), originalContext.getClass()); - //todo before this or super, not found etc - final PsiElement anchor = RefactoringUtil.getParentStatement(originalAnchor, false); - if (anchor == null) { + + final PsiClass containingClass = PsiTreeUtil.getParentOfType(originalAnchor, PsiClass.class); + if (containingClass == null) { return null; } - final PsiElement container = anchor.getParent(); + + PsiElement anchor = RefactoringUtil.getParentStatement(originalAnchor, false); + if (anchor == null) { + if (PsiTreeUtil.getParentOfType(originalAnchor, PsiCodeBlock.class) != null) { + anchor = originalAnchor; + } + } + + final PsiElement container; + if (anchor == null) { + container = ((PsiClassInitializer)containingClass.add(elementFactory.createClassInitializer())).getBody(); + anchor = container.getLastChild(); + } + else { + container = anchor.getParent(); + } + final PsiElement firstElementCopy = container.addRangeBefore(elements[0], elements[elements.length - 1], anchor); final PsiElement[] elementsCopy = CodeInsightUtil.findStatementsInRange(copy, firstElementCopy.getTextRange().getStartOffset(), diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnClosingBrace.java b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnClosingBrace.java new file mode 100644 index 000000000000..48a25567d205 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnClosingBrace.java @@ -0,0 +1,10 @@ +class Sample { + + void a() { + System.out.println(""); + } + + private int foo() { + return 1; + } +} diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnClosingBraceLocalClass.java b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnClosingBraceLocalClass.java new file mode 100644 index 000000000000..010af145aaca --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnClosingBraceLocalClass.java @@ -0,0 +1,12 @@ +class Sample { + + void a() { + class Local { + + } + } + + private int foo() { + return 1; + } +} diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnEmptyMethod.java b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnEmptyMethod.java new file mode 100644 index 000000000000..6436369d9d84 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnEmptyMethod.java @@ -0,0 +1,7 @@ +class Sample { + static {} + + int foo() { + return 1; + } +} diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnFieldInitialization.java b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnFieldInitialization.java new file mode 100644 index 000000000000..e1746e57ed23 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnFieldInitialization.java @@ -0,0 +1,7 @@ +class Sample { + int i = 0; + + int foo() { + return 1; + } +} diff --git a/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnSuperConstructorCall.java b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnSuperConstructorCall.java new file mode 100644 index 000000000000..69d6f91a4643 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractMethodObject4Debugger/OnSuperConstructorCall.java @@ -0,0 +1,9 @@ +class Sample { + public Sample() { + super(); + } + + int foo() { + return 1; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java index af1fee9363dc..d6440fd5de19 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodObject4DebuggerTest.java @@ -214,6 +214,56 @@ public class ExtractMethodObject4DebuggerTest extends LightRefactoringTestCase { " }", false); } + public void testOnClosingBrace() throws Exception { + doTest(" foo()", "int result = new Test().invoke();", + + "public class Test {\n" + + " public int invoke() {\n" + + " return foo();\n" + + " }\n" + + " }"); + } + + public void testOnClosingBraceLocalClass() throws Exception { + doTest(" foo()", "int result = new Test().invoke();", + + "public class Test {\n" + + " public int invoke() {\n" + + " return foo();\n" + + " }\n" + + " }"); + } + + public void testOnFieldInitialization() throws Exception { + doTest(" foo()", "int result = new Test().invoke();", + + "public class Test {\n" + + " public int invoke() {\n" + + " return foo();\n" + + " }\n" + + " }"); + } + + public void testOnEmptyMethod() throws Exception { + doTest(" foo()", "int result = Test.invoke();", + + "public static class Test {\n" + + " public static int invoke() {\n" + + " return foo();\n" + + " }\n" + + " }"); + } + + public void testOnSuperConstructorCall() throws Exception { + doTest(" foo()", "int result = new Test().invoke();", + + "public class Test {\n" + + " public int invoke() {\n" + + " return foo();\n" + + " }\n" + + " }"); + } + @Override protected Sdk getProjectJDK() { return IdeaTestUtil.getMockJdk18(); From be71edcb676ebe4151aeeee71c6fc5cbedd090ba Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Mon, 27 Oct 2014 17:40:20 +0300 Subject: [PATCH 33/55] use info about breakpoint's function for debugger performance improvement --- .../debugger/pydev/MultiProcessDebugger.java | 7 ++++ .../debugger/pydev/ProcessDebugger.java | 2 ++ .../python/debugger/pydev/RemoteDebugger.java | 10 ++++++ .../python/debugger/PyDebugProcess.java | 36 +++++++++++++++++-- 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java index d54bac8de85f..834916b0cf2b 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/MultiProcessDebugger.java @@ -359,6 +359,13 @@ public class MultiProcessDebugger implements ProcessDebugger { } } + @Override + public void setBreakpointWithFuncName(String typeId, String file, int line, String condition, String logExpression, String funcName) { + for (ProcessDebugger d : allDebuggers()) { + d.setBreakpointWithFuncName(typeId, file, line, condition, logExpression, funcName); + } + } + @Override public void removeBreakpoint(String typeId, String file, int line) { for (ProcessDebugger d : allDebuggers()) { diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java index 0fa5a5c21931..22344434252b 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/ProcessDebugger.java @@ -78,6 +78,8 @@ public interface ProcessDebugger { void setBreakpoint(String typeId, String file, int line, String condition, String logExpression); + void setBreakpointWithFuncName(String typeId, String file, int line, String condition, String logExpression, String funcName); + void removeBreakpoint(String typeId, String file, int line); void addCloseListener(RemoteDebuggerCloseListener remoteDebuggerCloseListener); diff --git a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java index 4ce7bdf67434..2d97a3fb1a7e 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/pydev/RemoteDebugger.java @@ -436,6 +436,16 @@ public class RemoteDebugger implements ProcessDebugger { execute(command); } + @Override + public void setBreakpointWithFuncName(String typeId, String file, int line, String condition, String logExpression, String funcName) { + final SetBreakpointCommand command = + new SetBreakpointCommand(this, typeId, file, line, + condition, + logExpression, + funcName); + execute(command); + } + @Override public void removeBreakpoint(String typeId, String file, int line) { final RemoveBreakpointCommand command = diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index dbeb5dedfd7c..532e374d5c74 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -24,6 +24,7 @@ import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.fileEditor.FileDocumentManager; @@ -34,6 +35,9 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.remote.RemoteProcessHandlerBase; import com.intellij.util.ui.UIUtil; import com.intellij.xdebugger.*; @@ -44,9 +48,11 @@ import com.intellij.xdebugger.breakpoints.XLineBreakpoint; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.frame.XValueChildrenList; import com.intellij.xdebugger.stepping.XSmartStepIntoHandler; +import com.jetbrains.python.PythonFileType; import com.jetbrains.python.console.PythonDebugLanguageConsoleView; import com.jetbrains.python.console.pydev.PydevCompletionVariant; import com.jetbrains.python.debugger.pydev.*; +import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.run.PythonProcessHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -594,12 +600,36 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr return frame; } + private String getFunctionName(final XLineBreakpoint breakpoint) { + final VirtualFile file = breakpoint.getSourcePosition().getFile(); + final Document document = FileDocumentManager.getInstance().getDocument(file); + final Project project = getSession().getProject(); + final String[] funcName = new String[1]; + if (document != null) { + if (file.getFileType() == PythonFileType.INSTANCE) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + PsiElement psiElement = XDebuggerUtil.getInstance().findContextElement(file, breakpoint.getSourcePosition().getOffset(), + project, false); + PyFunction function = PsiTreeUtil.getParentOfType(psiElement, PyFunction.class); + if (function != null) { + funcName[0] = function.getName(); + } + } + }); + } + } + return funcName[0]; + } + public void addBreakpoint(final PySourcePosition position, final XLineBreakpoint breakpoint) { myRegisteredBreakpoints.put(position, breakpoint); if (isConnected()) { - myDebugger.setBreakpoint(breakpoint.getType().getId(), position.getFile(), position.getLine(), - breakpoint.getCondition(), - breakpoint.getLogExpression()); + myDebugger.setBreakpointWithFuncName(breakpoint.getType().getId(), position.getFile(), position.getLine(), + breakpoint.getCondition(), + breakpoint.getLogExpression(), + getFunctionName(breakpoint)); } } From edac86f88df9d60c792a675fb7db1de56d228bd4 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Mon, 27 Oct 2014 17:40:17 +0300 Subject: [PATCH 34/55] IDEA-123797 It is impossible to edit watch item (set bounds equally) --- .../xdebugger/impl/ui/tree/TreeInplaceEditor.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java index 84e391b21a1a..1edfa484421a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java @@ -89,6 +89,10 @@ public abstract class TreeInplaceEditor implements AWTEventListener { protected abstract Project getProject(); + private static void setInplaceEditorBounds(JComponent component, int x, int y, int width, int height) { + component.setBounds(x, y, width, Math.max(height, component.getPreferredSize().height)); + } + public final void show() { LOG.assertTrue(myInplaceEditorComponent == null, "editor is not released"); final JTree tree = getTree(); @@ -108,12 +112,7 @@ public abstract class TreeInplaceEditor implements AWTEventListener { final JComponent inplaceEditorComponent = createInplaceEditorComponent(); myInplaceEditorComponent = inplaceEditorComponent; LOG.assertTrue(inplaceEditorComponent != null); - inplaceEditorComponent.setBounds( - layeredPanePoint.x, - layeredPanePoint.y, - bounds.width, - Math.max(bounds.height, inplaceEditorComponent.getPreferredSize().height) - ); + setInplaceEditorBounds(inplaceEditorComponent, layeredPanePoint.x, layeredPanePoint.y, bounds.width, bounds.height); layeredPane.add(inplaceEditorComponent, new Integer(250)); @@ -145,7 +144,7 @@ public abstract class TreeInplaceEditor implements AWTEventListener { return; } Point layeredPanePoint = SwingUtilities.convertPoint(tree, bounds.x, bounds.y, layeredPane); - inplaceEditorComponent.setBounds(layeredPanePoint.x, layeredPanePoint.y, bounds.width, bounds.height); + setInplaceEditorBounds(inplaceEditorComponent, layeredPanePoint.x, layeredPanePoint.y, bounds.width, bounds.height); inplaceEditorComponent.revalidate(); } }); From e4406b74b20a7333d920cca2334806f9854b064c Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 27 Oct 2014 15:43:29 +0100 Subject: [PATCH 35/55] cleanup --- .../updateSettings/impl/UpdateChecker.java | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index 1d8fa160a1e2..14366fc46aa7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -93,7 +93,7 @@ public final class UpdateChecker { @NonNls private static final String DISABLED_UPDATE = "disabled_update.txt"; private static Set ourDisabledToUpdatePlugins; - private static Map ourAdditionalRequestOptions = new HashMap(); + private static final Map ourAdditionalRequestOptions = new HashMap(); private static class Holder { private static final String UPDATE_URL = ApplicationInfoEx.getInstanceEx().getUpdateUrls().getCheckingUrl(); @@ -464,8 +464,7 @@ public final class UpdateChecker { private static CheckForUpdateResult checkForUpdates(final UpdateSettings settings) { UpdatesInfo info; try { - UpdatesXmlLoader loader = new UpdatesXmlLoader(getUpdateUrl()); - info = loader.loadUpdatesInfo(); + info = UpdatesXmlLoader.loadUpdatesInfo(getUpdateUrl()); if (info == null) { return new CheckForUpdateResult(UpdateStrategy.State.NOTHING_LOADED); } @@ -660,14 +659,12 @@ public final class UpdateChecker { return uid; } } - String uid; - if (!propertiesComponent.isValueSet(INSTALLATION_UID)) { + + String uid = propertiesComponent.getValue(INSTALLATION_UID); + if (uid == null) { uid = generateUUID(); propertiesComponent.setValue(INSTALLATION_UID, uid); } - else { - uid = propertiesComponent.getValue(INSTALLATION_UID); - } return uid; } @@ -683,11 +680,8 @@ public final class UpdateChecker { return FileUtil.loadFile(permanentIdFile).trim(); } - String uuid; - if (propertiesComponent.isValueSet(INSTALLATION_UID)) { - uuid = propertiesComponent.getValue(INSTALLATION_UID); - } - else { + String uuid = propertiesComponent.getValue(INSTALLATION_UID); + if (uuid == null) { uuid = generateUUID(); } FileUtil.writeToFile(permanentIdFile, uuid); @@ -816,7 +810,7 @@ public final class UpdateChecker { out.close(); } - String patchFileName = ("jetbrains.patch.jar." + platform).toLowerCase(); + String patchFileName = ("jetbrains.patch.jar." + platform).toLowerCase(Locale.ENGLISH); File patchFile = new File(FileUtil.getTempDirectory(), patchFileName); FileUtil.copy(tempFile, patchFile); FileUtil.delete(tempFile); From e2985c097d48ed463b7cf4cb4ee6ccf0a68cc31e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 27 Oct 2014 15:44:22 +0100 Subject: [PATCH 36/55] IDEA-131621 IDEA 139.144.2 takes forever to start. Hangs on 100% splash screen state --- .../updateSettings/impl/UpdatesXmlLoader.java | 95 ++++++------------- 1 file changed, 28 insertions(+), 67 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesXmlLoader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesXmlLoader.java index 9c6c6a2020e5..f8f9a71c120c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesXmlLoader.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesXmlLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -25,33 +25,19 @@ import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.net.HttpConfigurable; import org.jdom.JDOMException; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.net.URLConnection; -import java.util.concurrent.Callable; -import java.util.concurrent.FutureTask; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -public class UpdatesXmlLoader { - - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.updateSettings.impl.UpdatesXmlLoader"); - - private final String updateUrl; - - public UpdatesXmlLoader(final String updatesUrl) { - this.updateUrl = updatesUrl; - } +import java.util.concurrent.*; +class UpdatesXmlLoader { + private static final Logger LOG = Logger.getInstance(UpdatesXmlLoader.class); @Nullable - public UpdatesInfo loadUpdatesInfo() throws ConnectionException{ - LOG.debug("load update xml (UPDATE_URL='" + updateUrl + "' )"); + public static UpdatesInfo loadUpdatesInfo(@Nullable final String updateUrl) throws ConnectionException { + if (LOG.isDebugEnabled()) { + LOG.debug("load update xml (UPDATE_URL='" + updateUrl + "' )"); + } if (StringUtil.isEmpty(updateUrl)) { LOG.debug("update url is empty: updates will not be checked"); @@ -59,20 +45,13 @@ public class UpdatesXmlLoader { } final Ref error = new Ref(); - FutureTask ft = new FutureTask(new Callable() { + Future future = ApplicationManager.getApplication().executeOnPooledThread(new Callable() { @Nullable @Override public UpdatesInfo call() throws Exception { try { - prepareUrl(updateUrl); - - URL requestUrl = prepareRequestUrl(updateUrl); - - URLConnection connection = requestUrl.openConnection(); - connection.setConnectTimeout(HttpConfigurable.CONNECTION_TIMEOUT); - connection.setReadTimeout(HttpConfigurable.CONNECTION_TIMEOUT); - final InputStream inputStream = connection.getInputStream(); - Reader reader = new InputStreamReader(inputStream); + String url = updateUrl.startsWith("file:") ? updateUrl : updateUrl + '?' + UpdateChecker.prepareUpdateCheckArgs(); + InputStream inputStream = HttpConfigurable.getInstance().openConnection(url).getInputStream(); try { return new UpdatesInfo(JDOMUtil.loadDocument(inputStream).getRootElement()); } @@ -80,59 +59,41 @@ public class UpdatesXmlLoader { LOG.info(e); // Broken xml downloaded. Don't bother telling user. } finally { - reader.close(); inputStream.close(); } } catch (Exception e) { + LOG.debug(e); error.set(e); } return null; } }); - ApplicationManager.getApplication().executeOnPooledThread(ft); + + UpdatesInfo result = null; try { - UpdatesInfo result = ft.get(5, TimeUnit.SECONDS); - if (!error.isNull()) { - //noinspection ThrowableResultOfMethodCallIgnored - throw new ConnectionException(error.get()); - } - return result; + result = future.get(5, TimeUnit.SECONDS); } - catch (TimeoutException e) { - // ignore + catch (TimeoutException ignored) { } - catch (Exception e) { + catch (InterruptedException e) { LOG.debug(e); - throw new ConnectionException(e.getMessage(),e); + error.set(e); } - if (!ft.isDone()) { - ft.cancel(true); - throw new ConnectionException(IdeBundle.message("updates.timeout.error")); + catch (ExecutionException e) { + LOG.debug(e); + error.set(e); } - return null; - } - - - protected static void prepareUrl(@NotNull String url) throws ConnectionException { - try { - HttpConfigurable.getInstance().prepareURL(url); - } - catch (Exception e) { - throw new ConnectionException(e); - } - } - - protected URL prepareRequestUrl(@NotNull String url) throws ConnectionException { - try { - if (url.startsWith("file:")) { - return new URL(url); + if (!future.isDone()) { + future.cancel(true); + if (error.isNull()) { + throw new ConnectionException(IdeBundle.message("updates.timeout.error")); } - return new URL(url + "?" + UpdateChecker.prepareUpdateCheckArgs()); } - catch (Exception e) { - throw new ConnectionException(e); + if (!error.isNull()) { + throw new ConnectionException(error.get()); } + return result; } } From a06c75a1633e443ef188ce58397b63786689c7bf Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 27 Oct 2014 15:47:16 +0100 Subject: [PATCH 37/55] cleanup --- .../impl/pluginsAdvertisement/PluginsAdvertiser.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java index 4ae3caee88e1..b08adda9d2f9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginsAdvertiser.java @@ -245,6 +245,7 @@ public class PluginsAdvertiser implements StartupActivity { final KnownExtensions extensions = loadExtensions(); if (extensions != null && unknownFeatures.isEmpty()) return; final Runnable runnable = new Runnable() { + @Override public void run() { final Application application = ApplicationManager.getApplication(); if (application.isUnitTestMode() || application.isHeadlessEnvironment()) return; @@ -252,9 +253,10 @@ public class PluginsAdvertiser implements StartupActivity { private final Set myPlugins = new HashSet(); private List myAllPlugins; - private Map myDisabledPlugins = new HashMap(); + private final Map myDisabledPlugins = new HashMap(); private List myBundledPlugin; + @Override public void run() { try { myAllPlugins = RepositoryHelper.loadPluginsFromRepository(null); @@ -349,6 +351,7 @@ public class PluginsAdvertiser implements StartupActivity { @MapAnnotation(surroundWithTag = false, surroundKeyWithTag = false, surroundValueWithTag = false) public Map myExtensions = new HashMap(); + @SuppressWarnings("unused") public KnownExtensions() { } @@ -371,6 +374,7 @@ public class PluginsAdvertiser implements StartupActivity { public static class PluginSet { public Set myPlugins = new HashSet(); + @SuppressWarnings("unused") public PluginSet() { } From 9d8b6d25218d6e7f4356fe1bd97b8d5d65bd3777 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Mon, 27 Oct 2014 16:09:34 +0100 Subject: [PATCH 38/55] cleanup --- .../openapi/updateSettings/impl/Product.java | 18 +++++++++--------- .../updateSettings/impl/UpdateChannel.java | 13 ++++++------- .../updateSettings/impl/UpdatesInfo.java | 10 ++++------ 3 files changed, 19 insertions(+), 22 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/Product.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/Product.java index 56ae855dc317..2a576abf538a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/Product.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/Product.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -33,19 +33,17 @@ public class Product { private final Set myCodes; private final List myChannels; - public Product(Element node) { + public Product(@NotNull Element node) { myName = node.getAttributeValue("name"); myCodes = new LinkedHashSet(); myChannels = new ArrayList(); - List codes = node.getChildren("code"); - for (Object code : codes) { - myCodes.add(((Element)code).getValue()); + for (Element code : node.getChildren("code")) { + myCodes.add(code.getValue()); } - List channels = node.getChildren("channel"); - for (Object channel : channels) { - myChannels.add(new UpdateChannel((Element)channel)); + for (Element channel : node.getChildren("channel")) { + myChannels.add(new UpdateChannel(channel)); } } @@ -56,7 +54,9 @@ public class Product { @Nullable public UpdateChannel findUpdateChannelById(String id) { for (UpdateChannel channel : myChannels) { - if (id.equals(channel.getId())) return channel; + if (id.equals(channel.getId())) { + return channel; + } } return null; } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChannel.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChannel.java index 3a3869146e94..4d986b4a3cc2 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChannel.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChannel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -20,6 +20,7 @@ package com.intellij.openapi.updateSettings.impl; import org.jdom.Element; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -39,12 +40,11 @@ public class UpdateChannel { public static final String LICENSING_EAP = "eap"; public static final String LICENSING_PRODUCTION = "production"; - public UpdateChannel(Element node) { + public UpdateChannel(@NotNull Element node) { myId = node.getAttributeValue("id"); myName = node.getAttributeValue("name"); myStatus = ChannelStatus.fromCode(node.getAttributeValue("status")); - String licensing = node.getAttributeValue("licensing"); - myLicensing = licensing != null ? licensing : LICENSING_PRODUCTION; + myLicensing = node.getAttributeValue("licensing", LICENSING_PRODUCTION); String majorVersion = node.getAttributeValue("majorVersion"); myMajorVersion = majorVersion != null ? Integer.parseInt(majorVersion) : -1; @@ -56,8 +56,8 @@ public class UpdateChannel { myFeedbackUrl = node.getAttributeValue("feedback"); myBuilds = new ArrayList(); - for (Object child : node.getChildren("build")) { - myBuilds.add(new BuildInfo((Element)child)); + for (Element child : node.getChildren("build")) { + myBuilds.add(new BuildInfo(child)); } } @@ -69,7 +69,6 @@ public class UpdateChannel { build = info; } } - return build; } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesInfo.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesInfo.java index 46bd1182db61..0e2d93753958 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesInfo.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdatesInfo.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -15,7 +15,6 @@ */ package com.intellij.openapi.updateSettings.impl; - import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,11 +25,10 @@ import java.util.List; public class UpdatesInfo { @NotNull private final List myProducts; - public UpdatesInfo(Element element) { + public UpdatesInfo(@NotNull Element element) { myProducts = new ArrayList(); - List children = element.getChildren(); - for (Object child : children) { - myProducts.add(new Product((Element) child)); + for (Element child : element.getChildren()) { + myProducts.add(new Product(child)); } } From 868770fa81092338309499885406e4f54e1e80f7 Mon Sep 17 00:00:00 2001 From: "Vladimir.Orlov" Date: Mon, 27 Oct 2014 18:15:06 +0300 Subject: [PATCH 39/55] moved getCustomJDK to utils.gant to be available for all IDEA based products. --- build/scripts/utils.gant | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant index 2799ae550865..8e2376b71c55 100644 --- a/build/scripts/utils.gant +++ b/build/scripts/utils.gant @@ -691,6 +691,26 @@ private String submapToXml(Map properties, List keys) { return buff.toString() } +private List getChildren(File file) { + if (!file.isDirectory()) return [] + return file.listFiles().sort { File f -> f.name.toLowerCase() } +} + +binding.setVariable("getCustomJDK", { File customJdkDir -> + getChildren(customJdkDir).each { + if (it.getName().endsWith(".tar.gz")) { + def customJdkFileName = it.getAbsolutePath().substring(0, it.getAbsolutePath().length() - 3) + if (new File(customJdkFileName).exists()){ ant.delete(file: customJdkFileName) } + if (new File("${home}/build/jdk/custom_jdk_${buildNumber}.tar").exists()){ + ant.delete(file: "${home}/build/jdk/custom_jdk_${buildNumber}.tar") + } + ant.gunzip(src: it.getAbsolutePath()) + projectBuilder.info("customJdkFileName: " + customJdkFileName) + ant.copy(file: customJdkFileName, tofile: "${home}/build/jdk/custom_jdk_${buildNumber}.tar") + } + } +}) + binding.setVariable("buildWinZip", { String zipPath, List paths -> projectBuilder.stage(".win.zip") From f0556d52a6afcd9f5a92f06cfe54baa34ec9538f Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 27 Oct 2014 16:16:10 +0100 Subject: [PATCH 40/55] proper offset for light tree derived from nested lazy parseable --- .../intellij/lang/impl/PsiBuilderImpl.java | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index e03244e0e0e9..0bc853c76815 100644 --- a/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/core-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -89,6 +89,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { private final ASTNode myOriginalTree; private final MyTreeStructure myParentLightTree; + private final int myOffset; private static TokenSet ourAnyLanguageWhitespaceTokens = TokenSet.EMPTY; @@ -132,7 +133,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { @Nullable ASTNode originalTree, @Nullable MyTreeStructure parentLightTree) { this(project, containingFile, parserDefinition.getWhitespaceTokens(), parserDefinition.getCommentTokens(), lexer, charTable, text, - originalTree, parentLightTree); + originalTree, parentLightTree, 0); } public PsiBuilderImpl(Project project, @@ -144,6 +145,19 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { @NotNull final CharSequence text, @Nullable ASTNode originalTree, @Nullable MyTreeStructure parentLightTree) { + this(project, containingFile, whiteSpaces, comments, lexer, charTable, text, originalTree, parentLightTree, 0); + } + + private PsiBuilderImpl(Project project, + PsiFile containingFile, + @NotNull TokenSet whiteSpaces, + @NotNull TokenSet comments, + @NotNull Lexer lexer, + CharTable charTable, + @NotNull final CharSequence text, + @Nullable ASTNode originalTree, + @Nullable MyTreeStructure parentLightTree, + int offset) { myProject = project; myFile = containingFile; @@ -156,6 +170,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { myCharTable = charTable; myOriginalTree = originalTree; myParentLightTree = parentLightTree; + myOffset = offset; cacheLexemes(); } @@ -174,8 +189,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { @NotNull final Lexer lexer, @NotNull final LighterLazyParseableNode chameleon, @NotNull final CharSequence text) { - this(project, chameleon.getContainingFile(), parserDefinition, lexer, chameleon.getCharTable(), text, - null, ((LazyParseableToken)chameleon).myParent); + this(project, chameleon.getContainingFile(), parserDefinition.getWhitespaceTokens(), parserDefinition.getCommentTokens(), lexer, + chameleon.getCharTable(), text, null, ((LazyParseableToken)chameleon).myParent, chameleon.getStartOffset()); } private void cacheLexemes() { @@ -335,12 +350,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { @Override public int getStartOffset() { - return myBuilder.myLexStarts[myLexemeIndex]; + return myBuilder.myLexStarts[myLexemeIndex] + myBuilder.myOffset; } @Override public int getEndOffset() { - return myBuilder.myLexStarts[myDoneMarker.myLexemeIndex]; + return myBuilder.myLexStarts[myDoneMarker.myLexemeIndex] + myBuilder.myOffset; } @Override @@ -487,12 +502,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { @Override public int getEndOffset() { - return myTokenEnd; + return myTokenEnd + myBuilder.myOffset; } @Override public int getStartOffset() { - return myTokenStart; + return myTokenStart + myBuilder.myOffset; } public CharSequence getText() { @@ -636,12 +651,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { @Override public int getEndOffset() { - return myBuilder.myLexStarts[myLexemeIndex]; + return myBuilder.myLexStarts[myLexemeIndex] + myBuilder.myOffset; } @Override public int getStartOffset() { - return myBuilder.myLexStarts[myLexemeIndex]; + return myBuilder.myLexStarts[myLexemeIndex] + myBuilder.myOffset; } @Override @@ -1474,6 +1489,7 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { private final LimitedPool myPool; private final LimitedPool myLazyPool; private final StartMarker myRoot; + private final int myOffset; public MyTreeStructure(@NotNull StartMarker root, @Nullable final MyTreeStructure parentTree) { if (parentTree == null) { @@ -1499,10 +1515,12 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { return new LazyParseableToken(); } }); + myOffset = 0; } else { myPool = parentTree.myPool; myLazyPool = parentTree.myLazyPool; + myOffset = parentTree.getRoot().getStartOffset(); } myRoot = root; } From 29c1bfdc34378176f9bd348d124cfd368d4b469b Mon Sep 17 00:00:00 2001 From: nik Date: Mon, 27 Oct 2014 18:28:52 +0300 Subject: [PATCH 41/55] external build: try to load configuration file several times (workaround for IDEA-102580, IDEA-96471) --- .../model/serialization/JpsLoaderBase.java | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLoaderBase.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLoaderBase.java index 18ad56192055..cf8c0cba3667 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLoaderBase.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/JpsLoaderBase.java @@ -15,6 +15,7 @@ */ package org.jetbrains.jps.model.serialization; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.JDOMUtil; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtilRt; @@ -30,6 +31,8 @@ import java.io.IOException; * @author nik */ public abstract class JpsLoaderBase { + private static final Logger LOG = Logger.getInstance(JpsLoaderBase.class); + private static final int MAX_ATTEMPTS = 5; private final JpsMacroExpander myMacroExpander; protected JpsLoaderBase(JpsMacroExpander macroExpander) { @@ -66,7 +69,7 @@ public abstract class JpsLoaderBase { protected static Element loadRootElement(final File file, final JpsMacroExpander macroExpander) { try { - final Element element = JDOMUtil.loadDocument(file).getRootElement(); + final Element element = tryLoadRootElement(file); macroExpander.substitute(element, SystemInfo.isFileSystemCaseSensitive); return element; } @@ -78,6 +81,24 @@ public abstract class JpsLoaderBase { } } + private static Element tryLoadRootElement(File file) throws IOException, JDOMException { + for (int i = 0; i < MAX_ATTEMPTS - 1; i++) { + try { + return JDOMUtil.loadDocument(file).getRootElement(); + } + catch (Exception e) { + LOG.info("Loading attempt #" + i + " failed", e); + } + //most likely configuration file is being written by IDE so we'll wait a little + try { + //noinspection BusyWait + Thread.sleep(300); + } + catch (InterruptedException ignored) { } + } + return JDOMUtil.loadDocument(file).getRootElement(); + } + protected static boolean isXmlFile(File file) { return file.isFile() && FileUtilRt.extensionEquals(file.getName(), "xml"); } From f78b2033faaff2aff7e915f31993db9551f5736e Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 27 Oct 2014 16:37:43 +0100 Subject: [PATCH 42/55] ensure right launching sequence for preloaded build processes --- .../intellij/compiler/impl/CompileDriver.java | 8 +- .../compiler/server/BuildManager.java | 516 +++++++++++------- .../org/jetbrains/jps/api/BasicFuture.java | 7 +- .../src/org/jetbrains/jps/api/TaskFuture.java | 25 + 4 files changed, 343 insertions(+), 213 deletions(-) create mode 100644 jps/jps-builders/src/org/jetbrains/jps/api/TaskFuture.java 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 d4a69206c3ba..a5685017d365 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java @@ -71,9 +71,9 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; -import org.jetbrains.jps.api.BasicFuture; import org.jetbrains.jps.api.CmdlineProtoUtil; import org.jetbrains.jps.api.CmdlineRemoteProto; +import org.jetbrains.jps.api.TaskFuture; import org.jetbrains.jps.model.java.JavaSourceRootType; import javax.swing.*; @@ -138,7 +138,7 @@ public class CompileDriver { return; } try { - final BasicFuture future = compileInExternalProcess(compileContext, true); + final TaskFuture future = compileInExternalProcess(compileContext, true); if (future != null) { while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { @@ -194,7 +194,7 @@ public class CompileDriver { } @Nullable - private BasicFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, final boolean onlyCheckUpToDate) + private TaskFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext, final boolean onlyCheckUpToDate) throws Exception { final CompileScope scope = compileContext.getCompileScope(); final Collection paths = CompileScopeUtil.fetchFiles(compileContext); @@ -400,7 +400,7 @@ public class CompileDriver { return; } - final BasicFuture future = compileInExternalProcess(compileContext, false); + final TaskFuture future = compileInExternalProcess(compileContext, false); if (future != null) { while (!future.waitFor(200L, TimeUnit.MILLISECONDS)) { if (indicator.isCanceled()) { 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 2c5b378d96ea..efaf9e2b4346 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -100,7 +100,8 @@ import org.jetbrains.jps.cmdline.ClasspathBootstrap; import org.jetbrains.jps.incremental.Utils; import org.jetbrains.jps.model.serialization.JpsGlobalLoader; -import javax.tools.*; +import javax.tools.JavaCompiler; +import javax.tools.ToolProvider; import java.awt.*; import java.io.File; import java.io.IOException; @@ -108,8 +109,7 @@ import java.net.InetSocketAddress; import java.nio.charset.Charset; import java.util.*; import java.util.List; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicBoolean; import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope; @@ -148,10 +148,10 @@ public class BuildManager implements ApplicationComponent{ private final File mySystemDirectory; private final ProjectManager myProjectManager; - private final Map myAutomakeFutures = Collections.synchronizedMap(new HashMap()); + private final Map myAutomakeFutures = Collections.synchronizedMap(new HashMap()); private final Map myBuildsInProgress = Collections.synchronizedMap(new HashMap()); - private final Map, OSProcessHandler>> myPreloadedBuilds = - Collections.synchronizedMap(new HashMap, OSProcessHandler>>()); + private final Map, OSProcessHandler>>> myPreloadedBuilds = + Collections.synchronizedMap(new HashMap, OSProcessHandler>>>()); private final BuildProcessClasspathManager myClasspathManager = new BuildProcessClasspathManager(); private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(PooledThreadExecutor.INSTANCE); private final Map myProjectDataMap = Collections.synchronizedMap(new HashMap()); @@ -447,7 +447,7 @@ public class BuildManager implements ApplicationComponent{ } final List scopes = CmdlineProtoUtil.createAllModulesScopes(false); final AutoMakeMessageHandler handler = new AutoMakeMessageHandler(project); - final BasicFuture future = scheduleBuild( + final TaskFuture future = scheduleBuild( project, false, true, false, scopes, Collections.emptyList(), Collections.emptyMap(), handler ); if (future != null) { @@ -526,12 +526,12 @@ public class BuildManager implements ApplicationComponent{ return false; } - public Collection cancelAutoMakeTasks(Project project) { - final Collection futures = new SmartList(); + public Collection cancelAutoMakeTasks(Project project) { + final Collection futures = new SmartList(); synchronized (myAutomakeFutures) { - for (Map.Entry entry : myAutomakeFutures.entrySet()) { + for (Map.Entry entry : myAutomakeFutures.entrySet()) { if (entry.getValue().equals(project)) { - final BasicFuture future = entry.getKey(); + final TaskFuture future = entry.getKey(); future.cancel(false); futures.add(future); } @@ -542,15 +542,15 @@ public class BuildManager implements ApplicationComponent{ private void cancelPreloadedBuilds(Project project) { final String projectPath = getProjectPath(project); - final Pair, OSProcessHandler> pair = myPreloadedBuilds.remove(projectPath); - if (pair != null) { - final RequestFuture future = pair.first; - myMessageDispatcher.cancelSession(future.getRequestID()); - runCommand(new Runnable() { - @Override - public void run() { + runCommand(new Runnable() { + @Override + public void run() { + Pair, OSProcessHandler> pair = takePreloadedProcess(projectPath); + if (pair != null) { + final RequestFuture future = pair.first; + myMessageDispatcher.cancelSession(future.getRequestID()); // waiting for preloaded process from project's task queue guarantees no build is started for this project - // until this one gracefully exits and closes all its storages + // until this one gracefully exits and closes all its storages getProjectData(projectPath).taskQueue.submit(new Runnable() { @Override public void run() { @@ -558,207 +558,221 @@ public class BuildManager implements ApplicationComponent{ } }); } - }); - } + } + }); } @Nullable - public BasicFuture scheduleBuild( + private Pair, OSProcessHandler> takePreloadedProcess(String projectPath) { + Pair, OSProcessHandler> result; + final Future, OSProcessHandler>> preloadProgress = myPreloadedBuilds.remove(projectPath); + try { + result = preloadProgress != null ? preloadProgress.get() : null; + } + catch (Throwable e) { + LOG.info(e); + result = null; + } + return result; + } + + @Nullable + public TaskFuture scheduleBuild( final Project project, final boolean isRebuild, final boolean isMake, final boolean onlyCheckUpToDate, final List scopes, final Collection paths, final Map userData, final DefaultMessageHandler messageHandler) { final String projectPath = getProjectPath(project); - - final Pair, OSProcessHandler> preloaded = myPreloadedBuilds.remove(projectPath); - final RequestFuture preloadedFuture = preloaded != null? preloaded.first : null; - final boolean usingPreloadedProcess = preloadedFuture != null; - - final UUID sessionId; final BuilderMessageHandler handler = new NotifyingMessageHandler(project, messageHandler, messageHandler instanceof AutoMakeMessageHandler); - if (usingPreloadedProcess) { - LOG.info("Using preloaded build process to compile " + projectPath); - sessionId = preloadedFuture.getRequestID(); - preloadedFuture.getMessageHandler().setDelegateHandler(handler); - } - else { - sessionId = UUID.randomUUID(); - } - try { ensureListening(); } catch (Exception e) { + final UUID sessionId = UUID.randomUUID(); // the actual session did not start, use random UUID handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null)); handler.sessionTerminated(sessionId); return null; } - try { - final RequestFuture future = usingPreloadedProcess? preloadedFuture : new RequestFuture(handler, sessionId, new RequestFuture.CancelAction() { - @Override - public void cancel(RequestFuture future) throws Exception { - myMessageDispatcher.cancelSession(future.getRequestID()); + final DelegateFuture _future = new DelegateFuture(); + // by using the same queue that processes events we ensure that + // the build will be aware of all events that have happened before this request + runCommand(new Runnable() { + @Override + public void run() { + + final Pair, OSProcessHandler> preloaded = takePreloadedProcess(projectPath); + final RequestFuture preloadedFuture = preloaded != null? preloaded.first : null; + final boolean usingPreloadedProcess = preloadedFuture != null; + + final UUID sessionId; + if (usingPreloadedProcess) { + LOG.info("Using preloaded build process to compile " + projectPath); + sessionId = preloadedFuture.getRequestID(); + preloadedFuture.getMessageHandler().setDelegateHandler(handler); + } + else { + sessionId = UUID.randomUUID(); } - }); - // by using the same queue that processes events we ensure that - // the build will be aware of all events that have happened before this request - runCommand(new Runnable() { - @Override - public void run() { - if (!usingPreloadedProcess && (future.isCancelled() || project.isDisposed())) { - // in case of preloaded process the process was already running, so the handler will be notified upon process termination - handler.sessionTerminated(sessionId); - future.setDone(); - return; - } - final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = - CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.newBuilder().setGlobalOptionsPath(PathManager.getOptionsPath()).build(); - CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges; - final SequentialTaskExecutor projectTaskQueue; - synchronized (myProjectDataMap) { - final ProjectData data = getProjectData(projectPath); - if (isRebuild) { - data.dropChanges(); - } - if (IS_UNIT_TEST_MODE) { - LOG.info("Scheduling build for " + - projectPath + - "; CHANGED: " + - new HashSet(convertToStringPaths(data.myChanged)) + - "; DELETED: " + - new HashSet(convertToStringPaths(data.myDeleted))); - } - currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent(); - projectTaskQueue = data.taskQueue; + final RequestFuture future = usingPreloadedProcess? preloadedFuture : new RequestFuture(handler, sessionId, new RequestFuture.CancelAction() { + @Override + public void cancel(RequestFuture future) throws Exception { + myMessageDispatcher.cancelSession(future.getRequestID()); } + }); + _future.setDelegate(future); - final CmdlineRemoteProto.Message.ControllerMessage params; + if (!usingPreloadedProcess && (future.isCancelled() || project.isDisposed())) { + // in case of preloaded process the process was already running, so the handler will be notified upon process termination + handler.sessionTerminated(sessionId); + ((BasicFuture)future).setDone(); + return; + } + + final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = + CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.newBuilder().setGlobalOptionsPath(PathManager.getOptionsPath()).build(); + CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges; + final SequentialTaskExecutor projectTaskQueue; + synchronized (myProjectDataMap) { + final ProjectData data = getProjectData(projectPath); if (isRebuild) { - params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, Collections.emptyList(), userData, globals, null); + data.dropChanges(); } - else if (onlyCheckUpToDate) { - params = CmdlineProtoUtil.createUpToDateCheckRequest(projectPath, scopes, paths, userData, globals, currentFSChanges); - } - else { - params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, isMake ? Collections.emptyList() : paths, userData, globals, currentFSChanges); - } - if (!usingPreloadedProcess) { - myMessageDispatcher.registerBuildMessageHandler(future, params); + if (IS_UNIT_TEST_MODE) { + LOG.info("Scheduling build for " + + projectPath + + "; CHANGED: " + + new HashSet(convertToStringPaths(data.myChanged)) + + "; DELETED: " + + new HashSet(convertToStringPaths(data.myDeleted))); } + currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent(); + projectTaskQueue = data.taskQueue; + } - try { - projectTaskQueue.submit(new Runnable() { - @Override - public void run() { - Throwable execFailure = null; - try { - if (project.isDisposed()) { - if (usingPreloadedProcess) { - future.cancel(true); - } - else { - return; - } - } - myBuildsInProgress.put(projectPath, future); - final OSProcessHandler processHandler; - final StringBuilder errorsOnLaunch = new StringBuilder(); + final CmdlineRemoteProto.Message.ControllerMessage params; + if (isRebuild) { + params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, Collections.emptyList(), userData, globals, null); + } + else if (onlyCheckUpToDate) { + params = CmdlineProtoUtil.createUpToDateCheckRequest(projectPath, scopes, paths, userData, globals, currentFSChanges); + } + else { + params = CmdlineProtoUtil.createBuildRequest(projectPath, scopes, isMake ? Collections.emptyList() : paths, userData, globals, currentFSChanges); + } + if (!usingPreloadedProcess) { + myMessageDispatcher.registerBuildMessageHandler(future, params); + } + + try { + projectTaskQueue.submit(new Runnable() { + @Override + public void run() { + Throwable execFailure = null; + try { + if (project.isDisposed()) { if (usingPreloadedProcess) { - final boolean paramsSent = myMessageDispatcher.sendBuildParameters(future.getRequestID(), params); - if (!paramsSent) { - myMessageDispatcher.cancelSession(future.getRequestID()); - } - processHandler = preloaded.second; + future.cancel(true); } else { - processHandler = launchBuildProcess(project, myListenPort, sessionId, false); - processHandler.addProcessListener(new ProcessAdapter() { - @Override - public void onTextAvailable(ProcessEvent event, Key outputType) { - if (ProcessOutputTypes.STDERR.equals(outputType)) { - if (errorsOnLaunch.length() < 1024) { - final String text = event.getText(); - if (!StringUtil.isEmptyOrSpaces(text)) { - errorsOnLaunch.append(text); - } + return; + } + } + myBuildsInProgress.put(projectPath, future); + final OSProcessHandler processHandler; + final StringBuilder errorsOnLaunch = new StringBuilder(); + if (usingPreloadedProcess) { + final boolean paramsSent = myMessageDispatcher.sendBuildParameters(future.getRequestID(), params); + if (!paramsSent) { + myMessageDispatcher.cancelSession(future.getRequestID()); + } + processHandler = preloaded.second; + } + else { + processHandler = launchBuildProcess(project, myListenPort, sessionId, false); + processHandler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + if (ProcessOutputTypes.STDERR.equals(outputType)) { + if (errorsOnLaunch.length() < 1024) { + final String text = event.getText(); + if (!StringUtil.isEmptyOrSpaces(text)) { + errorsOnLaunch.append(text); } } } - }); - processHandler.startNotify(); - } - - final boolean terminated = processHandler.waitFor(); - if (terminated) { - final int exitValue = processHandler.getProcess().exitValue(); - if (exitValue != 0) { - final StringBuilder msg = new StringBuilder(); - msg.append("Abnormal build process termination: "); - if (errorsOnLaunch.length() > 0) { - msg.append("\n").append(errorsOnLaunch); - } - else { - msg.append("unknown error"); - } - handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null)); } - } - else { - handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null)); + }); + processHandler.startNotify(); + } + + final boolean terminated = processHandler.waitFor(); + if (terminated) { + final int exitValue = processHandler.getProcess().exitValue(); + if (exitValue != 0) { + final StringBuilder msg = new StringBuilder(); + msg.append("Abnormal build process termination: "); + if (errorsOnLaunch.length() > 0) { + msg.append("\n").append(errorsOnLaunch); + } + else { + msg.append("unknown error"); + } + handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null)); } } - catch (Throwable e) { - execFailure = e; - } - finally { - myBuildsInProgress.remove(projectPath); - if (myMessageDispatcher.getAssociatedChannel(sessionId) == null) { - // either the connection has never been established (process not started or execution failed), or no messages were sent from the launched process. - // in this case the session cannot be unregistered by the message dispatcher - final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId); - if (unregistered != null) { - if (execFailure != null) { - unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(execFailure.getMessage(), execFailure)); - } - unregistered.sessionTerminated(sessionId); - } - } - - if (Registry.is("compiler.process.preload") && !project.isDisposed()) { - try { - final Pair, OSProcessHandler> pair = launchPreloadedBuildProcess(project); - myPreloadedBuilds.put(projectPath, pair); - } - catch (Exception e) { - LOG.info("Error pre-loading build process for project " + projectPath, e); - } - } - + else { + handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null)); } } - }); - } - catch (Throwable e) { - final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId); - if (unregistered != null) { - unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e)); - unregistered.sessionTerminated(sessionId); + catch (Throwable e) { + execFailure = e; + } + finally { + myBuildsInProgress.remove(projectPath); + if (myMessageDispatcher.getAssociatedChannel(sessionId) == null) { + // either the connection has never been established (process not started or execution failed), or no messages were sent from the launched process. + // in this case the session cannot be unregistered by the message dispatcher + final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId); + if (unregistered != null) { + if (execFailure != null) { + unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(execFailure.getMessage(), execFailure)); + } + unregistered.sessionTerminated(sessionId); + } + } + + if (Registry.is("compiler.process.preload") && !project.isDisposed()) { + runCommand(new Runnable() { + public void run() { + try { + final Future, OSProcessHandler>> preloadResult = launchPreloadedBuildProcess(project, projectTaskQueue); + myPreloadedBuilds.put(projectPath, preloadResult); + } + catch (Exception e) { + LOG.info("Error pre-loading build process for project " + projectPath, e); + } + } + }); + } + + } } + }); + } + catch (Throwable e) { + final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId); + if (unregistered != null) { + unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e)); + unregistered.sessionTerminated(sessionId); } } - }); + } + }); - return future; - } - catch (Throwable e) { - handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e)); - handler.sessionTerminated(sessionId); - } - - return null; + return _future; } @NotNull @@ -798,37 +812,42 @@ public class BuildManager implements ApplicationComponent{ return "com.intellij.compiler.server.BuildManager"; } - private Pair, OSProcessHandler> launchPreloadedBuildProcess(final Project project) throws Exception { + private Future, OSProcessHandler>> launchPreloadedBuildProcess(final Project project, SequentialTaskExecutor projectTaskQueue) throws Exception { ensureListening(); - final RequestFuture future = new RequestFuture(new PreloadedProcessMessageHandler(project), UUID.randomUUID(), new RequestFuture.CancelAction() { - @Override - public void cancel(RequestFuture future) throws Exception { - myMessageDispatcher.cancelSession(future.getRequestID()); + // launching build process from projectTaskQueue ensures that no other build process for this project is currently running + return projectTaskQueue.submit(new Callable, OSProcessHandler>>() { + public Pair, OSProcessHandler> call() throws Exception { + final RequestFuture future = new RequestFuture(new PreloadedProcessMessageHandler(project), UUID.randomUUID(), new RequestFuture.CancelAction() { + @Override + public void cancel(RequestFuture future) throws Exception { + myMessageDispatcher.cancelSession(future.getRequestID()); + } + }); + try { + myMessageDispatcher.registerBuildMessageHandler(future, null); + final OSProcessHandler processHandler = launchBuildProcess(project, myListenPort, future.getRequestID(), true); + processHandler.addProcessListener(new ProcessAdapter() { + @Override + public void onTextAvailable(ProcessEvent event, Key outputType) { + if (ProcessOutputTypes.STDERR.equals(outputType)) { + final String text = event.getText(); + if (!StringUtil.isEmptyOrSpaces(text)) { + LOG.info("PRELOADED_BUILD_PROCESS: " + text); + } + } + } + }); + + processHandler.startNotify(); + return Pair.create(future, processHandler); + } + catch (ExecutionException e) { + myMessageDispatcher.unregisterBuildMessageHandler(future.getRequestID()); + throw e; + } } }); - myMessageDispatcher.registerBuildMessageHandler(future, null); - try { - final OSProcessHandler processHandler = launchBuildProcess(project, myListenPort, future.getRequestID(), true); - processHandler.addProcessListener(new ProcessAdapter() { - @Override - public void onTextAvailable(ProcessEvent event, Key outputType) { - if (ProcessOutputTypes.STDERR.equals(outputType)) { - final String text = event.getText(); - if (!StringUtil.isEmptyOrSpaces(text)) { - LOG.info("PRELOADED_BUILD_PROCESS: " + text); - } - } - } - }); - - processHandler.startNotify(); - return Pair.create(future, processHandler); - } - catch (ExecutionException e) { - myMessageDispatcher.unregisterBuildMessageHandler(future.getRequestID()); - throw e; - } } private OSProcessHandler launchBuildProcess(Project project, final int port, final UUID sessionId, boolean requestProjectPreload) throws ExecutionException { @@ -1300,7 +1319,7 @@ public class BuildManager implements ApplicationComponent{ @Override public void projectClosing(Project project) { cancelPreloadedBuilds(project); - for (BasicFuture future : cancelAutoMakeTasks(project)) { + for (TaskFuture future : cancelAutoMakeTasks(project)) { future.waitFor(500, TimeUnit.MILLISECONDS); } } @@ -1460,5 +1479,88 @@ public class BuildManager implements ApplicationComponent{ return "/"; } } - + + private static final class DelegateFuture implements TaskFuture { + @Nullable + private TaskFuture myDelegate; + private Boolean myRequestedCancelState = null; + + @NotNull + public synchronized TaskFuture getDelegate() { + TaskFuture delegate = myDelegate; + while (delegate == null) { + try { + wait(); + } + catch (InterruptedException ignored) { + } + delegate = myDelegate; + } + return delegate; + } + + public synchronized boolean setDelegate(@NotNull TaskFuture delegate) { + if (myDelegate == null) { + try { + myDelegate = delegate; + if (myRequestedCancelState != null) { + myDelegate.cancel(myRequestedCancelState); + } + } + finally { + notifyAll(); + } + return true; + } + return false; + } + + public synchronized boolean cancel(boolean mayInterruptIfRunning) { + final TaskFuture delegate = myDelegate; + if (delegate == null) { + myRequestedCancelState = mayInterruptIfRunning; + return true; + } + return delegate.cancel(mayInterruptIfRunning); + } + + public void waitFor() { + getDelegate().waitFor(); + } + + public boolean waitFor(long timeout, TimeUnit unit) { + return getDelegate().waitFor(timeout, unit); + } + + public boolean isCancelled() { + final TaskFuture delegate; + synchronized (this) { + delegate = myDelegate; + if (delegate == null) { + return myRequestedCancelState != null; + } + } + return delegate.isCancelled(); + } + + public boolean isDone() { + final TaskFuture delegate; + synchronized (this) { + delegate = myDelegate; + if (delegate == null) { + return false; + } + } + return delegate.isDone(); + } + + public T get() throws InterruptedException, java.util.concurrent.ExecutionException { + return getDelegate().get(); + } + + public T get(long timeout, TimeUnit unit) throws InterruptedException, java.util.concurrent.ExecutionException, TimeoutException { + return getDelegate().get(timeout, unit); + } + } + } diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/BasicFuture.java b/jps/jps-builders/src/org/jetbrains/jps/api/BasicFuture.java index 0717de1c61e7..514ec5efc8d4 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/api/BasicFuture.java +++ b/jps/jps-builders/src/org/jetbrains/jps/api/BasicFuture.java @@ -15,14 +15,17 @@ */ package org.jetbrains.jps.api; -import java.util.concurrent.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; /** * @author Eugene Zhuravlev * Date: 5/3/12 */ -public class BasicFuture implements Future { +public class BasicFuture implements TaskFuture { protected final Semaphore mySemaphore = new Semaphore(1); private final AtomicBoolean myDone = new AtomicBoolean(false); private final AtomicBoolean myCanceledState = new AtomicBoolean(false); diff --git a/jps/jps-builders/src/org/jetbrains/jps/api/TaskFuture.java b/jps/jps-builders/src/org/jetbrains/jps/api/TaskFuture.java new file mode 100644 index 000000000000..c09c8446422b --- /dev/null +++ b/jps/jps-builders/src/org/jetbrains/jps/api/TaskFuture.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2014 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 org.jetbrains.jps.api; + +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +public interface TaskFuture extends Future { + void waitFor(); + + boolean waitFor(long timeout, TimeUnit unit); +} From a17c63dc86891f15d8e6191c0a2e382dd4cfc19c Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 27 Oct 2014 18:48:57 +0300 Subject: [PATCH 43/55] IDEA-131922 Debugger: Inspect from Referring Objects causes NPE at ClassRenderer.createFieldDescriptor() --- .../debugger/actions/JavaReferringObjectsValue.java | 6 +++--- .../impl/src/com/intellij/debugger/engine/JavaValue.java | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java index e892a425ca75..96ba9e6eb54d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java @@ -50,7 +50,7 @@ public class JavaReferringObjectsValue extends JavaValue { } public JavaReferringObjectsValue(@NotNull JavaValue javaValue, boolean isField) { - super(null, javaValue.getDescriptor(), javaValue.getEvaluationContext(), null, false); + super(null, javaValue.getDescriptor(), javaValue.getEvaluationContext(), javaValue.getNodeManager(), false); myIsField = isField; } @@ -84,7 +84,7 @@ public class JavaReferringObjectsValue extends JavaValue { return reference; } }; - children.add(new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), null, true)); + children.add(new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), getNodeManager(), true)); i++; } else { @@ -109,7 +109,7 @@ public class JavaReferringObjectsValue extends JavaValue { return null; } }; - children.add("Referrer " + i++, new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), null, false)); + children.add("Referrer " + i++, new JavaReferringObjectsValue(null, descriptor, getEvaluationContext(), getNodeManager(), false)); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index 3df508e331a9..6ea0b626cd00 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -113,6 +113,10 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV return myEvaluationContext; } + public NodeManagerImpl getNodeManager() { + return myNodeManager; + } + @Override public void computePresentation(@NotNull final XValueNode node, @NotNull XValuePlace place) { final SuspendContextImpl suspendContext = myEvaluationContext.getSuspendContext(); From 96f572b2544cfb62ae580a12275ae36aed167b5d Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Mon, 27 Oct 2014 18:31:39 +0300 Subject: [PATCH 44/55] use RecursionManager instead of manual recursion prevention #WEB-331 fixed --- .../psi/impl/source/xml/XmlEntityRefImpl.java | 156 +++++++++--------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java index b74834a28162..ee6248b6c1bf 100644 --- a/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java +++ b/xml/xml-psi-impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java @@ -16,7 +16,10 @@ package com.intellij.psi.impl.source.xml; import com.intellij.ide.highlighter.DTDFileType; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Key; +import com.intellij.openapi.util.RecursionManager; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry; import com.intellij.psi.search.PsiElementProcessor; @@ -49,8 +52,6 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef { super(XmlElementType.XML_ENTITY_REF); } - private static final Key EVALUATION_IN_PROCESS = Key.create("EvalKey"); - @Override public XmlEntityDecl resolve(PsiFile targetFile) { String text = getText(); @@ -77,12 +78,12 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef { if (value == null) { final PsiManager manager = element.getManager(); if(manager == null){ - return resolveEntity(targetElement, entityName, containingFile).getValue(); + return doResolveEntity(targetElement, entityName, containingFile).getValue(); } value = CachedValuesManager.getManager(manager.getProject()).createCachedValue(new CachedValueProvider() { @Override public Result compute() { - return resolveEntity(targetElement, entityName, containingFile); + return doResolveEntity(targetElement, entityName, containingFile); } }); @@ -95,95 +96,94 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef { private static final Key DISABLE_ENTITY_EXPAND = Key.create("disable.entity.expand"); - private static CachedValueProvider.Result resolveEntity(final PsiElement targetElement, final String entityName, PsiFile contextFile) { - if (targetElement.getUserData(EVALUATION_IN_PROCESS) != null) { - return new CachedValueProvider.Result(null,targetElement); - } - try { - targetElement.putUserData(EVALUATION_IN_PROCESS, ""); - final List deps = new ArrayList(); - final XmlEntityDecl[] result = {null}; + private static CachedValueProvider.Result doResolveEntity(final PsiElement targetElement, + final String entityName, + final PsiFile contextFile) { + return RecursionManager.doPreventingRecursion(targetElement, true, new Computable>() { + @Override + public CachedValueProvider.Result compute() { + final List deps = new ArrayList(); + final XmlEntityDecl[] result = {null}; - PsiElementProcessor processor = new PsiElementProcessor() { - @Override - public boolean execute(@NotNull PsiElement element) { - if (element instanceof XmlDoctype) { - XmlDoctype xmlDoctype = (XmlDoctype)element; - final String dtdUri = getDtdForEntity(xmlDoctype); - if (dtdUri != null) { - XmlFile file = XmlUtil.getContainingFile(element); - if (file == null) return true; - final XmlFile xmlFile = XmlUtil.findNamespace(file, dtdUri); - if (xmlFile != null) { - if (xmlFile != targetElement) { - deps.add(xmlFile); - if(!XmlUtil.processXmlElements(xmlFile, this,true)) return false; + PsiElementProcessor processor = new PsiElementProcessor() { + @Override + public boolean execute(@NotNull PsiElement element) { + if (element instanceof XmlDoctype) { + XmlDoctype xmlDoctype = (XmlDoctype)element; + final String dtdUri = getDtdForEntity(xmlDoctype); + if (dtdUri != null) { + XmlFile file = XmlUtil.getContainingFile(element); + if (file == null) return true; + final XmlFile xmlFile = XmlUtil.findNamespace(file, dtdUri); + if (xmlFile != null) { + if (xmlFile != targetElement) { + deps.add(xmlFile); + if (!XmlUtil.processXmlElements(xmlFile, this, true)) return false; + } } } + final XmlMarkupDecl markupDecl = xmlDoctype.getMarkupDecl(); + if (markupDecl != null) { + if (!XmlUtil.processXmlElements(markupDecl, this, true)) return false; + } } - final XmlMarkupDecl markupDecl = xmlDoctype.getMarkupDecl(); - if (markupDecl != null) { - if (!XmlUtil.processXmlElements(markupDecl, this, true)) return false; + else if (element instanceof XmlEntityDecl) { + XmlEntityDecl entityDecl = (XmlEntityDecl)element; + final String declName = entityDecl.getName(); + if (StringUtil.equals(declName, entityName)) { + result[0] = entityDecl; + return false; + } } + + return true; } - else if (element instanceof XmlEntityDecl) { - XmlEntityDecl entityDecl = (XmlEntityDecl)element; - final String declName = entityDecl.getName(); - if (declName.equals(entityName)) { - result[0] = entityDecl; - return false; - } + }; + FileViewProvider provider = targetElement.getContainingFile().getViewProvider(); + deps.add(provider.getPsi(provider.getBaseLanguage())); + + boolean notfound = PsiTreeUtil.processElements(targetElement, processor); + if (notfound) { + if (contextFile != targetElement && contextFile != null && contextFile.isValid()) { + notfound = PsiTreeUtil.processElements(contextFile, processor); } - - return true; } - }; - FileViewProvider provider = targetElement.getContainingFile().getViewProvider(); - deps.add(provider.getPsi(provider.getBaseLanguage())); - boolean notfound = PsiTreeUtil.processElements(targetElement, processor); - if (notfound) { - if (contextFile != targetElement && contextFile != null && contextFile.isValid()) { - notfound = PsiTreeUtil.processElements(contextFile, processor); - } - } + if (notfound && // no dtd ref at all + targetElement instanceof XmlFile && + deps.size() == 1 && + ((XmlFile)targetElement).getFileType() != DTDFileType.INSTANCE + ) { + XmlDocument document = ((XmlFile)targetElement).getDocument(); + final XmlTag rootTag = document != null ? document.getRootTag() : null; + XmlFile descriptorFile = null; - if (notfound && // no dtd ref at all - targetElement instanceof XmlFile && - deps.size() == 1 && - ((XmlFile)targetElement).getFileType() != DTDFileType.INSTANCE - ) { - XmlDocument document = ((XmlFile)targetElement).getDocument(); - final XmlTag rootTag = document.getRootTag(); - XmlFile descriptorFile = null; - - if (HtmlUtil.isHtml5Document(document)) { - descriptorFile = XmlUtil.findXmlFile((XmlFile)targetElement, Html5SchemaProvider.getCharsDtdLocation()); - } else if (rootTag != null && document.getUserData(DISABLE_ENTITY_EXPAND) == null) { - final XmlElementDescriptor descriptor = rootTag.getDescriptor(); + if (HtmlUtil.isHtml5Document(document)) { + descriptorFile = XmlUtil.findXmlFile((XmlFile)targetElement, Html5SchemaProvider.getCharsDtdLocation()); + } + else if (rootTag != null && document.getUserData(DISABLE_ENTITY_EXPAND) == null) { + final XmlElementDescriptor descriptor = rootTag.getDescriptor(); if (descriptor != null && !(descriptor instanceof AnyXmlElementDescriptor)) { PsiElement element = descriptor.getDeclaration(); - final PsiFile containingFile = element != null ? element.getContainingFile():null; - descriptorFile = containingFile instanceof XmlFile ? (XmlFile)containingFile:null; + final PsiFile containingFile = element != null ? element.getContainingFile() : null; + descriptorFile = containingFile instanceof XmlFile ? (XmlFile)containingFile : null; } + } + if (descriptorFile != null && + !descriptorFile.getName().equals(((XmlFile)targetElement).getName() + ".dtd")) { + deps.add(descriptorFile); + XmlUtil.processXmlElements( + descriptorFile, + processor, + true + ); + } } - if (descriptorFile != null && - !descriptorFile.getName().equals(((XmlFile)targetElement).getName() + ".dtd")) { - deps.add(descriptorFile); - XmlUtil.processXmlElements( - descriptorFile, - processor, - true - ); - } - } - return new CachedValueProvider.Result(result[0], ArrayUtil.toObjectArray(deps)); - } - finally { - targetElement.putUserData(EVALUATION_IN_PROCESS, null); - } + return new CachedValueProvider.Result(result[0], ArrayUtil.toObjectArray(deps)); + } + }); } private static String getDtdForEntity(XmlDoctype xmlDoctype) { @@ -214,7 +214,7 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef { @Override @NotNull public PsiReference[] getReferences() { - return ReferenceProvidersRegistry.getReferencesFromProviders(this,XmlEntityRef.class); + return ReferenceProvidersRegistry.getReferencesFromProviders(this); } @Override From 541d42ae4647ffd9d501c929f1010222f36f25e9 Mon Sep 17 00:00:00 2001 From: Liana Bakradze Date: Mon, 27 Oct 2014 19:06:42 +0300 Subject: [PATCH 45/55] EDU-254 Change course information: invalid case --- .../plugins/coursecreator/actions/CCChangeCourseInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java index 0f3b3ae4a092..ffb777e1a050 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java @@ -20,7 +20,7 @@ import javax.swing.*; public class CCChangeCourseInfo extends DumbAwareAction { public CCChangeCourseInfo() { - super("Change course information", "Change course information", null); + super("Change Course information", "Change Course Information", null); } @Override From 92d39f1832e40fc4015e8ada1ff87ec179399753 Mon Sep 17 00:00:00 2001 From: Liana Bakradze Date: Mon, 27 Oct 2014 19:28:54 +0300 Subject: [PATCH 46/55] EDU-255 Change course information: course name in project view is not updated --- .../plugins/coursecreator/actions/CCChangeCourseInfo.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java index ffb777e1a050..a556cd1113f1 100644 --- a/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java +++ b/python/edu/course-creator/src/org/jetbrains/plugins/coursecreator/actions/CCChangeCourseInfo.java @@ -1,6 +1,7 @@ package org.jetbrains.plugins.coursecreator.actions; import com.intellij.ide.IdeView; +import com.intellij.ide.projectView.ProjectView; import com.intellij.ide.util.DirectoryChooserUtil; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; @@ -85,6 +86,7 @@ public class CCChangeCourseInfo extends DumbAwareAction { course.setAuthor(panel.getAuthor()); course.setName(panel.getName()); course.setDescription(panel.getDescription()); + ProjectView.getInstance(project).refresh(); } } @@ -93,6 +95,7 @@ public class CCChangeCourseInfo extends DumbAwareAction { CCNewProjectPanel myNewProjectPanel; public ChangeCourseInfoDialog(@Nullable Project project, CCNewProjectPanel panel) { super(project); + setTitle("Change Course Information"); myNewProjectPanel = panel; init(); } From 44ea42deaf1fe24c9738387ac330b37e92b0bc64 Mon Sep 17 00:00:00 2001 From: Sergey Simonchik Date: Mon, 27 Oct 2014 19:44:25 +0400 Subject: [PATCH 47/55] adding a new ExtensionFileNameMatcher should re-assign file type for files previously associated with ExactFileNameMatcher --- .../fileTypes/impl/FileTypeManagerImpl.java | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java index 37e9dc583628..1891e59711bd 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileTypes/impl/FileTypeManagerImpl.java @@ -358,8 +358,10 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME for (final StandardFileType pair : myStandardFileTypes.values()) { registerFileTypeWithoutNotification(pair.fileType, pair.matchers); } - for (StandardFileType pair : myStandardFileTypes.values()) { - registerReDetectedMappings(pair); + if (!myUnresolvedMappings.isEmpty()) { + for (StandardFileType pair : myStandardFileTypes.values()) { + registerReDetectedMappings(pair); + } } // Resolve unresolved mappings initialized before certain plugin initialized. for (final StandardFileType pair : myStandardFileTypes.values()) { @@ -1297,14 +1299,23 @@ public class FileTypeManagerImpl extends FileTypeManagerEx implements NamedJDOME FileType fileType = pair.fileType; if (fileType == PlainTextFileType.INSTANCE) return; for (FileNameMatcher matcher : pair.matchers) { - String typeName = myUnresolvedMappings.get(matcher); - if (typeName != null && !typeName.equals(fileType.getName())) { - Trinity trinity = myUnresolvedRemovedMappings.get(matcher); - myRemovedMappings.put(matcher, Pair.create(fileType, trinity != null && trinity.third)); + registerReDetectedMapping(fileType, matcher); + if (matcher instanceof ExtensionFileNameMatcher) { + // also check exact file name matcher + ExtensionFileNameMatcher extMatcher = (ExtensionFileNameMatcher)matcher; + registerReDetectedMapping(fileType, new ExactFileNameMatcher("." + extMatcher.getExtension())); } } } + private void registerReDetectedMapping(@NotNull FileType fileType, @NotNull FileNameMatcher matcher) { + String typeName = myUnresolvedMappings.get(matcher); + if (typeName != null && !typeName.equals(fileType.getName())) { + Trinity trinity = myUnresolvedRemovedMappings.get(matcher); + myRemovedMappings.put(matcher, Pair.create(fileType, trinity != null && trinity.third)); + } + } + Map> getRemovedMappings() { return myRemovedMappings; } From 0c4529fb6eccf4b967a958a53332eb2680424453 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Mon, 27 Oct 2014 16:44:32 +0100 Subject: [PATCH 48/55] unnecessary unboxing: search for overloads in correct container (IDEA-131911) --- .../UnnecessaryUnboxingInspection.java | 55 +++++++++++-------- .../UnnecessaryUnboxing.java | 15 +++++ .../UnnecessaryUnboxing.java | 13 +++++ .../unnecessary_unboxing/expected.xml | 7 ++- 4 files changed, 66 insertions(+), 24 deletions(-) diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/UnnecessaryUnboxingInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/UnnecessaryUnboxingInspection.java index 9118a798f612..3da2504df69a 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/UnnecessaryUnboxingInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/UnnecessaryUnboxingInspection.java @@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.intellij.refactoring.util.RefactoringChangeUtil; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; @@ -243,12 +244,9 @@ public class UnnecessaryUnboxingInspection extends BaseInspection { if (!(expression instanceof PsiMethodCallExpression)) { return false; } - final PsiMethodCallExpression methodCallExpression = - (PsiMethodCallExpression)expression; - final PsiReferenceExpression methodExpression = - methodCallExpression.getMethodExpression(); - final PsiExpression qualifier = - methodExpression.getQualifierExpression(); + final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression; + final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); + final PsiExpression qualifier = methodExpression.getQualifierExpression(); if (qualifier == null) { return false; } @@ -261,31 +259,45 @@ public class UnnecessaryUnboxingInspection extends BaseInspection { return false; } final String methodName = methodExpression.getReferenceName(); - final String unboxingMethod = - s_unboxingMethods.get(qualifierTypeName); + final String unboxingMethod = s_unboxingMethods.get(qualifierTypeName); return unboxingMethod.equals(methodName); } - private boolean isSameMethodCalledWithoutUnboxing( - @NotNull PsiCallExpression callExpression, - @NotNull PsiMethodCallExpression unboxingExpression) { - final PsiExpressionList argumentList = - callExpression.getArgumentList(); + private boolean isSameMethodCalledWithoutUnboxing(@NotNull PsiCallExpression callExpression, + @NotNull PsiMethodCallExpression unboxingExpression) { + final PsiExpressionList argumentList = callExpression.getArgumentList(); if (argumentList == null) { return false; } final PsiExpression[] expressions = argumentList.getExpressions(); - final PsiMethod originalMethod = - callExpression.resolveMethod(); + final PsiMethod originalMethod = callExpression.resolveMethod(); if (originalMethod == null) { return false; } final String name = originalMethod.getName(); - final PsiClass containingClass = - originalMethod.getContainingClass(); + + final PsiExpression qualifierExpression; + if (callExpression instanceof PsiMethodCallExpression) { + qualifierExpression = ((PsiMethodCallExpression)callExpression).getMethodExpression().getQualifierExpression(); + } else if (callExpression instanceof PsiNewExpression) { + qualifierExpression = ((PsiNewExpression)callExpression).getQualifier(); + } else { + return false; + } + + final PsiClass containingClass; + if (qualifierExpression == null) { + final PsiElement scope = callExpression.resolveMethodGenerics().getCurrentFileResolveScope(); + containingClass = scope instanceof PsiClass ? (PsiClass)scope : null; + } + else { + containingClass = PsiUtil.resolveClassInType(GenericsUtil.getVariableTypeByExpressionType(qualifierExpression.getType())); + } + if (containingClass == null) { return false; } + final PsiType[] types = PsiType.createArray(expressions.length); for (int i = 0; i < expressions.length; i++) { final PsiExpression expression = expressions[i]; @@ -294,20 +306,17 @@ public class UnnecessaryUnboxingInspection extends BaseInspection { if (!(type instanceof PsiPrimitiveType)) { return false; } - final PsiPrimitiveType primitiveType = - (PsiPrimitiveType)type; + final PsiPrimitiveType primitiveType = (PsiPrimitiveType)type; types[i] = primitiveType.getBoxedType(unboxingExpression); } else { types[i] = type; } } - final PsiMethod[] methods = - containingClass.findMethodsByName(name, true); + final PsiMethod[] methods = containingClass.findMethodsByName(name, true); for (final PsiMethod method : methods) { if (!originalMethod.equals(method)) { - if (MethodCallUtils.isApplicable(method, - PsiSubstitutor.EMPTY, types)) { + if (MethodCallUtils.isApplicable(method, PsiSubstitutor.EMPTY, types)) { return false; } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_superfluous_unboxing/UnnecessaryUnboxing.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_superfluous_unboxing/UnnecessaryUnboxing.java index 96d22a045a7a..e2a096e059ca 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_superfluous_unboxing/UnnecessaryUnboxing.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_superfluous_unboxing/UnnecessaryUnboxing.java @@ -38,4 +38,19 @@ public class UnnecessaryUnboxing { Integer boxcutter(Integer i) { return i.intValue(); } +} + + +class B23 { + public void set(double value) {} +} +class A23 extends B23 { + public void set(Object value) {} + private A23() { + Object o = 2d; + set(((Double) o).doubleValue()); + + B23 b23 = new B23(); + b23.set(((Double) o).doubleValue()); + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_unboxing/UnnecessaryUnboxing.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_unboxing/UnnecessaryUnboxing.java index 366d21ddbae8..414960e321d6 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_unboxing/UnnecessaryUnboxing.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_unboxing/UnnecessaryUnboxing.java @@ -43,4 +43,17 @@ public class UnnecessaryUnboxing { byte cast(Integer v) { return (byte)v.intValue(); } +} + + +class B23 { + public void set(double value) {} +} +class A23 extends B23 { + public void set(Object value) {} + private A23() { + Object o = 2d; + B23 b23 = new B23(); + b23.set(((Double) o).doubleValue()); + } } \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_unboxing/expected.xml b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_unboxing/expected.xml index 35c78be16577..d208b3f7867a 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_unboxing/expected.xml +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/migration/unnecessary_unboxing/expected.xml @@ -55,5 +55,10 @@ Unnecessary unboxing Unnecessary unboxing <code>b.byteValue()</code> #loc - + + UnnecessaryUnboxing.java + 57 + Unnecessary unboxing + Unnecessary unboxing <code>((Double) o).doubleValue()</code> #loc + \ No newline at end of file From 657c1243cb5ed4896eacf54015af3b63c83310d4 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Mon, 27 Oct 2014 20:10:59 +0300 Subject: [PATCH 49/55] IDEA-125176 Check that token is not empty before trying to update boards Also add diagnostic records to log and remove debug dumping of formatted responses (this data may be retrieved using standard httpclient logs). --- .../com/intellij/tasks/trello/TrelloRepository.java | 3 --- .../intellij/tasks/trello/TrelloRepositoryEditor.java | 11 ++++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepository.java index eafe341d3989..8ea6b8618d71 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepository.java @@ -26,7 +26,6 @@ import com.intellij.tasks.TaskBundle; import com.intellij.tasks.TaskRepositoryType; import com.intellij.tasks.impl.BaseRepository; import com.intellij.tasks.impl.BaseRepositoryImpl; -import com.intellij.tasks.impl.TaskUtil; import com.intellij.tasks.impl.httpclient.ResponseUtil; import com.intellij.tasks.trello.model.TrelloBoard; import com.intellij.tasks.trello.model.TrelloCard; @@ -320,8 +319,6 @@ public final class TrelloRepository extends BaseRepositoryImpl { HttpClient client = getHttpClient(); client.executeMethod(method); String entityContent = ResponseUtil.getResponseContentAsString(method); - TaskUtil.prettyFormatJsonToLog(LOG, entityContent); - // LOG.debug("Response size: " + method.getResponseHeader("Content-Length").getValue() + " bytes"); if (method.getStatusCode() != HttpStatus.SC_OK) { Header header = method.getResponseHeader("Content-Type"); if (header != null && header.getValue().startsWith("text/plain")) { diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepositoryEditor.java index 31584497f43a..3ad4b12de380 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/trello/TrelloRepositoryEditor.java @@ -43,7 +43,7 @@ import java.util.List; * @author Mikhail Golubev */ public class TrelloRepositoryEditor extends BaseRepositoryEditor { - private static final Logger LOG = Logger.getInstance("#com.intellij.tasks.trello.TrelloRepositoryEditor"); + private static final Logger LOG = Logger.getInstance(TrelloRepositoryEditor.class); private static final TrelloBoard UNSPECIFIED_BOARD = new TrelloBoard() { @NotNull @@ -83,9 +83,10 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor download() throws Exception { + LOG.debug("Updating information about boards available to user when repository setting are shown"); List boards = super.download(); if (myBoard == null) { return boards; @@ -157,6 +159,7 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor download() throws Exception { + LOG.debug("Updating information about lists of board " + myRepository.getCurrentBoard() + " when repository setting are shown"); List lists = super.download(); if (myList == null) { return lists; @@ -266,6 +269,7 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor boards) { myBoardComboBox.setModel(new DefaultComboBoxModel(boards.toArray())); @@ -296,6 +300,7 @@ public class TrelloRepositoryEditor extends BaseRepositoryEditor lists) { myListComboBox.setModel(new DefaultComboBoxModel(lists.toArray())); From 9e87820daa75ed0dfad291cb3d4257e86d31dca5 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 27 Oct 2014 19:47:22 +0300 Subject: [PATCH 50/55] IDEA-131931 Debugger: Throwable at SuspendContextImpl.getDebugProcess() on opening Referring Objects dialog from itself --- .../com/intellij/debugger/engine/JavaValue.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index 6ea0b626cd00..9cba64ac544a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -70,6 +70,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV private final EvaluationContextImpl myEvaluationContext; private final NodeManagerImpl myNodeManager; private final boolean myContextSet; + private final DebuggerManagerThreadImpl myDebuggerManagerThread; protected JavaValue(JavaValue parent, @NotNull ValueDescriptorImpl valueDescriptor, @@ -82,6 +83,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV myEvaluationContext = evaluationContext; myNodeManager = nodeManager; myContextSet = contextSet; + myDebuggerManagerThread = evaluationContext.getDebugProcess().getManagerThread(); } static JavaValue create(JavaValue parent, @@ -353,7 +355,11 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV } boolean scheduleCommand(SuspendContextCommandImpl command) { - return scheduleCommand(myEvaluationContext, null, command); + if (myEvaluationContext.getSuspendContext().isResumed()) { + return false; + } + myDebuggerManagerThread.schedule(command); + return true; } protected static boolean scheduleCommand(EvaluationContextImpl evaluationContext, @@ -490,6 +496,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV @Nullable @Override public XReferrersProvider getReferrersProvider() { + if (myEvaluationContext.getSuspendContext().isResumed()) return null; return new XReferrersProvider() { @Override public XValue getReferringObjectsValue() { @@ -501,16 +508,15 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV @Nullable @Override public XInstanceEvaluator getInstanceEvaluator() { - final DebugProcessImpl process = myEvaluationContext.getDebugProcess(); return new XInstanceEvaluator() { @Override public void evaluate(@NotNull final XDebuggerEvaluator.XEvaluationCallback callback, @NotNull final XStackFrame frame) { - process.getManagerThread().schedule(new DebuggerCommandImpl() { + myDebuggerManagerThread.schedule(new DebuggerCommandImpl() { @Override protected void action() throws Exception { ValueDescriptorImpl inspectDescriptor = myValueDescriptor; if (myValueDescriptor instanceof WatchItemDescriptor) { - inspectDescriptor = (ValueDescriptorImpl) ((WatchItemDescriptor) myValueDescriptor).getModifier().getInspectItem(getProject()); + inspectDescriptor = (ValueDescriptorImpl)((WatchItemDescriptor)myValueDescriptor).getModifier().getInspectItem(getProject()); } EvaluationContextImpl evaluationContext = ((JavaStackFrame)frame).getFrameDebuggerContext().createEvaluationContext(); if (evaluationContext != null) { From fd9ead508c5842a65ac57374ad8323dbf5afb505 Mon Sep 17 00:00:00 2001 From: Michael Golubev Date: Mon, 27 Oct 2014 17:32:49 +0100 Subject: [PATCH 51/55] IDEA-131963 - Redesign application servers view actions --- .../impl/src/META-INF/RemoteServers.xml | 14 +- .../runtime/ui/ServersToolWindowContent.java | 29 +--- .../impl/runtime/ui/tree/DeploymentNode.java | 16 +- .../impl/runtime/ui/tree/ServerNode.java | 19 +-- .../impl/runtime/ui/tree/ServersTreeNode.java | 20 +++ .../runtime/ui/tree/ServersTreeStructure.java | 152 +++++++++--------- .../tree/actions/ChooseDeploymentAction.java | 39 +++++ .../ChooseDeploymentWithDebugAction.java | 39 +++++ .../ui/tree/actions/DebugServerAction.java | 19 --- .../runtime/ui/tree/actions/DeployAction.java | 63 +++----- .../ui/tree/actions/DeployAllAction.java | 27 ---- .../tree/actions/DeployWithDebugAction.java | 46 ++++++ .../ui/tree/actions/DeploymentActionBase.java | 52 ------ .../tree/actions/DeploymentConfigAction.java | 40 +++++ .../tree/actions/EditConfigurationAction.java | 42 ----- .../actions/EditConfigurationActionBase.java | 26 +++ .../actions/RemoteServerConfigAction.java | 35 ++++ .../actions/RemoteServerConnectAction.java | 42 +++++ .../actions/RemoteServerDisconnectAction.java | 46 ++++++ .../ui/tree/actions/RunServerAction.java | 20 --- .../ui/tree/actions/RunServerActionBase.java | 31 ---- .../ui/tree/actions/ServerActionBase.java | 46 ------ .../ui/tree/actions/ServersTreeAction.java | 91 +++++++++++ .../tree/actions/ServersTreeActionBase.java | 44 ----- .../tree/actions/SingleServerActionBase.java | 49 ------ .../ui/tree/actions/StopServerAction.java | 26 --- .../ui/tree/actions/UndeployAction.java | 21 ++- 27 files changed, 560 insertions(+), 534 deletions(-) create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeNode.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ChooseDeploymentAction.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ChooseDeploymentWithDebugAction.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DebugServerAction.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployAllAction.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployWithDebugAction.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeploymentActionBase.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeploymentConfigAction.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/EditConfigurationAction.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/EditConfigurationActionBase.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerConfigAction.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerConnectAction.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerDisconnectAction.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RunServerAction.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RunServerActionBase.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServerActionBase.java create mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServersTreeAction.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServersTreeActionBase.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/SingleServerActionBase.java delete mode 100644 platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/StopServerAction.java diff --git a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml index 0ce5eae571a9..eae970f46594 100644 --- a/platform/remote-servers/impl/src/META-INF/RemoteServers.xml +++ b/platform/remote-servers/impl/src/META-INF/RemoteServers.xml @@ -38,14 +38,16 @@ - - - - - - + + + + + + + + \ No newline at end of file diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java index 8a46887be6cf..2d3fb8cc1b86 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/ServersToolWindowContent.java @@ -6,18 +6,16 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.ide.util.treeView.NodeDescriptor; import com.intellij.ide.util.treeView.NodeRenderer; import com.intellij.ide.util.treeView.TreeVisitor; -import com.intellij.openapi.application.ModalityState; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Disposer; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.impl.runtime.log.LoggingHandlerImpl; -import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode; +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure; import com.intellij.remoteServer.impl.runtime.ui.tree.TreeBuilderBase; import com.intellij.remoteServer.runtime.ConnectionStatus; import com.intellij.remoteServer.runtime.ServerConnection; @@ -108,13 +106,10 @@ public class ServersToolWindowContent extends JPanel implements Disposable { new DoubleClickListener() { @Override protected boolean onDoubleClick(MouseEvent event) { - Set nodes = getSelectedRemoteServerNodes(); - if (nodes.size() == 1) { - RemoteServer server = nodes.iterator().next().getValue(); - ServerConnectionManager.getInstance().getOrCreateConnection(server); - return true; - } - return false; + AnAction connectAction = ActionManager.getInstance().getAction("RemoteServers.ConnectServer"); + AnActionEvent actionEvent = AnActionEvent.createFromInputEvent(connectAction, event, ActionPlaces.UNKNOWN); + connectAction.actionPerformed(actionEvent); + return true; } }.installOn(myTree); } @@ -265,18 +260,6 @@ public class ServersToolWindowContent extends JPanel implements Disposable { return this; } - public Set getSelectedServerNodes() { - return myBuilder.getSelectedElements(ServerNode.class); - } - - public Set getSelectedDeploymentNodes() { - return myBuilder.getSelectedElements(DeploymentNode.class); - } - - public Set getSelectedRemoteServerNodes() { - return myBuilder.getSelectedElements(ServersTreeStructure.RemoteServerNode.class); - } - @Override public void dispose() { } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/DeploymentNode.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/DeploymentNode.java index d859d61b7f3e..b147ee72df6c 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/DeploymentNode.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/DeploymentNode.java @@ -5,18 +5,24 @@ import org.jetbrains.annotations.NotNull; /** * @author nik */ -public interface DeploymentNode { +public interface DeploymentNode extends ServersTreeNode { + @NotNull ServerNode getServerNode(); - boolean isRedeployActionEnabled(); - void redeploy(); + boolean isDeployActionVisible(); + + boolean isDeployActionEnabled(); + + void deploy(); boolean isUndeployActionEnabled(); + void undeploy(); - boolean isEditConfigurationActionEnabled(); - void editConfiguration(); + boolean isDebugActionVisible(); + + void deployWithDebug(); boolean isDeployed(); diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServerNode.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServerNode.java index d17a730002fb..d3d160cff2e3 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServerNode.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServerNode.java @@ -1,26 +1,9 @@ package com.intellij.remoteServer.impl.runtime.ui.tree; -import com.intellij.execution.Executor; -import com.intellij.openapi.actionSystem.AnActionEvent; -import org.jetbrains.annotations.NotNull; - /** * @author nik */ -public interface ServerNode { - boolean isConnected(); - boolean isStopActionEnabled(); - void stopServer(); +public interface ServerNode extends ServersTreeNode { - boolean isStartActionEnabled(@NotNull Executor executor); - void startServer(@NotNull Executor executor); - - boolean isDeployActionEnabled(); - void deploy(AnActionEvent e); - - boolean isDeployAllActionEnabled(); - void deployAll(); - - void editConfiguration(); } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeNode.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeNode.java new file mode 100644 index 000000000000..84cd735aaba6 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeNode.java @@ -0,0 +1,20 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree; + +public interface ServersTreeNode { + +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java index 7a2a053779d5..5f1969ecbea3 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/ServersTreeStructure.java @@ -3,6 +3,7 @@ package com.intellij.remoteServer.impl.runtime.ui.tree; import com.intellij.execution.Executor; import com.intellij.execution.ProgramRunnerUtil; import com.intellij.execution.RunnerAndConfigurationSettings; +import com.intellij.execution.executors.DefaultDebugExecutor; import com.intellij.execution.executors.DefaultRunExecutor; import com.intellij.execution.impl.RunDialog; import com.intellij.execution.runners.ExecutionEnvironment; @@ -18,13 +19,16 @@ import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.remoteServer.ServerType; import com.intellij.remoteServer.configuration.RemoteServer; import com.intellij.remoteServer.configuration.RemoteServersManager; import com.intellij.remoteServer.configuration.ServerConfiguration; import com.intellij.remoteServer.configuration.deployment.DeploymentConfigurationManager; import com.intellij.remoteServer.impl.configuration.SingleRemoteServerConfigurable; +import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration; import com.intellij.remoteServer.impl.runtime.deployment.DeploymentTaskImpl; import com.intellij.remoteServer.impl.runtime.log.DeploymentLogManagerImpl; import com.intellij.remoteServer.impl.runtime.log.LoggingHandlerImpl; @@ -38,6 +42,7 @@ import com.intellij.remoteServer.runtime.deployment.DeploymentStatus; import com.intellij.remoteServer.runtime.deployment.DeploymentTask; import com.intellij.ui.LayeredIcon; import com.intellij.ui.awt.RelativePoint; +import com.intellij.util.containers.ContainerUtil; import icons.RemoteServersIcons; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -160,50 +165,65 @@ public class ServersTreeStructure extends AbstractTreeStructureBase { return ServerConnectionManager.getInstance().getConnection(getValue()); } - @Override public boolean isConnected() { ServerConnection connection = getConnection(); return connection != null && connection.getStatus() == ConnectionStatus.CONNECTED; } - @Override - public boolean isDeployActionEnabled() { - return true; + public void deploy(AnActionEvent e) { + doDeploy(e, DefaultRunExecutor.getRunExecutorInstance(), "Deploy Configuration", true); } - @Override - public void deploy(AnActionEvent e) { - final ServerType serverType = getValue().getType(); + public void deployWithDebug(AnActionEvent e) { + doDeploy(e, DefaultDebugExecutor.getDebugExecutorInstance(), "Deploy and Debug Configuration", false); + } + + public void doDeploy(AnActionEvent e, final Executor executor, String popupTitle, boolean canCreate) { + final RemoteServer server = getValue(); + final ServerType serverType = server.getType(); final DeploymentConfigurationManager configurationManager = DeploymentConfigurationManager.getInstance(doGetProject()); - List list = new ArrayList(configurationManager.getDeploymentConfigurations(serverType)); - list.add(null); - ListPopup popup = JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep("Deploy Configuration", list) { - @Override - public Icon getIconFor(RunnerAndConfigurationSettings value) { - return value != null ? serverType.getIcon() : null; - } + List list + = ContainerUtil.filter(configurationManager.getDeploymentConfigurations(serverType), + new Condition() { - @NotNull - @Override - public String getTextFor(RunnerAndConfigurationSettings value) { - return value != null ? value.getName() : "Create..."; - } + @Override + public boolean value(RunnerAndConfigurationSettings settings) { + DeployToServerRunConfiguration configuration = + (DeployToServerRunConfiguration)settings.getConfiguration(); + return StringUtil.equals(server.getName(), configuration.getServerName()); + } + }); + if (canCreate) { + list.add(null); + } + ListPopup popup = + JBPopupFactory.getInstance().createListPopup(new BaseListPopupStep(popupTitle, list) { + @Override + public Icon getIconFor(RunnerAndConfigurationSettings value) { + return value != null ? serverType.getIcon() : null; + } - @Override - public PopupStep onChosen(final RunnerAndConfigurationSettings selectedValue, boolean finalChoice) { - return doFinalStep(new Runnable() { - @Override - public void run() { - if (selectedValue != null) { - ProgramRunnerUtil.executeConfiguration(doGetProject(), selectedValue, DefaultRunExecutor.getRunExecutorInstance()); + @NotNull + @Override + public String getTextFor(RunnerAndConfigurationSettings value) { + return value != null ? value.getName() : "Create..."; + } + + @Override + public PopupStep onChosen(final RunnerAndConfigurationSettings selectedValue, boolean finalChoice) { + return doFinalStep(new Runnable() { + @Override + public void run() { + if (selectedValue != null) { + ProgramRunnerUtil.executeConfiguration(doGetProject(), selectedValue, executor); + } + else { + configurationManager.createAndRunConfiguration(serverType, RemoteServerNode.this.getValue()); + } } - else { - configurationManager.createAndRunConfiguration(serverType, RemoteServerNode.this.getValue()); - } - } - }); - } - }); + }); + } + }); if (e.getInputEvent() instanceof MouseEvent) { popup.show(new RelativePoint((MouseEvent)e.getInputEvent())); } @@ -212,45 +232,10 @@ public class ServersTreeStructure extends AbstractTreeStructureBase { } } - @Override - public boolean isStopActionEnabled() { - return isConnected(); - } - - @Override - public void stopServer() { - ServerConnection connection = getConnection(); - if (connection != null) { - connection.disconnect(); - } - } - - @Override public void editConfiguration() { ShowSettingsUtil.getInstance().editConfigurable(doGetProject(), new SingleRemoteServerConfigurable(getValue(), null, false)); } - @Override - public boolean isStartActionEnabled(@NotNull Executor executor) { - ServerConnection connection = getConnection(); - return executor.equals(DefaultRunExecutor.getRunExecutorInstance()) && - (connection == null || connection.getStatus() == ConnectionStatus.DISCONNECTED); - } - - @Override - public void startServer(@NotNull Executor executor) { - ServerConnectionManager.getInstance().getOrCreateConnection(getValue()); - } - - @Override - public boolean isDeployAllActionEnabled() { - return false; - } - - @Override - public void deployAll() { - } - @Nullable private Icon getStatusIcon(final ConnectionStatus status) { switch (status) { @@ -278,23 +263,42 @@ public class ServersTreeStructure extends AbstractTreeStructureBase { } @Override - public boolean isRedeployActionEnabled() { + public boolean isDeployActionVisible() { DeploymentTask deploymentTask = getValue().getDeploymentTask(); return deploymentTask instanceof DeploymentTaskImpl && ((DeploymentTaskImpl)deploymentTask).getExecutionEnvironment().getRunnerAndConfigurationSettings() != null; } @Override - public void redeploy() { + public boolean isDeployActionEnabled() { + return true; + } + + @Override + public void deploy() { + doDeploy(DefaultRunExecutor.getRunExecutorInstance()); + } + + public void doDeploy(Executor executor) { DeploymentTask deploymentTask = getValue().getDeploymentTask(); if (deploymentTask != null) { ExecutionEnvironment environment = ((DeploymentTaskImpl)deploymentTask).getExecutionEnvironment(); RunnerAndConfigurationSettings settings = environment.getRunnerAndConfigurationSettings(); if (settings != null) { - ProgramRunnerUtil.executeConfiguration(doGetProject(), settings, DefaultRunExecutor.getRunExecutorInstance()); + ProgramRunnerUtil.executeConfiguration(doGetProject(), settings, executor); } } } + @Override + public boolean isDebugActionVisible() { + return myParentNode.getValue().getType().createDebugConnector() != null; + } + + @Override + public void deployWithDebug() { + doDeploy(DefaultDebugExecutor.getDebugExecutorInstance()); + } + @Override public boolean isUndeployActionEnabled() { DeploymentRuntime runtime = getValue().getRuntime(); @@ -309,12 +313,10 @@ public class ServersTreeStructure extends AbstractTreeStructureBase { } } - @Override - public boolean isEditConfigurationActionEnabled() { + public boolean isEditConfigurationActionVisible() { return getValue().getDeploymentTask() != null; } - @Override public void editConfiguration() { DeploymentTask task = getValue().getDeploymentTask(); if (task != null) { @@ -396,7 +398,7 @@ public class ServersTreeStructure extends AbstractTreeStructureBase { } } - public class DeploymentLogNode extends AbstractTreeNode> implements LogProvidingNode { + public class DeploymentLogNode extends AbstractTreeNode> implements ServersTreeNode, LogProvidingNode { @NotNull private final DeploymentNodeImpl myDeploymentNode; public DeploymentLogNode(@NotNull Pair value, @NotNull DeploymentNodeImpl deploymentNode) { diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ChooseDeploymentAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ChooseDeploymentAction.java new file mode 100644 index 000000000000..1a762f75cf01 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ChooseDeploymentAction.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure; +import org.jetbrains.annotations.NotNull; + +public class ChooseDeploymentAction extends ServersTreeAction { + + public ChooseDeploymentAction() { + super("Deploy", "Deploy a chosen item to the selected remote server", AllIcons.Nodes.Deploy); + } + + @Override + protected Class getTargetNodeClass() { + return ServersTreeStructure.RemoteServerNode.class; + } + + @Override + protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e, ServersTreeStructure.RemoteServerNode node) { + node.deploy(e); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ChooseDeploymentWithDebugAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ChooseDeploymentWithDebugAction.java new file mode 100644 index 000000000000..55e2b1cb509f --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ChooseDeploymentWithDebugAction.java @@ -0,0 +1,39 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure; +import org.jetbrains.annotations.NotNull; + +public class ChooseDeploymentWithDebugAction extends ServersTreeAction { + + public ChooseDeploymentWithDebugAction() { + super("Debug", "Deploy and debug a chosen item on the selected remote server", AllIcons.Actions.StartDebugger); + } + + @Override + protected Class getTargetNodeClass() { + return ServersTreeStructure.RemoteServerNode.class; + } + + @Override + protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e, ServersTreeStructure.RemoteServerNode node) { + node.deployWithDebug(e); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DebugServerAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DebugServerAction.java deleted file mode 100644 index f519478ef84c..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DebugServerAction.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.execution.Executor; -import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.icons.AllIcons; - -/** - * @author michael.golubev - */ -public class DebugServerAction extends RunServerActionBase { - public DebugServerAction() { - super("Debug", "Start the selected server in debug mode", AllIcons.Actions.StartDebugger); - } - - @Override - protected Executor getExecutor() { - return DefaultDebugExecutor.getDebugExecutorInstance(); - } -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployAction.java index c6a38404192e..4b8bbeeea7e7 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployAction.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployAction.java @@ -1,67 +1,50 @@ package com.intellij.remoteServer.impl.runtime.ui.tree.actions; import com.intellij.icons.AllIcons; -import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Set; - /** * @author michael.golubev */ -public class DeployAction extends ServersTreeActionBase { +public class DeployAction extends ServersTreeAction { + public DeployAction() { super("Deploy", "Deploy the selected item", AllIcons.Nodes.Deploy); } @Override - protected void updatePresentation(@NotNull Presentation presentation, @Nullable ServersToolWindowContent content) { - if (content != null) { - Set nodes = content.getSelectedDeploymentNodes(); - if (nodes.size() == 1) { - DeploymentNode node = nodes.iterator().next(); - if (node.isDeployed()) { - presentation.setText("Redeploy"); - presentation.setDescription("Redeploy '" + node.getDeploymentName() + "'"); - return; - } - } - } - presentation.setText(getTemplatePresentation().getText()); - presentation.setDescription(getTemplatePresentation().getDescription()); + protected Class getTargetNodeClass() { + return DeploymentNode.class; } @Override - protected boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) { - Set deploymentNodes = content.getSelectedDeploymentNodes(); - Set serverNodes = content.getSelectedServerNodes(); - if (deploymentNodes.size() + serverNodes.size() != 1) return false; - for (DeploymentNode node : deploymentNodes) { - if (!node.isRedeployActionEnabled()) { - return false; - } + protected void updatePresentation(@NotNull Presentation presentation, @Nullable DeploymentNode node) { + if (node != null && node.isDeployed()) { + presentation.setText("Redeploy"); + presentation.setDescription("Redeploy '" + node.getDeploymentName() + "'"); } - for (ServerNode serverNode : serverNodes) { - if (!serverNode.isDeployActionEnabled()) { - return false; - } + else { + presentation.setText(getTemplatePresentation().getText()); + presentation.setDescription(getTemplatePresentation().getDescription()); } - return true; } @Override - protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) { - for (DeploymentNode node : content.getSelectedDeploymentNodes()) { - node.redeploy(); - } - for (ServerNode node : content.getSelectedServerNodes()) { - node.deploy(e); - } + protected boolean isVisible4(DeploymentNode node) { + return node.isDeployActionVisible(); + } + + @Override + protected boolean isEnabled4(DeploymentNode node) { + return node.isDeployActionEnabled(); + } + + @Override + protected void doActionPerformed(DeploymentNode node) { + node.deploy(); } } diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployAllAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployAllAction.java deleted file mode 100644 index 818f0ad7619e..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployAllAction.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.icons.AllIcons; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode; -import org.jetbrains.annotations.NotNull; - -/** - * @author michael.golubev - */ -public class DeployAllAction extends ServerActionBase { - - public DeployAllAction() { - super("Deploy All", "Deploy all the artifacts of the selected server", AllIcons.Nodes.Deploy); - } - - @Override - protected void performAction(@NotNull ServerNode serverNode) { - if (serverNode.isDeployAllActionEnabled()) { - serverNode.deployAll(); - } - } - - @Override - protected boolean isEnabledForServer(@NotNull ServerNode serverNode) { - return serverNode.isDeployAllActionEnabled(); - } -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployWithDebugAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployWithDebugAction.java new file mode 100644 index 000000000000..d9c00380b9e2 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeployWithDebugAction.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.icons.AllIcons; +import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode; + +public class DeployWithDebugAction extends ServersTreeAction { + + public DeployWithDebugAction() { + super("Debug", "Deploy and debug the selected item", AllIcons.Actions.StartDebugger); + } + + @Override + protected Class getTargetNodeClass() { + return DeploymentNode.class; + } + + @Override + protected boolean isVisible4(DeploymentNode node) { + return node.isDeployActionVisible() && node.isDebugActionVisible(); + } + + @Override + protected boolean isEnabled4(DeploymentNode node) { + return node.isDeployActionEnabled(); + } + + @Override + protected void doActionPerformed(DeploymentNode node) { + node.deployWithDebug(); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeploymentActionBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeploymentActionBase.java deleted file mode 100644 index 27bace389c41..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeploymentActionBase.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; -import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -/** - * @author nik - */ -public abstract class DeploymentActionBase extends ServersTreeActionBase { - protected DeploymentActionBase(String text, String description, Icon icon) { - super(text, description, icon); - } - - protected abstract void perform(@NotNull List nodes, ServersToolWindowContent content, AnActionEvent e); - - protected abstract boolean isApplicable(@NotNull DeploymentNode node); - - @Override - public void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) { - List toPerform = new ArrayList(); - for (DeploymentNode node : content.getSelectedDeploymentNodes()) { - if (isApplicable(node)) { - toPerform.add(node); - } - } - if (!toPerform.isEmpty()) { - perform(toPerform, content, e); - } - } - - @Override - protected boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) { - Set selectedElements = content.getBuilder().getSelectedElements(); - if (selectedElements.isEmpty() || selectedElements.size() != content.getSelectedDeploymentNodes().size()) { - return false; - } - - for (DeploymentNode node : content.getSelectedDeploymentNodes()) { - if (!isApplicable(node)) { - return false; - } - } - return true; - } -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeploymentConfigAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeploymentConfigAction.java new file mode 100644 index 000000000000..e7f1960ae41f --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/DeploymentConfigAction.java @@ -0,0 +1,40 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure; + +public class DeploymentConfigAction extends EditConfigurationActionBase { + + public DeploymentConfigAction() { + super("Edit the selected deployment run configuration"); + } + + @Override + protected Class getTargetNodeClass() { + return ServersTreeStructure.DeploymentNodeImpl.class; + } + + @Override + protected boolean isVisible4(ServersTreeStructure.DeploymentNodeImpl node) { + return node.isEditConfigurationActionVisible(); + } + + @Override + protected void doActionPerformed(ServersTreeStructure.DeploymentNodeImpl node) { + node.editConfiguration(); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/EditConfigurationAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/EditConfigurationAction.java deleted file mode 100644 index 75d22a854114..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/EditConfigurationAction.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.icons.AllIcons; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; -import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode; -import org.jetbrains.annotations.NotNull; - -import java.util.Set; - -/** - * @author michael.golubev - */ -public class EditConfigurationAction extends ServersTreeActionBase { - public EditConfigurationAction() { - super("Edit Configuration", "Edit configuration of the selected server", AllIcons.Actions.EditSource); - } - - @Override - protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) { - Set deploymentNodes = content.getSelectedDeploymentNodes(); - Set serverNodes = content.getSelectedServerNodes(); - if (deploymentNodes.size() == 1) { - deploymentNodes.iterator().next().editConfiguration(); - } - else { - serverNodes.iterator().next().editConfiguration(); - } - } - - @Override - protected boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) { - Set deploymentNodes = content.getSelectedDeploymentNodes(); - Set serverNodes = content.getSelectedServerNodes(); - if (deploymentNodes.size() + serverNodes.size() != 1) return false; - if (deploymentNodes.size() == 1) { - return deploymentNodes.iterator().next().isEditConfigurationActionEnabled(); - } - return true; - } -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/EditConfigurationActionBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/EditConfigurationActionBase.java new file mode 100644 index 000000000000..05fcb95fede5 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/EditConfigurationActionBase.java @@ -0,0 +1,26 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.icons.AllIcons; +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNode; + +public abstract class EditConfigurationActionBase extends ServersTreeAction { + + public EditConfigurationActionBase(String description) { + super("Edit Configuration", description, AllIcons.Actions.EditSource); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerConfigAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerConfigAction.java new file mode 100644 index 000000000000..b5f5456318da --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerConfigAction.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure; + +public class RemoteServerConfigAction extends EditConfigurationActionBase { + + public RemoteServerConfigAction() { + super("Edit the selected remote server configuration"); + } + + @Override + protected Class getTargetNodeClass() { + return ServersTreeStructure.RemoteServerNode.class; + } + + @Override + protected void doActionPerformed(ServersTreeStructure.RemoteServerNode node) { + node.editConfiguration(); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerConnectAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerConnectAction.java new file mode 100644 index 000000000000..8fd5f7891748 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerConnectAction.java @@ -0,0 +1,42 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.icons.AllIcons; +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure; +import com.intellij.remoteServer.runtime.ServerConnectionManager; + +public class RemoteServerConnectAction extends ServersTreeAction { + + public RemoteServerConnectAction() { + super("Connect", "Connect to the selected remote server", AllIcons.Actions.Execute); + } + + @Override + protected Class getTargetNodeClass() { + return ServersTreeStructure.RemoteServerNode.class; + } + + @Override + protected boolean isEnabled4(ServersTreeStructure.RemoteServerNode node) { + return !node.isConnected(); + } + + @Override + protected void doActionPerformed(ServersTreeStructure.RemoteServerNode node) { + ServerConnectionManager.getInstance().getOrCreateConnection(node.getValue()); + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerDisconnectAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerDisconnectAction.java new file mode 100644 index 000000000000..96f21e56671f --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RemoteServerDisconnectAction.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2014 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.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.icons.AllIcons; +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeStructure; +import com.intellij.remoteServer.runtime.ServerConnection; +import com.intellij.remoteServer.runtime.ServerConnectionManager; + +public class RemoteServerDisconnectAction extends ServersTreeAction { + + public RemoteServerDisconnectAction() { + super("Disconnect", "Disconnect from the selected remote server", AllIcons.Actions.Suspend); + } + + @Override + protected Class getTargetNodeClass() { + return ServersTreeStructure.RemoteServerNode.class; + } + + @Override + protected boolean isEnabled4(ServersTreeStructure.RemoteServerNode node) { + return node.isConnected(); + } + + @Override + protected void doActionPerformed(ServersTreeStructure.RemoteServerNode node) { + ServerConnection connection = ServerConnectionManager.getInstance().getConnection(node.getValue()); + if (connection != null) { + connection.disconnect(); + } + } +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RunServerAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RunServerAction.java deleted file mode 100644 index aa16c77e2aeb..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RunServerAction.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.execution.Executor; -import com.intellij.execution.executors.DefaultRunExecutor; -import com.intellij.icons.AllIcons; - -/** - * @author michael.golubev - */ -public class RunServerAction extends RunServerActionBase { - - public RunServerAction() { - super("Run/Connect", "Run/Connect to the selected server", AllIcons.Actions.Execute); - } - - @Override - protected Executor getExecutor() { - return DefaultRunExecutor.getRunExecutorInstance(); - } -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RunServerActionBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RunServerActionBase.java deleted file mode 100644 index 07b1e4b683f1..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/RunServerActionBase.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - - -import com.intellij.execution.Executor; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; - -/** - * @author michael.golubev - */ -public abstract class RunServerActionBase extends ServerActionBase { - - protected RunServerActionBase(String text, String description, Icon icon) { - super(text, description, icon); - } - - protected void performAction(@NotNull ServerNode serverNode) { - if (serverNode.isStartActionEnabled(getExecutor())) { - serverNode.startServer(getExecutor()); - } - } - - @Override - protected boolean isEnabledForServer(@NotNull ServerNode serverNode) { - return serverNode.isStartActionEnabled(getExecutor()); - } - - protected abstract Executor getExecutor(); -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServerActionBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServerActionBase.java deleted file mode 100644 index 1b4d4f8bbd89..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServerActionBase.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import java.util.Set; - -/** - * @author michael.golubev - */ -public abstract class ServerActionBase extends ServersTreeActionBase { - - protected ServerActionBase(String text, String description, Icon icon) { - super(text, description, icon); - } - - @Override - protected final boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) { - Set selectedServerNodes = content.getSelectedServerNodes(); - Set selectedElements = content.getBuilder().getSelectedElements(); - if (selectedElements.size() != selectedServerNodes.size() || selectedElements.isEmpty()) { - return false; - } - - for (ServerNode selectedServer : selectedServerNodes) { - if (!isEnabledForServer(selectedServer)) { - return false; - } - } - return true; - } - - @Override - protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) { - for (ServerNode node : content.getSelectedServerNodes()) { - performAction(node); - } - } - - protected abstract void performAction(@NotNull ServerNode serverNode); - - protected abstract boolean isEnabledForServer(@NotNull ServerNode serverNode); -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServersTreeAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServersTreeAction.java new file mode 100644 index 000000000000..d86a708196d2 --- /dev/null +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServersTreeAction.java @@ -0,0 +1,91 @@ +package com.intellij.remoteServer.impl.runtime.ui.tree.actions; + +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; +import com.intellij.remoteServer.impl.runtime.ui.tree.ServersTreeNode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.Set; + +public abstract class ServersTreeAction extends AnAction { + + protected ServersTreeAction(String text, String description, Icon icon) { + super(text, description, icon); + } + + @Override + public void update(@NotNull AnActionEvent e) { + Presentation presentation = e.getPresentation(); + T targetNode = getTargetNode(e); + + boolean visible = false; + boolean enabled = false; + + if (targetNode != null) { + visible = isVisible4(targetNode); + if (visible) { + enabled = isEnabled4(targetNode); + } + } + + presentation.setVisible(visible); + presentation.setEnabled(enabled); + updatePresentation(presentation, targetNode); + } + + private T getTargetNode(AnActionEvent e) { + ServersToolWindowContent content = getContent(e); + if (content == null) { + return null; + } + Set selectedElements = content.getBuilder().getSelectedElements(); + if (selectedElements.size() != 1) { + return null; + } + ServersTreeNode node = (ServersTreeNode)selectedElements.iterator().next(); + Class targetNodeClass = getTargetNodeClass(); + if (!targetNodeClass.isInstance(node)) { + return null; + } + return targetNodeClass.cast(node); + } + + private static ServersToolWindowContent getContent(AnActionEvent e) { + return e.getData(ServersToolWindowContent.KEY); + } + + @Override + public void actionPerformed(@NotNull AnActionEvent e) { + T targetNode = getTargetNode(e); + if (targetNode != null && isVisible4(targetNode) && isEnabled4(targetNode)) { + doActionPerformed(getContent(e), e, targetNode); + } + } + + + protected boolean isVisible4(T node) { + return true; + } + + protected boolean isEnabled4(T node) { + return true; + } + + protected void updatePresentation(@NotNull Presentation presentation, @Nullable T node) { + } + + + protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e, T node) { + doActionPerformed(node); + } + + protected void doActionPerformed(T node) { + throw new UnsupportedOperationException(); + } + + protected abstract Class getTargetNodeClass(); +} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServersTreeActionBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServersTreeActionBase.java deleted file mode 100644 index 7e505bd06aab..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/ServersTreeActionBase.java +++ /dev/null @@ -1,44 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -/** - * @author michael.golubev - */ -public abstract class ServersTreeActionBase extends AnAction { - - protected ServersTreeActionBase(String text, String description, Icon icon) { - super(text, description, icon); - } - - @Override - public void update(AnActionEvent e) { - ServersToolWindowContent content = e.getData(ServersToolWindowContent.KEY); - Presentation presentation = e.getPresentation(); - presentation.setEnabled(content != null && isEnabled(content, e)); - updatePresentation(presentation, content); - } - - protected void updatePresentation(@NotNull Presentation presentation, @Nullable ServersToolWindowContent content) { - } - - @Override - public void actionPerformed(AnActionEvent e) { - ServersToolWindowContent content = e.getData(ServersToolWindowContent.KEY); - if (content == null) { - return; - } - doActionPerformed(content, e); - } - - protected abstract boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e); - - protected abstract void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e); -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/SingleServerActionBase.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/SingleServerActionBase.java deleted file mode 100644 index 50ec63646922..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/SingleServerActionBase.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2000-2013 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.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import java.util.Set; - -/** - * @author michael.golubev - */ -public abstract class SingleServerActionBase extends ServersTreeActionBase { - protected SingleServerActionBase(String text, String description, Icon icon) { - super(text, description, icon); - } - - @Override - protected void doActionPerformed(@NotNull ServersToolWindowContent content, AnActionEvent e) { - doActionPerformed(content, content.getSelectedServerNodes().iterator().next()); - } - - @Override - protected boolean isEnabled(@NotNull ServersToolWindowContent content, AnActionEvent e) { - Set serverNodes = content.getSelectedServerNodes(); - return content.getBuilder().getSelectedElements().size() == serverNodes.size() && serverNodes.size() == 1 && - isEnabledForServer(serverNodes.iterator().next()); - } - - protected abstract boolean isEnabledForServer(ServerNode serverNode); - - protected abstract void doActionPerformed(@NotNull ServersToolWindowContent content, @NotNull ServerNode server); -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/StopServerAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/StopServerAction.java deleted file mode 100644 index 7984c119036c..000000000000 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/StopServerAction.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.intellij.remoteServer.impl.runtime.ui.tree.actions; - -import com.intellij.icons.AllIcons; -import com.intellij.remoteServer.impl.runtime.ui.tree.ServerNode; -import org.jetbrains.annotations.NotNull; - -/** - * @author michael.golubev - */ -public class StopServerAction extends ServerActionBase { - - public StopServerAction() { - super("Stop/Disconnect", "Stop/disconnect from the selected server", AllIcons.Actions.Suspend); - } - - protected void performAction(@NotNull ServerNode serverNode) { - if (serverNode.isStopActionEnabled()) { - serverNode.stopServer(); - } - } - - @Override - protected boolean isEnabledForServer(@NotNull ServerNode serverNode) { - return serverNode.isStopActionEnabled(); - } -} diff --git a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/UndeployAction.java b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/UndeployAction.java index bc11f8aa94a8..50c247eabd91 100644 --- a/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/UndeployAction.java +++ b/platform/remote-servers/impl/src/com/intellij/remoteServer/impl/runtime/ui/tree/actions/UndeployAction.java @@ -1,30 +1,29 @@ package com.intellij.remoteServer.impl.runtime.ui.tree.actions; import com.intellij.icons.AllIcons; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.remoteServer.impl.runtime.ui.ServersToolWindowContent; import com.intellij.remoteServer.impl.runtime.ui.tree.DeploymentNode; -import org.jetbrains.annotations.NotNull; - -import java.util.List; /** * @author michael.golubev */ -public class UndeployAction extends DeploymentActionBase { +public class UndeployAction extends ServersTreeAction { + public UndeployAction() { super("Undeploy", "Undeploy the selected item", AllIcons.Nodes.Undeploy); } @Override - protected boolean isApplicable(@NotNull DeploymentNode node) { + protected Class getTargetNodeClass() { + return DeploymentNode.class; + } + + @Override + protected boolean isEnabled4(DeploymentNode node) { return node.isUndeployActionEnabled(); } @Override - protected void perform(@NotNull List nodes, ServersToolWindowContent content, AnActionEvent e) { - for (DeploymentNode node : nodes) { - node.undeploy(); - } + protected void doActionPerformed(DeploymentNode node) { + node.undeploy(); } } From f8c22ac4ee888f14f0c2869d85689d6bf669d39b Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Mon, 27 Oct 2014 20:30:44 +0300 Subject: [PATCH 52/55] IDEA-131923 Debugger: Referring Objects can't update on Set Value --- .../debugger/actions/JavaReferringObjectsValue.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java index 96ba9e6eb54d..34959665d0cf 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java @@ -168,4 +168,10 @@ public class JavaReferringObjectsValue extends JavaValue { } return null; } + + @Nullable + @Override + public XValueModifier getModifier() { + return null; + } } From 4715175804e2b9f67dd2560cd6c772928431a720 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Mon, 27 Oct 2014 18:51:33 +0100 Subject: [PATCH 53/55] java duplicates uses light tree processing --- .../dupLocator/index/DuplicatesIndex.java | 2 +- .../index/DuplicatesInspectionBase.java | 243 +++++++++++++----- 2 files changed, 177 insertions(+), 68 deletions(-) diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java index b3e94c465e70..cf4249cecd65 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesIndex.java @@ -55,7 +55,7 @@ import java.util.Map; public class DuplicatesIndex extends FileBasedIndexExtension implements PsiDependentIndex { static boolean ourEnabled = SystemProperties.getBooleanProperty("idea.enable.duplicates.online.calculation", isEnabledByDefault()); - static boolean ourEnabledLightProfiles = false; + static boolean ourEnabledLightProfiles = true; private static boolean isEnabledByDefault() { Application application = ApplicationManager.getApplication(); diff --git a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesInspectionBase.java b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesInspectionBase.java index f015fe21213b..f44a3e2953c7 100644 --- a/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesInspectionBase.java +++ b/platform/duplicates-analysis/src/com/intellij/dupLocator/index/DuplicatesInspectionBase.java @@ -3,10 +3,16 @@ package com.intellij.dupLocator.index; import com.intellij.codeInspection.*; import com.intellij.dupLocator.DuplicatesProfile; import com.intellij.dupLocator.DuplocatorState; +import com.intellij.dupLocator.LightDuplicateProfile; import com.intellij.dupLocator.treeHash.FragmentsCollector; import com.intellij.dupLocator.util.PsiFragment; +import com.intellij.lang.LighterAST; +import com.intellij.lang.LighterASTNode; +import com.intellij.lang.TreeBackedLighterAST; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileWithId; @@ -35,94 +41,126 @@ public class DuplicatesInspectionBase extends LocalInspectionTool { final DuplicatesProfile profile = DuplicatesIndex.findDuplicatesProfile(psiFile.getFileType()); if (profile == null) return ProblemDescriptor.EMPTY_ARRAY; - final DuplocatorState state = profile.getDuplocatorState(psiFile.getLanguage()); - final SmartList descriptors = new SmartList(); + final Ref myProcessorRef = new Ref(); - final TreeMap reportedRanges = new TreeMap(); - final TIntObjectHashMap reportedFiles = new TIntObjectHashMap(); - final TIntObjectHashMap reportedPsi = new TIntObjectHashMap(); - final TIntIntHashMap reportedOffsetInOtherFiles = new TIntIntHashMap(); - final TIntIntHashMap fragmentSize = new TIntIntHashMap(); + if (profile instanceof LightDuplicateProfile && DuplicatesIndex.ourEnabledLightProfiles) { - profile.createVisitor(new FragmentsCollector() { - @Override - public void add(int hash, final int cost, @Nullable final PsiFragment frag) { - if (!DuplicatesIndex.isIndexedFragment(frag, cost, profile, state)) { - return; + ((LightDuplicateProfile)profile).process(psiFile, new LightDuplicateProfile.Callback() { + DuplicatedCodeProcessor myProcessor; + @Override + public void process(final LighterAST ast, final LighterASTNode node, int hash) { + class LightDuplicatedCodeProcessor extends DuplicatedCodeProcessor { + + LightDuplicatedCodeProcessor(VirtualFile file, Project project) { + super(file, project); + } + + @Override + protected TextRange getRangeInElement(LighterASTNode node) { + return null; + } + + @Override + protected PsiElement getPsi(LighterASTNode node) { + return ((TreeBackedLighterAST)ast).unwrap(node).getPsi(); + } + + @Override + protected int getStartOffset(LighterASTNode node) { + return node.getStartOffset(); + } + + @Override + protected int getEndOffset(LighterASTNode node) { + return node.getEndOffset(); + } + } + if (myProcessor == null) { + myProcessor = new LightDuplicatedCodeProcessor(virtualFile, psiFile.getProject()); + myProcessorRef.set(myProcessor); + } + myProcessor.process(hash, node); } + }); + } else { + final DuplocatorState state = profile.getDuplocatorState(psiFile.getLanguage()); + profile.createVisitor(new FragmentsCollector() { + DuplicatedCodeProcessor myProcessor; + @Override + public void add(int hash, final int cost, @Nullable final PsiFragment frag) { + if (!DuplicatesIndex.isIndexedFragment(frag, cost, profile, state)) { + return; + } - ProgressManager.checkCanceled(); - FileBasedIndex.getInstance().processValues(DuplicatesIndex.NAME, hash, null, new FileBasedIndex.ValueProcessor() { - final ProjectFileIndex myProjectFileIndex = ProjectFileIndex.SERVICE.getInstance(psiFile.getProject()); - @Override - public boolean process(final VirtualFile file, final TIntArrayList list) { - for(int i = 0, len = list.size(); i < len; ++i) { - ProgressManager.checkCanceled(); + class OldDuplicatedCodeProcessor extends DuplicatedCodeProcessor { - int value = list.getQuick(i); + OldDuplicatedCodeProcessor(VirtualFile file, Project project) { + super(file, project); + } - if (myProjectFileIndex.isInSource(virtualFile) && !myProjectFileIndex.isInSource(file)) return true; - if (!myProjectFileIndex.isInSource(virtualFile) && myProjectFileIndex.isInSource(file)) return true; - final int startOffset = frag.getStartOffset(); - final int endOffset = frag.getEndOffset(); - if (file.equals(virtualFile) && value >= startOffset && value < endOffset) continue; - - PsiElement[] elements = frag.getElements(); - PsiElement target = elements[0]; + @Override + protected TextRange getRangeInElement(PsiFragment node) { + PsiElement[] elements = node.getElements(); TextRange rangeInElement = null; if (elements.length > 1) { - PsiElement firstElement = elements[0]; - target = firstElement.getParent(); + PsiElement lastElement = elements[elements.length - 1]; rangeInElement = new TextRange( elements[0].getStartOffsetInParent(), lastElement.getStartOffsetInParent() + lastElement.getTextLength() ); } + return rangeInElement; + } - Integer fragmentStartOffsetInteger = startOffset; - SortedMap map = reportedRanges.subMap(fragmentStartOffsetInteger, endOffset); - int newFragmentSize = !map.isEmpty() ? 0:1; + @Override + protected PsiElement getPsi(PsiFragment node) { + PsiElement[] elements = node.getElements(); - Iterator iterator = map.keySet().iterator(); - while(iterator.hasNext()) { - Integer next = iterator.next(); - iterator.remove(); - reportedFiles.remove(next); - reportedOffsetInOtherFiles.remove(next); - reportedPsi.remove(next); - newFragmentSize += fragmentSize.remove(next); - } + return elements.length > 1 ? elements[0].getParent() : elements[0]; + } - reportedRanges.put(fragmentStartOffsetInteger, rangeInElement); - reportedFiles.put(fragmentStartOffsetInteger, file); - reportedOffsetInOtherFiles.put(fragmentStartOffsetInteger, value); - reportedPsi.put(fragmentStartOffsetInteger, target); - fragmentSize.put(fragmentStartOffsetInteger, newFragmentSize); + @Override + protected int getStartOffset(PsiFragment node) { + return node.getStartOffset(); + } - return false; + @Override + protected int getEndOffset(PsiFragment node) { + return node.getEndOffset(); } - return true; } - }, GlobalSearchScope.projectScope(psiFile.getProject())); + if (myProcessor == null) { + myProcessor = new OldDuplicatedCodeProcessor(virtualFile, psiFile.getProject()); + myProcessorRef.set(myProcessor); + } + myProcessor.process(hash, frag); + } + }, true).visitNode(psiFile); + } + + DuplicatedCodeProcessor processor = myProcessorRef.get(); + + final SmartList descriptors = new SmartList(); + + if (processor != null) { + + for(Map.Entry entry:processor.reportedRanges.entrySet()) { + final Integer offset = entry.getKey(); + // todo 3 statements constant + if (processor.fragmentSize.get(offset) < 3) continue; + final VirtualFile file = processor.reportedFiles.get(offset); + String message = "Found duplicated code in " + file.getPath(); + + PsiElement targetElement = processor.reportedPsi.get(offset); + TextRange rangeInElement = entry.getValue(); + final int offsetInOtherFile = processor.reportedOffsetInOtherFiles.get(offset); + + LocalQuickFix fix = createNavigateToDupeFix(file, offsetInOtherFile); + ProblemDescriptor descriptor = manager + .createProblemDescriptor(targetElement, rangeInElement, message, ProblemHighlightType.WEAK_WARNING, isOnTheFly, fix); + descriptors.add(descriptor); } - }, true).visitNode(psiFile); - - for(Map.Entry entry:reportedRanges.entrySet()) { - final Integer offset = entry.getKey(); - // todo 3 statements constant - if (fragmentSize.get(offset) < 3) continue; - final VirtualFile file = reportedFiles.get(offset); - String message = "Found duplicated code in " + file.getPath(); - - PsiElement targetElement = reportedPsi.get(offset); - TextRange rangeInElement = entry.getValue(); - final int offsetInOtherFile = reportedOffsetInOtherFiles.get(offset); - - LocalQuickFix fix = createNavigateToDupeFix(file, offsetInOtherFile); - ProblemDescriptor descriptor = manager - .createProblemDescriptor(targetElement, rangeInElement, message, ProblemHighlightType.WEAK_WARNING, isOnTheFly, fix); - descriptors.add(descriptor); } return descriptors.isEmpty() ? null : descriptors.toArray(new ProblemDescriptor[descriptors.size()]); @@ -131,4 +169,75 @@ public class DuplicatesInspectionBase extends LocalInspectionTool { protected LocalQuickFix createNavigateToDupeFix(@NotNull VirtualFile file, int offsetInOtherFile) { return null; } + + static abstract class DuplicatedCodeProcessor implements FileBasedIndex.ValueProcessor { + final TreeMap reportedRanges = new TreeMap(); + final TIntObjectHashMap reportedFiles = new TIntObjectHashMap(); + final TIntObjectHashMap reportedPsi = new TIntObjectHashMap(); + final TIntIntHashMap reportedOffsetInOtherFiles = new TIntIntHashMap(); + final TIntIntHashMap fragmentSize = new TIntIntHashMap(); + final VirtualFile virtualFile; + final Project project; + final ProjectFileIndex myProjectFileIndex; + T myNode; + + DuplicatedCodeProcessor(VirtualFile file, Project project) { + virtualFile = file; + this.project = project; + myProjectFileIndex = ProjectFileIndex.SERVICE.getInstance(project); + } + + void process(int hash, T node) { + ProgressManager.checkCanceled(); + myNode = node; + FileBasedIndex.getInstance().processValues(DuplicatesIndex.NAME, hash, null, this, GlobalSearchScope.projectScope(project)); + } + + @Override + public boolean process(VirtualFile file, TIntArrayList list) { + for(int i = 0, len = list.size(); i < len; ++i) { + ProgressManager.checkCanceled(); + + int value = list.getQuick(i); + + if (myProjectFileIndex.isInSource(virtualFile) && !myProjectFileIndex.isInSource(file)) return true; + if (!myProjectFileIndex.isInSource(virtualFile) && myProjectFileIndex.isInSource(file)) return true; + final int startOffset = getStartOffset(myNode); + final int endOffset = getEndOffset(myNode); + if (file.equals(virtualFile) && value >= startOffset && value < endOffset) continue; + + PsiElement target = getPsi(myNode); + TextRange rangeInElement = getRangeInElement(myNode); + + Integer fragmentStartOffsetInteger = startOffset; + SortedMap map = reportedRanges.subMap(fragmentStartOffsetInteger, endOffset); + int newFragmentSize = !map.isEmpty() ? 0:1; + + Iterator iterator = map.keySet().iterator(); + while(iterator.hasNext()) { + Integer next = iterator.next(); + iterator.remove(); + reportedFiles.remove(next); + reportedOffsetInOtherFiles.remove(next); + reportedPsi.remove(next); + newFragmentSize += fragmentSize.remove(next); + } + + reportedRanges.put(fragmentStartOffsetInteger, rangeInElement); + reportedFiles.put(fragmentStartOffsetInteger, file); + reportedOffsetInOtherFiles.put(fragmentStartOffsetInteger, value); + reportedPsi.put(fragmentStartOffsetInteger, target); + fragmentSize.put(fragmentStartOffsetInteger, newFragmentSize); + + return false; + } + return true; + } + + protected abstract TextRange getRangeInElement(T node); + protected abstract PsiElement getPsi(T node); + + protected abstract int getStartOffset(T node); + protected abstract int getEndOffset(T node); + } } From d63bcb17924d116455c17cd8a0b176142f534901 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 27 Oct 2014 19:05:24 +0100 Subject: [PATCH 54/55] handle wrapped CompilationCanceledExceptions --- .../src/org/jetbrains/jps/javac/JavacMain.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java index ac4f4a0b78fc..751b74b459e2 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/javac/JavacMain.java @@ -168,7 +168,16 @@ public class JavacMain { diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.ERROR, e.getMessage())); } catch (CompilationCanceledException ignored) { - diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.OTHER, "Compilation was canceled")); + handleCancelException(diagnosticConsumer); + } + catch (RuntimeException e) { + final Throwable cause = e.getCause(); + if (cause instanceof CompilationCanceledException) { + handleCancelException(diagnosticConsumer); + } + else { + throw e; + } } finally { fileManager.close(); @@ -179,6 +188,10 @@ public class JavacMain { return false; } + private static void handleCancelException(DiagnosticOutputConsumer diagnosticConsumer) { + diagnosticConsumer.report(new PlainMessageDiagnostic(Diagnostic.Kind.OTHER, "Compilation was canceled")); + } + private static List getSourceTransformers() { final Class transformerClass = JavaSourceTransformer.class; final ServiceLoader loader = ServiceLoader.load(transformerClass, transformerClass.getClassLoader()); From fac1f6a90694c4d1937c8d0f675779105ea5bf35 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Mon, 27 Oct 2014 19:08:00 +0100 Subject: [PATCH 55/55] logging pre-load process timings --- .../src/org/jetbrains/jps/cmdline/BuildMain.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java index e42d009d7122..7837b954da81 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java +++ b/jps/jps-builders/src/org/jetbrains/jps/cmdline/BuildMain.java @@ -16,6 +16,7 @@ package org.jetbrains.jps.cmdline; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.io.FileSystemUtil; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import io.netty.bootstrap.Bootstrap; @@ -124,9 +125,12 @@ public class BuildMain { final String projectPathToPreload = System.getProperty(PRELOAD_PROJECT_PATH, null); final String globalsPathToPreload = System.getProperty(PRELOAD_CONFIG_PATH, null); if (projectPathToPreload != null && globalsPathToPreload != null) { + final long preloadStart = System.currentTimeMillis(); final PreloadedData data = new PreloadedData(); ourPreloadedData = data; try { + FileSystemUtil.getAttributes(projectPathToPreload); // this will pre-load all FS optimizations + final BuildRunner runner = new BuildRunner(new JpsModelLoaderImpl(projectPathToPreload, globalsPathToPreload, null)); data.setRunner(runner); @@ -162,10 +166,11 @@ public class BuildMain { LOG.info("Error pre-loading FS state", e); fsState.clearAll(); } + LOG.info("Pre-loaded project model in " + (System.currentTimeMillis() - preloadStart) + " ms"); } catch (Throwable e) { LOG.info("Failed to pre-load project " + projectPathToPreload, e); - // just failed to preload the project, the situation will be handled later, when real build starts + // just failed to preload the project, the situation will be handled later, when real build starts } } else if (projectPathToPreload != null || globalsPathToPreload != null){