Merge remote-tracking branch 'origin/master'

This commit is contained in:
Vladimir Orlov
2014-03-11 13:22:46 +04:00
11 changed files with 217 additions and 20 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 KiB

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

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;
}
}