Merge remote-tracking branch 'origin/master'
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 79 KiB |
|
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 228 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 346 KiB After Width: | Height: | Size: 374 KiB |
@@ -0,0 +1,14 @@
|
||||
package com.intellij.execution.configurations;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface CompatibilityAwareRunProfile {
|
||||
/**
|
||||
* Checks whether the run configuration is compatible with the configuration passed as a parameter
|
||||
* and may still run if the configuration passed as a parameter starts as well.
|
||||
*
|
||||
* @param configuration the run configuration to check a compatibility to run with the current configuration.
|
||||
* @return true if the configuration can still run along side with the configuration passed as parameter, false otherwise.
|
||||
*/
|
||||
boolean isCompatibleWith(@NotNull RunConfiguration configuration);
|
||||
}
|
||||
@@ -38,7 +38,8 @@ import java.util.List;
|
||||
*
|
||||
* @author dyoma
|
||||
*/
|
||||
public abstract class RunConfigurationBase extends UserDataHolderBase implements RunConfiguration, TargetAwareRunProfile {
|
||||
public abstract class RunConfigurationBase extends UserDataHolderBase
|
||||
implements RunConfiguration, TargetAwareRunProfile, CompatibilityAwareRunProfile {
|
||||
private final ConfigurationFactory myFactory;
|
||||
private final Project myProject;
|
||||
private String myName = "";
|
||||
@@ -119,6 +120,11 @@ public abstract class RunConfigurationBase extends UserDataHolderBase implements
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCompatibleWith(@NotNull RunConfiguration configuration) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public final boolean equals(final Object obj) {
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public class RunManagerConfig {
|
||||
public static final int MIN_RECENT_LIMIT = 0;
|
||||
@NonNls private static final String RECENTS_LIMIT = "recentsLimit";
|
||||
@NonNls private static final String RESTART_REQUIRES_CONFIRMATION = "restartRequiresConfirmation";
|
||||
@NonNls private static final String STOP_INCOMPATIBLE_REQUIRES_CONFIRMATION = "stopIncompatibleRequiresConfirmation";
|
||||
|
||||
public RunManagerConfig(PropertiesComponent propertiesComponent,
|
||||
RunManagerImpl manager) {
|
||||
@@ -52,7 +53,15 @@ public class RunManagerConfig {
|
||||
return myPropertiesComponent.getBoolean(RESTART_REQUIRES_CONFIRMATION, true);
|
||||
}
|
||||
|
||||
public void setRestartRequiresConfirmation (boolean restartRequiresConfirmation) {
|
||||
public void setRestartRequiresConfirmation(boolean restartRequiresConfirmation) {
|
||||
myPropertiesComponent.setValue(RESTART_REQUIRES_CONFIRMATION, String.valueOf(restartRequiresConfirmation));
|
||||
}
|
||||
|
||||
public boolean isStopIncompatibleRequiresConfirmation() {
|
||||
return myPropertiesComponent.getBoolean(STOP_INCOMPATIBLE_REQUIRES_CONFIRMATION, true);
|
||||
}
|
||||
|
||||
public void setStopIncompatibleRequiresConfirmation(boolean stopIncompatibleRequiresConfirmation) {
|
||||
myPropertiesComponent.setValue(STOP_INCOMPATIBLE_REQUIRES_CONFIRMATION, String.valueOf(stopIncompatibleRequiresConfirmation));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ import com.intellij.openapi.vfs.VirtualFileManager;
|
||||
import com.intellij.ui.docking.DockManager;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Predicate;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -143,8 +145,9 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
|
||||
@Override
|
||||
public void run() {
|
||||
for (BeforeRunTask task : activeTasks) {
|
||||
if (myProject.isDisposed())
|
||||
if (myProject.isDisposed()) {
|
||||
return;
|
||||
}
|
||||
BeforeRunTaskProvider<BeforeRunTask> provider = BeforeRunTaskProvider.getProvider(myProject, task.getProviderId());
|
||||
if (provider == null) {
|
||||
LOG.warn("Cannot find BeforeRunTaskProvider for id='" + task.getProviderId() + "'");
|
||||
@@ -313,26 +316,43 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
|
||||
RunnerRegistry.getInstance().getRunner(executor.getId(),
|
||||
configuration != null && configuration.getConfiguration() != null
|
||||
? configuration.getConfiguration()
|
||||
: runProfile);
|
||||
: runProfile
|
||||
);
|
||||
if (configuration != null && runner == null) {
|
||||
LOG.error("Cannot find runner for " + configuration.getName());
|
||||
return;
|
||||
}
|
||||
|
||||
final List<RunContentDescriptor> descriptorsToStop = new ArrayList<RunContentDescriptor>();
|
||||
final List<RunContentDescriptor> runningConfigurationsOfTheSameType = new ArrayList<RunContentDescriptor>();
|
||||
final List<RunContentDescriptor> runningIncompatibleConfigurations = new ArrayList<RunContentDescriptor>();
|
||||
|
||||
if (configuration != null) {
|
||||
runningIncompatibleConfigurations.addAll(getIncompatibleRunningDescriptors(configuration));
|
||||
}
|
||||
if (configuration != null && configuration.isSingleton()) {
|
||||
descriptorsToStop.addAll(getRunningDescriptors(configuration));
|
||||
runningConfigurationsOfTheSameType.addAll(getRunningDescriptorsOfTheSameConfigType(configuration));
|
||||
}
|
||||
else if (currentDescriptor != null) {
|
||||
descriptorsToStop.add(currentDescriptor);
|
||||
runningConfigurationsOfTheSameType.add(currentDescriptor);
|
||||
}
|
||||
|
||||
if (!descriptorsToStop.isEmpty()) {
|
||||
if (configuration != null && (descriptorsToStop.size() > 1 || currentDescriptor == null || descriptorsToStop.get(0) != currentDescriptor) &&
|
||||
!userApprovesStop(project, configuration.getName(), descriptorsToStop.size())) {
|
||||
return;
|
||||
final List<RunContentDescriptor> runningConfigurationsToStop = ContainerUtil.concat(runningConfigurationsOfTheSameType,
|
||||
runningIncompatibleConfigurations);
|
||||
if (!runningConfigurationsToStop.isEmpty()) {
|
||||
if (configuration != null) {
|
||||
if (!runningConfigurationsOfTheSameType.isEmpty()
|
||||
&& (runningConfigurationsOfTheSameType.size() > 1 ||
|
||||
currentDescriptor == null ||
|
||||
runningConfigurationsOfTheSameType.get(0) != currentDescriptor) &&
|
||||
!userApprovesStopForSameTypeConfigurations(project, configuration.getName(), runningConfigurationsOfTheSameType.size())) {
|
||||
return;
|
||||
}
|
||||
if (!runningIncompatibleConfigurations.isEmpty()
|
||||
&& !userApprovesStopForIncompatibleConfigurations(myProject, configuration.getName(), runningIncompatibleConfigurations)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (RunContentDescriptor descriptor : descriptorsToStop) {
|
||||
for (RunContentDescriptor descriptor : runningConfigurationsToStop) {
|
||||
stop(descriptor);
|
||||
}
|
||||
}
|
||||
@@ -344,14 +364,15 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
|
||||
awaitingTerminationAlarm.addRequest(this, 100);
|
||||
return;
|
||||
}
|
||||
for (RunContentDescriptor descriptor : descriptorsToStop) {
|
||||
for (RunContentDescriptor descriptor : runningConfigurationsOfTheSameType) {
|
||||
ProcessHandler processHandler = descriptor.getProcessHandler();
|
||||
if (processHandler != null && !processHandler.isProcessTerminated()) {
|
||||
awaitingTerminationAlarm.addRequest(this, 100);
|
||||
return;
|
||||
}
|
||||
}
|
||||
start(project, context, runner, runProfile, runnerSettings, configurationPerRunnerSettings, configuration, executor, target, currentDescriptor);
|
||||
start(project, context, runner, runProfile, runnerSettings, configurationPerRunnerSettings, configuration, executor, target,
|
||||
currentDescriptor);
|
||||
}
|
||||
};
|
||||
awaitingTerminationAlarm.addRequest(runnable, 50);
|
||||
@@ -380,7 +401,7 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean userApprovesStop(Project project, String configName, int instancesCount) {
|
||||
private static boolean userApprovesStopForSameTypeConfigurations(Project project, String configName, int instancesCount) {
|
||||
RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(project);
|
||||
final RunManagerConfig config = runManager.getConfig();
|
||||
if (!config.isRestartRequiresConfirmation()) return true;
|
||||
@@ -420,10 +441,90 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
|
||||
Messages.getQuestionIcon(), option) == Messages.OK;
|
||||
}
|
||||
|
||||
private List<RunContentDescriptor> getRunningDescriptors(RunnerAndConfigurationSettings configuration) {
|
||||
private static boolean userApprovesStopForIncompatibleConfigurations(Project project,
|
||||
String configName,
|
||||
List<RunContentDescriptor> runningIncompatibleDescriptors) {
|
||||
RunManagerImpl runManager = RunManagerImpl.getInstanceImpl(project);
|
||||
final RunManagerConfig config = runManager.getConfig();
|
||||
if (!config.isStopIncompatibleRequiresConfirmation()) return true;
|
||||
|
||||
DialogWrapper.DoNotAskOption option = new DialogWrapper.DoNotAskOption() {
|
||||
@Override
|
||||
public boolean isToBeShown() {
|
||||
return config.isStopIncompatibleRequiresConfirmation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setToBeShown(boolean value, int exitCode) {
|
||||
config.setStopIncompatibleRequiresConfirmation(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeHidden() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSaveOptionsOnCancel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDoNotShowMessage() {
|
||||
return CommonBundle.message("dialog.options.do.not.show");
|
||||
}
|
||||
};
|
||||
|
||||
final StringBuilder names = new StringBuilder();
|
||||
for (final RunContentDescriptor descriptor : runningIncompatibleDescriptors) {
|
||||
String name = descriptor.getDisplayName();
|
||||
if (names.length() > 0) {
|
||||
names.append(", ");
|
||||
}
|
||||
names.append(name.equals(null) || name.isEmpty() ? ExecutionBundle.message("run.configuration.no.name")
|
||||
: String.format("'%s'", name));
|
||||
}
|
||||
|
||||
//noinspection DialogTitleCapitalization
|
||||
return Messages.showOkCancelDialog(
|
||||
project,
|
||||
ExecutionBundle.message("stop.incompatible.confirmation.message",
|
||||
configName, names.toString(), runningIncompatibleDescriptors.size()),
|
||||
ExecutionBundle.message("incompatible.configuration.is.running.dialog.title", runningIncompatibleDescriptors.size()),
|
||||
ExecutionBundle.message("stop.incompatible.confirmation.button.text"),
|
||||
CommonBundle.message("button.cancel"),
|
||||
Messages.getQuestionIcon(), option) == Messages.OK;
|
||||
}
|
||||
|
||||
private List<RunContentDescriptor> getRunningDescriptorsOfTheSameConfigType(
|
||||
@NotNull final RunnerAndConfigurationSettings configurationAndSettings) {
|
||||
return getRunningDescriptors(new Predicate<RunnerAndConfigurationSettings>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable RunnerAndConfigurationSettings runningConfigurationAndSettings) {
|
||||
return configurationAndSettings == runningConfigurationAndSettings;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<RunContentDescriptor> getIncompatibleRunningDescriptors(
|
||||
@NotNull final RunnerAndConfigurationSettings configurationAndSettings) {
|
||||
final RunConfiguration configurationToCheckCompatibility = configurationAndSettings.getConfiguration();
|
||||
return getRunningDescriptors(new Predicate<RunnerAndConfigurationSettings>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable RunnerAndConfigurationSettings runningConfigurationAndSettings) {
|
||||
if (runningConfigurationAndSettings == null) return false;
|
||||
RunConfiguration runningConfiguration = runningConfigurationAndSettings.getConfiguration();
|
||||
if (runningConfiguration == null || !(runningConfiguration instanceof CompatibilityAwareRunProfile)) return false;
|
||||
return !((CompatibilityAwareRunProfile)runningConfiguration).isCompatibleWith(configurationToCheckCompatibility);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<RunContentDescriptor> getRunningDescriptors(
|
||||
Predicate<RunnerAndConfigurationSettings> condition) {
|
||||
List<RunContentDescriptor> result = new ArrayList<RunContentDescriptor>();
|
||||
for (Trinity<RunContentDescriptor, RunnerAndConfigurationSettings, Executor> trinity : myRunningConfigurations) {
|
||||
if (trinity.getSecond() == configuration) {
|
||||
if (condition.apply(trinity.getSecond())) {
|
||||
ProcessHandler processHandler = trinity.getFirst().getProcessHandler();
|
||||
if (processHandler != null && !processHandler.isProcessTerminating() && !processHandler.isProcessTerminated()) {
|
||||
result.add(trinity.getFirst());
|
||||
@@ -433,7 +534,6 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static void stop(RunContentDescriptor runContentDescriptor) {
|
||||
ProcessHandler processHandler = runContentDescriptor != null ? runContentDescriptor.getProcessHandler() : null;
|
||||
if (processHandler == null) {
|
||||
|
||||
@@ -74,6 +74,7 @@ template.settings.configurable.display.name=Template Settings
|
||||
default.run.configuration.name=<unnamed>
|
||||
|
||||
process.is.running.dialog.title=Process ''{0}'' Is Running
|
||||
incompatible.configuration.is.running.dialog.title=Incompatible Configuration{0, choice, 1# Is|2#s Are} Running
|
||||
button.disconnect=Disconnect
|
||||
button.terminate=Terminate
|
||||
disconnect.process.confirmation.text=Do you want to disconnect from the process ''{0}''?
|
||||
@@ -162,6 +163,7 @@ run.configuration.use.alternate.jre.checkbox=Use alternative &JRE:
|
||||
run.configuration.select.alternate.jre.label=Select Alternative JRE
|
||||
run.configuration.select.jre.dir.label=Select directory with JRE to run with
|
||||
run.configuration.arguments.help.panel.copy.action.name=Copy
|
||||
run.configuration.no.name=<No Name>
|
||||
terminating.process.progress.title=Terminating ''{0}''
|
||||
terminating.process.progress.kill=Kill process
|
||||
waiting.for.vm.detach.progress.text=Waiting for process detach
|
||||
@@ -170,6 +172,8 @@ rerun.configuration.action.name=Rerun ''{0}''
|
||||
rerun.singleton.confirmation.message=''{0}'' is single-instance run configuration.\nAre you sure you want to stop {1, choice, 1#the running one|2#{1, number} running instances}?
|
||||
rerun.confirmation.button.text=Stop and Rerun
|
||||
rerun.confirmation.checkbox=Confirm rerun with process termination
|
||||
stop.incompatible.confirmation.message=''{0}'' run configuration is not compatible with {2, choice, 1#currently running {1} configuration.|2#following running configurations:\n{1}}\nAre you sure you want to stop {2, choice, 1#incompatible running instance|2#{2, number} incompatible running instances}?
|
||||
stop.incompatible.confirmation.button.text=Stop incompatible
|
||||
run.configuration.dump.threads.action.name=Dump Threads
|
||||
run.configuration.exit.action.name=Exit
|
||||
run.error.message.title=Run Error
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports any variables declared as or uses of <b>java.lang.StringBuffer</b> and <b>java.lang.StringBuilder</b>
|
||||
which are effectively constant. These may be replaced with <b>java.lang.String</b> expressions which results in simpler and possibly
|
||||
more efficient code.
|
||||
which can be replaced with a single <b>java.lang.String</b> concatenation. Using a <b>String</b> concatenation
|
||||
makes the code shorter and simpler.
|
||||
This inspection only reports when the resulting concatenation is at least as efficient or more efficient than the original
|
||||
<b>StringBuffer</b> or <b>StringBuilder</b> use.
|
||||
<!-- tooltip end -->
|
||||
<p>
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.siyeh.ig.threading;
|
||||
|
||||
import com.intellij.codeInspection.InspectionProfileEntry;
|
||||
import com.siyeh.ig.LightInspectionTestCase;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class DoubleCheckedLockingInspectionTest extends LightInspectionTestCase {
|
||||
|
||||
public void testSimple() {
|
||||
doTest("class A {" +
|
||||
" private boolean initialized;\n" +
|
||||
" private void initialize() {\n" +
|
||||
" /*Double-checked locking*/if/**/ (initialized == false) {\n" +
|
||||
" synchronized (this) {\n" +
|
||||
" if (initialized == false) {\n" +
|
||||
" initialized = true;\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testVolatile() {
|
||||
doTest("class X {" +
|
||||
" private volatile boolean initialized;\n" +
|
||||
" private void initialize() {\n" +
|
||||
" if (initialized == false) {\n" +
|
||||
" synchronized (this) {\n" +
|
||||
" if (initialized == false) {\n" +
|
||||
" initialized = true;\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
" }\n" +
|
||||
"}");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InspectionProfileEntry getInspection() {
|
||||
final DoubleCheckedLockingInspection inspection = new DoubleCheckedLockingInspection();
|
||||
inspection.ignoreOnVolatileVariables = true;
|
||||
return inspection;
|
||||
}
|
||||
}
|
||||