Merge remote-tracking branch 'origin/master'

This commit is contained in:
Roman Shevchenko
2014-10-31 17:45:00 +01:00
64 changed files with 567 additions and 259 deletions
@@ -546,9 +546,11 @@ public class BuildManager implements ApplicationComponent{
runCommand(new Runnable() {
@Override
public void run() {
LOG.info("Cancelling preloaded process for project " + projectPath);
Pair<RequestFuture<PreloadedProcessMessageHandler>, OSProcessHandler> pair = takePreloadedProcess(projectPath);
if (pair != null) {
final RequestFuture<PreloadedProcessMessageHandler> future = pair.first;
LOG.info("Cancelling preloaded process, sessionID=" + future.getRequestID());
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
@@ -559,6 +561,9 @@ public class BuildManager implements ApplicationComponent{
}
});
}
else {
LOG.info("takePreloadedProcess() returned null");
}
}
});
}
@@ -675,7 +680,7 @@ public class BuildManager implements ApplicationComponent{
try {
if (project.isDisposed()) {
if (usingPreloadedProcess) {
future.cancel(true);
future.cancel(false);
}
else {
return;
@@ -709,24 +714,23 @@ public class BuildManager implements ApplicationComponent{
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));
while (!processHandler.waitFor()) {
LOG.info("processHandler.waitFor() returned false for session " + sessionId + ", continue waiting");
}
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));
}
}
catch (Throwable e) {
execFailure = e;
@@ -75,11 +75,19 @@ class BuildMessageDispatcher extends SimpleChannelInboundHandlerAdapter<CmdlineR
}
public void cancelSession(UUID sessionId) {
LOG.info("Cancelling session " + sessionId);
if (myCanceledSessions.add(sessionId)) {
final Channel channel = getConnectedChannel(sessionId);
if (channel != null) {
channel.writeAndFlush(CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createCancelCommand()));
LOG.info("Cancelling session " + sessionId + "; message sent");
}
else {
LOG.info("Cancelling session " + sessionId + "; channel not ready");
}
}
else {
LOG.info("Cancelling session " + sessionId + "; already marked as 'cancelled'");
}
}
@@ -582,7 +582,7 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent
GenericDebuggerRunnerSettings settings,
boolean checkValidity)
throws ExecutionException {
return createDebugParameters(parameters, settings.LOCAL, settings.getTransport(), settings.DEBUG_PORT, checkValidity);
return createDebugParameters(parameters, settings.LOCAL, settings.getTransport(), settings.getDebugPort(), checkValidity);
}
private static class MyDebuggerStateManager extends DebuggerStateManager {
@@ -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.
@@ -132,7 +132,7 @@ public class GenericDebuggerParametersRunnerConfigurable extends SettingsEditor<
}
private int getTransport() {
if(myIsLocal) {
if (myIsLocal) {
return DebuggerSettings.getInstance().DEBUGGER_TRANSPORT;
}
else {
@@ -134,7 +134,7 @@ public class GenericDebuggerRunner extends JavaPatchableProgramRunner<GenericDeb
if (debuggerRunnerSettings != null) {
remoteConnection.setUseSockets(debuggerRunnerSettings.getTransport() == DebuggerSettings.SOCKET_TRANSPORT);
remoteConnection.setAddress(debuggerRunnerSettings.DEBUG_PORT);
remoteConnection.setAddress(debuggerRunnerSettings.getDebugPort());
}
return remoteConnection;
@@ -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.
@@ -17,23 +17,29 @@ package com.intellij.debugger.impl;
import com.intellij.debugger.settings.DebuggerSettings;
import com.intellij.execution.configurations.DebuggingRunnerData;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.openapi.util.DefaultJDOMExternalizer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import org.jdom.Element;
import com.intellij.execution.configurations.RunnerSettingsEx;
import com.intellij.util.xmlb.annotations.OptionTag;
import com.intellij.util.xmlb.annotations.Transient;
public class GenericDebuggerRunnerSettings implements RunnerSettings, DebuggingRunnerData {
public class GenericDebuggerRunnerSettings extends RunnerSettingsEx implements DebuggingRunnerData {
@Transient
@Deprecated
public String DEBUG_PORT = "";
public int TRANSPORT = DebuggerSettings.SOCKET_TRANSPORT;
public boolean LOCAL = true;
public GenericDebuggerRunnerSettings() {
@Override
@OptionTag("DEBUG_PORT")
public String getDebugPort() {
//noinspection deprecation
return DEBUG_PORT;
}
@Override
public String getDebugPort() {
return DEBUG_PORT;
public void setDebugPort(String port) {
//noinspection deprecation
DEBUG_PORT = port;
}
@Override
@@ -46,31 +52,12 @@ public class GenericDebuggerRunnerSettings implements RunnerSettings, DebuggingR
LOCAL = isLocal;
}
@Override
public void setDebugPort(String port) {
DEBUG_PORT = port;
@Transient
public int getTransport() {
return LOCAL ? DebuggerSettings.getInstance().DEBUGGER_TRANSPORT : TRANSPORT;
}
public void setTransport(int transport) {
TRANSPORT = transport;
}
@Override
public void readExternal(Element element) throws InvalidDataException {
DefaultJDOMExternalizer.readExternal(this, element);
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
DefaultJDOMExternalizer.writeExternal(this, element);
}
public int getTransport() {
if (LOCAL) {
return DebuggerSettings.getInstance().DEBUGGER_TRANSPORT;
}
else {
return TRANSPORT;
}
}
}
@@ -86,7 +86,7 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider {
public Pair<PsiElement, TextRange> findExpression(PsiElement element, boolean allowMethodCalls) {
PsiElement expression = null;
PsiElement parent = element.getParent();
if (parent instanceof PsiLiteralExpression) {
if (parent instanceof PsiLiteralExpression || parent instanceof PsiLambdaExpression) {
element = parent;
parent = parent.getParent();
}
@@ -95,7 +95,7 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider {
}
else if (parent instanceof PsiReferenceExpression) {
final PsiElement pparent = parent.getParent();
if (pparent instanceof PsiCallExpression) {
if (parent instanceof PsiMethodReferenceExpression || pparent instanceof PsiCallExpression) {
parent = pparent;
}
else if (pparent instanceof PsiReferenceExpression) {
@@ -116,11 +116,19 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider {
expression = parent;
}
}
else if (allowMethodCalls) {
PsiElement e = PsiTreeUtil.getParentOfType(element, PsiVariable.class, PsiExpression.class, PsiMethod.class);
if (e instanceof PsiNewExpression) {
if (((PsiNewExpression)e).getAnonymousClass() == null) {
expression = e;
else {
PsiElement castExpr = PsiTreeUtil.getParentOfType(element, PsiTypeCastExpression.class);
if (castExpr != null) {
if (allowMethodCalls || !DebuggerUtils.hasSideEffects(castExpr)) {
expression = castExpr;
}
}
else if (allowMethodCalls) {
PsiElement e = PsiTreeUtil.getParentOfType(element, PsiVariable.class, PsiExpression.class, PsiMethod.class);
if (e instanceof PsiNewExpression) {
if (((PsiNewExpression)e).getAnonymousClass() == null) {
expression = e;
}
}
}
}
@@ -16,6 +16,7 @@
package com.intellij.debugger.engine.evaluation;
import com.intellij.debugger.DebuggerBundle;
import com.intellij.openapi.util.text.StringUtil;
import com.sun.jdi.*;
/**
@@ -81,7 +82,12 @@ public class EvaluateExceptionUtil {
return th.getMessage();
}
else {
return th.getClass().getName() + " : " + (th.getMessage() != null ? th.getMessage() : "");
StringBuilder res = new StringBuilder(th.getClass().getName());
String message = th.getMessage();
if (!StringUtil.isEmpty(message)) {
res.append(" : ").append(message);
}
return res.toString();
}
}
}
@@ -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.
@@ -17,7 +17,6 @@ package com.intellij.execution;
import com.intellij.execution.configuration.RunConfigurationExtensionsManager;
import com.intellij.execution.configurations.RunConfigurationBase;
import com.intellij.execution.configurations.RuntimeConfigurationException;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
@@ -26,7 +25,7 @@ import com.intellij.openapi.diagnostic.Logger;
* Date: 10/4/11
*/
public class JavaRunConfigurationExtensionManager extends RunConfigurationExtensionsManager<RunConfigurationBase, RunConfigurationExtension> {
private static final Logger LOG = Logger.getInstance("#" + RunConfigurationExtension.class.getName());
private static final Logger LOG = Logger.getInstance(RunConfigurationExtension.class);
public JavaRunConfigurationExtensionManager() {
super(RunConfigurationExtension.EP_NAME);
@@ -36,7 +35,7 @@ public class JavaRunConfigurationExtensionManager extends RunConfigurationExtens
return ServiceManager.getService(JavaRunConfigurationExtensionManager.class);
}
public static void checkConfigurationIsValid(RunConfigurationBase configuration) throws RuntimeConfigurationException {
public static void checkConfigurationIsValid(RunConfigurationBase configuration) {
try {
getInstance().validateConfiguration(configuration, false);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 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.
@@ -56,7 +56,7 @@ public class ApplicationConfiguration extends ModuleBasedConfiguration<JavaRunCo
public boolean ENABLE_SWING_INSPECTOR;
public String ENV_VARIABLES;
private Map<String,String> myEnvs = new LinkedHashMap<String, String>();
private final Map<String,String> myEnvs = new LinkedHashMap<String, String>();
public boolean PASS_PARENT_ENVS = true;
public ApplicationConfiguration(final String name, final Project project, ApplicationConfigurationType applicationConfigurationType) {
@@ -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,10 +33,9 @@ import javax.swing.*;
public class ApplicationConfigurationType implements ConfigurationType {
private final ConfigurationFactory myFactory;
/**reflection*/
public ApplicationConfigurationType() {
myFactory = new ConfigurationFactoryEx(this) {
@Override
public RunConfiguration createTemplateConfiguration(Project project) {
return new ApplicationConfiguration("", project, ApplicationConfigurationType.this);
}
@@ -48,18 +47,22 @@ public class ApplicationConfigurationType implements ConfigurationType {
};
}
@Override
public String getDisplayName() {
return ExecutionBundle.message("application.configuration.name");
}
@Override
public String getConfigurationTypeDescription() {
return ExecutionBundle.message("application.configuration.description");
}
@Override
public Icon getIcon() {
return AllIcons.RunConfigurations.Application;
}
@Override
public ConfigurationFactory[] getConfigurationFactories() {
return new ConfigurationFactory[]{myFactory};
}
@@ -87,6 +90,7 @@ public class ApplicationConfigurationType implements ConfigurationType {
}
@Override
@NotNull
@NonNls
public String getId() {
@@ -97,5 +101,4 @@ public class ApplicationConfigurationType implements ConfigurationType {
public static ApplicationConfigurationType getInstance() {
return ConfigurationTypeUtil.findConfigurationType(ApplicationConfigurationType.class);
}
}
@@ -62,9 +62,11 @@ public class DefaultSymbolNavigationContributor implements ChooseByNameContribut
GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project);
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(project);
Condition<PsiMember> qualifiedMatcher = getQualifiedNameMatcher(pattern);
List<PsiMember> result = new ArrayList<PsiMember>();
for (PsiMethod method : cache.getMethodsByName(name, scope)) {
if (!method.isConstructor() && isOpenable(method) && !hasSuperMethod(method, scope)) {
if (!method.isConstructor() && isOpenable(method) && !hasSuperMethod(method, scope, qualifiedMatcher)) {
result.add(method);
}
}
@@ -87,13 +89,14 @@ public class DefaultSymbolNavigationContributor implements ChooseByNameContribut
return member.getContainingFile().getVirtualFile() != null;
}
private static boolean hasSuperMethod(PsiMethod method, GlobalSearchScope scope) {
private static boolean hasSuperMethod(PsiMethod method, GlobalSearchScope scope, Condition<PsiMember> qualifiedMatcher) {
PsiClass containingClass = method.getContainingClass();
if (containingClass == null) return false;
for (PsiMethod candidate : containingClass.findMethodsByName(method.getName(), true)) {
if (candidate.getContainingClass() != containingClass &&
PsiSearchScopeUtil.isInScope(scope, candidate) &&
qualifiedMatcher.value(candidate) &&
PsiSuperMethodImplUtil.isSuperMethodSmart(method, candidate)) {
return true;
}
@@ -118,20 +121,7 @@ public class DefaultSymbolNavigationContributor implements ChooseByNameContribut
PsiShortNamesCache cache = PsiShortNamesCache.getInstance(scope.getProject());
String completePattern = parameters.getCompletePattern();
final Condition<PsiMember> qualifiedMatcher;
if (completePattern.contains(".")) {
final MinusculeMatcher matcher = new MinusculeMatcher("*" + StringUtil.replace(completePattern, ".", ".*"), NameUtil.MatchingCaseSensitivity.NONE);
qualifiedMatcher = new Condition<PsiMember>() {
@Override
public boolean value(PsiMember member) {
String qualifiedName = PsiUtil.getMemberQualifiedName(member);
return qualifiedName != null && matcher.matches(qualifiedName);
}
};
} else {
//noinspection unchecked
qualifiedMatcher = Condition.TRUE;
}
final Condition<PsiMember> qualifiedMatcher = getQualifiedNameMatcher(completePattern);
//noinspection UnusedDeclaration
final Set<PsiMethod> collectedMethods = new THashSet<PsiMethod>();
@@ -163,13 +153,31 @@ public class DefaultSymbolNavigationContributor implements ChooseByNameContribut
Iterator<PsiMethod> iterator = collectedMethods.iterator();
while(iterator.hasNext()) {
PsiMethod method = iterator.next();
if (!hasSuperMethod(method, scope) && !processor.process(method)) return;
if (!hasSuperMethod(method, scope, qualifiedMatcher) && !processor.process(method)) return;
ProgressManager.checkCanceled();
iterator.remove();
}
}
}
private static Condition<PsiMember> getQualifiedNameMatcher(String completePattern) {
final Condition<PsiMember> qualifiedMatcher;
if (completePattern.contains(".")) {
final MinusculeMatcher matcher = new MinusculeMatcher("*" + StringUtil.replace(completePattern, ".", ".*"), NameUtil.MatchingCaseSensitivity.NONE);
qualifiedMatcher = new Condition<PsiMember>() {
@Override
public boolean value(PsiMember member) {
String qualifiedName = PsiUtil.getMemberQualifiedName(member);
return qualifiedName != null && matcher.matches(qualifiedName);
}
};
} else {
//noinspection unchecked
qualifiedMatcher = Condition.TRUE;
}
return qualifiedMatcher;
}
private static class MyComparator implements Comparator<PsiModifierListOwner>{
public static final MyComparator INSTANCE = new MyComparator();
@@ -384,7 +384,7 @@ public class TypeConversionUtil {
return aClass != null &&
bClass != null &&
aClass.getManager().areElementsEquivalent(aClass, bClass) &&
areSameArgumentTypes(aClass, resolveResult1.getSubstitutor(), resolveResult2.getSubstitutor());
areSameArgumentTypes(aClass, resolveResult1.getSubstitutor(), resolveResult2.getSubstitutor(), 1);
}
private static boolean areSameArgumentTypes(@NotNull PsiClass aClass, @NotNull PsiSubstitutor substitutor1, @NotNull PsiSubstitutor substitutor2) {
@@ -0,0 +1,5 @@
class ImmutableSet<E> {
void foo(final ImmutableSet<Class<String>> of) {
Object types = <error descr="Inconvertible types; cannot cast 'ImmutableSet<java.lang.Class<java.lang.String>>' to 'ImmutableSet<java.lang.Class<?>>'">(ImmutableSet<Class<?>>) of</error>;
}
}
@@ -430,6 +430,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
}
public void testNestedLevelsToCheckTypeArguments() throws Exception {
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
}
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
assertNotNull(collectionsClass);
@@ -239,6 +239,14 @@ class Intf {
assert !(sdkRun in noLibs)
}
public void "test super method not matching query qualifier"() {
def base = myFixture.addClass("class Base { void xpaint() {} }").methods[0]
def sub = myFixture.addClass("class Sub extends Base { void xpaint() {} }").methods[0]
assert getPopupElements(new GotoSymbolModel2(project), 'Ba.xpai', false) == [base]
assert getPopupElements(new GotoSymbolModel2(project), 'Su.xpai', false) == [sub]
}
private List<Object> getPopupElements(ChooseByNameModel model, String text, boolean checkboxState = false) {
return calcPopupElements(createPopup(model), text, checkboxState)
}
@@ -30,7 +30,7 @@ public abstract class CloudModuleBuilderContributionFactory {
public static CloudModuleBuilderContributionFactory getInstanceByType(ServerType<?> cloudType) {
for (CloudModuleBuilderContributionFactory contribution : EP_NAME.getExtensions()) {
if (contribution.getCloudType() == cloudType) {
if (contribution.getCloudType().equals(cloudType)) {
return contribution;
}
}
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
import com.intellij.codeInsight.highlighting.HighlightUsagesHandler;
import com.intellij.ide.DataManager;
import com.intellij.injected.editor.EditorWindow;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
@@ -40,9 +41,11 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
@@ -119,6 +122,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
for (int i = 0; i < files.length; i++) {
String path = files[i];
final String fullPath = FileUtil.toSystemIndependentName(getTestDataPath() + path);
allowRootAccess(fullPath);
VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath);
vFiles[i] = vFile;
assertNotNull("file " + fullPath + " not found", vFile);
@@ -129,8 +133,19 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
return configureByFiles(projectFile, vFiles);
}
private void allowRootAccess(final String filePath) {
VfsRootAccess.allowRootAccess(filePath);
Disposer.register(myTestRootDisposable, new Disposable() {
@Override
public void dispose() {
VfsRootAccess.disallowRootAccess(filePath);
}
});
}
protected VirtualFile configureByFile(@NonNls String filePath, @Nullable String projectRoot) throws Exception {
String fullPath = getTestDataPath() + filePath;
allowRootAccess(fullPath);
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
assertNotNull("file " + fullPath + " not found", vFile);
@@ -475,6 +490,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
String fullPath = getTestDataPath() + filePath;
allowRootAccess(fullPath);
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
assertNotNull("Cannot find file " + fullPath, vFile);
@@ -549,6 +565,7 @@ public abstract class CodeInsightTestCase extends PsiTestCase {
protected VirtualFile getVirtualFile(@NonNls @NotNull String filePath) {
String fullPath = getTestDataPath() + filePath;
allowRootAccess(fullPath);
final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
assertNotNull("file " + fullPath + " not found", vFile);
@@ -205,7 +205,7 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas
GenericDebuggerRunnerSettings debuggerRunnerSettings = new GenericDebuggerRunnerSettings();
debuggerRunnerSettings.LOCAL = true;
debuggerRunnerSettings.DEBUG_PORT = "3456";
debuggerRunnerSettings.setDebugPort("3456");
ExecutionEnvironment environment = new ExecutionEnvironmentBuilder(myProject, DefaultDebugExecutor.getDebugExecutorInstance())
.runnerSettings(debuggerRunnerSettings)
@@ -23,7 +23,14 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Project interface class.
* An object representing IntelliJ project.<br/>
*
* <li/>To get all its modules, use {@link com.intellij.openapi.module.ModuleManager#getModules()}<br/>
*
* <li/>To iterate over all project source files and directories, use {@code com.intellij.openapi.roots.ProjectFileIndex.SERVICE.getInstance(project).iterateContent(iterator)}<br/>
*
* <li/>To get the list of all open projects, use {@link com.intellij.openapi.project.ProjectManager#getOpenProjects()}
*
*/
public interface Project extends ComponentManager, AreaInstance {
@NonNls String DIRECTORY_STORE_FOLDER = ProjectCoreUtil.DIRECTORY_BASED_PROJECT_DIR;
@@ -17,12 +17,45 @@ package com.intellij.psi.util;
import org.jetbrains.annotations.NotNull;
/**
* A wrapper object that holds a computation ({@link #getValueProvider()}) and caches the result of the computation.<p/>
*
* The recommended way of creation is to use one of {@link com.intellij.psi.util.CachedValuesManager} methods, e.g.
* {@link com.intellij.psi.util.CachedValuesManager#getCachedValue(com.intellij.psi.PsiElement, CachedValueProvider)}
*
* When {@link #getValue()} is invoked the first time, the computation is run and its result is returned and remembered internally.
* In subsequent invocations, the result will be reused to avoid running the same code again and again.<p/>
*
* The computation will be re-run in the following circumstances:
* <ol>
* <li/>Garbage collector collects the result cached internally (it's kept via a {@link java.lang.ref.SoftReference}).
* <li/>IDEA determines that cached value is outdated because some its dependencies are changed. See
* {@link com.intellij.psi.util.CachedValueProvider.Result#getDependencyItems()}
* </ol>
*
* The implementation is thread-safe but not atomic, i.e. if several threads request the cached value simultaneously, the computation may
* be run concurrently on more than one thread.
*
* @param <T> The type of the computation result.
*
* @see com.intellij.psi.util.CachedValueProvider
* @see com.intellij.psi.util.CachedValuesManager
*/
public interface CachedValue<T> {
/**
* @return cached value if it's already computed and not outdated, newly computed value otherwise
*/
T getValue();
/**
* @return the object calculating the value to cache
*/
@NotNull
CachedValueProvider<T> getValueProvider();
/**
* @return whether there is a cached result inside this object and it's not outdated
*/
boolean hasUpToDateValue();
}
@@ -22,15 +22,31 @@ import org.jetbrains.annotations.Nullable;
import java.util.Collection;
/**
* A computation (typically an anonymous class) to used in {@link com.intellij.psi.util.CachedValue} to cache some computation result.
* @param <T> the type of the cached value
*/
public interface CachedValueProvider<T> {
/**
* @return result object holding the value to cache and the dependencies indicating when that value will be outdated
*/
@Nullable
Result<T> compute();
/**
* The object holding the value to cache and the dependencies indicating when that value will be outdated
* @param <T> the type of the cached value
*/
class Result<T> {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.util.CachedValueProvider.Result");
private final T myValue;
private final Object[] myDependencyItems;
/**
* Constructor
* @see #getDependencyItems()
*/
public Result(@Nullable T value, @NotNull Object... dependencyItems) {
myValue = value;
myDependencyItems = dependencyItems;
@@ -50,19 +66,49 @@ public interface CachedValueProvider<T> {
return myValue;
}
/**
* Dependency items are used in cached values to remember the state of the environment as it was when the value was computed
* and to compare that to the state of the world when querying {@link CachedValue#getValue()}. The state is remembered as
* a collection of {@code long} values representing some time stamps. When changes occur, these stamps are incremented.<p/>
*
* Dependencies can be following:
* <ul>
* <li/>Instances of {@link com.intellij.openapi.util.ModificationTracker} returning stamps explicitly
* <li/>Constant fields of {@link PsiModificationTracker} class, e.g. {@link com.intellij.psi.util.PsiModificationTracker#MODIFICATION_COUNT}
* <li/>{@link com.intellij.psi.PsiElement} or {@link com.intellij.openapi.vfs.VirtualFile} objects. Such cache would be dropped
* on any change in the corresponding file
* </ul>
*
* @return the dependency items
* @see com.intellij.openapi.util.ModificationTracker
* @see com.intellij.psi.util.PsiModificationTracker
* @see com.intellij.openapi.roots.ProjectRootModificationTracker
*/
@NotNull
public Object[] getDependencyItems() {
return myDependencyItems;
}
/**
* Creates a result
* @see #getDependencyItems()
*/
public static <T> Result<T> createSingleDependency(@Nullable T value, @NotNull Object dependency) {
return create(value, dependency);
}
/**
* Creates a result
* @see #getDependencyItems()
*/
public static <T> Result<T> create(@Nullable T value, @NotNull Object... dependencies) {
return new Result<T>(value, dependencies);
}
/**
* Creates a result
* @see #getDependencyItems()
*/
public static <T> Result<T> create(@Nullable T value, @NotNull Collection<?> dependencies) {
return new Result<T>(value, ArrayUtil.toObjectArray(dependencies));
}
@@ -28,6 +28,15 @@ import org.jetbrains.annotations.NotNull;
import java.util.concurrent.ConcurrentMap;
/**
* A service used to create and store {@link com.intellij.psi.util.CachedValue} objects.<p/>
*
* By default cached values are stored in the user data of associated objects implementing {@link com.intellij.openapi.util.UserDataHolder}.
*
* @see #createCachedValue(CachedValueProvider, boolean)
* @see #getCachedValue(com.intellij.psi.PsiElement, CachedValueProvider)
* @see #getCachedValue(com.intellij.openapi.util.UserDataHolder, CachedValueProvider)
*/
public abstract class CachedValuesManager {
private static final NotNullLazyKey<CachedValuesManager, Project> INSTANCE_KEY = ServiceManager.createLazyKey(CachedValuesManager.class);
@@ -36,7 +45,9 @@ public abstract class CachedValuesManager {
}
/**
* Creates new CachedValue instance with given provider.
* Creates new CachedValue instance with given provider. If the return value is marked as trackable, it's treated as
* yet another dependency and must comply its specification. See {@link com.intellij.psi.util.CachedValueProvider.Result#getDependencyItems()} for
* the details.
*
* @param provider computes values.
* @param trackValue if value tracking required. T should be trackable in this case.
@@ -47,6 +58,10 @@ public abstract class CachedValuesManager {
@NotNull
public abstract <T,P> ParameterizedCachedValue<T,P> createParameterizedCachedValue(@NotNull ParameterizedCachedValueProvider<T,P> provider, boolean trackValue);
/**
* Rarely needed because it tracks the return value as a dependency.
* @return a CachedValue like in {@link #createCachedValue(CachedValueProvider, boolean)}, with trackable return value.
*/
@NotNull
public <T> CachedValue<T> createCachedValue(@NotNull CachedValueProvider<T> provider) {
return createCachedValue(provider, true);
@@ -93,9 +108,18 @@ public abstract class CachedValuesManager {
@NotNull CachedValueProvider<T> provider,
boolean trackValue);
/**
* Create a cached value with the given provider and non-tracked return value, store it in the first argument's user data. If it's already stored, reuse it.
* @return The cached value
*/
public <T, D extends UserDataHolder> T getCachedValue(@NotNull D dataHolder, @NotNull CachedValueProvider<T> provider) {
return getCachedValue(dataHolder, this.<T>getKeyForClass(provider.getClass()), provider, false);
}
/**
* Create a cached value with the given provider and non-tracked return value, store it in PSI element's user data. If it's already stored, reuse it.
* @return The cached value
*/
public static <T> T getCachedValue(@NotNull PsiElement psi, @NotNull CachedValueProvider<T> provider) {
CachedValuesManager manager = getManager(psi.getProject());
return manager.getCachedValue(psi, manager.<T>getKeyForClass(provider.getClass()), provider, false);
@@ -22,11 +22,37 @@ import com.intellij.openapi.util.ModificationTracker;
import com.intellij.util.messages.Topic;
import org.jetbrains.annotations.NotNull;
/**
* An interface used to support tracking of common PSI modifications. It has three main usage patterns:
* <ol>
* <li/> Get a stamp of current PSI state. This stamp is increased when PSI is modified, allowing other subsystems
* to check if PSI has changed since they accessed it last time. This can be used to flush and rebuild various internal caches.
* See {@link #getModificationCount()}, {@link #getJavaStructureModificationCount()}, {@link #getOutOfCodeBlockModificationCount()}
*
* <li/> Make a {@link com.intellij.psi.util.CachedValue} instance dependent on a specific PSI modification tracker.
* To achieve that, one should can one of the constants in this interface as {@link com.intellij.psi.util.CachedValueProvider.Result}
* dependencies.
* See {@link #MODIFICATION_COUNT}, {@link #JAVA_STRUCTURE_MODIFICATION_COUNT}, {@link #OUT_OF_CODE_BLOCK_MODIFICATION_COUNT}
*
* <li/> Subscribe to any PSI change (for example, to drop caches in the listener manually).
* See {@link com.intellij.psi.util.PsiModificationTracker.Listener}
*
* </ol>
*/
public interface PsiModificationTracker extends ModificationTracker {
/**
* Provides a way to get the instance of {@link com.intellij.psi.util.PsiModificationTracker} corresponding to a given project.
* @see #getInstance(com.intellij.openapi.project.Project)
*/
class SERVICE {
private SERVICE() {
}
/**
* @param project
* @return The instance of {@link com.intellij.psi.util.PsiModificationTracker} corresponding to the given project.
*/
public static PsiModificationTracker getInstance(Project project) {
return ServiceManager.getService(project, PsiModificationTracker.class);
}
@@ -34,42 +60,71 @@ public interface PsiModificationTracker extends ModificationTracker {
/**
* This key can be passed as a dependency in a {@link com.intellij.psi.util.CachedValueProvider}.
* The corresponding {@link com.intellij.psi.util.CachedValue} will then be flushed on every physical PSI change.
* @see #getModificationCount()
*/
Key MODIFICATION_COUNT = Key.create("MODIFICATION_COUNT");
/**
* This key can be passed as a dependency in a {@link com.intellij.psi.util.CachedValueProvider}.
* The corresponding {@link com.intellij.psi.util.CachedValue} will then be flushed on every physical PSI change that doesn't happen inside a Java code block.
* @see #getOutOfCodeBlockModificationCount()
*/
Key OUT_OF_CODE_BLOCK_MODIFICATION_COUNT = Key.create("OUT_OF_CODE_BLOCK_MODIFICATION_COUNT");
/**
* This key can be passed as a dependency in a {@link com.intellij.psi.util.CachedValueProvider}.
* The corresponding {@link com.intellij.psi.util.CachedValue} will then be flushed on every physical PSI change that can affect Java structure and resolve.
* @see #getJavaStructureModificationCount()
*/
Key JAVA_STRUCTURE_MODIFICATION_COUNT = Key.create("JAVA_STRUCTURE_MODIFICATION_COUNT");
/**
* A topic to subscribe for all PSI modification count changes.
* @see com.intellij.util.messages.MessageBus
*/
Topic<Listener> TOPIC = new Topic<Listener>("modification tracker", Listener.class, Topic.BroadcastDirection.TO_PARENT);
/**
* Tracks any PSI modification.
* @return current counter value.
* @return current counter value. Increased whenever any physical PSI is changed.
*/
@Override
long getModificationCount();
/**
* @return Same as {@link #getJavaStructureModificationCount()}, but also includes changes in non-Java files, e.g. XML. Rarely needed.
*/
long getOutOfCodeBlockModificationCount();
/**
* @return an object returning {@link #getOutOfCodeBlockModificationCount()}
*/
@NotNull
ModificationTracker getOutOfCodeBlockModificationTracker();
/**
* Tracks structural Java modifications, i.e. the ones on class/method/field/file level. Modifications inside method bodies are not tracked.
* Useful to work with resolve caches that only depend on Java structure, and not the method code.
* @return current counter value. Increased whenever any physical PSI in Java structure is changed.
*/
long getJavaStructureModificationCount();
/**
* @return an object returning {@link #getJavaStructureModificationCount()}
*/
@NotNull
ModificationTracker getJavaStructureModificationTracker();
/**
* A listener to be notified on any PSI modification count change (which happens on any physical PSI change).
* @see #TOPIC
*/
interface Listener {
/**
* A method invoked on Swing EventDispatchThread each time any physical PSI change is detected
*/
void modificationCountChanged();
}
}
@@ -57,7 +57,7 @@ public class FileElement extends LazyParseableElement implements FileASTNode, Ge
@Override
public LighterAST getLighterAST() {
final IFileElementType contentType = (IFileElementType)getElementType();
assert contentType instanceof ILightStubFileElementType;
assert contentType instanceof ILightStubFileElementType:contentType;
LighterAST tree;
if (!isParsed()) {
@@ -65,7 +65,7 @@ public class FileElement extends LazyParseableElement implements FileASTNode, Ge
if (tree == null) {
final ILightStubFileElementType<?> type = (ILightStubFileElementType)contentType;
tree = new FCTSBackedLighterAST(getCharTable(), type.parseContentsLight(this));
putUserData(ourTreeKey, new SoftReference<LighterAST>(tree));
tree = SoftReference.dereference(putUserDataIfAbsent(ourTreeKey, new SoftReference<LighterAST>(tree)));
}
}
else {
@@ -11,12 +11,11 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.options.SettingsEditorGroup;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMUtil;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.StringInterner;
import com.intellij.util.containers.WeakStringInterner;
import gnu.trove.THashMap;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -33,28 +32,25 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
public static final Key<List<Element>> RUN_EXTENSIONS = Key.create("run.extension.elements");
private static final String EXT_ID_ATTR = "ID";
private static final String EXTENSION_ROOT_ATTR = "EXTENSION";
protected final ExtensionPointName<T> myExtensionPointName;
private final StringInterner myInterner = new WeakStringInterner();
public RunConfigurationExtensionsManager(ExtensionPointName<T> extensionPointName) {
myExtensionPointName = extensionPointName;
}
public void readExternal(@NotNull final U configuration,
@NotNull final Element parentNode) throws InvalidDataException {
final List<Element> children = parentNode.getChildren(getExtensionRootAttr());
final Map<String, T> extensions = ContainerUtil.newHashMap();
public void readExternal(@NotNull U configuration, @NotNull Element parentNode) throws InvalidDataException {
Map<String, T> extensions = new THashMap<String, T>();
for (T extension : getApplicableExtensions(configuration)) {
extensions.put(extension.getSerializationId(), extension);
}
List<Element> children = parentNode.getChildren(getExtensionRootAttr());
// if some of extensions settings weren't found we should just keep it because some plugin with extension
// may be turned off
boolean found = true;
for (Object o : children) {
final Element element = (Element)o;
final String extensionName = element.getAttributeValue(getIdAttrName());
final T extension = extensions.remove(extensionName);
for (Element element : children) {
final T extension = extensions.remove(element.getAttributeValue(getIdAttrName()));
if (extension != null) {
extension.readExternal(configuration, element);
}
@@ -65,9 +61,7 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
if (!found) {
List<Element> copy = new ArrayList<Element>(children.size());
for (Element child : children) {
Element clone = child.clone();
JDOMUtil.internElement(clone, myInterner);
copy.add(clone);
copy.add(child.clone());
}
configuration.putCopyableUserData(RUN_EXTENSIONS, copy);
}
@@ -81,31 +75,30 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
return EXTENSION_ROOT_ATTR;
}
public void writeExternal(@NotNull final U configuration,
@NotNull final Element parentNode) throws WriteExternalException {
public void writeExternal(@NotNull U configuration, @NotNull Element parentNode) {
final TreeMap<String, Element> map = ContainerUtil.newTreeMap();
final List<Element> elements = configuration.getCopyableUserData(RUN_EXTENSIONS);
if (elements != null) {
for (Element el : elements) {
map.put(el.getAttributeValue(getIdAttrName()), el.clone());
for (Element element : elements) {
map.put(element.getAttributeValue(getIdAttrName()), element.clone());
}
}
for (T extension : getApplicableExtensions(configuration)) {
Element el = new Element(getExtensionRootAttr());
el.setAttribute(getIdAttrName(), extension.getSerializationId());
Element element = new Element(getExtensionRootAttr());
element.setAttribute(getIdAttrName(), extension.getSerializationId());
try {
extension.writeExternal(configuration, el);
extension.writeExternal(configuration, element);
}
catch (WriteExternalException e) {
catch (WriteExternalException ignored) {
map.remove(extension.getSerializationId());
continue;
}
map.put(extension.getSerializationId(), el);
map.put(extension.getSerializationId(), element);
}
for (Element val : map.values()) {
parentNode.addContent(val);
for (Element values : map.values()) {
parentNode.addContent(values);
}
}
@@ -160,8 +153,8 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
}
}
protected List<T> getApplicableExtensions(@NotNull final U configuration) {
final List<T> extensions = new ArrayList<T>();
protected List<T> getApplicableExtensions(@NotNull U configuration) {
List<T> extensions = new SmartList<T>();
for (T extension : Extensions.getExtensions(myExtensionPointName)) {
if (extension.isApplicableFor(configuration)) {
extensions.add(extension);
@@ -170,8 +163,8 @@ public class RunConfigurationExtensionsManager<U extends RunConfigurationBase, T
return extensions;
}
protected List<T> getEnabledExtensions(@NotNull final U configuration, @Nullable RunnerSettings runnerSettings) {
final List<T> extensions = new ArrayList<T>();
protected List<T> getEnabledExtensions(@NotNull U configuration, @Nullable RunnerSettings runnerSettings) {
List<T> extensions = new SmartList<T>();
for (T extension : Extensions.getExtensions(myExtensionPointName)) {
if (extension.isApplicableFor(configuration) && extension.isEnabledFor(configuration, runnerSettings)) {
extensions.add(extension);
@@ -18,7 +18,6 @@ package com.intellij.execution.configurations;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.JDOMExternalizable;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.SmartHashSet;
@@ -204,13 +203,13 @@ public class LogFileOptions implements JDOMExternalizable {
try {
setCharset(Charset.forName(charsetStr));
}
catch (Exception e) {
catch (Exception ignored) {
setCharset(Charset.defaultCharset());
}
}
@Override
public void writeExternal(Element element) throws WriteExternalException {
public void writeExternal(Element element) {
element.setAttribute(PATH, FileUtil.toSystemIndependentName(getPathPattern()));
element.setAttribute(CHECKED, String.valueOf(isEnabled()));
element.setAttribute(SKIPPED, String.valueOf(isSkipContent()));
@@ -64,15 +64,6 @@ public abstract class ModuleBasedConfiguration<ConfigurationModule extends RunCo
myModule.setModule(module);
}
@Override
public void readExternal(Element element) throws InvalidDataException{
super.readExternal(element);
}
@Override
public void writeExternal(Element element) throws WriteExternalException{
super.writeExternal(element);
}
protected void readModule(final Element element) throws InvalidDataException {
myModule.readExternal(element);
}
@@ -236,10 +236,10 @@ public abstract class RunConfigurationBase extends UserDataHolderBase
element.addContent(fileOutputPathElement);
}
if (myShowConsoleOnStdOut) {//default value shouldn't be written
element.setAttribute(SHOW_CONSOLE_ON_STD_OUT, String.valueOf(myShowConsoleOnStdOut));
element.setAttribute(SHOW_CONSOLE_ON_STD_OUT, String.valueOf(true));
}
if (myShowConsoleOnStdErr) {//default value shouldn't be written
element.setAttribute(SHOW_CONSOLE_ON_STD_ERR, String.valueOf(myShowConsoleOnStdErr));
element.setAttribute(SHOW_CONSOLE_ON_STD_ERR, String.valueOf(true));
}
}
@@ -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.
@@ -0,0 +1,35 @@
package com.intellij.execution.configurations;
import com.intellij.util.xmlb.Accessor;
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
import com.intellij.util.xmlb.XmlSerializer;
import gnu.trove.THashSet;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
public abstract class RunnerSettingsEx implements RunnerSettings {
private final Set<String> mySerializedAccessorNameTracker = new THashSet<String>();
private final SkipDefaultValuesSerializationFilters mySerializationFilter = new SkipDefaultValuesSerializationFilters() {
@Override
protected boolean accepts(@NotNull Accessor accessor, @NotNull Object bean, @Nullable Object beanValue) {
if (mySerializedAccessorNameTracker.contains(accessor.getName())) {
return true;
}
return super.accepts(accessor, bean, beanValue);
}
};
@Override
public final void readExternal(Element element) {
mySerializedAccessorNameTracker.clear();
XmlSerializer.deserializeInto(this, element, mySerializedAccessorNameTracker);
}
@Override
public final void writeExternal(Element element) {
XmlSerializer.serializeInto(this, element, mySerializationFilter);
}
}
@@ -28,8 +28,6 @@ import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.SelectionModel;
@@ -40,16 +38,17 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.arrangement.engine.ArrangementEngine;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -59,6 +58,7 @@ import javax.swing.*;
import javax.swing.event.HyperlinkEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
@@ -170,6 +170,12 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
}
}
if (file == null) return;
if (!showDialog && processChangedTextOnly && isChangeNotTrackedForFile(project, file)) {
processChangedTextOnly = false;
}
final TextRange range;
final boolean processSelectedText = !processWholeFile && hasSelection;
if (processSelectedText) {
@@ -186,7 +192,7 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
new ReformatCodeProcessor(project, file, range, !processSelectedText && processChangedTextOnly).run();
}
if (rearrangeEntries && file != null && editor != null) {
if (rearrangeEntries && editor != null) {
SelectionModel selectionModel = editor.getSelectionModel();
final TextRange rangeToUse = selectionModel.hasSelection()
? TextRange.create(selectionModel.getSelectionStart(), selectionModel.getSelectionEnd())
@@ -195,6 +201,19 @@ public class ReformatCodeAction extends AnAction implements DumbAware {
}
}
private static boolean isChangeNotTrackedForFile(@NotNull Project project, @NotNull PsiFile file) {
boolean isUnderVcs = VcsUtil.isFileUnderVcs(project, VcsUtil.getFilePath(file.getVirtualFile()));
if (!isUnderVcs) return true;
ChangeListManagerImpl changeListManager = ChangeListManagerImpl.getInstanceImpl(project);
List<VirtualFile> unversionedFiles = changeListManager.getUnversionedFiles();
if (unversionedFiles.contains(file.getVirtualFile())) {
return true;
}
return false;
}
@Nullable
private static DirectoryFormattingOptions getDirectoryFormattingOptions(@NotNull Project project, @NotNull PsiDirectory dir) {
LayoutDirectoryDialog dialog = new LayoutDirectoryDialog(
@@ -102,7 +102,7 @@ public class EnvironmentVariablesComponent extends LabeledComponent<TextFieldWit
}
}
public static void writeExternal(Element element, Map<String, String> envs) {
public static void writeExternal(@NotNull Element element, @NotNull Map<String, String> envs) {
final Element envsElement = new Element(ENVS);
for (String envName : envs.keySet()) {
final Element envElement = new Element(ENV);
@@ -24,7 +24,8 @@ import com.intellij.openapi.extensions.ExtensionException;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.StringInterner;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -44,6 +45,18 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
private static final String CONFIGURATION_ELEMENT = "ConfigurationWrapper";
@NonNls
private static final String RUNNER_ID = "RunnerId";
private static final Comparator<Element> RUNNER_COMPARATOR = new Comparator<Element>() {
@Override
public int compare(@NotNull Element o1, @NotNull Element o2) {
String attributeValue1 = o1.getAttributeValue(RUNNER_ID);
if (attributeValue1 == null) {
return 1;
}
return StringUtil.compare(attributeValue1, o2.getAttributeValue(RUNNER_ID), false);
}
};
@NonNls
private static final String CONFIGURATION_TYPE_ATTRIBUTE = "type";
@NonNls
@@ -57,7 +70,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
//@NonNls
//public static final String UNIQUE_ID = "id";
@NonNls
protected static final String DUMMY_ELEMENT_NANE = "dummy";
protected static final String DUMMY_ELEMENT_NAME = "dummy";
@NonNls
private static final String TEMPORARY_ATTRIBUTE = "temporary";
@NonNls
@@ -65,7 +78,6 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
@NonNls
public static final String SINGLETON = "singleton";
/** for compatibility */
@NonNls
private static final String TEMP_CONFIGURATION = "tempConfiguration";
@@ -74,11 +86,13 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
private RunConfiguration myConfiguration;
private boolean myIsTemplate;
private final Map<ProgramRunner, RunnerSettings> myRunnerSettings = new HashMap<ProgramRunner, RunnerSettings>();
private List<Element> myUnloadedRunnerSettings = null;
private final Map<ProgramRunner, RunnerSettings> myRunnerSettings = new THashMap<ProgramRunner, RunnerSettings>();
private List<Element> myUnloadedRunnerSettings;
// to avoid changed files
private final Set<String> myLoadedRunnerSettings = new THashSet<String>();
private final Map<ProgramRunner, ConfigurationPerRunnerSettings> myConfigurationPerRunnerSettings = new HashMap<ProgramRunner, ConfigurationPerRunnerSettings>();
private List<Element> myUnloadedConfigurationPerRunnerSettings = null;
private final Map<ProgramRunner, ConfigurationPerRunnerSettings> myConfigurationPerRunnerSettings = new THashMap<ProgramRunner, ConfigurationPerRunnerSettings>();
private List<Element> myUnloadedConfigurationPerRunnerSettings;
private boolean myTemporary;
private boolean myEditBeforeRun;
@@ -146,6 +160,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
@Override
public String getUniqueID() {
//noinspection deprecation
return myConfiguration.getType().getDisplayName() + "." + myConfiguration.getName() +
(myConfiguration instanceof UnknownRunConfiguration ? myConfiguration.getUniqueID() : "");
//if (myID == null) {
@@ -220,21 +235,23 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
if (myIsTemplate) {
myConfiguration = myManager.getConfigurationTemplate(factory).getConfiguration();
} else {
final String name = element.getAttributeValue(NAME_ATTR);
}
else {
// shouldn't call createConfiguration since it calls StepBeforeRunProviders that
// may not be loaded yet. This creates initialization order issue.
myConfiguration = myManager.doCreateConfiguration(name, factory, false);
myConfiguration = myManager.doCreateConfiguration(element.getAttributeValue(NAME_ATTR), factory, false);
}
myConfiguration.readExternal(element);
List<Element> runners = element.getChildren(RUNNER_ELEMENT);
myUnloadedRunnerSettings = null;
StringInterner interner = new StringInterner();
for (final Element runnerElement : runners) {
if (myUnloadedRunnerSettings != null) {
myUnloadedRunnerSettings.clear();
}
myLoadedRunnerSettings.clear();
for (Element runnerElement : element.getChildren(RUNNER_ELEMENT)) {
String id = runnerElement.getAttributeValue(RUNNER_ID);
ProgramRunner runner = RunnerRegistry.getInstance().findRunnerById(id);
if (runner != null) {
myLoadedRunnerSettings.add(id);
RunnerSettings settings = createRunnerSettings(runner);
if (settings != null) {
settings.readExternal(runnerElement);
@@ -242,36 +259,38 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
myRunnerSettings.put(runner, settings);
}
else {
if (myUnloadedRunnerSettings == null) myUnloadedRunnerSettings = new SmartList<Element>();
JDOMUtil.internElement(runnerElement, interner);
if (myUnloadedRunnerSettings == null) {
myUnloadedRunnerSettings = new SmartList<Element>();
}
myUnloadedRunnerSettings.add(runnerElement);
}
}
List configurations = element.getChildren(CONFIGURATION_ELEMENT);
myUnloadedConfigurationPerRunnerSettings = null;
for (final Object configuration : configurations) {
Element configurationElement = (Element) configuration;
String id = configurationElement.getAttributeValue(RUNNER_ID);
ProgramRunner runner = RunnerRegistry.getInstance().findRunnerById(id);
for (Iterator<Element> iterator = element.getChildren(CONFIGURATION_ELEMENT).iterator(); iterator.hasNext(); ) {
Element configurationElement = iterator.next();
ProgramRunner runner = RunnerRegistry.getInstance().findRunnerById(configurationElement.getAttributeValue(RUNNER_ID));
if (runner != null) {
ConfigurationPerRunnerSettings settings = myConfiguration.createRunnerSettings(new InfoProvider(runner));
if (settings != null) {
settings.readExternal(configurationElement);
}
myConfigurationPerRunnerSettings.put(runner, settings);
} else {
if (myUnloadedConfigurationPerRunnerSettings == null)
myUnloadedConfigurationPerRunnerSettings = new ArrayList<Element>(1);
}
else {
if (myUnloadedConfigurationPerRunnerSettings == null) {
myUnloadedConfigurationPerRunnerSettings = new SmartList<Element>();
}
iterator.remove();
myUnloadedConfigurationPerRunnerSettings.add(configurationElement);
}
}
}
@Override
public void writeExternal(final Element element) throws WriteExternalException {
public void writeExternal(Element element) throws WriteExternalException {
final ConfigurationFactory factory = myConfiguration.getFactory();
if (!(myConfiguration instanceof UnknownRunConfiguration)) {
element.setAttribute(TEMPLATE_FLAG_ATTRIBUTE, String.valueOf(myIsTemplate));
if (!myIsTemplate) {
@@ -284,21 +303,22 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
}
//element.setAttribute(UNIQUE_ID, getUniqueID());
if (isEditBeforeRun()) element.setAttribute(EDIT_BEFORE_RUN, String.valueOf(true));
if (isEditBeforeRun()) {
element.setAttribute(EDIT_BEFORE_RUN, String.valueOf(true));
}
if (myWasSingletonSpecifiedExplicitly || mySingleton != factory.isConfigurationSingletonByDefault()) {
element.setAttribute(SINGLETON, String.valueOf(mySingleton));
}
if (myTemporary) {
element.setAttribute(TEMPORARY_ATTRIBUTE, Boolean.toString(myTemporary));
element.setAttribute(TEMPORARY_ATTRIBUTE, Boolean.toString(true));
}
}
myConfiguration.writeExternal(element);
if (!(myConfiguration instanceof UnknownRunConfiguration)) {
final Comparator<Element> runnerComparator = createRunnerComparator();
writeRunnerSettings(runnerComparator, element);
writeConfigurationPerRunnerSettings(runnerComparator, element);
writeRunnerSettings(RUNNER_COMPARATOR, element);
writeConfigurationPerRunnerSettings(RUNNER_COMPARATOR, element);
}
}
@@ -325,16 +345,23 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
}
}
private void writeRunnerSettings(final Comparator<Element> runnerComparator, final Element element) throws WriteExternalException {
final ArrayList<Element> runnerSettings = new ArrayList<Element>();
private void writeRunnerSettings(@NotNull Comparator<Element> runnerComparator, @NotNull Element element) throws WriteExternalException {
List<Element> runnerSettings = new SmartList<Element>();
for (ProgramRunner runner : myRunnerSettings.keySet()) {
RunnerSettings settings = myRunnerSettings.get(runner);
boolean wasLoaded = myLoadedRunnerSettings.contains(runner.getRunnerId());
if (settings == null && !wasLoaded) {
continue;
}
Element runnerElement = new Element(RUNNER_ELEMENT);
if (settings != null) {
settings.writeExternal(runnerElement);
}
runnerElement.setAttribute(RUNNER_ID, runner.getRunnerId());
runnerSettings.add(runnerElement);
if (wasLoaded || !JDOMUtil.isEmpty(runnerElement)) {
runnerElement.setAttribute(RUNNER_ID, runner.getRunnerId());
runnerSettings.add(runnerElement);
}
}
if (myUnloadedRunnerSettings != null) {
for (Element unloadedRunnerSetting : myUnloadedRunnerSettings) {
@@ -357,7 +384,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
myConfiguration.checkConfiguration();
if (myConfiguration instanceof RunConfigurationBase) {
final RunConfigurationBase runConfigurationBase = (RunConfigurationBase) myConfiguration;
Set<ProgramRunner> runners = new HashSet<ProgramRunner>();
Set<ProgramRunner> runners = new THashSet<ProgramRunner>();
runners.addAll(myRunnerSettings.keySet());
runners.addAll(myConfigurationPerRunnerSettings.keySet());
for (ProgramRunner runner : runners) {
@@ -379,24 +406,6 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
return true;
}
private static Comparator<Element> createRunnerComparator() {
return new Comparator<Element>() {
@Override
public int compare(final Element o1, final Element o2) {
final String attributeValue1 = o1.getAttributeValue(RUNNER_ID);
if (attributeValue1 == null) {
return 1;
}
final String attributeValue2 = o2.getAttributeValue(RUNNER_ID);
if (attributeValue2 == null) {
return -1;
}
return attributeValue1.compareTo(attributeValue2);
}
};
}
@Override
public RunnerSettings getRunnerSettings(@NotNull ProgramRunner runner) {
if (!myRunnerSettings.containsKey(runner)) {
@@ -405,7 +414,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
myRunnerSettings.put(runner, runnerSettings);
return runnerSettings;
}
catch (AbstractMethodError e) {
catch (AbstractMethodError ignored) {
LOG.error("Update failed for: " + myConfiguration.getType().getDisplayName() + ", runner: " + runner.getRunnerId(), new ExtensionException(runner.getClass()));
}
}
@@ -442,7 +451,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
RunnerSettings data = createRunnerSettings(runner);
myRunnerSettings.put(runner, data);
if (data != null) {
Element temp = new Element(DUMMY_ELEMENT_NANE);
Element temp = new Element(DUMMY_ELEMENT_NAME);
RunnerSettings templateSettings = template.myRunnerSettings.get(runner);
if (templateSettings != null) {
templateSettings.writeExternal(temp);
@@ -455,7 +464,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
ConfigurationPerRunnerSettings data = myConfiguration.createRunnerSettings(new InfoProvider(runner));
myConfigurationPerRunnerSettings.put(runner, data);
if (data != null) {
Element temp = new Element(DUMMY_ELEMENT_NANE);
Element temp = new Element(DUMMY_ELEMENT_NAME);
ConfigurationPerRunnerSettings templateSettings = template.myConfigurationPerRunnerSettings.get(runner);
if (templateSettings != null) {
templateSettings.writeExternal(temp);
@@ -479,7 +488,7 @@ public class RunnerAndConfigurationSettingsImpl implements JDOMExternalizable, C
}
@Override
public int compareTo(final Object o) {
public int compareTo(@NotNull final Object o) {
if (o instanceof RunnerAndConfigurationSettings) {
return getName().compareTo(((RunnerAndConfigurationSettings) o).getName());
}
@@ -327,7 +327,7 @@ public class AllFileTemplatesConfigurable implements SearchableConfigurable, Con
});
myMainPanel = new JPanel(new BorderLayout());
Splitter splitter = new Splitter();
Splitter splitter = new Splitter(false, 0.3f);
JPanel leftPanel = new JPanel(new BorderLayout());
leftPanel.add(myToolBar, BorderLayout.NORTH);
leftPanel.add(myTabbedPane.getComponent(), BorderLayout.CENTER);
@@ -42,6 +42,7 @@ import com.intellij.openapi.editor.ex.util.LayeredLexerEditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighter;
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.fileTypes.ex.FileTypeChooser;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
@@ -316,9 +317,14 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc
myTemplate.setText(myTemplateEditor.getDocument().getText());
String name = myNameField.getText();
String extension = myExtensionField.getText();
if (name.length() == 0 || !isValidFilename(name + "." + extension)) {
String filename = name + "." + extension;
if (name.length() == 0 || !isValidFilename(filename)) {
throw new ConfigurationException(IdeBundle.message("error.invalid.template.file.name.or.extension"));
}
FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(filename);
if (fileType == UnknownFileType.INSTANCE) {
FileTypeChooser.associateFileType(filename);
}
myTemplate.setName(name);
myTemplate.setExtension(extension);
myTemplate.setReformatCode(myAdjustBox.isSelected());
@@ -15,7 +15,6 @@
*/
package com.intellij.execution.configurations;
import com.google.common.collect.Maps;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.util.ArrayUtil;
@@ -24,6 +23,7 @@ import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -54,7 +54,7 @@ public class PtyCommandLine extends GeneralCommandLine {
@NotNull
public Process startProcessWithPty(@NotNull List<String> commands, boolean console) throws IOException {
Map<String, String> env = Maps.newHashMap();
Map<String, String> env = new HashMap<String, String>();
setupEnvironment(env);
if (isRedirectErrorStream()) {
@@ -16,10 +16,10 @@
package com.intellij.execution.process;
import com.google.common.collect.Lists;
import com.intellij.execution.ExecutionException;
import com.intellij.execution.configurations.GeneralCommandLine;
import com.intellij.openapi.util.Key;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import java.nio.charset.Charset;
@@ -32,7 +32,7 @@ import java.util.List;
public class ColoredProcessHandler extends OSProcessHandler implements AnsiEscapeDecoder.ColoredTextAcceptor {
private final AnsiEscapeDecoder myAnsiEscapeDecoder = new AnsiEscapeDecoder();
private final List<AnsiEscapeDecoder.ColoredTextAcceptor> myColoredTextListeners = Lists.newArrayList();
private final List<AnsiEscapeDecoder.ColoredTextAcceptor> myColoredTextListeners = ContainerUtil.newArrayList();
public ColoredProcessHandler(final GeneralCommandLine commandLine) throws ExecutionException {
super(commandLine.createProcess(), commandLine.getCommandLineString(), commandLine.getCharset());
@@ -26,6 +26,7 @@ import com.intellij.openapi.options.ExternalInfo;
import com.intellij.openapi.options.ExternalizableScheme;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.text.StringTokenizer;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
@@ -279,12 +280,12 @@ public class AbstractFileType extends UserFileType<AbstractFileType> implements
private static Element writeKeywords(Set<String> keywords, String tagName, Element highlightingElement) {
if (keywords.size() == 0 && !ELEMENT_KEYWORDS.equals(tagName)) return null;
Element keywordsElement = new Element(tagName);
String[] strings = keywords.toArray(new String[keywords.size()]);
String[] strings = ArrayUtil.toStringArray(keywords);
Arrays.sort(strings);
StringBuilder keywordsAttribute = new StringBuilder();
for (final String keyword : strings) {
if (keyword.indexOf(SEMICOLON) == -1) {
if (!keyword.contains(SEMICOLON)) {
if (keywordsAttribute.length() != 0) keywordsAttribute.append(SEMICOLON);
keywordsAttribute.append(keyword);
} else {
@@ -19,8 +19,8 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.popup.AbstractPopup;
import com.intellij.ui.popup.OurHeavyWeightPopup;
import com.intellij.util.Alarm;
import com.intellij.util.JBHiDPIScaledImage;
import com.intellij.util.ui.UIUtil;
@@ -42,7 +42,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
private final TipComponent myTipComponent;
private boolean myEnabled = Registry.is("ide.expansion.hints.enabled");
private Hint myHint;
private Popup myPopup;
private KeyType myKey;
private Rectangle myKeyItemBounds;
private BufferedImage myImage;
@@ -293,7 +293,7 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
if (location == null) {
hideHint();
}
else if (myHint == null) {
else if (myPopup == null) {
showHint(location);
}
else {
@@ -320,34 +320,36 @@ public abstract class AbstractExpandableItemsHandler<KeyType, ComponentType exte
private void hideHint() {
myUpdateAlarm.cancelAllRequests();
if (myHint != null) {
myHint.hide();
myHint = null;
if (myPopup != null) {
myPopup.hide();
myPopup = null;
repaintKeyItem();
}
myKey = null;
}
public boolean isShowing() {
return myHint != null && myHint.isVisible();
return myPopup != null;
}
private void showHint(Point location) {
assert myHint == null;
assert myPopup == null;
if (!myComponent.isShowing()) {
return;
}
myHint = new ExpansionHint(myTipComponent);
myHint.show(myComponent, location.x, location.y, myComponent, new HintHint(myComponent, location));
SwingUtilities.convertPointToScreen(location, myComponent);
myPopup = new OurHeavyWeightPopup(myComponent, myTipComponent, location.x, location.y);
myPopup.show();
repaintKeyItem();
}
private void repaintHint(Point location) {
if (myHint != null && myKey != null && myComponent.isShowing()) {
myHint.setLocation(new RelativePoint(myComponent, location));
if (myPopup != null && myKey != null && myComponent.isShowing()) {
SwingUtilities.convertPointToScreen(location, myComponent);
SwingUtilities.getWindowAncestor(myTipComponent).setLocation(location);
myTipComponent.repaint();
repaintKeyItem();
}
@@ -5,13 +5,9 @@
<body>
<p>In <span class="product">&productName;</span>, you can have multiple cursors.
Having pressed <span class="shortcut">Alt+Shift</span>, click the left mouse button
at the desired position to set additional cursors in the editor.</p>
<p>Press <span class="shortcut">&shortcut:EditorEscape;</span> to remove all the additional cursors
but one that resides at the line at caret.</p>
<p>Add several cursors to your editor. To do that,
press <span class="shortcut">Ctrl</span> twice and hold the key, and then press the arrow keys.</p>
</p>
<p class="image"><img src="images/multicursor.png"></p>
</body>
</html>
@@ -6,7 +6,7 @@
<p>Clone the cursor strictly upwards or downwards. To do that,
press <span class="shortcut">&shortcut:GotoAction;</span> twice, type
press <span class="shortcut">&shortcut:GotoAction;</span>, type
<span class="control">Clone caret</span>, and then choose the desired action.</p>
<p class="image"><img src="images/multicursor1.png"></p>
</body>
@@ -6,5 +6,8 @@
<p>
Scratch files allows you experiment and prototype right in the editor,
without creating any project files.</p>
<p>To create a scratch file, press <span class="shortcut">&shortcut:NewScratchFile;</span>,
and then select its language.</p>
<p class="image"><img src="images/scratch.png"></p>
</body>
</html>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 18 KiB

@@ -165,6 +165,15 @@ public class ServerConnectionImpl<D extends DeploymentConfiguration> implements
@Override
public void succeeded() {
synchronized (myRemoteDeployments) {
for (DeploymentImpl deployment : new ArrayList<DeploymentImpl>(myDeployments)) {
DeploymentImpl oldDeployment = myRemoteDeployments.get(deployment.getName());
if (oldDeployment != null) {
oldDeployment.changeState(oldDeployment.getStatus(),
deployment.getStatus(), deployment.getStatusText(), deployment.getRuntime());
myDeployments.remove(deployment);
myDeployments.add(oldDeployment);
}
}
myRemoteDeployments.clear();
for (DeploymentImpl deployment : myDeployments) {
myRemoteDeployments.put(deployment.getName(), deployment);
@@ -7,6 +7,7 @@ import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.runtime.log.LoggingHandler;
import org.jetbrains.annotations.NotNull;
@@ -18,6 +19,7 @@ public class LoggingHandlerImpl implements LoggingHandler {
public LoggingHandlerImpl(@NotNull Project project) {
myConsole = TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole();
Disposer.register(project, myConsole);
}
@NotNull
@@ -18,8 +18,18 @@ package com.intellij.openapi.util;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
/**
* Allows to store custom user data within a model object. This might be preferred to an explicit Map with model objects as keys and
* custom data in values because this allows the data to be garbage-collected together with the values.
*/
public interface UserDataHolder {
/**
* @return a user data value associated with this object. Doesn't require read action.
*/
@Nullable <T> T getUserData(@NotNull Key<T> key);
/**
* Add a new user data value to this object. Doesn't require write action.
*/
<T> void putUserData(@NotNull Key<T> key, @Nullable T value);
}
@@ -1827,7 +1827,7 @@ public class StringUtil extends StringUtilRt {
@Contract(pure = true)
public static int indexOf(@NotNull CharSequence sequence, @NotNull CharSequence infix) {
for (int i = 0; i < sequence.length() - infix.length(); i++) {
for (int i = 0; i <= sequence.length() - infix.length(); i++) {
if (startsWith(sequence, i, infix)) {
return i;
}
@@ -100,11 +100,12 @@ class BeanBinding implements Binding {
}
}
if (element == null) {
element = new Element(myTagName);
}
Object node = binding.serialize(o, element, filter);
if (node != null) {
if (element == null) {
element = new Element(myTagName);
}
if (node instanceof org.jdom.Attribute) {
element.setAttribute((org.jdom.Attribute)node);
}
@@ -129,10 +130,12 @@ class BeanBinding implements Binding {
if (element == null) {
return o;
}
return deserializeInto(XmlSerializerImpl.newInstance(myBeanClass), element);
Object instance = XmlSerializerImpl.newInstance(myBeanClass);
deserializeInto(instance, element, null);
return instance;
}
public Object deserializeInto(@NotNull Object result, @NotNull Element element) {
public void deserializeInto(@NotNull Object result, @NotNull Element element, @Nullable Set<String> accessorNameTracker) {
Set<Binding> bindings = myPropertyBindings.keySet();
MultiMap<Binding, Object> data = MultiMap.createSmartList();
nextNode:
@@ -155,10 +158,11 @@ class BeanBinding implements Binding {
}
for (Binding binding : data.keySet()) {
if (accessorNameTracker != null) {
accessorNameTracker.add(myPropertyBindings.get(binding).getName());
}
binding.deserialize(result, ArrayUtil.toObjectArray(data.get(binding)));
}
return result;
}
@Override
@@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.Set;
public class XmlSerializer {
private static final SerializationFilter TRUE_FILTER = new SerializationFilter() {
@@ -101,8 +102,12 @@ public class XmlSerializer {
}
public static void deserializeInto(@NotNull Object bean, @NotNull Element element) {
deserializeInto(bean, element, null);
}
public static void deserializeInto(@NotNull Object bean, @NotNull Element element, @Nullable Set<String> accessorNameTracker) {
try {
((BeanBinding)XmlSerializerImpl.getBinding(bean.getClass())).deserializeInto(bean, element);
((BeanBinding)XmlSerializerImpl.getBinding(bean.getClass())).deserializeInto(bean, element, accessorNameTracker);
}
catch (XmlSerializationException e) {
throw e;
@@ -281,4 +281,11 @@ public class StringUtilTest extends TestCase {
assertFalse(Comparing.equal(StringUtil.stringHashCodeIgnoreWhitespaces("xyx"), StringUtil.stringHashCodeIgnoreWhitespaces("xxx")));
assertFalse(Comparing.equal(StringUtil.stringHashCodeIgnoreWhitespaces("xyx"), StringUtil.stringHashCodeIgnoreWhitespaces("xYx")));
}
public void testContains() {
assertTrue(StringUtil.contains("1", "1"));
assertFalse(StringUtil.contains("1", "12"));
assertTrue(StringUtil.contains("12", "1"));
assertTrue(StringUtil.contains("12", "2"));
}
}
@@ -17,12 +17,14 @@ package com.intellij.vcs.log.statistics;
import com.intellij.internal.statistic.AbstractApplicationUsagesCollector;
import com.intellij.internal.statistic.CollectUsagesException;
import com.intellij.internal.statistic.beans.ConvertUsagesUtil;
import com.intellij.internal.statistic.beans.GroupDescriptor;
import com.intellij.internal.statistic.beans.UsageDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.vcs.log.VcsLogProvider;
import com.intellij.vcs.log.graph.PermanentGraph;
import com.intellij.vcs.log.impl.VcsLogContentProvider;
@@ -46,12 +48,12 @@ public class VcsLogRepoSizeCollector extends AbstractApplicationUsagesCollector
VcsLogUiImpl ui = logManager.getLogUi();
if (ui != null) {
PermanentGraph<Integer> permanentGraph = ui.getDataPack().getPermanentGraph();
Map<VcsKey, Integer> rootCounts = groupRootsByVcs(ui.getDataPack().getLogProviders());
MultiMap<VcsKey, VirtualFile> groupedRoots = groupRootsByVcs(ui.getDataPack().getLogProviders());
Set<UsageDescriptor> usages = ContainerUtil.newHashSet();
usages.add(new UsageDescriptor("vcs.log.commit.count", permanentGraph.getAllCommits().size()));
for (Map.Entry<VcsKey, Integer> entry : rootCounts.entrySet()) {
usages.add(new RootUsage(entry.getKey(), entry.getValue()));
for (VcsKey vcs : groupedRoots.keySet()) {
usages.add(new RootUsage(vcs, groupedRoots.get(vcs).size()));
}
return usages;
}
@@ -60,18 +62,12 @@ public class VcsLogRepoSizeCollector extends AbstractApplicationUsagesCollector
}
@NotNull
private static Map<VcsKey, Integer> groupRootsByVcs(@NotNull Map<VirtualFile, VcsLogProvider> providers) {
Map<VcsKey, Integer> result = ContainerUtil.newHashMap();
private static MultiMap<VcsKey, VirtualFile> groupRootsByVcs(@NotNull Map<VirtualFile, VcsLogProvider> providers) {
MultiMap<VcsKey, VirtualFile> result = MultiMap.create();
for (Map.Entry<VirtualFile, VcsLogProvider> entry : providers.entrySet()) {
VcsLogProvider provider = entry.getValue();
VcsKey vcs = provider.getSupportedVcs();
Integer count = result.get(vcs);
if (count == null) {
result.put(vcs, 1);
}
else {
result.put(vcs, count + 1);
}
VirtualFile root = entry.getKey();
VcsKey vcs = entry.getValue().getSupportedVcs();
result.putValue(vcs, root);
}
return result;
}
@@ -85,7 +81,7 @@ public class VcsLogRepoSizeCollector extends AbstractApplicationUsagesCollector
@SuppressWarnings("StringToUpperCaseOrToLowerCaseWithoutLocale")
private static class RootUsage extends UsageDescriptor {
RootUsage(VcsKey vcs, int value) {
super("vcs.log." + vcs.getName().toLowerCase() + ".root.count", value);
super(ConvertUsagesUtil.ensureProperKey("vcs.log." + vcs.getName().toLowerCase() + ".root.count"), value);
}
}
+2 -3
View File
@@ -5,9 +5,8 @@
<body>
<p>You don't need to leave <span class="product">&productName;</span> to work with your favorite shell. Just choose
<span class="control">Tools | Open Terminal</span> on the main menu,
and enjoy using the embedded local terminal. </p>
<p>You don't need to leave <span class="product">&productName;</span> to work with your favorite shell.
Just click the Terminal tool window button, and enjoy using the embedded local terminal. </p>
<p class="image"><img src="images/terminal.png"></p>
</body>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 14 KiB