Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2014-08-05 01:58:16 +04:00
780 changed files with 1251 additions and 9635 deletions
+3
View File
@@ -119,6 +119,7 @@
<module fileurl="file://$PROJECT_DIR$/platform/lvcs-impl/lvcs-impl.iml" filepath="$PROJECT_DIR$/platform/lvcs-impl/lvcs-impl.iml" group="platform" />
<module fileurl="file://$PROJECT_DIR$/python/main_idea_python_plugin.iml" filepath="$PROJECT_DIR$/python/main_idea_python_plugin.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/python/main_pycharm_ce.iml" filepath="$PROJECT_DIR$/python/main_pycharm_ce.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/python/edu/main_pycharm_edu.iml" filepath="$PROJECT_DIR$/python/edu/main_pycharm_edu.iml" group="python/educational" />
<module fileurl="file://$PROJECT_DIR$/java/manifest/manifest.iml" filepath="$PROJECT_DIR$/java/manifest/manifest.iml" group="java" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/maven.iml" filepath="$PROJECT_DIR$/plugins/maven/maven.iml" group="plugins/maven" />
<module fileurl="file://$PROJECT_DIR$/plugins/maven/artifact-resolver-m2/maven-artifact-resolver-m2.iml" filepath="$PROJECT_DIR$/plugins/maven/artifact-resolver-m2/maven-artifact-resolver-m2.iml" group="plugins/maven" />
@@ -145,6 +146,8 @@
<module fileurl="file://$PROJECT_DIR$/python/build/python-community-build.iml" filepath="$PROJECT_DIR$/python/build/python-community-build.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/python/pluginSrc/python-community-plugin.iml" filepath="$PROJECT_DIR$/python/pluginSrc/python-community-plugin.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/python/testSrc/python-community-tests.iml" filepath="$PROJECT_DIR$/python/testSrc/python-community-tests.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/python/edu/build/python-edu-build.iml" filepath="$PROJECT_DIR$/python/edu/build/python-edu-build.iml" group="python/educational" />
<module fileurl="file://$PROJECT_DIR$/python/edu/python-educational.iml" filepath="$PROJECT_DIR$/python/edu/python-educational.iml" group="python/educational" />
<module fileurl="file://$PROJECT_DIR$/python/python-helpers.iml" filepath="$PROJECT_DIR$/python/python-helpers.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/python/ide/python-ide-community.iml" filepath="$PROJECT_DIR$/python/ide/python-ide-community.iml" group="python" />
<module fileurl="file://$PROJECT_DIR$/python/openapi/python-openapi.iml" filepath="$PROJECT_DIR$/python/openapi/python-openapi.iml" group="python" />
@@ -26,10 +26,7 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.packaging.artifacts.Artifact;
import com.intellij.packaging.artifacts.ArtifactManager;
import com.intellij.packaging.artifacts.ArtifactProperties;
import com.intellij.packaging.artifacts.ArtifactType;
import com.intellij.packaging.artifacts.*;
import com.intellij.packaging.elements.*;
import com.intellij.packaging.impl.elements.*;
import com.intellij.util.PathUtil;
@@ -599,5 +596,31 @@ public class ArtifactUtil {
public static String suggestArtifactFileName(String artifactName) {
return PathUtil.suggestFileName(artifactName, true, true);
}
@Nullable
public static Artifact addArtifact(@NotNull ModifiableArtifactModel artifactModel,
@NotNull ArtifactType type,
@NotNull ArtifactTemplate artifactTemplate) {
final ArtifactTemplate.NewArtifactConfiguration configuration = artifactTemplate.createArtifact();
if (configuration == null) {
return null;
}
final String baseName = configuration.getArtifactName();
String name = baseName;
int i = 2;
while (artifactModel.findArtifact(name) != null) {
name = baseName + i;
i++;
}
ArtifactType actualType = configuration.getArtifactType();
if (actualType == null) {
actualType = type;
}
final ModifiableArtifact artifact = artifactModel.addArtifact(name, actualType, configuration.getRootElement());
artifactTemplate.setUpArtifact(artifact, configuration);
return artifact;
}
}
@@ -286,25 +286,7 @@ public class ArtifactsStructureConfigurable extends BaseStructureConfigurable {
}
private void addArtifact(@NotNull ArtifactType type, @NotNull ArtifactTemplate artifactTemplate) {
final ArtifactTemplate.NewArtifactConfiguration configuration = artifactTemplate.createArtifact();
if (configuration == null) {
return;
}
final String baseName = configuration.getArtifactName();
String name = baseName;
int i = 2;
while (myPackagingEditorContext.getArtifactModel().findArtifact(name) != null) {
name = baseName + i;
i++;
}
ArtifactType actualType = configuration.getArtifactType();
if (actualType == null) {
actualType = type;
}
final ModifiableArtifact artifact = myPackagingEditorContext.getOrCreateModifiableArtifactModel().addArtifact(name, actualType, configuration.getRootElement());
artifactTemplate.setUpArtifact(artifact, configuration);
Artifact artifact = ArtifactUtil.addArtifact(myPackagingEditorContext.getOrCreateModifiableArtifactModel(), type, artifactTemplate);
selectNodeInTree(findNodeByObject(myRoot, artifact));
}
@@ -696,14 +696,17 @@ public class HighlightControlFlowUtil {
return true;
}
if (ControlFlowUtil.isVariableDefinitelyAssigned(variable, controlFlow)) {
final Collection<ControlFlowUtil.VariableInfo> initializedTwice = ControlFlowUtil.getInitializedTwice(controlFlow);
effectivelyFinal = !initializedTwice.contains(new ControlFlowUtil.VariableInfo(variable, null));
if (effectivelyFinal) {
effectivelyFinal = notAccessedForWriting(variable, new LocalSearchScope(scope));
final List<PsiReferenceExpression> readBeforeWriteLocals = ControlFlowUtil.getReadBeforeWriteLocals(controlFlow);
for (PsiReferenceExpression expression : readBeforeWriteLocals) {
if (expression.resolve() == variable) {
return PsiUtil.isAccessedForReading(expression);
}
} else {
effectivelyFinal = false;
}
final Collection<ControlFlowUtil.VariableInfo> initializedTwice = ControlFlowUtil.getInitializedTwice(controlFlow);
effectivelyFinal = !initializedTwice.contains(new ControlFlowUtil.VariableInfo(variable, null));
if (effectivelyFinal) {
effectivelyFinal = notAccessedForWriting(variable, new LocalSearchScope(scope));
}
}
return effectivelyFinal;
@@ -148,6 +148,9 @@ class ContractInferenceInterpreter {
}
else {
answer = withConstraint(answer, paramIndex, argConstraint);
if (answer == null) {
return null;
}
}
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.psi.PsiAnonymousClass;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
public class AnonymousTargetClassPreselectionUtil {
private static final String PRESELECT_ANONYMOUS = "create.member.preselect.anonymous";
public static void rememberSelection(PsiClass aClass, PsiClass firstClass) {
if (firstClass instanceof PsiAnonymousClass) {
PropertiesComponent.getInstance().setValue(PRESELECT_ANONYMOUS, String.valueOf(aClass == firstClass));
}
}
@Nullable
public static PsiClass getPreselection(Collection<PsiClass> classes, PsiClass firstClass) {
if (firstClass instanceof PsiAnonymousClass && !PropertiesComponent.getInstance().getBoolean(PRESELECT_ANONYMOUS, true)) {
for (PsiClass aClass : classes) {
if (!(aClass instanceof PsiAnonymousClass)) {
return aClass;
}
}
}
return null;
}
}
@@ -119,7 +119,8 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
protected abstract PsiElement getElement();
private void chooseTargetClass(List<PsiClass> classes, final Editor editor) {
final Project project = classes.get(0).getProject();
final PsiClass firstClass = classes.get(0);
final Project project = firstClass.getProject();
final JList list = new JBList(classes);
PsiElementListCellRenderer renderer = new PsiClassListCellRenderer();
@@ -128,12 +129,18 @@ public abstract class CreateFromUsageBaseFix extends BaseIntentionAction {
final PopupChooserBuilder builder = new PopupChooserBuilder(list);
renderer.installSpeedSearch(builder);
final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, firstClass);
if (preselection != null) {
list.setSelectedValue(preselection, true);
}
Runnable runnable = new Runnable() {
@Override
public void run() {
int index = list.getSelectedIndex();
if (index < 0) return;
final PsiClass aClass = (PsiClass) list.getSelectedValue();
AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, firstClass);
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.codeInsight.NullableNotNullManager;
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
import com.intellij.codeInsight.navigation.NavigationUtil;
@@ -1133,6 +1134,7 @@ public class ExtractMethodProcessor implements MatchProvider {
final PsiElementProcessor<PsiClass> processor = new PsiElementProcessor<PsiClass>() {
@Override
public boolean execute(@NotNull PsiClass selectedClass) {
AnonymousTargetClassPreselectionUtil.rememberSelection(selectedClass, myTargetClass);
final List<PsiVariable> array = classes.get(selectedClass);
myNeedChangeContext = myTargetClass != selectedClass;
myTargetClass = selectedClass;
@@ -1184,7 +1186,9 @@ public class ExtractMethodProcessor implements MatchProvider {
if (classes.size() > 1) {
final PsiClass[] psiClasses = classes.keySet().toArray(new PsiClass[classes.size()]);
NavigationUtil.getPsiElementPopup(psiClasses, new PsiClassListCellRenderer(), "Choose Destination Class", processor).showInBestPositionFor(myEditor);
final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes.keySet(), psiClasses[0]);
NavigationUtil.getPsiElementPopup(psiClasses, new PsiClassListCellRenderer(), "Choose Destination Class", processor, preselection)
.showInBestPositionFor(myEditor);
return true;
}
}
@@ -27,6 +27,7 @@ package com.intellij.refactoring.introduceField;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.TestFrameworks;
import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil;
import com.intellij.codeInsight.highlighting.HighlightManager;
import com.intellij.codeInsight.lookup.LookupManager;
import com.intellij.codeInsight.navigation.NavigationUtil;
@@ -129,18 +130,13 @@ public abstract class BaseExpressionToFieldHandler extends IntroduceHandlerBase
return !convertExpressionToField(selectedExpr, editor, file, project, tempType);
}
else {
PsiClass selection = null;
for (PsiClass psiClass : classes) {
if (!(psiClass instanceof PsiAnonymousClass)) {
selection = psiClass;
break;
}
}
PsiClass selection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, myParentClass);
NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(),
"Choose class to introduce " + (myIsConstant ? "constant" : "field"),
new PsiElementProcessor<PsiClass>() {
@Override
public boolean execute(@NotNull PsiClass aClass) {
AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, myParentClass);
myParentClass = aClass;
convertExpressionToField(selectedExpr, editor, file, project, tempType);
return false;
@@ -18,6 +18,7 @@ package com.intellij.refactoring.introduceField;
import com.intellij.codeInsight.ChangeContextUtil;
import com.intellij.codeInsight.CodeInsightUtil;
import com.intellij.codeInsight.TestFrameworks;
import com.intellij.codeInsight.daemon.impl.quickfix.AnonymousTargetClassPreselectionUtil;
import com.intellij.codeInsight.navigation.NavigationUtil;
import com.intellij.ide.util.PsiClassListCellRenderer;
import com.intellij.openapi.application.ApplicationManager;
@@ -66,7 +67,7 @@ public abstract class LocalToFieldHandler {
public boolean convertLocalToField(final PsiLocalVariable local, final Editor editor) {
boolean tempIsStatic = myIsConstant;
PsiElement parent = local.getParent();
List<PsiClass> classes = new ArrayList<PsiClass>();
final List<PsiClass> classes = new ArrayList<PsiClass>();
while (parent != null && parent.getContainingFile() != null) {
if (parent instanceof PsiClass && !(myIsConstant && parent instanceof PsiAnonymousClass)) {
classes.add((PsiClass)parent);
@@ -90,13 +91,16 @@ public abstract class LocalToFieldHandler {
if (convertLocalToField(local, classes.get(getChosenClassIndex(classes)), editor, tempIsStatic)) return false;
} else {
final boolean isStatic = tempIsStatic;
final PsiClass firstClass = classes.get(0);
final PsiClass preselection = AnonymousTargetClassPreselectionUtil.getPreselection(classes, firstClass);
NavigationUtil.getPsiElementPopup(classes.toArray(new PsiClass[classes.size()]), new PsiClassListCellRenderer(), "Choose class to introduce " + (myIsConstant ? "constant" : "field"), new PsiElementProcessor<PsiClass>() {
@Override
public boolean execute(@NotNull PsiClass aClass) {
AnonymousTargetClassPreselectionUtil.rememberSelection(aClass, aClass);
convertLocalToField(local, aClass, editor, isStatic);
return false;
}
}).showInBestPositionFor(editor);
}, preselection).showInBestPositionFor(editor);
}
return true;
@@ -39,7 +39,7 @@ public class XXX {
void m3(int x, boolean cond) {
int y;
if (cond) y = 1;
foo(() -> x+<error descr="Variable used in lambda expression should be effectively final">y</error>);
foo(() -> x+<error descr="Variable 'y' might not have been initialized">y</error>);
}
void m4(int x, boolean cond) {
@@ -128,3 +128,17 @@ class IDEA114737 {
};
}
}
class IDEA128196 {
void a() {
int value;
try {
value = 1;
} catch (Exception e) {
return;
}
new Thread(() -> System.out.println(value));
}
}
@@ -15,6 +15,7 @@
<orderEntry type="module" module-name="remote-servers-impl" />
<orderEntry type="module" module-name="java-impl" />
<orderEntry type="module" module-name="openapi" />
<orderEntry type="module" module-name="idea-ui" />
</component>
</module>
@@ -2,7 +2,7 @@
<extensionPoints>
<extensionPoint qualifiedName="com.intellij.remoteServer.moduleBuilderContribution"
interface="com.intellij.remoteServer.impl.module.CloudModuleBuilderContribution"/>
interface="com.intellij.remoteServer.impl.module.CloudModuleBuilderContributionFactory"/>
</extensionPoints>
<extensions defaultExtensionNs="com.intellij">
@@ -15,152 +15,20 @@
*/
package com.intellij.remoteServer.impl.module;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.runtime.Deployment;
import com.intellij.remoteServer.runtime.ServerConnection;
import com.intellij.remoteServer.runtime.ServerConnector;
import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
import com.intellij.remoteServer.util.*;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicReference;
import java.awt.*;
public abstract class CloudApplicationConfigurable<
SC extends CloudConfigurationBase,
DC extends CloudDeploymentNameConfiguration,
SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>,
AC extends CloudApplicationConfiguration> {
public abstract class CloudApplicationConfigurable {
private final Project myProject;
private final Disposable myParentDisposable;
public abstract Component getComponent();
private DelayedRunner myRunner;
public abstract void setAccount(RemoteServer<?> account);
private RemoteServer<?> myAccount;
public CloudApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) {
myProject = project;
myParentDisposable = parentDisposable;
}
public void setAccount(RemoteServer<?> account) {
myAccount = account;
clearCloudData();
}
protected RemoteServer<SC> getAccount() {
return (RemoteServer<SC>)myAccount;
}
public JComponent getComponent() {
JComponent result = getMainPanel();
if (myRunner == null) {
myRunner = new DelayedRunner(result) {
private RemoteServer<?> myPreviousAccount;
@Override
protected boolean wasChanged() {
boolean result = myPreviousAccount != myAccount;
if (result) {
myPreviousAccount = myAccount;
}
return result;
}
@Override
protected void run() {
loadCloudData();
}
};
Disposer.register(myParentDisposable, myRunner);
}
return result;
}
protected void clearCloudData() {
getExistingComboBox().removeAllItems();
}
protected void loadCloudData() {
new ConnectionTask<Collection<Deployment>>("Loading existing applications list") {
@Override
protected void run(final ServerConnection<DC> connection,
final Semaphore semaphore,
final AtomicReference<Collection<Deployment>> result) {
connection.connectIfNeeded(new ServerConnector.ConnectionCallback<DC>() {
@Override
public void connected(@NotNull ServerRuntimeInstance<DC> serverRuntimeInstance) {
connection.computeDeployments(new Runnable() {
@Override
public void run() {
result.set(connection.getDeployments());
semaphore.up();
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (!Disposer.isDisposed(myParentDisposable)) {
setupExistingApplications(result.get());
}
}
});
}
});
}
@Override
public void errorOccurred(@NotNull String errorMessage) {
runtimeErrorOccurred(errorMessage);
semaphore.up();
}
});
}
@Override
protected Collection<Deployment> run(SR serverRuntimeInstance) throws ServerRuntimeException {
return null;
}
}.performAsync();
}
private void setupExistingApplications(Collection<Deployment> deployments) {
JComboBox existingComboBox = getExistingComboBox();
existingComboBox.removeAllItems();
for (Deployment deployment : deployments) {
existingComboBox.addItem(deployment.getName());
}
}
protected Project getProject() {
return myProject;
}
protected abstract JComboBox getExistingComboBox();
protected abstract JComponent getMainPanel();
public abstract AC createConfiguration();
public abstract CloudApplicationConfiguration createConfiguration();
public abstract void validate() throws ConfigurationException;
protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> {
public ConnectionTask(String title) {
super(myProject, title, CloudApplicationConfigurable.this.getAccount());
}
}
}
@@ -18,19 +18,4 @@ package com.intellij.remoteServer.impl.module;
public abstract class CloudApplicationConfiguration {
private boolean myExisting;
private final String myExistingAppName;
protected CloudApplicationConfiguration(boolean existing, String existingAppName) {
myExisting = existing;
myExistingAppName = existingAppName;
}
public boolean isExisting() {
return myExisting;
}
public String getExistingAppName() {
return myExistingAppName;
}
}
@@ -16,6 +16,7 @@
package com.intellij.remoteServer.impl.module;
import com.intellij.icons.AllIcons;
import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
import com.intellij.ide.util.projectWizard.JavaModuleBuilder;
import com.intellij.ide.util.projectWizard.ModuleBuilderListener;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
@@ -23,20 +24,42 @@ import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.module.JavaModuleType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainerFactory;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.util.containers.hash.HashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Map;
public class CloudModuleBuilder extends JavaModuleBuilder {
private RemoteServer<?> myAccount;
private CloudApplicationConfiguration myApplicationConfiguration;
private FrameworkSupportModelBase myFrameworkSupportModel;
private Map<ServerType<?>, CloudModuleBuilderContribution> myCloudType2Contribution;
private Project myProject;
public CloudModuleBuilder() {
myCloudType2Contribution = new HashMap<ServerType<?>, CloudModuleBuilderContribution>();
ModuleConfigurationUpdater configurationUpdater = new ModuleConfigurationUpdater() {
public void update(@NotNull final Module module, @NotNull final ModifiableRootModel rootModel) {
preConfigureModule(module, rootModel);
}
};
addModuleConfigurationUpdater(configurationUpdater);
addListener(new ModuleBuilderListener() {
@Override
@@ -93,7 +116,8 @@ public class CloudModuleBuilder extends JavaModuleBuilder {
@Nullable
@Override
public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) {
return new CloudModuleWizardStep(this, context.getProject(), parentDisposable);
myProject = context.getProject();
return new CloudModuleWizardStep(this, myProject, parentDisposable);
}
public void setAccount(RemoteServer<?> account) {
@@ -108,7 +132,43 @@ public class CloudModuleBuilder extends JavaModuleBuilder {
myApplicationConfiguration = applicationConfiguration;
}
public CloudApplicationConfiguration getApplicationConfiguration() {
return myApplicationConfiguration;
}
public CloudModuleBuilderContribution getContribution(ServerType<?> cloudType) {
CloudModuleBuilderContribution result = myCloudType2Contribution.get(cloudType);
if (result == null) {
result = CloudModuleBuilderContributionFactory.getInstanceByType(cloudType).createContribution(this);
myCloudType2Contribution.put(cloudType, result);
}
return result;
}
private CloudModuleBuilderContribution getContribution() {
return getContribution(myAccount.getType());
}
private void preConfigureModule(Module module, ModifiableRootModel model) {
getContribution().preConfigureModule(module, model);
}
private void configureModule(final Module module) {
CloudModuleBuilderContribution.getInstanceByType(myAccount.getType()).configureModule(module, myAccount, myApplicationConfiguration);
getContribution().configureModule(module);
}
public FrameworkSupportModelBase getFrameworkSupportModel() {
if (myFrameworkSupportModel == null) {
final LibrariesContainer librariesContainer = LibrariesContainerFactory.createContainer(myProject);
myFrameworkSupportModel = new FrameworkSupportModelBase(myProject, this, librariesContainer) {
@NotNull
@Override
public String getBaseDirectoryForLibrariesPath() {
return StringUtil.notNullize(getContentEntryPath());
}
};
}
return myFrameworkSupportModel;
}
}
@@ -16,33 +16,51 @@
package com.intellij.remoteServer.impl.module;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import org.jetbrains.annotations.Nullable;
public abstract class CloudModuleBuilderContribution {
public static final ExtensionPointName<CloudModuleBuilderContribution> EP_NAME
= ExtensionPointName.create("com.intellij.remoteServer.moduleBuilderContribution");
private final CloudModuleBuilder myModuleBuilder;
public abstract ServerType<?> getCloudType();
private final ServerType<?> myCloudType;
private CloudApplicationConfigurable myApplicationConfigurable;
public abstract CloudApplicationConfigurable createApplicationConfigurable(@Nullable Project project, Disposable parentDisposable);
public CloudModuleBuilderContribution(CloudModuleBuilder moduleBuilder, ServerType<?> cloudType) {
myModuleBuilder = moduleBuilder;
myCloudType = cloudType;
}
public abstract void configureModule(Module module,
RemoteServer<?> account,
CloudApplicationConfiguration configuration);
protected CloudModuleBuilder getModuleBuilder() {
return myModuleBuilder;
}
public static CloudModuleBuilderContribution getInstanceByType(ServerType<?> cloudType) {
for (CloudModuleBuilderContribution contribution : EP_NAME.getExtensions()) {
if (contribution.getCloudType() == cloudType) {
return contribution;
}
protected ServerType<?> getCloudType() {
return myCloudType;
}
public CloudApplicationConfigurable getApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) {
if (myApplicationConfigurable == null) {
myApplicationConfigurable = createApplicationConfigurable(project, parentDisposable);
}
return null;
return myApplicationConfigurable;
}
public void preConfigureModule(Module module, ModifiableRootModel model) {
}
public abstract void configureModule(Module module);
protected abstract CloudApplicationConfigurable createApplicationConfigurable(@Nullable Project project, Disposable parentDisposable);
protected DeploymentConfiguration createDeploymentConfiguration(DeploymentSource deploymentSource) {
return myCloudType.createDeploymentConfigurator(null).createDefaultConfiguration(deploymentSource);
}
}
@@ -1,142 +0,0 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.remoteServer.impl.module;
import com.intellij.execution.RunManagerEx;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl;
import com.intellij.remoteServer.util.*;
import com.intellij.remoteServer.util.ssh.SshKeyChecker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class CloudModuleBuilderContributionBase<
SC extends CloudConfigurationBase,
DC extends CloudDeploymentNameConfiguration,
AC extends CloudApplicationConfiguration,
SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>>
extends CloudModuleBuilderContribution {
@Override
public void configureModule(Module module,
RemoteServer<?> account,
CloudApplicationConfiguration applicationConfiguration) {
RemoteServer<SC> castedAccount = (RemoteServer<SC>)account;
final AC castedApplicationConfiguration = (AC)applicationConfiguration;
DC deploymentConfiguration = createDeploymentConfiguration();
if (applicationConfiguration.isExisting()) {
deploymentConfiguration.setDefaultDeploymentName(false);
deploymentConfiguration.setDeploymentName(applicationConfiguration.getExistingAppName());
}
final DeployToServerRunConfiguration<SC, DC> runConfiguration = createRunConfiguration(module, castedAccount, deploymentConfiguration);
final String cloudName = account.getType().getPresentableName();
final Project project = module.getProject();
new CloudConnectionTask<Object, SC, DC, SR>(project, CloudBundle.getText("cloud.support", cloudName), castedAccount) {
CloudNotifier myNotifier = new CloudNotifier(cloudName);
boolean myFirstAttempt = true;
@Override
protected Object run(SR serverRuntime) throws ServerRuntimeException {
doConfigureModule(castedApplicationConfiguration, runConfiguration, myFirstAttempt, serverRuntime);
myNotifier.showMessage(CloudBundle.getText("cloud.support.added", cloudName), MessageType.INFO);
return null;
}
@Override
protected void runtimeErrorOccurred(@NotNull String errorMessage) {
myFirstAttempt = false;
new SshKeyChecker().checkServerError(errorMessage, myNotifier, project, this);
}
}.performAsync();
}
private DeployToServerRunConfiguration<SC, DC> createRunConfiguration(Module module,
RemoteServer<SC> server,
DC deploymentConfiguration) {
Project project = module.getProject();
String serverName = server.getName();
String name = generateRunConfigurationName(serverName, module.getName());
final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
final RunnerAndConfigurationSettings runSettings
= runManager.createRunConfiguration(name, getRunConfigurationType().getConfigurationFactories()[0]);
final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration();
result.setServerName(serverName);
final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module);
result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer));
result.setDeploymentConfiguration(deploymentConfiguration);
runManager.addConfiguration(runSettings, false);
runManager.setSelectedConfiguration(runSettings);
return result;
}
private static String generateRunConfigurationName(String serverName, String moduleName) {
return CloudBundle.getText("run.configuration.name", serverName, moduleName);
}
private DeployToServerConfigurationType getRunConfigurationType() {
String id = DeployToServerConfigurationType.getId(getCloudType());
for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) {
if (configurationType instanceof DeployToServerConfigurationType) {
DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType;
if (deployConfigurationType.getId().equals(id)) {
return deployConfigurationType;
}
}
}
return null;
}
@Override
public abstract ServerType<SC> getCloudType();
@Override
public abstract CloudApplicationConfigurable<SC, DC, SR, AC> createApplicationConfigurable(@Nullable Project project,
Disposable parentDisposable);
protected abstract DC createDeploymentConfiguration();
protected abstract void doConfigureModule(AC applicationConfiguration,
DeployToServerRunConfiguration<SC, DC> runConfiguration,
boolean firstAttempt,
SR serverRuntime) throws ServerRuntimeException;
}
@@ -0,0 +1,39 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.remoteServer.impl.module;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.remoteServer.ServerType;
public abstract class CloudModuleBuilderContributionFactory {
public static final ExtensionPointName<CloudModuleBuilderContributionFactory> EP_NAME
= ExtensionPointName.create("com.intellij.remoteServer.moduleBuilderContribution");
public abstract ServerType<?> getCloudType();
public abstract CloudModuleBuilderContribution createContribution(CloudModuleBuilder moduleBuilder);
public static CloudModuleBuilderContributionFactory getInstanceByType(ServerType<?> cloudType) {
for (CloudModuleBuilderContributionFactory contribution : EP_NAME.getExtensions()) {
if (contribution.getCloudType() == cloudType) {
return contribution;
}
}
return null;
}
}
@@ -0,0 +1,191 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.remoteServer.impl.module;
import com.intellij.ide.util.newProjectWizard.StepSequence;
import com.intellij.ide.util.newProjectWizard.modes.CreateFromSourcesMode;
import com.intellij.ide.util.projectWizard.AbstractStepWithProgress;
import com.intellij.ide.util.projectWizard.ModuleWizardStep;
import com.intellij.ide.util.projectWizard.ProjectBuilder;
import com.intellij.ide.util.projectWizard.WizardContext;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
import com.intellij.remoteServer.util.*;
import com.intellij.remoteServer.util.ssh.SshKeyChecker;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class CloudModuleBuilderSourceContribution<
SC extends CloudConfigurationBase,
DC extends CloudDeploymentNameConfiguration,
AC extends CloudSourceApplicationConfiguration,
SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>>
extends CloudModuleBuilderContribution {
private CloudNotifier myNotifier;
public CloudModuleBuilderSourceContribution(CloudModuleBuilder moduleBuilder, ServerType<SC> cloudType) {
super(moduleBuilder, cloudType);
}
@Override
public void configureModule(final Module module) {
final CloudModuleBuilder moduleBuilder = getModuleBuilder();
RemoteServer<SC> account = (RemoteServer<SC>)moduleBuilder.getAccount();
final AC applicationConfiguration = (AC)moduleBuilder.getApplicationConfiguration();
DC deploymentConfiguration = createDeploymentConfiguration();
if (applicationConfiguration.isExisting()) {
deploymentConfiguration.setDefaultDeploymentName(false);
deploymentConfiguration.setDeploymentName(applicationConfiguration.getExistingAppName());
}
final DeployToServerRunConfiguration<SC, DC> runConfiguration
= CloudRunConfigurationUtil.createRunConfiguration(account, module, deploymentConfiguration);
final ServerType<?> cloudType = account.getType();
final Project project = module.getProject();
new CloudConnectionTask<Object, SC, DC, SR>(project,
CloudBundle.getText("cloud.support", cloudType.getPresentableName()),
account) {
boolean myFirstAttempt = true;
@Override
protected Object run(SR serverRuntime) throws ServerRuntimeException {
doConfigureModule(applicationConfiguration, runConfiguration, myFirstAttempt, serverRuntime);
return null;
}
@Override
protected void runtimeErrorOccurred(@NotNull String errorMessage) {
myFirstAttempt = false;
new SshKeyChecker().checkServerError(errorMessage, getNotifier(), project, this);
}
@Override
protected void postPerform(Object result) {
detectModuleStructure(module, moduleBuilder.getContentEntryPath());
}
@Override
protected boolean shouldStartInBackground() {
return false;
}
}.performAsync();
}
private CloudNotifier getNotifier() {
if (myNotifier == null) {
myNotifier = new CloudNotifier(getCloudType().getPresentableName());
}
return myNotifier;
}
private void detectModuleStructure(Module module, final String contentPath) {
final Project project = module.getProject();
final CreateFromSourcesMode mode = new CreateFromSourcesMode() {
@Override
public boolean isAvailable(WizardContext context) {
return true;
}
@Override
public void addSteps(WizardContext context, ModulesProvider modulesProvider, StepSequence sequence, String specific) {
super.addSteps(context, modulesProvider, sequence, specific);
myProjectBuilder.setFileToImport(contentPath);
}
};
final WizardContext context = new WizardContext(project);
final StepSequence stepSequence = mode.getSteps(context, DefaultModulesProvider.createForProject(context.getProject()));
if (stepSequence == null) {
return;
}
Disposer.register(project, new Disposable() {
@Override
public void dispose() {
for (ModuleWizardStep step : stepSequence.getAllSteps()) {
step.disposeUIResources();
}
}
});
ProgressManager.getInstance()
.run(new Task.Backgroundable(project, CloudBundle.getText("detect.module.structure", getCloudType().getPresentableName()), false) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
for (ModuleWizardStep step = ContainerUtil.getFirstItem(stepSequence.getSelectedSteps());
step != null;
step = stepSequence.getNextStep(step)) {
if (step instanceof AbstractStepWithProgress<?>) {
((AbstractStepWithProgress)step).performStep();
}
else {
step.updateDataModel();
}
}
CloudAccountSelectionEditor.unsetAccountOnContext(context, getCloudType());
}
@Override
public boolean shouldStartInBackground() {
return false;
}
@Override
public void onSuccess() {
ProjectBuilder moduleBuilder = mode.getModuleBuilder();
if (moduleBuilder == null) {
return;
}
moduleBuilder.commit(project);
getNotifier().showMessage(CloudBundle.getText("cloud.support.added", getCloudType().getPresentableName()), MessageType.INFO);
}
});
}
@Override
protected abstract CloudSourceApplicationConfigurable<SC, DC, SR, AC> createApplicationConfigurable(@Nullable Project project,
Disposable parentDisposable);
protected abstract DC createDeploymentConfiguration();
protected abstract void doConfigureModule(AC applicationConfiguration,
DeployToServerRunConfiguration<SC, DC> runConfiguration,
boolean firstAttempt,
SR serverRuntime) throws ServerRuntimeException;
}
@@ -22,13 +22,13 @@ import com.intellij.openapi.project.Project;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.util.CloudAccountSelectionEditor;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.containers.HashSet;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CloudModuleWizardStep extends ModuleWizardStep {
@@ -43,17 +43,17 @@ public class CloudModuleWizardStep extends ModuleWizardStep {
private CloudAccountSelectionEditor myAccountSelectionPanel;
private Map<ServerType<?>, CloudApplicationConfigurable> myCloudType2ApplicationConfigurable;
private Set<ServerType<?>> myApplicationConfigurableTypes;
public CloudModuleWizardStep(CloudModuleBuilder moduleBuilder, Project project, Disposable parentDisposable) {
myModuleBuilder = moduleBuilder;
myProject = project;
myParentDisposable = parentDisposable;
myCloudType2ApplicationConfigurable = new HashMap<ServerType<?>, CloudApplicationConfigurable>();
myApplicationConfigurableTypes = new HashSet<ServerType<?>>();
List<ServerType<?>> cloudTypes = new ArrayList<ServerType<?>>();
for (CloudModuleBuilderContribution contribution : CloudModuleBuilderContribution.EP_NAME.getExtensions()) {
for (CloudModuleBuilderContributionFactory contribution : CloudModuleBuilderContributionFactory.EP_NAME.getExtensions()) {
cloudTypes.add(contribution.getCloudType());
}
@@ -86,11 +86,8 @@ public class CloudModuleWizardStep extends ModuleWizardStep {
ServerType<?> cloudType = account.getType();
String cardName = cloudType.getId();
CloudApplicationConfigurable<?, ?, ?, ?> applicationConfigurable = getApplicationConfigurable();
if (applicationConfigurable == null) {
applicationConfigurable
= CloudModuleBuilderContribution.getInstanceByType(cloudType).createApplicationConfigurable(myProject, myParentDisposable);
myCloudType2ApplicationConfigurable.put(cloudType, applicationConfigurable);
CloudApplicationConfigurable applicationConfigurable = getApplicationConfigurable();
if (myApplicationConfigurableTypes.add(cloudType)) {
myApplicationPanelPlaceHolder.add(applicationConfigurable.getComponent(), cardName);
}
applicationPlaceHolderLayout.show(myApplicationPanelPlaceHolder, cardName);
@@ -103,25 +100,25 @@ public class CloudModuleWizardStep extends ModuleWizardStep {
return myMainPanel;
}
private CloudApplicationConfigurable<?, ?, ?, ?> getApplicationConfigurable() {
private CloudApplicationConfigurable getApplicationConfigurable() {
RemoteServer<?> account = getSelectedAccount();
if (account == null) {
return null;
}
return myCloudType2ApplicationConfigurable.get(account.getType());
return myModuleBuilder.getContribution(account.getType()).getApplicationConfigurable(myProject, myParentDisposable);
}
@Override
public void updateDataModel() {
myModuleBuilder.setAccount(myAccountSelectionPanel.getSelectedAccount());
CloudApplicationConfigurable<?, ?, ?, ?> configurable = getApplicationConfigurable();
CloudApplicationConfigurable configurable = getApplicationConfigurable();
myModuleBuilder.setApplicationConfiguration(configurable == null ? null : configurable.createConfiguration());
}
@Override
public boolean validate() throws ConfigurationException {
myAccountSelectionPanel.validate();
CloudApplicationConfigurable<?, ?, ?, ?> configurable = getApplicationConfigurable();
CloudApplicationConfigurable configurable = getApplicationConfigurable();
if (configurable != null) {
configurable.validate();
}
@@ -0,0 +1,165 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.remoteServer.impl.module;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.runtime.Deployment;
import com.intellij.remoteServer.runtime.ServerConnection;
import com.intellij.remoteServer.runtime.ServerConnector;
import com.intellij.remoteServer.runtime.deployment.ServerRuntimeInstance;
import com.intellij.remoteServer.util.*;
import com.intellij.util.concurrency.Semaphore;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicReference;
public abstract class CloudSourceApplicationConfigurable<
SC extends CloudConfigurationBase,
DC extends CloudDeploymentNameConfiguration,
SR extends CloudMultiSourceServerRuntimeInstance<DC, ?, ?, ?>,
AC extends CloudApplicationConfiguration> extends CloudApplicationConfigurable {
private final Project myProject;
private final Disposable myParentDisposable;
private DelayedRunner myRunner;
private RemoteServer<?> myAccount;
public CloudSourceApplicationConfigurable(@Nullable Project project, Disposable parentDisposable) {
myProject = project;
myParentDisposable = parentDisposable;
}
@Override
public void setAccount(RemoteServer<?> account) {
myAccount = account;
clearCloudData();
}
protected RemoteServer<SC> getAccount() {
return (RemoteServer<SC>)myAccount;
}
@Override
public JComponent getComponent() {
JComponent result = getMainPanel();
if (myRunner == null) {
myRunner = new DelayedRunner(result) {
private RemoteServer<?> myPreviousAccount;
@Override
protected boolean wasChanged() {
boolean result = myPreviousAccount != myAccount;
if (result) {
myPreviousAccount = myAccount;
}
return result;
}
@Override
protected void run() {
loadCloudData();
}
};
Disposer.register(myParentDisposable, myRunner);
}
return result;
}
protected void clearCloudData() {
getExistingComboBox().removeAllItems();
}
protected void loadCloudData() {
new ConnectionTask<Collection<Deployment>>("Loading existing applications list") {
@Override
protected void run(final ServerConnection<DC> connection,
final Semaphore semaphore,
final AtomicReference<Collection<Deployment>> result) {
connection.connectIfNeeded(new ServerConnector.ConnectionCallback<DC>() {
@Override
public void connected(@NotNull ServerRuntimeInstance<DC> serverRuntimeInstance) {
connection.computeDeployments(new Runnable() {
@Override
public void run() {
result.set(connection.getDeployments());
semaphore.up();
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
if (!Disposer.isDisposed(myParentDisposable)) {
setupExistingApplications(result.get());
}
}
});
}
});
}
@Override
public void errorOccurred(@NotNull String errorMessage) {
runtimeErrorOccurred(errorMessage);
semaphore.up();
}
});
}
@Override
protected Collection<Deployment> run(SR serverRuntimeInstance) throws ServerRuntimeException {
return null;
}
}.performAsync();
}
private void setupExistingApplications(Collection<Deployment> deployments) {
JComboBox existingComboBox = getExistingComboBox();
existingComboBox.removeAllItems();
for (Deployment deployment : deployments) {
existingComboBox.addItem(deployment.getName());
}
}
protected Project getProject() {
return myProject;
}
protected abstract JComboBox getExistingComboBox();
protected abstract JComponent getMainPanel();
@Override
public abstract AC createConfiguration();
protected abstract class ConnectionTask<T> extends CloudConnectionTask<T, SC, DC, SR> {
public ConnectionTask(String title) {
super(myProject, title, CloudSourceApplicationConfigurable.this.getAccount());
}
}
}
@@ -0,0 +1,36 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.remoteServer.impl.module;
public abstract class CloudSourceApplicationConfiguration extends CloudApplicationConfiguration {
private boolean myExisting;
private final String myExistingAppName;
protected CloudSourceApplicationConfiguration(boolean existing, String existingAppName) {
myExisting = existing;
myExistingAppName = existingAppName;
}
public boolean isExisting() {
return myExisting;
}
public String getExistingAppName() {
return myExistingAppName;
}
}
@@ -17,8 +17,10 @@ package com.intellij.ide.util;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.reflect.Field;
@@ -31,6 +33,7 @@ public abstract class PropertiesComponent {
public abstract boolean isValueSet(String name);
@Nullable
public abstract String getValue(@NonNls String name);
public abstract void setValue(@NonNls String name, String value);
@@ -62,7 +65,10 @@ public abstract class PropertiesComponent {
@NotNull
public String getValue(@NonNls String name, @NotNull String defaultValue) {
return isValueSet(name) ? getValue(name) : defaultValue;
if (!isValueSet(name)) {
return defaultValue;
}
return ObjectUtils.notNull(getValue(name), defaultValue);
}
public final int getOrInitInt(@NonNls String name, int defaultValue) {
@@ -149,7 +149,7 @@ public class IdTableBuilding {
}
private int convertToMask(final WordOccurrence.Kind kind) {
if (kind == null) return UsageSearchContext.ANY;
if (kind == null) return UsageSearchContext.IN_PLAIN_TEXT;
if (kind == WordOccurrence.Kind.CODE) return UsageSearchContext.IN_CODE;
if (kind == WordOccurrence.Kind.COMMENTS) return UsageSearchContext.IN_COMMENTS;
if (kind == WordOccurrence.Kind.LITERALS) return UsageSearchContext.IN_STRINGS;
@@ -188,7 +188,7 @@ public class EditorTabsConfigurable implements EditorOptionsProvider {
if (temp.trim().length() > 0) {
try {
int newTabTitleLimit = Integer.parseInt(temp);
newTabTitleLimit = Math.max(10, Math.min(100, newTabTitleLimit));
newTabTitleLimit = Math.max(25, Math.min(100, newTabTitleLimit));
if (newTabTitleLimit != uiSettings.EDITOR_TAB_TITLE_LIMIT){
uiSettings.EDITOR_TAB_TITLE_LIMIT = newTabTitleLimit;
uiSettingsChanged = true;
@@ -59,7 +59,7 @@ public class IndexingStamp {
private static final long UNINDEXED_STAMP = -1L; // we don't store trivial "absent" state
private static final long INDEX_DATA_OUTDATED_STAMP = -2L;
private static final int VERSION = 12;
private static final int VERSION = 13;
private static final ConcurrentHashMap<ID<?, ?>, Long> ourIndexIdToCreationStamp = new ConcurrentHashMap<ID<?, ?>, Long>();
private static volatile long ourLastStamp; // ensure any file index stamp increases
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util.ui;
import com.intellij.ide.BrowserUtil;
@@ -48,7 +63,7 @@ public class SwingHelper {
* stacked vertically each on another in a given order.
*
* @param childAlignmentX Component.LEFT_ALIGNMENT, Component.CENTER_ALIGNMENT or Component.RIGHT_ALIGNMENT
* @param children children components
* @param children children components
* @return created panel
*/
@NotNull
@@ -76,7 +91,7 @@ public class SwingHelper {
* stacked each on another in a given order.
*
* @param childAlignmentY Component.TOP_ALIGNMENT, Component.CENTER_ALIGNMENT or Component.BOTTOM_ALIGNMENT
* @param children children components
* @param children children components
* @return created panel
*/
@NotNull
@@ -98,10 +113,11 @@ public class SwingHelper {
for (Component child : children) {
panel.add(child, childAlignment);
if (child instanceof JComponent) {
JComponent jChild = (JComponent) child;
JComponent jChild = (JComponent)child;
if (verticalOrientation) {
jChild.setAlignmentX(childAlignment);
} else {
}
else {
jChild.setAlignmentY(childAlignment);
}
}
@@ -291,7 +307,7 @@ public class SwingHelper {
Object prototypeDisplayValue = comboBox.getPrototypeDisplayValue();
String prototypeDisplayValueStr = null;
if (prototypeDisplayValue instanceof String) {
prototypeDisplayValueStr = (String) prototypeDisplayValue;
prototypeDisplayValueStr = (String)prototypeDisplayValue;
}
else if (prototypeDisplayValue != null) {
return;
@@ -424,6 +440,24 @@ public class SwingHelper {
editorPane.setText(html);
}
public static TextFieldWithHistoryWithBrowseButton createTextFieldWithHistoryWithBrowseButton(@Nullable Project project,
@NotNull String browseDialogTitle,
@NotNull FileChooserDescriptor fileChooserDescriptor,
@NotNull NotNullProducer<List<String>> historyProvider) {
TextFieldWithHistoryWithBrowseButton textFieldWithHistoryWithBrowseButton = new TextFieldWithHistoryWithBrowseButton();
final TextFieldWithHistory textFieldWithHistory = textFieldWithHistoryWithBrowseButton.getChildComponent();
textFieldWithHistory.setHistorySize(-1);
textFieldWithHistory.setMinimumAndPreferredWidth(0);
addHistoryOnExpansion(textFieldWithHistory, historyProvider);
installFileCompletionAndBrowseDialog(
project,
textFieldWithHistoryWithBrowseButton,
browseDialogTitle, fileChooserDescriptor
);
return textFieldWithHistoryWithBrowseButton;
}
private static class CopyLinkAction extends AnAction {
private final String myUrl;
@@ -15,9 +15,6 @@
*/
package com.intellij.remoteServer.util;
import com.intellij.execution.RunManagerEx;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.ide.DataManager;
import com.intellij.ide.actions.ShowSettingsUtilImpl;
import com.intellij.ide.util.projectWizard.WizardContext;
@@ -25,11 +22,8 @@ import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.options.ex.SingleConfigurableEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.Condition;
@@ -38,12 +32,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.RemoteServersManager;
import com.intellij.remoteServer.configuration.ServerConfiguration;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.remoteServer.impl.configuration.RemoteServerConfigurable;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl;
import com.intellij.util.Consumer;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.hash.HashMap;
@@ -224,52 +213,7 @@ public class CloudAccountSelectionEditor {
if (account == null) {
return;
}
createRunConfiguration(account, module, configuration);
}
public static <SC extends ServerConfiguration, DC extends DeploymentConfiguration>
DeployToServerRunConfiguration<SC, DC> createRunConfiguration(RemoteServer<SC> account, Module module, DC deploymentConfiguration) {
Project project = module.getProject();
String accountName = account.getName();
String name = generateRunConfigurationName(accountName, module.getName());
final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
final RunnerAndConfigurationSettings runSettings
= runManager.createRunConfiguration(name, getRunConfigurationType(account.getType()).getConfigurationFactories()[0]);
final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration();
result.setServerName(accountName);
final ModulePointer modulePointer = ModulePointerManager.getInstance(project).create(module);
result.setDeploymentSource(new ModuleDeploymentSourceImpl(modulePointer));
result.setDeploymentConfiguration(deploymentConfiguration);
runManager.addConfiguration(runSettings, false);
runManager.setSelectedConfiguration(runSettings);
return result;
}
private static DeployToServerConfigurationType getRunConfigurationType(ServerType<?> cloudType) {
String id = DeployToServerConfigurationType.getId(cloudType);
for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) {
if (configurationType instanceof DeployToServerConfigurationType) {
DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType;
if (deployConfigurationType.getId().equals(id)) {
return deployConfigurationType;
}
}
}
return null;
}
private static String generateRunConfigurationName(String serverName, String moduleName) {
return CloudBundle.getText("run.configuration.name", serverName, moduleName);
CloudRunConfigurationUtil.createRunConfiguration(account, module, configuration);
}
private static class AccountItem {
@@ -0,0 +1,93 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.remoteServer.util;
import com.intellij.execution.RunManagerEx;
import com.intellij.execution.RunnerAndConfigurationSettings;
import com.intellij.execution.configuration.ConfigurationFactoryEx;
import com.intellij.execution.configurations.ConfigurationFactory;
import com.intellij.execution.configurations.ConfigurationType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModulePointer;
import com.intellij.openapi.module.ModulePointerManager;
import com.intellij.openapi.project.Project;
import com.intellij.remoteServer.ServerType;
import com.intellij.remoteServer.configuration.RemoteServer;
import com.intellij.remoteServer.configuration.ServerConfiguration;
import com.intellij.remoteServer.configuration.deployment.DeploymentConfiguration;
import com.intellij.remoteServer.configuration.deployment.DeploymentSource;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerConfigurationType;
import com.intellij.remoteServer.impl.configuration.deployment.DeployToServerRunConfiguration;
import com.intellij.remoteServer.impl.configuration.deployment.ModuleDeploymentSourceImpl;
public class CloudRunConfigurationUtil {
public static <SC extends ServerConfiguration, DC extends DeploymentConfiguration>
DeployToServerRunConfiguration<SC, DC> createRunConfiguration(RemoteServer<SC> account, Module module, DC deploymentConfiguration) {
final ModulePointer modulePointer = ModulePointerManager.getInstance(module.getProject()).create(module);
DeploymentSource deploymentSource = new ModuleDeploymentSourceImpl(modulePointer);
return createRunConfiguration(account, module, deploymentSource, deploymentConfiguration);
}
public static <SC extends ServerConfiguration, DC extends DeploymentConfiguration>
DeployToServerRunConfiguration<SC, DC> createRunConfiguration(RemoteServer<SC> account,
Module module,
DeploymentSource deploymentSource,
DC deploymentConfiguration) {
Project project = module.getProject();
String accountName = account.getName();
String name = generateRunConfigurationName(accountName, module.getName());
final RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
ConfigurationFactory configurationFactory = getRunConfigurationType(account.getType()).getConfigurationFactories()[0];
final RunnerAndConfigurationSettings runSettings = runManager.createRunConfiguration(name, configurationFactory);
final DeployToServerRunConfiguration<SC, DC> result = (DeployToServerRunConfiguration<SC, DC>)runSettings.getConfiguration();
result.setServerName(accountName);
result.setDeploymentSource(deploymentSource);
result.setDeploymentConfiguration(deploymentConfiguration);
((ConfigurationFactoryEx)configurationFactory).onNewConfigurationCreated(runSettings.getConfiguration());
runManager.addConfiguration(runSettings, false);
runManager.setSelectedConfiguration(runSettings);
return result;
}
private static DeployToServerConfigurationType getRunConfigurationType(ServerType<?> cloudType) {
String id = DeployToServerConfigurationType.getId(cloudType);
for (ConfigurationType configurationType : ConfigurationType.CONFIGURATION_TYPE_EP.getExtensions()) {
if (configurationType instanceof DeployToServerConfigurationType) {
DeployToServerConfigurationType deployConfigurationType = (DeployToServerConfigurationType)configurationType;
if (deployConfigurationType.getId().equals(id)) {
return deployConfigurationType;
}
}
}
return null;
}
private static String generateRunConfigurationName(String serverName, String moduleName) {
return CloudBundle.getText("run.configuration.name", serverName, moduleName);
}
}
@@ -2674,12 +2674,19 @@ public class StringUtil extends StringUtilRt {
continue;
}
if (i > 0 && (ch == '/' || ch == '.' || Character.isUpperCase(ch))) {
if (i > 0 && (ch == '/' || ch == '\\' || ch == '.' || Character.isUpperCase(ch))) {
words.add(builder.toString());
builder.delete(0, builder.length());
}
builder.append(ch);
}
for (int i = 0; i < words.size(); i++) {
String word = words.get(i);
if (i < words.size() - 1 && word.length() == 1) {
words.remove(i);
words.set(i, word + words.get(i));
}
}
int removedLength = 0;
@@ -197,7 +197,7 @@ public class StringUtilTest extends TestCase {
}
public void testShortened() {
String[] names = {"AVeryVeeryLongClassName.java", "com.test.SomeJAVAClassName.java", "strangelowercaseclassname.java", "PrefixPostfix.java"};
String[] names = {"AVeryVeeryLongClassName.java", "com.test.SomeJAVAClassName.java", "strangelowercaseclassname.java", "PrefixPostfix.java", "SomeJAVAClassName.java"};
for (String name : names) {
for (int i = name.length() + 1; i > 15; i--) {
String shortened = StringUtil.getShortened(name, i);
@@ -20,7 +20,7 @@ import com.intellij.vcs.log.graph.GraphCommit;
import java.util.List;
/**
* A {@link GraphCommit} with information about date & time when this commit was made.
* A typified {@link GraphCommit}.
* <p/>
* An instance of this object can be obtained via
* {@link VcsLogObjectsFactory#createTimedCommit(Hash, List, long) VcsLogObjectsFactory#createTimedCommit}.
@@ -31,12 +31,4 @@ import java.util.List;
*/
public interface TimedVcsCommit extends GraphCommit<Hash> {
/**
* <p>Returns the timestamp indicating the date & time when this commit was made.</p>
* <p>This time is displayed in the table by default;
* is used for joining commits from different repositories;
* is used for ordering commits in a single repository (keeping the preference of the topological ordering of course).</p>
*/
long getTimestamp();
}
@@ -29,8 +29,8 @@ public interface VcsLogProvider {
* <p>Reads the whole history, but only hashes & parents.</p>
* <p>Also reports authors/committers of this repository to the given user registry.</p>
*/
@NotNull
List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException;
void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
@NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException;
/**
* Reads those details of the given commits, which are necessary to be shown in the log table.
@@ -21,20 +21,9 @@ import java.util.List;
*/
public interface VcsShortCommitDetails extends TimedVcsCommit {
@Override
@NotNull
Hash getId();
@NotNull
VirtualFile getRoot();
@Override
@NotNull
List<Hash> getParents();
@Override
long getTimestamp();
@NotNull
String getSubject();
@@ -29,6 +29,12 @@ public interface GraphCommit<CommitId> {
@NotNull
List<CommitId> getParents();
/**
* <p>Returns the timestamp indicating the date & time when this commit was made.</p>
* <p>This time is displayed in the table by default;
* it is used for joining commits from different repositories;
* it is used for ordering commits in a single repository (keeping the preference of the topological ordering of course).</p>
*/
long getTimestamp();
}
@@ -1,36 +1,36 @@
package com.intellij.vcs.log.data;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.vcs.log.TimedVcsCommit;
import com.intellij.vcs.log.graph.GraphCommit;
import org.jetbrains.annotations.NotNull;
import java.util.*;
public class VcsLogMultiRepoJoiner {
public class VcsLogMultiRepoJoiner<CommitId> {
@NotNull
public List<? extends TimedVcsCommit> join(@NotNull Collection<List<? extends TimedVcsCommit>> logsFromRepos) {
public List<? extends GraphCommit<CommitId>> join(@NotNull Collection<List<? extends GraphCommit<CommitId>>> logsFromRepos) {
if (logsFromRepos.size() == 1) {
return logsFromRepos.iterator().next();
}
int size = 0;
for (List<? extends TimedVcsCommit> repo : logsFromRepos) {
for (List<? extends GraphCommit<CommitId>> repo : logsFromRepos) {
size += repo.size();
}
List<TimedVcsCommit> result = new ArrayList<TimedVcsCommit>(size);
List<GraphCommit<CommitId>> result = new ArrayList<GraphCommit<CommitId>>(size);
Map<TimedVcsCommit, Iterator<? extends TimedVcsCommit>> nextCommits = ContainerUtil.newHashMap();
for (List<? extends TimedVcsCommit> log : logsFromRepos) {
Iterator<? extends TimedVcsCommit> iterator = log.iterator();
Map<GraphCommit<CommitId>, Iterator<? extends GraphCommit<CommitId>>> nextCommits = ContainerUtil.newHashMap();
for (List<? extends GraphCommit<CommitId>> log : logsFromRepos) {
Iterator<? extends GraphCommit<CommitId>> iterator = log.iterator();
if (iterator.hasNext()) {
nextCommits.put(iterator.next(), iterator);
}
}
while (!nextCommits.isEmpty()) {
TimedVcsCommit lastCommit = findLatestCommit(nextCommits.keySet());
Iterator<? extends TimedVcsCommit> iterator = nextCommits.get(lastCommit);
GraphCommit<CommitId> lastCommit = findLatestCommit(nextCommits.keySet());
Iterator<? extends GraphCommit<CommitId>> iterator = nextCommits.get(lastCommit);
result.add(lastCommit);
nextCommits.remove(lastCommit);
@@ -43,10 +43,10 @@ public class VcsLogMultiRepoJoiner {
}
@NotNull
private static TimedVcsCommit findLatestCommit(@NotNull Set<TimedVcsCommit> commits) {
private GraphCommit<CommitId> findLatestCommit(@NotNull Set<GraphCommit<CommitId>> commits) {
long maxTimeStamp = Long.MIN_VALUE;
TimedVcsCommit lastCommit = null;
for (TimedVcsCommit commit : commits) {
GraphCommit<CommitId> lastCommit = null;
for (GraphCommit<CommitId> commit : commits) {
if (commit.getTimestamp() >= maxTimeStamp) {
maxTimeStamp = commit.getTimestamp();
lastCommit = commit;
@@ -96,11 +96,11 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
Map<VirtualFile, Collection<VcsRef>> refs = loadRefsFromVcs(myProviders);
Set<VirtualFile> roots = myProviders.keySet();
Map<VirtualFile, VcsLogProvider.Requirements> requirements = prepareSimpleRequirements(roots, myRecentCommitCount);
Map<VirtualFile, List<? extends TimedVcsCommit>> commits = loadRecentCommitsFromVcs(myProviders, requirements,
myUserRegistry, myTopCommitsDetailsCache);
List<? extends TimedVcsCommit> compoundLog = compound(commits.values());
List<GraphCommit<Integer>> compactedLog = compactCommits(compoundLog, myHashMap);
DataPack dataPack = DataPack.build(compactedLog, new RefsModel(refs, myHashMap.asIndexGetter()),
Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = loadRecentCommitsFromVcs(myProviders, requirements,
myUserRegistry, myTopCommitsDetailsCache,
myHashMap);
List<? extends GraphCommit<Integer>> compoundLog = compound(commits.values());
DataPack dataPack = DataPack.build(compoundLog, new RefsModel(refs, myHashMap.asIndexGetter()),
myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, false);
mySingleTaskController.request(RefreshRequest.RELOAD_ALL); // build/rebuild the full log in bg
return dataPack;
@@ -152,19 +152,21 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
}
@NotNull
private static Map<VirtualFile, List<? extends TimedVcsCommit>> loadRecentCommitsFromVcs(@NotNull Map<VirtualFile, VcsLogProvider> providers,
@NotNull final Map<VirtualFile, VcsLogProvider.Requirements> requirements,
@NotNull final VcsUserRegistryImpl userRegistry,
@NotNull final Map<Hash, VcsCommitMetadata> topCommitsDetailsCache)
throws VcsException {
private static Map<VirtualFile, List<? extends GraphCommit<Integer>>> loadRecentCommitsFromVcs(
@NotNull Map<VirtualFile, VcsLogProvider> providers,
@NotNull final Map<VirtualFile, VcsLogProvider.Requirements> requirements,
@NotNull final VcsUserRegistryImpl userRegistry,
@NotNull final Map<Hash, VcsCommitMetadata> topCommitsDetailsCache,
@NotNull final VcsLogHashMap hashMap) throws VcsException
{
final StopWatch sw = StopWatch.start("loading commits");
final Map<VirtualFile, List<? extends TimedVcsCommit>> commits = ContainerUtil.newHashMap();
final Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = ContainerUtil.newHashMap();
new ProviderIterator() {
@Override
public void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException {
List<? extends VcsCommitMetadata> metadatas = provider.readFirstBlock(root, requirements.get(root));
storeUsersAndDetails(metadatas, userRegistry, topCommitsDetailsCache);
commits.put(root, metadatas);
commits.put(root, compactCommits(metadatas, hashMap));
sw.rootCompleted(root);
}
}.iterate(providers);
@@ -177,9 +179,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
* Compounds logs from different repositories into a single multi-repository log.
*/
@NotNull
private static List<? extends TimedVcsCommit> compound(@NotNull Collection<List<? extends TimedVcsCommit>> commits) {
private static List<? extends GraphCommit<Integer>> compound(@NotNull Collection<List<? extends GraphCommit<Integer>>> commits) {
StopWatch sw = StopWatch.start("multi-repo join");
List<? extends TimedVcsCommit> joined = new VcsLogMultiRepoJoiner().join(commits);
List<? extends GraphCommit<Integer>> joined = new VcsLogMultiRepoJoiner<Integer>().join(commits);
sw.report();
return joined;
}
@@ -192,8 +194,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
@NotNull
@Override
public GraphCommit<Integer> fun(@NotNull TimedVcsCommit commit) {
return new GraphCommitImpl<Integer>(hashMap.getCommitIndex(commit.getId()),
ContainerUtil.map(commit.getParents(), hashMap.asIndexGetter()), commit.getTimestamp());
return compactCommit(commit, hashMap);
}
});
hashMap.flush();
@@ -201,6 +202,12 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
return map;
}
@NotNull
private static GraphCommitImpl<Integer> compactCommit(@NotNull TimedVcsCommit commit, @NotNull VcsLogHashMap hashMap) {
return new GraphCommitImpl<Integer>(hashMap.getCommitIndex(commit.getId()),
ContainerUtil.map(commit.getParents(), hashMap.asIndexGetter()), commit.getTimestamp());
}
private static void storeUsersAndDetails(@NotNull List<? extends VcsCommitMetadata> metadatas, @NotNull VcsUserRegistryImpl userRegistry,
@NotNull Map<Hash, VcsCommitMetadata> topCommitsDetailsCache) {
for (VcsCommitMetadata detail : metadatas) {
@@ -218,9 +225,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
private final Map<VirtualFile, LogAndRefs> myLoadedInfos = ContainerUtil.newHashMap();
private class LogAndRefs {
List<? extends TimedVcsCommit> log;
List<? extends GraphCommit<Integer>> log;
Collection<VcsRef> refs;
LogAndRefs(Collection<VcsRef> refs, List<? extends TimedVcsCommit> commits) {
LogAndRefs(Collection<VcsRef> refs, List<? extends GraphCommit<Integer>> commits) {
this.refs = refs;
this.log = commits;
}
@@ -266,16 +273,16 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
try {
if (permanentGraph != null) {
loadLogAndRefs(roots, currentRefs, myRecentCommitCount);
List<? extends TimedVcsCommit> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
new Function<LogAndRefs, List<? extends TimedVcsCommit>>() {
List<? extends GraphCommit<Integer>> compoundLog = compound(ContainerUtil.map(myLoadedInfos.values(),
new Function<LogAndRefs, List<? extends GraphCommit<Integer>>>() {
@Override
public List<? extends TimedVcsCommit> fun(LogAndRefs refs) {
public List<? extends GraphCommit<Integer>> fun(
LogAndRefs refs) {
return refs.log;
}
}));
List<GraphCommit<Integer>> preparedLog = compactCommits(compoundLog, myHashMap);
Map<VirtualFile, Collection<VcsRef>> allNewRefs = getAllNewRefs(myLoadedInfos, currentRefs);
List<GraphCommit<Integer>> joinedFullLog = join(preparedLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
List<GraphCommit<Integer>> joinedFullLog = join(compoundLog, permanentGraph.getAllCommits(), currentRefs, allNewRefs);
if (joinedFullLog != null) {
return DataPack.build(joinedFullLog, new RefsModel(allNewRefs, myHashMap.asIndexGetter()),
myHashMap.asIndexGetter(), myHashMap.asHashGetter(), myProviders, true);
@@ -310,8 +317,9 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
Map<VirtualFile, VcsLogProvider> providers = getProviders(roots);
Map<VirtualFile, Collection<VcsRef>> refs = loadRefsFromVcs(providers);
Map<VirtualFile, VcsLogProvider.Requirements> requirements = prepareRequirements(roots, commitCount, prevRefs, refs);
Map<VirtualFile, List<? extends TimedVcsCommit>> commits = loadRecentCommitsFromVcs(providers, requirements,
myUserRegistry, myTopCommitsDetailsCache);
Map<VirtualFile, List<? extends GraphCommit<Integer>>> commits = loadRecentCommitsFromVcs(providers, requirements,
myUserRegistry, myTopCommitsDetailsCache,
myHashMap);
for (VirtualFile root : roots) {
myLoadedInfos.put(root, new LogAndRefs(refs.get(root), commits.get(root)));
}
@@ -345,7 +353,7 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
}
@Nullable
private List<GraphCommit<Integer>> join(@NotNull List<GraphCommit<Integer>> recentCommits, @NotNull List<GraphCommit<Integer>> fullLog,
private List<GraphCommit<Integer>> join(@NotNull List<? extends GraphCommit<Integer>> recentCommits, @NotNull List<GraphCommit<Integer>> fullLog,
@NotNull Map<VirtualFile, Collection<VcsRef>> previousRefs,
@NotNull Map<VirtualFile, Collection<VcsRef>> newRefs) {
StopWatch sw = StopWatch.start("joining new commits");
@@ -374,9 +382,8 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
@NotNull
private Pair<PermanentGraph<Integer>, Map<VirtualFile, Collection<VcsRef>>> loadFullLog() throws VcsException {
StopWatch sw = StopWatch.start("full log reload");
Collection<List<? extends TimedVcsCommit>> commits = readFullLogFromVcs();
List<? extends TimedVcsCommit> compoundLog = compound(commits);
List<GraphCommit<Integer>> graphCommits = compactCommits(compoundLog, myHashMap);
Collection<List<? extends GraphCommit<Integer>>> commits = readFullLogFromVcs();
List<? extends GraphCommit<Integer>> graphCommits = compound(commits);
Map<VirtualFile, Collection<VcsRef>> refMap = loadRefsFromVcs(myProviders);
PermanentGraph<Integer> permanentGraph = DataPack.buildPermanentGraph(graphCommits, new RefsModel(refMap, myHashMap.asIndexGetter()),
myHashMap.asIndexGetter(),
@@ -386,24 +393,31 @@ public class VcsLogRefresherImpl implements VcsLogRefresher {
}
@NotNull
private Collection<List<? extends TimedVcsCommit>> readFullLogFromVcs() throws VcsException {
private Collection<List<? extends GraphCommit<Integer>>> readFullLogFromVcs() throws VcsException {
final StopWatch sw = StopWatch.start("read full log from VCS");
final Collection<List<? extends TimedVcsCommit>> commits = ContainerUtil.newArrayList();
final Collection<List<? extends GraphCommit<Integer>>> logs = ContainerUtil.newArrayList();
new ProviderIterator() {
@Override
void each(@NotNull VirtualFile root, @NotNull VcsLogProvider provider) throws VcsException {
commits.add(provider.readAllHashes(root, new Consumer<VcsUser>() {
final List<GraphCommit<Integer>> graphCommits = ContainerUtil.newArrayList();
provider.readAllHashes(root, new Consumer<VcsUser>() {
@Override
public void consume(@NotNull VcsUser user) {
myUserRegistry.addUser(user);
}
}));
}, new Consumer<TimedVcsCommit>() {
@Override
public void consume(TimedVcsCommit commit) {
graphCommits.add(compactCommit(commit, myHashMap));
}
});
logs.add(graphCommits);
sw.rootCompleted(root);
}
}.iterate(myProviders);
myUserRegistry.flush();
sw.report();
return commits;
return logs;
}
}
@@ -93,9 +93,9 @@ public class TestVcsLogProvider implements VcsLogProvider {
return ContainerUtil.map(myCommits.subList(0, requirements.getCommitCount()), myCommitToMetadataConvertor);
}
@NotNull
@Override
public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
@NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
try {
myFullLogSemaphore.acquire();
}
@@ -103,7 +103,9 @@ public class TestVcsLogProvider implements VcsLogProvider {
throw new RuntimeException(e);
}
assertRoot(root);
return myCommits;
for (TimedVcsCommit commit : myCommits) {
commitConsumer.consume(commit);
}
}
private void assertRoot(@NotNull VirtualFile root) {
@@ -15,7 +15,6 @@
*/
package com.intellij.xdebugger.impl.actions.handlers;
import com.intellij.xdebugger.XDebuggerUtil;
import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler;
import com.intellij.xdebugger.impl.XDebuggerUtilImpl;
import com.intellij.xdebugger.XDebugSession;
@@ -34,9 +33,7 @@ public class XDebuggerRunToCursorActionHandler extends XDebuggerSuspendedActionH
}
protected boolean isEnabled(final @NotNull XDebugSession session, final DataContext dataContext) {
if (!super.isEnabled(session, dataContext)) return false;
XSourcePosition position = XDebuggerUtilImpl.getCaretPosition(session.getProject(), dataContext);
return position != null && XDebuggerUtil.getInstance().canPutBreakpointAt(session.getProject(), position.getFile(), position.getLine());
return super.isEnabled(session, dataContext) && XDebuggerUtilImpl.getCaretPosition(session.getProject(), dataContext) != null;
}
protected void perform(@NotNull final XDebugSession session, final DataContext dataContext) {
@@ -104,6 +104,7 @@ public class XValueHint extends AbstractValueHint {
public void evaluated(@NotNull final XValue result) {
result.computePresentation(new XValueNodePresentationConfigurator.ConfigurableXValueNodeImpl() {
private XFullValueEvaluator myFullValueEvaluator;
private boolean myShown = false;
@Override
public void applyPresentation(@Nullable Icon icon,
@@ -131,7 +132,7 @@ public class XValueHint extends AbstractValueHint {
}
showHint(component);
}
else if (getType() == ValueHintType.MOUSE_CLICK_HINT) {
else if (getType() == ValueHintType.MOUSE_CLICK_HINT && !myShown) {
showTree(result);
}
else {
@@ -143,6 +144,7 @@ public class XValueHint extends AbstractValueHint {
});
showHint(component);
}
myShown = true;
}
@Override
@@ -520,9 +520,19 @@ public class GitHistoryUtils {
@NotNull VirtualFile root,
@NotNull final Consumer<VcsUser> userRegistry,
@NotNull List<String> parameters) throws VcsException {
List<TimedVcsCommit> collector = ContainerUtil.newArrayList();
readCommits(project, root, userRegistry, parameters, new CollectConsumer<TimedVcsCommit>(collector));
return collector;
}
public static void readCommits(@NotNull final Project project,
@NotNull VirtualFile root,
@NotNull final Consumer<VcsUser> userRegistry,
@NotNull List<String> parameters,
@NotNull final Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
final VcsLogObjectsFactory factory = getObjectsFactoryWithDisposeCheck(project);
if (factory == null) {
return Collections.emptyList();
return;
}
final int COMMIT_BUFFER = 1000;
@@ -536,8 +546,6 @@ public class GitHistoryUtils {
h.addParameters(parameters);
h.endOptions();
final List<TimedVcsCommit> commits = ContainerUtil.newArrayList();
final StringBuilder record = new StringBuilder();
final AtomicInteger records = new AtomicInteger();
final Ref<VcsException> ex = new Ref<VcsException>();
@@ -560,7 +568,10 @@ public class GitHistoryUtils {
afterParseRemainder = line.substring(recordEnd + 1);
}
if (afterParseRemainder != null && records.incrementAndGet() > COMMIT_BUFFER) { // null means can't parse now
commits.addAll(parseCommit(parser, record, userRegistry, factory));
List<TimedVcsCommit> commits = parseCommit(parser, record, userRegistry, factory);
for (TimedVcsCommit commit : commits) {
commitConsumer.consume(commit);
}
record.setLength(0);
record.append(afterParseRemainder);
}
@@ -573,7 +584,10 @@ public class GitHistoryUtils {
@Override
public void processTerminated(int exitCode) {
try {
commits.addAll(parseCommit(parser, record, userRegistry, factory));
List<TimedVcsCommit> commits = parseCommit(parser, record, userRegistry, factory);
for (TimedVcsCommit commit : commits) {
commitConsumer.consume(commit);
}
}
catch (Exception e) {
ex.set(new VcsException(e));
@@ -589,7 +603,6 @@ public class GitHistoryUtils {
if (!ex.isNull()) {
throw ex.get();
}
return commits;
}
@NotNull
@@ -27,49 +27,34 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
class GitBekParentFixer {
@NotNull
private final static String MAGIC_TEXT = "Merge remote";
@NotNull
private final VcsLogFilterCollection MAGIC_FILTER = createVcsLogFilterCollection();
@NotNull private static final String MAGIC_TEXT = "Merge remote";
@NotNull private static final VcsLogFilterCollection MAGIC_FILTER = createVcsLogFilterCollection();
@NotNull
private final VirtualFile myRoot;
@NotNull
private final GitLogProvider myGitLogProvider;
@NotNull
private final List<TimedVcsCommit> myAllCommits;
@NotNull private final Set<Hash> myWrongCommits;
GitBekParentFixer(@NotNull VirtualFile root, @NotNull GitLogProvider gitLogProvider, @NotNull List<TimedVcsCommit> allCommits) {
myRoot = root;
myGitLogProvider = gitLogProvider;
myAllCommits = allCommits;
private GitBekParentFixer(@NotNull Set<Hash> wrongCommits) {
myWrongCommits = wrongCommits;
}
@NotNull
List<TimedVcsCommit> getCorrectCommits() throws VcsException {
if (!BekSorter.isBekEnabled())
return myAllCommits;
final Set<Hash> wrongCommits = getWrongCommits();
return new AbstractList<TimedVcsCommit>() {
@Override
public TimedVcsCommit get(int index) {
TimedVcsCommit commit = myAllCommits.get(index);
if (!wrongCommits.contains(commit.getId()))
return commit;
return reverseParents(commit);
}
@Override
public int size() {
return myAllCommits.size();
}
};
static GitBekParentFixer prepare(@NotNull VirtualFile root, @NotNull GitLogProvider provider) throws VcsException {
if (!BekSorter.isBekEnabled()) {
return new GitBekParentFixer(Collections.<Hash>emptySet());
}
return new GitBekParentFixer(getWrongCommits(provider, root));
}
private Set<Hash> getWrongCommits() throws VcsException {
List<TimedVcsCommit> commitsMatchingFilter = myGitLogProvider.getCommitsMatchingFilter(myRoot, MAGIC_FILTER, -1);
@NotNull
TimedVcsCommit fixCommit(@NotNull TimedVcsCommit commit) {
if (!myWrongCommits.contains(commit.getId())) {
return commit;
}
return reverseParents(commit);
}
@NotNull
private static Set<Hash> getWrongCommits(@NotNull GitLogProvider provider, @NotNull VirtualFile root) throws VcsException {
List<TimedVcsCommit> commitsMatchingFilter = provider.getCommitsMatchingFilter(root, MAGIC_FILTER, -1);
return ContainerUtil.map2Set(commitsMatchingFilter, new Function<TimedVcsCommit, Hash>() {
@Override
public Hash fun(TimedVcsCommit timedVcsCommit) {
@@ -154,18 +154,23 @@ public class GitLogProvider implements VcsLogProvider {
});
}
@NotNull
@Override
public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
@NotNull final Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
if (!isRepositoryReady(root)) {
return Collections.emptyList();
return;
}
List<String> parameters = new ArrayList<String>(GitHistoryUtils.LOG_ALL);
parameters.add("--sparse");
List<TimedVcsCommit> timedVcsCommits = GitHistoryUtils.readCommits(myProject, root, userRegistry, parameters);
return new GitBekParentFixer(root, this, timedVcsCommits).getCorrectCommits();
final GitBekParentFixer parentFixer = GitBekParentFixer.prepare(root, this);
GitHistoryUtils.readCommits(myProject, root, userRegistry, parameters, new Consumer<TimedVcsCommit>() {
@Override
public void consume(TimedVcsCommit commit) {
commitConsumer.consume(parentFixer.fixCommit(commit));
}
});
}
@NotNull
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.util.ArrayUtil;
import com.intellij.util.CollectConsumer;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
@@ -84,9 +85,10 @@ public class GitLogProviderTest extends GitSingleRepoTest {
prepareSomeHistory();
createTaggedBranch();
List<VcsCommitMetadata> expectedLog = log();
@SuppressWarnings("unchecked")
List<TimedVcsCommit> actualLog = myLogProvider.readAllHashes(myProjectRoot, Consumer.EMPTY_CONSUMER);
assertOrderedEquals(expectedLog, actualLog);
List<TimedVcsCommit> collector = ContainerUtil.newArrayList();
//noinspection unchecked
myLogProvider.readAllHashes(myProjectRoot, Consumer.EMPTY_CONSUMER, new CollectConsumer<TimedVcsCommit>(collector));
assertOrderedEquals(expectedLog, collector);
}
public void test_get_current_user() throws Exception {
@@ -64,10 +64,13 @@ public class HgLogProvider implements VcsLogProvider {
return HgHistoryUtil.loadMetadata(myProject, root, requirements.getCommitCount(), Collections.<String>emptyList());
}
@NotNull
@Override
public List<TimedVcsCommit> readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry) throws VcsException {
return HgHistoryUtil.readAllHashes(myProject, root, userRegistry, Collections.<String>emptyList());
public void readAllHashes(@NotNull VirtualFile root, @NotNull Consumer<VcsUser> userRegistry,
@NotNull Consumer<TimedVcsCommit> commitConsumer) throws VcsException {
List<TimedVcsCommit> commits = HgHistoryUtil.readAllHashes(myProject, root, userRegistry, Collections.<String>emptyList());
for (TimedVcsCommit commit : commits) {
commitConsumer.consume(commit);
}
}
@NotNull
+1 -2
View File
@@ -331,8 +331,7 @@ private layoutWin(Map args, String target) {
}
winScripts(target, ch, "pycharm.bat", args)
winVMOptions(target, null, "pycharm.exe")
winVMOptions(target, null, "pycharm.exe", "pycharm64.exe")
ant.copy(file: "$home/python/help/pycharmhelp.jar", todir: "$target/help", failonerror: false)
}
+2 -2
View File
@@ -1,5 +1,5 @@
<project name="PyCharm Educational Edition" default="all">
<property name="project.home" value="${basedir}/../.."/>
<property name="project.home" value="${basedir}/../../.."/>
<property name="python.home" value="${basedir}"/>
<property name="out.dir" value="${project.home}/out"/>
<property name="tmp.dir" value="${project.home}/out/tmp"/>
@@ -30,7 +30,7 @@
</macrodef>
<target name="build" depends="init">
<call_gant script="${python.home}/build/pycharm_edu_build.gant"/>
<call_gant script="${python.home}/pycharm_edu_build.gant"/>
</target>
<!--<target name="plugin" depends="init">-->
+6 -6
View File
@@ -29,7 +29,7 @@ setProperty("pythonCommunityHome", "$home/python")
setProperty("pythonEduHome", "$home/python/edu")
// load ApplicationInfo.xml properties
ant.xmlproperty(file: "$pythonCommunityHome/resources/idea/PyCharmEduApplicationInfo.xml", collapseAttributes: "true")
ant.xmlproperty(file: "$pythonEduHome/resources/idea/PyCharmEduApplicationInfo.xml", collapseAttributes: "true")
setProperty("system_selector", "PyCharm${p("component.version.major")}0")
setProperty("dryRun", false)
@@ -44,8 +44,8 @@ private List<String> pycharmPlatformApiModules() {
private List pycharmImplementationModules() { //modules to put into pycharm.jar
return [platformImplementationModules, "dom-impl", "python-community", "python-ide-community", "python-openapi", "python-psi-api",
"platform-main", "python-educational"].flatten()
return [platformImplementationModules, "dom-impl", "python-community", "python-ide-community", "python-educational", "python-openapi", "python-psi-api",
"platform-main"].flatten()
}
private List modules() {
@@ -182,7 +182,7 @@ public layoutEducational(String classesPath, Set usedJars) {
"$ch/platform/icons/src",
"$pythonEduHome/resources"]
buildWinLauncher("$ch", "$ch/bin/WinLauncher/WinLauncher.exe", launcher,
appInfo, "$pythonCommunityHome/build/pycharm_edu_launcher.properties", system_selector, resourcePaths)
appInfo, "$pythonEduHome/build/pycharm_edu_launcher.properties", system_selector, resourcePaths)
buildWinZip("${paths.artifacts}/pycharmPE-${buildNumber}.zip", [paths.distAll, paths.distWin])
@@ -199,11 +199,11 @@ private layoutPlugins(layouts) {
layouts.layoutPlugin("python-rest")
}
layouts.layoutEducationalPlugins(ch)
layouts.layoutCommunityPlugins(ch)
}
private String appInfoFile(String classesPath) {
return "$classesPath/python-community/idea/PyCharmEduApplicationInfo.xml"
return "$classesPath/python-educational/idea/PyCharmEduApplicationInfo.xml"
}
private layoutFull(Map args, String target, Set usedJars) {
@@ -1,293 +0,0 @@
<component>
<group id="navigation">
<feature
id="navigation.popup.class"
tip-file="GoToClass.html"
min-usage-count="3"
first-show="1"
successive-show="5"/>
<feature
id="navigation.popup.file"
tip-file="GoToClass.html"
min-usage-count="2"
first-show="3"
successive-show="5"/>
<feature
id="navigation.popup.symbol"
tip-file="GoToSymbol.html"
first-show="5"
successive-show="8"/>
<feature
id="SearchEverywhere"
tip-file="SearchEverywhere.html"
first-show="1"
successive-show="1"
min-usage-count="1"
/>
<feature
id="navigation.popup.camelprefix"
tip-file="CamelPrefixesInNavigationPopups.html"
min-usage-count="3"
first-show="4"
successive-show="7">
<dependency id="navigation.popup.class"/>
<dependency id="navigation.popup.file"/>
<dependency id="navigation.popup.symbol"/>
</feature>
<feature
id="navigation.popup.wildcards"
tip-file="WildcardsInNavigationPopups.html"
min-usage-count="2"
first-show="3"
successive-show="5">
<dependency id="navigation.popup.class"/>
<dependency id="navigation.popup.file"/>
<dependency id="navigation.popup.symbol"/>
</feature>
<feature
id="navigation.popup.file.structure"
tip-file="FileStructurePopup.html"
min-usage-count="3"
first-show="2"
successive-show="5"
/>
<feature
id="navigation.recent.files"
tip-file="RecentFiles.html"
min-usage-count="3"
first-show="3"
successive-show="5"
/>
<feature
id="navigation.select.in"
tip-file="SelectIn.html"
min-usage-count="3"
first-show="4"
successive-show="7"
/>
<feature
id="navigation.goto.declaration"
tip-file="GoToDeclaration.html"
min-usage-count="15"
first-show="1"
successive-show="4"
/>
<feature
id="navigation.goto.usages"
tip-file="ShowUsages.html"
min-usage-count="3"
first-show="5"
successive-show="5"/>
</group>
<group id="completion">
<feature
id="editing.completion.basic"
tip-file="CodeCompletion.html"
min-usage-count="15"
first-show="1"
successive-show="3"/>
<feature
id="editing.completion.replace"
tip-file="TabInLookups.html"
min-usage-count="10"
first-show="6"
successive-show="8"
/>
<feature
id="editing.completion.finishByCtrlDot"
tip-file="CtrlDotInLookups.html"
min-usage-count="7"
first-show="4"
successive-show="8"
/>
<feature
id="editing.completion.finishByDotEtc"
tip-file="DotEtcInLookups.html"
min-usage-count="7"
first-show="4"
successive-show="8"
/>
<feature
id="editing.completion.camelHumps"
tip-file="CamelHumpsInCodeCompletion.html"
min-usage-count="8"
first-show="5"
successive-show="7"
/>
<feature
id="editing.completion.cancelByControlArrows"
tip-file="CancelByControlArrows.html"
min-usage-count="10"
first-show="2"
successive-show="3"/>
<feature
id="editing.completion.changeSorting"
tip-file="ChangeSorting.html"
min-usage-count="10"
first-show="2"
successive-show="3"/>
</group>
<group id="editing">
<feature
id="editing.select.word"
tip-file="CtrlW.html"
min-usage-count="10"
first-show="2"
successive-show="4"/>
</group>
<group id="codeassists">
<feature
id="codeassists.quickjavadoc"
tip-file="QuickJavaDoc.html"
min-usage-count="3"
first-show="3"
successive-show="5"
/>
<feature
id="codeassists.quickdefinition"
tip-file="CtrlShiftI.html"
min-usage-count="9"
first-show="3"
successive-show="5"
/>
<feature
id="codeassists.quickdefinition.lookup"
tip-file="CtrlShiftIForLookup.html"
min-usage-count="1"
first-show="5"
successive-show="7">
<dependency id="codeassists.quickdefinition"/>
</feature>
<feature
id="codeassists.quickjavadoc.lookup"
tip-file="QuickJavaDocInLookups.html"
min-usage-count="1"
first-show="5"
successive-show="7">
<dependency id="codeassists.quickjavadoc"/>
</feature>
<feature
id="codeassists.quickjavadoc.ctrln"
tip-file="QuickJavaDocInLookups.html"
min-usage-count="1"
first-show="5"
successive-show="7">
<dependency id="codeassists.quickjavadoc"/>
</feature>
<feature
id="codeassists.surroundwith.statement"
tip-file="Surround.html"
first-show="5"
successive-show="5"
min-usage-count="4"
/>
<!--
<feature
id="codeassists.surroundwith.expression"
tip-file="Surround.html"
first-show="6"
successive-show="5"
min-usage-count="3"
/>
<feature
id="codeassists.comment.block"
tip-file="CommentCode.html"
first-show="6"
successive-show="5"
min-usage-count="3"
/>
-->
<feature
id="codeassists.comment.line"
tip-file="Comment.html"
first-show="6"
successive-show="5"
min-usage-count="3"
/>
</group>
<group id="refactoring">
<feature
id="refactoring.introduceVariable"
tip-file="IntroduceVariable.html"
min-usage-count="5"
first-show="1"
successive-show="3"
/>
<feature
id="refactoring.rename"
tip-file="Rename.html"
min-usage-count="2"
first-show="1"
successive-show="3"
/>
</group>
<group id="ui">
<feature
id="ui.tree.speedsearch"
tip-file="SpeedSearch.html"
first-show="5"
successive-show="4"
min-usage-count="6"
/>
<feature
id="ui.scheme.quickswitch"
tip-file="QuickSwitchScheme.html"
first-show="7"
successive-show="3"
min-usage-count="1"
/>
<feature
id="ui.recentchanges"
tip-file="RecentChanges.html"
first-show="5"
successive-show="5"
min-usage-count="1"
/>
<feature
id="ui.horizontal.scrolling"
tip-file="HorizontalScrolling.html"
first-show="1"
successive-show="1"
min-usage-count="1"
/>
<!-- TODO: Uncomment usage in InsertPathAction when FeatureUsageTracker goes to OpenApi
<feature
id="ui.commandLine.insertPath"
name="Insert path in command line"
tip-file="InsertPathShortcut.html"
first-show="6"
successive-show="5"
min-usage-count="3"
/>
-->
<feature id="navigation.popup.action"
tip-file="GoToAction.html"
first-show="7"
successive-show="3"
min-usage-count="1"/>
<feature
id="navigation.goto.inspection"
tip-file="GoToInspection.html"
min-usage-count="3"
first-show="5"
successive-show="5"/>
<feature id="find.recent.search"
tip-file="RecentSearch.html"
first-show="10"
successive-show="3"
min-usage-count="5"/>
<feature id="find.completion"
tip-file="CodeCompletionInSearch.html"
first-show="10"
successive-show="3"
min-usage-count="5"/>
</group>
</component>
@@ -1,68 +0,0 @@
<?xml version='1.0'?>
<list>
<option name="MAKO.SUBSTITUTION">
<value>
<option name="BACKGROUND" value="232364" />
<option name="EFFECT_TYPE" value="-1" />
</value>
</option>
<option name="MAKO.TAG">
<value>
<option name="EFFECT_TYPE" value="-1" />
</value>
</option>
<option name="PY.CLASS_DEFINITION">
<value>
<option name="FONT_TYPE" value="1" />
<option name="EFFECT_TYPE" value="1" />
</value>
</option>
<option name="PY.DECORATOR">
<value>
<option name="FOREGROUND" value="bbb529" />
<option name="EFFECT_TYPE" value="1" />
</value>
</option>
<option name="PY.FUNC_DEFINITION">
<value>
<option name="FONT_TYPE" value="1" />
<option name="EFFECT_TYPE" value="1" />
</value>
</option>
<option name="PY.KEYWORD">
<value>
<option name="FOREGROUND" value="cc7832" />
<option name="FONT_TYPE" value="1" />
</value>
</option>
<option name="PY.KEYWORD_ARGUMENT">
<value>
<option name="FOREGROUND" value="aa4926" />
</value>
</option>
<option name="PY.PREDEFINED_DEFINITION">
<value>
<option name="FOREGROUND" value="B200B2" />
</value>
</option>
<option name="PY.PREDEFINED_USAGE">
<value>
<option name="FOREGROUND" value="B200B2" />
</value>
</option>
<option name="PY.SELF_PARAMETER">
<value>
<option name="FOREGROUND" value="94558D" />
</value>
</option>
<option name="PY.STRING.B">
<value>
<option name="FOREGROUND" value="a5c261" />
</value>
</option>
<option name="PY.STRING.U">
<value>
<option name="FOREGROUND" value="008080" />
</value>
</option>
</list>
@@ -1,62 +0,0 @@
<?xml version='1.0'?>
<list>
<option name="MAKO.SUBSTITUTION">
<value>
<option name="BACKGROUND" value="E6E6FA" />
<option name="EFFECT_TYPE" value="-1" />
</value>
</option>
<option name="MAKO.TAG">
<value>
<option name="EFFECT_TYPE" value="-1" />
</value>
</option>
<option name="PY.BUILTIN_NAME">
<value>
<option name="FOREGROUND" value="80" />
</value>
</option>
<option name="PY.CLASS_DEFINITION">
<value>
<option name="FOREGROUND" value="000000" />
<option name="EFFECT_TYPE" value="1" />
</value>
</option>
<option name="PY.DECORATOR">
<value>
<option name="FOREGROUND" value="0000B2" />
</value>
</option>
<option name="PY.FUNC_DEFINITION">
<value>
<option name="FOREGROUND" value="000000" />
<option name="EFFECT_TYPE" value="1" />
</value>
</option>
<option name="PY.KEYWORD_ARGUMENT">
<value>
<option name="FOREGROUND" value="660099" />
</value>
</option>
<option name="PY.PREDEFINED_DEFINITION">
<value>
<option name="FOREGROUND" value="B200B2" />
</value>
</option>
<option name="PY.PREDEFINED_USAGE">
<value>
<option name="FOREGROUND" value="B200B2" />
</value>
</option>
<option name="PY.SELF_PARAMETER">
<value>
<option name="FOREGROUND" value="94558D" />
</value>
</option>
<option name="PY.STRING.U">
<value>
<option name="FOREGROUND" value="008080" />
<option name="FONT_TYPE" value="1" />
</value>
</option>
</list>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 866 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 534 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1019 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 341 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 880 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 585 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 668 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 628 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 981 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1020 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 227 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 715 B

Some files were not shown because too many files have changed in this diff Show More