Merge remote-tracking branch 'origin/master'
@@ -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>
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 9.8 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 9.3 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 53 KiB |
|
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 14 KiB |