diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index d23727fb896d..df4487148e04 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -268,7 +268,7 @@ public def layoutCommunityPlugins(String home) { } } - dir("properties") { + pluginDir("properties") { dir("lib") { jar("properties.jar") { module("properties-psi-api") diff --git a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java index 1e2cc6c22c4e..c84a6aa54edf 100644 --- a/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java +++ b/java/idea-ui/src/com/intellij/ide/projectWizard/ProjectTypeStep.java @@ -112,7 +112,6 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable { private final MultiMap myTemplatesMap; private boolean myRemoteTemplatesLoaded; private Cards myCurrentCard; - private boolean myNeedDownload; public ProjectTypeStep(WizardContext context, NewProjectWizard wizard, ModulesProvider modulesProvider) { myContext = context; @@ -163,7 +162,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable { myConfigurationUpdater = new ModuleBuilder.ModuleConfigurationUpdater() { @Override public void update(@NotNull Module module, @NotNull ModifiableRootModel rootModel) { - if (myCurrentCard == Cards.FRAMEWORKS) { + if (isFrameworksMode()) { myFrameworksPanel.addSupport(module, rootModel); } } @@ -210,6 +209,10 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable { myTemplatesList.restoreSelection(); } + private boolean isFrameworksMode() { + return myCurrentCard == Cards.FRAMEWORKS && getSelectedBuilder().equals(myContext.getProjectBuilder()); + } + private List fillTemplatesMap(WizardContext context) { List builders = ModuleBuilder.getAllBuilders(); @@ -306,7 +309,6 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable { // new TemplatesGroup selected public void projectTypeChanged() { - myNeedDownload = false; TemplatesGroup group = getSelectedGroup(); if (group == null) return; PropertiesComponent.getInstance().setValue(PROJECT_WIZARD_GROUP, group.getId() ); @@ -332,7 +334,6 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable { myFrameworksPanel.setProviders(providers); } getSelectedBuilder().addModuleConfigurationUpdater(myConfigurationUpdater); - myNeedDownload = true; showCard(FRAMEWORKS_CARD); } @@ -412,7 +413,7 @@ public class ProjectTypeStep extends ModuleWizardStep implements Disposable { } public void onWizardFinished() throws CommitStepException { - if (myNeedDownload) { + if (isFrameworksMode()) { boolean ok = myFrameworksPanel.downloadLibraries(); if (!ok) { int answer = Messages.showYesNoDialog(getComponent(), diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java index eae38cc03a17..715da62323de 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImplementMethodsFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -50,7 +50,7 @@ public class ImplementMethodsFix extends LocalQuickFixAndIntentionActionOnPsiEle @Override @NotNull public String getFamilyName() { - return QuickFixBundle.message("implement.methods.fix"); + return getText(); } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java index 510a79e4705a..957893ffe680 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java @@ -113,6 +113,7 @@ public abstract class ImportClassFixBase classList = new ArrayList(classes.length); boolean isAnnotationReference = myElement.getParent() instanceof PsiAnnotation; + final PsiFile file = myElement.getContainingFile(); for (PsiClass aClass : classes) { if (isAnnotationReference && !aClass.isAnnotationType()) continue; if (JavaCompletionUtil.isInExcludedPackage(aClass, false)) continue; @@ -120,7 +121,7 @@ public abstract class ImportClassFixBase() { + @Override public String fun(final PsiExpression expr) { return expr.getText(); } @@ -294,8 +295,10 @@ public class InlineUtil { public static boolean allUsagesAreTailCalls(final PsiMethod method) { final List nonTailCallUsages = Collections.synchronizedList(new ArrayList()); boolean result = ProgressManager.getInstance().runProcessWithProgressSynchronously(new Runnable() { + @Override public void run() { ReferencesSearch.search(method).forEach(new Processor() { + @Override public boolean process(final PsiReference psiReference) { ProgressManager.checkCanceled(); if (getTailCallType(psiReference) == TailCallType.None) { diff --git a/java/java-psi-api/src/com/intellij/codeInsight/ImportFilter.java b/java/java-psi-api/src/com/intellij/codeInsight/ImportFilter.java index 4863b8217dc8..a862c9d1e2ef 100644 --- a/java/java-psi-api/src/com/intellij/codeInsight/ImportFilter.java +++ b/java/java-psi-api/src/com/intellij/codeInsight/ImportFilter.java @@ -1,7 +1,9 @@ package com.intellij.codeInsight; import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author Eugene.Kudelevsky @@ -9,11 +11,11 @@ import org.jetbrains.annotations.NotNull; public abstract class ImportFilter { public static final ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.importFilter"); - public abstract boolean shouldUseFullyQualifiedName(@NotNull String classQualifiedName); + public abstract boolean shouldUseFullyQualifiedName(@Nullable PsiFile targetFile, @NotNull String classQualifiedName); - public static boolean shouldImport(@NotNull String classQualifiedName) { + public static boolean shouldImport(@Nullable PsiFile targetFile, @NotNull String classQualifiedName) { for (ImportFilter filter : EP_NAME.getExtensions()) { - if (filter.shouldUseFullyQualifiedName(classQualifiedName)) { + if (filter.shouldUseFullyQualifiedName(targetFile, classQualifiedName)) { return false; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java index adb86e5ad49a..0de45be17786 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiImplUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -370,7 +370,7 @@ public class PsiImplUtil { // todo[r.sh] cache? @Nullable - public static Set getAnnotationTargets(PsiClass annotationType) { + public static Set getAnnotationTargets(@NotNull PsiClass annotationType) { if (!annotationType.isAnnotationType()) return null; PsiModifierList modifierList = annotationType.getModifierList(); if (modifierList == null) return null; diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java index 968d078f6e10..89d37921f11c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/AdvHighlightingTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,7 +49,7 @@ import java.io.File; import java.util.Collection; /** - * This class intended for "heavily-loaded" tests only, e.g. those need to setup separate project directory structure to run. + * This class intended for "heavy-loaded" tests only, e.g. those need to setup separate project directory structure to run. * For "lightweight" tests use LightAdvHighlightingTest. */ public class AdvHighlightingTest extends DaemonAnalyzerTestCase { diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java index 7d28d8ed12bd..eafc24d7d15f 100644 --- a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -189,7 +189,7 @@ public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase return findActionWithText(getAvailableActions(), text); } - public static IntentionAction findActionWithText(final List actions, final String text) { + public static IntentionAction findActionWithText(@NotNull List actions, final String text) { for (IntentionAction action : actions) { if (text.equals(action.getText())) { return action; diff --git a/platform/lang-api/src/com/intellij/lang/ExternalAnnotatorsFilter.java b/platform/analysis-api/src/com/intellij/lang/ExternalAnnotatorsFilter.java similarity index 96% rename from platform/lang-api/src/com/intellij/lang/ExternalAnnotatorsFilter.java rename to platform/analysis-api/src/com/intellij/lang/ExternalAnnotatorsFilter.java index e4050f0f491a..1ca4a369cc0d 100644 --- a/platform/lang-api/src/com/intellij/lang/ExternalAnnotatorsFilter.java +++ b/platform/analysis-api/src/com/intellij/lang/ExternalAnnotatorsFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/platform/lang-api/src/com/intellij/lang/ExternalLanguageAnnotators.java b/platform/analysis-api/src/com/intellij/lang/ExternalLanguageAnnotators.java similarity index 97% rename from platform/lang-api/src/com/intellij/lang/ExternalLanguageAnnotators.java rename to platform/analysis-api/src/com/intellij/lang/ExternalLanguageAnnotators.java index 4a46297597b9..90bd7a13f89a 100644 --- a/platform/lang-api/src/com/intellij/lang/ExternalLanguageAnnotators.java +++ b/platform/analysis-api/src/com/intellij/lang/ExternalLanguageAnnotators.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java b/platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java similarity index 98% rename from platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java rename to platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java index 9f8644c02708..9381a2a04c1b 100644 --- a/platform/lang-api/src/com/intellij/lang/annotation/ExternalAnnotator.java +++ b/platform/analysis-api/src/com/intellij/lang/annotation/ExternalAnnotator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java b/platform/analysis-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java similarity index 75% rename from platform/lang-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java rename to platform/analysis-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java index 54caec4262e6..f2a7c67be5c4 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ExternalAnnotatorInspectionVisitor.java @@ -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.codeInspection; import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl; @@ -19,7 +34,7 @@ public class ExternalAnnotatorInspectionVisitor extends PsiElementVisitor { private final ProblemsHolder myHolder; private final ExternalAnnotator myAnnotator; - private boolean myOnTheFly; + private final boolean myOnTheFly; public ExternalAnnotatorInspectionVisitor(ProblemsHolder holder, ExternalAnnotator annotator, boolean onTheFly) { myHolder = holder; @@ -27,17 +42,19 @@ public class ExternalAnnotatorInspectionVisitor extends PsiElementVisitor { myOnTheFly = onTheFly; } - public static ProblemDescriptor[] checkFileWithExternalAnnotator(PsiFile file, - InspectionManager manager, - boolean isOnTheFly, ExternalAnnotator annotator) { + @NotNull + public static ProblemDescriptor[] checkFileWithExternalAnnotator(@NotNull PsiFile file, + @NotNull InspectionManager manager, + boolean isOnTheFly, + @NotNull ExternalAnnotator annotator) { if (isOnTheFly) { // concrete JSLinterExternalAnnotator implementation does this work return ProblemDescriptor.EMPTY_ARRAY; } - Object info = annotator.collectInformation(file); + Init info = annotator.collectInformation(file); if (info != null) { - Object annotationResult = annotator.doAnnotate(info); + Result annotationResult = annotator.doAnnotate(info); if (annotationResult == null) { return ProblemDescriptor.EMPTY_ARRAY; } @@ -48,10 +65,11 @@ public class ExternalAnnotatorInspectionVisitor extends PsiElementVisitor { return ProblemDescriptor.EMPTY_ARRAY; } + @NotNull private static ProblemDescriptor[] convertToProblemDescriptors(@NotNull final List annotations, @NotNull final InspectionManager manager, @NotNull final PsiFile file) { - if (annotations.size() == 0) { + if (annotations.isEmpty()) { return ProblemDescriptor.EMPTY_ARRAY; } diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java index 45997b0579af..3ac277c96d8e 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -102,6 +102,7 @@ public class ProblemDescriptorBase extends CommonProblemDescriptorImpl implement return PsiTreeUtil.findCommonParent(startElement, endElement); } + @Override @Nullable public TextRange getTextRangeInElement() { return myTextRangeInElement; diff --git a/platform/core-api/src/com/intellij/openapi/application/ModalityState.java b/platform/core-api/src/com/intellij/openapi/application/ModalityState.java index fde756290433..7ade35e7ca71 100644 --- a/platform/core-api/src/com/intellij/openapi/application/ModalityState.java +++ b/platform/core-api/src/com/intellij/openapi/application/ModalityState.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,4 +63,7 @@ public abstract class ModalityState { } public abstract boolean dominates(@NotNull ModalityState anotherState); + + @Override + public abstract String toString(); } diff --git a/platform/core-api/src/com/intellij/patterns/ObjectPattern.java b/platform/core-api/src/com/intellij/patterns/ObjectPattern.java index a76ee94c6b73..cf9f751c9852 100644 --- a/platform/core-api/src/com/intellij/patterns/ObjectPattern.java +++ b/platform/core-api/src/com/intellij/patterns/ObjectPattern.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,11 +58,13 @@ public abstract class ObjectPattern> impl } public Self andNot(final ElementPattern pattern) { - return and(StandardPatterns.not(pattern)); + ElementPattern not = StandardPatterns.not(pattern); + return and(not); } - public Self andOr(final ElementPattern... patterns) { - return and(StandardPatterns.or(patterns)); + public Self andOr(@NotNull ElementPattern... patterns) { + ElementPattern or = StandardPatterns.or(patterns); + return and(or); } public Self and(final ElementPattern pattern) { diff --git a/platform/core-impl/src/com/intellij/mock/MockApplication.java b/platform/core-impl/src/com/intellij/mock/MockApplication.java index 5a888c827aa1..f331a7dd9c8f 100644 --- a/platform/core-impl/src/com/intellij/mock/MockApplication.java +++ b/platform/core-impl/src/com/intellij/mock/MockApplication.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -195,6 +195,11 @@ public class MockApplication extends MockComponentManager implements Application public boolean dominates(@NotNull ModalityState anotherState) { return false; } + + @Override + public String toString() { + return "NONE"; + } }; } return MODALITY_STATE_NONE; diff --git a/platform/editor-ui-api/src/com/intellij/openapi/editor/Editor.java b/platform/editor-ui-api/src/com/intellij/openapi/editor/Editor.java index 3a5d9d415257..bd63b43f1af3 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/editor/Editor.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/editor/Editor.java @@ -22,7 +22,6 @@ import com.intellij.openapi.editor.event.EditorMouseMotionListener; import com.intellij.openapi.editor.markup.MarkupModel; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.UserDataHolder; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/platform/lang-api/src/com/intellij/execution/actions/ConsoleActionsPostProcessor.java b/platform/lang-api/src/com/intellij/execution/actions/ConsoleActionsPostProcessor.java index 859cd8162108..792208811bd3 100644 --- a/platform/lang-api/src/com/intellij/execution/actions/ConsoleActionsPostProcessor.java +++ b/platform/lang-api/src/com/intellij/execution/actions/ConsoleActionsPostProcessor.java @@ -26,9 +26,9 @@ import org.jetbrains.annotations.NotNull; * @author Denis Zhdanov * @since 4/25/11 1:16 PM */ -public interface ConsoleActionsPostProcessor { +public abstract class ConsoleActionsPostProcessor { - ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.consoleActionsPostProcessor"); + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.consoleActionsPostProcessor"); /** * Allows to adjust actions to use within the given console instance. @@ -40,5 +40,12 @@ public interface ConsoleActionsPostProcessor { * @return actions to use within the given console instance (given actions may be returned by default) */ @NotNull - AnAction[] postProcess(@NotNull ConsoleView console, @NotNull AnAction[] actions); + public AnAction[] postProcess(@NotNull ConsoleView console, @NotNull AnAction[] actions) { + return actions; + } + + @NotNull + public AnAction[] postProcessPopupActions(@NotNull ConsoleView console, @NotNull AnAction[] actions) { + return actions; + } } diff --git a/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java b/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java index 020ff5658a98..485514fd9e58 100644 --- a/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java +++ b/platform/lang-api/src/com/intellij/ide/util/projectWizard/AbstractModuleBuilder.java @@ -53,4 +53,9 @@ public abstract class AbstractModuleBuilder extends ProjectBuilder { public abstract void setModuleFilePath(@NonNls String path); public abstract void setContentEntryPath(String moduleRootPath); + + @Override + public boolean equals(Object obj) { + return obj instanceof AbstractModuleBuilder && getBuilderId() != null && getBuilderId().equals(((AbstractModuleBuilder)obj).getBuilderId()); + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java index f07d31847302..f4563f47e53e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PsiChangeHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -107,9 +107,11 @@ public class PsiChangeHandler extends PsiTreeChangeAdapter implements Disposable application.invokeLater(new Runnable() { @Override public void run() { - EditorMarkupModel markupModel = (EditorMarkupModel)editor.getMarkupModel(); - PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument()); - TrafficLightRenderer.setOrRefreshErrorStripeRenderer(markupModel, myProject, editor.getDocument(), file); + if (!editor.isDisposed()) { + EditorMarkupModel markupModel = (EditorMarkupModel)editor.getMarkupModel(); + PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument()); + TrafficLightRenderer.setOrRefreshErrorStripeRenderer(markupModel, myProject, editor.getDocument(), file); + } } }, ModalityState.stateForComponent(editor.getComponent()), myProject.getDisposed()); } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java index c5ad2799230e..79e0220c1174 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ConsoleViewImpl.java @@ -922,7 +922,21 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo if (group == null) { group = (ActionGroup)actionManager.getAction(CONSOLE_VIEW_POPUP_MENU); } - final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.EDITOR_POPUP, group); + final ConsoleActionsPostProcessor[] postProcessors = Extensions.getExtensions(ConsoleActionsPostProcessor.EP_NAME); + AnAction[] result = group.getChildren(null); + + for (ConsoleActionsPostProcessor postProcessor : postProcessors) { + result = postProcessor.postProcessPopupActions(this, result); + } + final AnAction[] processedActions = result; + final ActionGroup processedGroup = new ActionGroup() { + @NotNull + @Override + public AnAction[] getChildren(@Nullable AnActionEvent e) { + return processedActions; + } + }; + final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.EDITOR_POPUP, processedGroup); menu.getComponent().show(mouseEvent.getComponent(), mouseEvent.getX(), mouseEvent.getY()); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java index eeb09fbec56a..1d9ef8c6525b 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/file/impl/PsiVFSListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,6 @@ import com.intellij.psi.impl.PsiDocumentManagerImpl; import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.psi.impl.PsiTreeChangeEventImpl; import com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl; -import com.intellij.util.FileContentUtil; import com.intellij.util.FileContentUtilCore; import com.intellij.util.messages.MessageBusConnection; import org.jetbrains.annotations.NotNull; diff --git a/platform/platform-api/src/com/intellij/openapi/ui/dialogs/AgreementDialog.java b/platform/platform-api/src/com/intellij/openapi/ui/dialogs/AgreementDialog.java new file mode 100644 index 000000000000..9addc1cf15ef --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/ui/dialogs/AgreementDialog.java @@ -0,0 +1,104 @@ +/* + * 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.openapi.ui.dialogs; + +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.ui.ScrollPaneFactory; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.text.MessageFormat; +import java.util.ResourceBundle; + +public class AgreementDialog extends DialogWrapper { + private final Font myFont = new Font("SansSerif", Font.PLAIN, 12); + private final ResourceBundle myBundle = ResourceBundle.getBundle("messages.LicenseCommonBundle"); + + private final String myText; + private JCheckBox myAcceptCheckBox; + private boolean myOK = false; + + public AgreementDialog(String text, String programName) { + super(null, false, true); + getPeer().setAppIcons(); + + myText = text; + String title; + if (programName != null) { + title = MessageFormat.format(myBundle.getString("license.agreement.title.for"), programName); + } + else { + title = myBundle.getString("license.agreement.title"); + } + + setTitle(title); + + init(); + + getOKAction().setEnabled(false); + } + + protected void doOKAction() { + myOK = true; + super.doOKAction(); + } + + protected JComponent createNorthPanel() { + JPanel panel = new JPanel(new BorderLayout()); + String text = myBundle.getString("license.agreement.prompt"); + JLabel licensePrompt = new JLabel(text); + licensePrompt.setFocusable(false); + licensePrompt.setFont(myFont); + licensePrompt.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 5)); + panel.add(licensePrompt, BorderLayout.WEST); + panel.add(new JPanel(), BorderLayout.CENTER); + return panel; + } + + public boolean isAgreed() { + return myOK && myAcceptCheckBox.isSelected(); + } + + protected JComponent createCenterPanel() { + JPanel optionsPanel = new JPanel(new BorderLayout()); + JTextArea licenseTextArea = new JTextArea(myText, 20, 50); + licenseTextArea.getCaret().setDot(0); + licenseTextArea.setFont(myFont); + licenseTextArea.setLineWrap(true); + licenseTextArea.setWrapStyleWord(true); + licenseTextArea.setEditable(false); + JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(licenseTextArea); + + optionsPanel.add(scrollPane, BorderLayout.CENTER); + JPanel agreePanel = new JPanel(new GridLayout(1, 1)); + agreePanel.setBorder(BorderFactory.createEmptyBorder(10, 5, 5, 5)); + myAcceptCheckBox = new JCheckBox(myBundle.getString("license.agreement.accept.checkbox")); + myAcceptCheckBox.setMnemonic(myAcceptCheckBox.getText().charAt(0)); + myAcceptCheckBox.setFont(myFont); + + agreePanel.add(myAcceptCheckBox); + optionsPanel.add(agreePanel, BorderLayout.SOUTH); + + myAcceptCheckBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent event) { + getOKAction().setEnabled(myAcceptCheckBox.isSelected()); + } + }); + return optionsPanel; + } +} diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java index 1605a167cc7f..9cafa8debef1 100644 --- a/platform/platform-api/src/com/intellij/util/Alarm.java +++ b/platform/platform-api/src/com/intellij/util/Alarm.java @@ -357,7 +357,7 @@ public class Alarm implements Disposable { @Override public String toString() { Runnable task = getTask(); - return super.toString() + (task != null ? " "+task:null); + return super.toString() + (task != null ? ": "+task : ""); } } diff --git a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateConfigurable.java b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateConfigurable.java index f28b103a5cd8..8c706bc59283 100644 --- a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateConfigurable.java +++ b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateConfigurable.java @@ -27,7 +27,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; -import static com.intellij.util.net.ssl.CertificateWrapper.CommonField.COMMON_NAME; +import static com.intellij.util.net.ssl.CertificateUtil.getCommonName; import static com.intellij.util.net.ssl.ConfirmingTrustManager.MutableTrustManager; /** @@ -63,7 +63,7 @@ public class CertificateConfigurable implements SearchableConfigurable, Configur if (!new CertificateWrapper(certificate).isValid()) { setForeground(UIUtil.getLabelDisabledForeground()); } - setText(new CertificateWrapper(certificate).getSubjectField(COMMON_NAME)); + setText(getCommonName(certificate)); } }); @@ -136,7 +136,7 @@ public class CertificateConfigurable implements SearchableConfigurable, Configur myDetailsPanel.add(scrollPane, uniqueName); } - private String getCardName(X509Certificate certificate) { + private static String getCardName(X509Certificate certificate) { return certificate.getSubjectX500Principal().getName(); } @@ -203,13 +203,13 @@ public class CertificateConfigurable implements SearchableConfigurable, Configur for (X509Certificate certificate : added) { if (!myTrustManager.addCertificate(certificate)) { - throw new ConfigurationException("Cannot add certificate", "Cannot Add Certificate"); + throw new ConfigurationException("Cannot add certificate for " + getCommonName(certificate), "Cannot Add Certificate"); } } for (X509Certificate certificate : removed) { if (!myTrustManager.removeCertificate(certificate)) { - throw new ConfigurationException("Cannot remove certificate", "Cannot Remove Certificate"); + throw new ConfigurationException("Cannot remove certificate for " + getCommonName(certificate), "Cannot Remove Certificate"); } } @@ -256,12 +256,18 @@ public class CertificateConfigurable implements SearchableConfigurable, Configur @Override public void certificateAdded(X509Certificate certificate) { - getListModel().add(certificate); + CollectionListModel model = getListModel(); + if (model.getElementIndex(certificate) < 0) { + model.add(certificate); + } addCertificatePanel(certificate); } @Override public void certificateRemoved(X509Certificate certificate) { - getListModel().remove(certificate); + CollectionListModel model = getListModel(); + if (model.getElementIndex(certificate) >= 0) { + model.remove(certificate); + } } } diff --git a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateUtil.java b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateUtil.java index c02a9382a721..a1e36236c0e4 100644 --- a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateUtil.java +++ b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateUtil.java @@ -63,4 +63,11 @@ public class CertificateUtil { StreamUtil.closeStream(stream); } } + + /** + * @return subjects common name, usually it's domain name pattern, e.g. *.github.com + */ + public static String getCommonName(@NotNull X509Certificate certificate) { + return new CertificateWrapper(certificate).getSubjectField(CertificateWrapper.CommonField.COMMON_NAME); + } } diff --git a/platform/platform-api/src/com/intellij/util/net/ssl/ConfirmingTrustManager.java b/platform/platform-api/src/com/intellij/util/net/ssl/ConfirmingTrustManager.java index 8a8f05a44f0c..8d430ebe7c7b 100644 --- a/platform/platform-api/src/com/intellij/util/net/ssl/ConfirmingTrustManager.java +++ b/platform/platform-api/src/com/intellij/util/net/ssl/ConfirmingTrustManager.java @@ -260,7 +260,7 @@ public class ConfirmingTrustManager extends ClientOnlyTrustManager { } private static String createAlias(@NotNull X509Certificate certificate) { - return new CertificateWrapper(certificate).getSubjectField(CertificateWrapper.CommonField.COMMON_NAME); + return CertificateUtil.getCommonName(certificate); } /** @@ -287,6 +287,10 @@ public class ConfirmingTrustManager extends ClientOnlyTrustManager { } // for listeners X509Certificate certificate = getCertificate(alias); + if (certificate == null) { + LOG.error("No certificate found for alias: " + alias); + return false; + } myKeyStore.deleteEntry(alias); flushKeyStore(); // trust manager should be updated each time its key store was modified diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties index 10113e560409..116adfe47398 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties @@ -151,6 +151,8 @@ Tree.paintLines=false Tree.textBackground=ffffff Tree.selectionBorderColor=3875d6 +EditorPane.background=ffffff + List.background=ffffff Hyperlink.linkColor=589df6 diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/LaterInvocator.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/LaterInvocator.java index 841cda70bc5a..adb76477f181 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/LaterInvocator.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/LaterInvocator.java @@ -57,10 +57,10 @@ public class LaterInvocator { } private static class RunnableInfo { - final Runnable runnable; - final ModalityState modalityState; - final Condition expired; - final ActionCallback callback; + @NotNull private final Runnable runnable; + @NotNull private final ModalityState modalityState; + @NotNull private final Condition expired; + @NotNull private final ActionCallback callback; public RunnableInfo(@NotNull Runnable runnable, @NotNull ModalityState modalityState, @@ -74,7 +74,7 @@ public class LaterInvocator { @NonNls public String toString() { - return "[runnable: " + runnable + "; state=" + modalityState + "] "; + return "[runnable: " + runnable + "; state=" + modalityState + (expired.value(null) ? "; expired" : "")+"] "; } } @@ -88,21 +88,12 @@ public class LaterInvocator { private static final EventDispatcher ourModalityStateMulticaster = EventDispatcher.create(ModalityStateListener.class); - - private static final ArrayList ourForcedFlushQueue = new ArrayList(); - - public static void addModalityStateListener(@NotNull ModalityStateListener listener) { - ourModalityStateMulticaster.addListener(listener); - } + private static final List ourForcedFlushQueue = new ArrayList(); public static void addModalityStateListener(@NotNull ModalityStateListener listener, @NotNull Disposable parentDisposable) { ourModalityStateMulticaster.addListener(listener, parentDisposable); } - public static void removeModalityStateListener(@NotNull ModalityStateListener listener) { - ourModalityStateMulticaster.removeListener(listener); - } - @NotNull static ModalityStateEx modalityStateForWindow(@NotNull Window window) { int index = ourModalEntities.indexOf(window); @@ -113,9 +104,7 @@ public class LaterInvocator { if (window instanceof Dialog && ((Dialog)window).isModal()) { return ownerState.appendEntity(window); } - else { - return ownerState; - } + return ownerState; } ArrayList result = new ArrayList(); @@ -132,27 +121,32 @@ public class LaterInvocator { return new ModalityStateEx(result.toArray()); } + @NotNull public static ActionCallback invokeLater(@NotNull Runnable runnable) { return invokeLater(runnable, Conditions.FALSE); } + @NotNull public static ActionCallback invokeLater(@NotNull Runnable runnable, @NotNull Condition expired) { ModalityState modalityState = ModalityState.defaultModalityState(); return invokeLater(runnable, modalityState, expired); } + @NotNull public static ActionCallback invokeLater(@NotNull Runnable runnable, @NotNull ModalityState modalityState) { return invokeLater(runnable, modalityState, Conditions.FALSE); } + @NotNull public static ActionCallback invokeLater(@NotNull Runnable runnable, @NotNull ModalityState modalityState, @NotNull Condition expired) { ourFrequentEventDetector.eventHappened(); final ActionCallback callback = new ActionCallback(); + RunnableInfo runnableInfo = new RunnableInfo(runnable, modalityState, expired, callback); synchronized (LOCK) { - ourQueue.add(new RunnableInfo(runnable, modalityState, expired, callback)); + ourQueue.add(runnableInfo); } requestFlush(); return callback; @@ -177,7 +171,7 @@ public class LaterInvocator { @NonNls public String toString() { - return "InvokeAndWait[" + runnable.toString() + "]"; + return "InvokeAndWait[" + runnable + "]"; } }; invokeLater(runnable1, modalityState); @@ -326,7 +320,7 @@ public class LaterInvocator { lastInfo.callback.setDone(); } catch (ProcessCanceledException ex) { - // ignore + // ignore } catch (Throwable t) { if (t instanceof StackOverflowError) { @@ -348,20 +342,23 @@ public class LaterInvocator { @NonNls public String toString() { - return "LaterInvocator[lastRunnable=" + myLastInfo + "]"; + return "LaterInvocator.FlushQueue" + (myLastInfo == null ? "" : " lastInfo="+myLastInfo); } } @TestOnly - public static List dumpQueue() { + static String dumpQueue() { synchronized (LOCK) { - if (!ourQueue.isEmpty()) { - ArrayList r = new ArrayList(); - r.addAll(ourQueue); - Collections.reverse(r); - return r; + @NonNls String result = ""; + if (!ourForcedFlushQueue.isEmpty()) { + result = "(Forced queue: " + ourForcedFlushQueue + ") "; } + List r = new ArrayList(ourQueue); + result += r + (ourQueueSkipCount == 0 ? "" : " (ourQueueSkipCount="+ourQueueSkipCount+")") + + (ourModalEntities.isEmpty() ? " (non-modal)" : " (modal entities: "+ourModalEntities+")" + + (FLUSHER_SCHEDULED.get() ? " (Flusher scheduled)" : "") + ); + return result; } - return null; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java new file mode 100644 index 000000000000..06e25a95fe57 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/HighlightModeAction.java @@ -0,0 +1,103 @@ +/* + * 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.openapi.diff.actions; + +import com.intellij.CommonBundle; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ex.ComboBoxAction; +import com.intellij.openapi.diff.DiffBundle; +import com.intellij.openapi.diff.ex.DiffPanelEx; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.diff.impl.processing.HighlightMode; +import com.intellij.openapi.project.DumbAware; +import com.intellij.util.containers.HashMap; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import java.awt.*; +import java.util.Map; + +public class HighlightModeAction extends ComboBoxAction implements DumbAware { + private final Map myActions = new HashMap(); + private static final HighlightMode[] ourActionOrder = + new HighlightMode[]{HighlightMode.BY_WORD, HighlightMode.BY_LINE, HighlightMode.NO_HIGHLIGHTING}; + + public HighlightModeAction() { + myActions.put(HighlightMode.BY_WORD, + new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.word"), HighlightMode.BY_WORD)); + myActions.put(HighlightMode.BY_LINE, + new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.by.line"), HighlightMode.BY_LINE)); + myActions.put(HighlightMode.NO_HIGHLIGHTING, + new SetHighlightModeAction(DiffBundle.message("diff.acton.highlight.mode.action.no.highlighting"), + HighlightMode.NO_HIGHLIGHTING)); + } + + @Override + public JComponent createCustomComponent(final Presentation presentation) { + JPanel panel = new JPanel(new BorderLayout()); + final JLabel label = new JLabel(CommonBundle.message("diff.acton.highlight.mode.action.name")); + label.setBorder(BorderFactory.createEmptyBorder(0, 4, 0, 4)); + panel.add(label, BorderLayout.WEST); + panel.add(super.createCustomComponent(presentation), BorderLayout.CENTER); + return panel; + } + + @NotNull + protected DefaultActionGroup createPopupActionGroup(JComponent button) { + DefaultActionGroup actionGroup = new DefaultActionGroup(); + for (HighlightMode comparisonPolicy : ourActionOrder) { + actionGroup.add(myActions.get(comparisonPolicy)); + } + return actionGroup; + } + + public void update(AnActionEvent e) { + super.update(e); + Presentation presentation = e.getPresentation(); + DiffPanelEx diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext()); + if (diffPanel != null && diffPanel.getComponent().isDisplayable()) { + AnAction action = myActions.get(diffPanel.getHighlightMode()); + Presentation templatePresentation = action.getTemplatePresentation(); + presentation.setIcon(templatePresentation.getIcon()); + presentation.setText(templatePresentation.getText()); + presentation.setEnabled(true); + } + else { + presentation.setIcon(null); + presentation.setText(DiffBundle.message("diff.acton.highlight.mode.not.available.action.name")); + presentation.setEnabled(false); + } + } + + private static class SetHighlightModeAction extends AnAction implements DumbAware { + private final HighlightMode myHighlightMode; + + public SetHighlightModeAction(String text, HighlightMode mode) { + super(text); + myHighlightMode = mode; + } + + public void actionPerformed(AnActionEvent e) { + final DiffPanelImpl diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext()); + if (diffPanel != null) { + diffPanel.setHighlightMode(myHighlightMode); + } + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java index 78c5ba756923..6a68ad75d5d8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/IgnoreWhiteSpacesAction.java @@ -82,7 +82,7 @@ public class IgnoreWhiteSpacesAction extends ComboBoxAction implements DumbAware } } - private static class IgnoringPolicyAction extends AnAction { + private static class IgnoringPolicyAction extends AnAction implements DumbAware { private final ComparisonPolicy myPolicy; public IgnoringPolicyAction(String text, ComparisonPolicy policy) { diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/actions/ToggleAutoScrollAction.java b/platform/platform-impl/src/com/intellij/openapi/diff/actions/ToggleAutoScrollAction.java new file mode 100644 index 000000000000..04ec31e10ff6 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/diff/actions/ToggleAutoScrollAction.java @@ -0,0 +1,50 @@ +/* + * 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.openapi.diff.actions; + +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.diff.ex.DiffPanelEx; +import com.intellij.openapi.diff.impl.DiffPanelImpl; +import com.intellij.openapi.project.DumbAware; +import com.intellij.ui.ToggleActionButton; + +import javax.swing.*; + +public class ToggleAutoScrollAction extends ToggleActionButton implements DumbAware { + public ToggleAutoScrollAction() { + super("Auto Scroll", AllIcons.General.AutoscrollToSource); + } + + @Override + public boolean isSelected(AnActionEvent e) { + DiffPanelEx diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext()); + if (diffPanel != null) { + return diffPanel.isAutoScrollEnabled(); + } + else { + return true; + } + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + final DiffPanelImpl diffPanel = DiffPanelImpl.fromDataContext(e.getDataContext()); + if (diffPanel != null) { + diffPanel.setAutoScrollEnabled(state); + } + } +} diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelEx.java b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelEx.java index e0df0bb7dc2b..933d017be2ef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/ex/DiffPanelEx.java @@ -27,6 +27,7 @@ package com.intellij.openapi.diff.ex; import com.intellij.openapi.Disposable; import com.intellij.openapi.diff.DiffPanel; import com.intellij.openapi.diff.impl.ComparisonPolicy; +import com.intellij.openapi.diff.impl.processing.HighlightMode; import com.intellij.openapi.editor.Editor; import org.jetbrains.annotations.Nullable; @@ -41,4 +42,12 @@ public interface DiffPanelEx extends DiffPanel, Disposable { void setComparisonPolicy(ComparisonPolicy comparisonPolicy); ComparisonPolicy getComparisonPolicy(); + + void setAutoScrollEnabled(boolean enabled); + + boolean isAutoScrollEnabled(); + + void setHighlightMode(HighlightMode highlightMode); + + HighlightMode getHighlightMode(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java index 9978b78f8533..913d5e7cc8f9 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/DiffPanelImpl.java @@ -26,6 +26,7 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.diff.*; import com.intellij.openapi.diff.actions.MergeActionGroup; +import com.intellij.openapi.diff.actions.ToggleAutoScrollAction; import com.intellij.openapi.diff.ex.DiffPanelEx; import com.intellij.openapi.diff.ex.DiffPanelOptions; import com.intellij.openapi.diff.impl.external.DiffManagerImpl; @@ -33,6 +34,7 @@ import com.intellij.openapi.diff.impl.fragments.Fragment; import com.intellij.openapi.diff.impl.fragments.FragmentList; import com.intellij.openapi.diff.impl.highlighting.DiffPanelState; import com.intellij.openapi.diff.impl.highlighting.FragmentSide; +import com.intellij.openapi.diff.impl.processing.HighlightMode; import com.intellij.openapi.diff.impl.processing.HorizontalDiffSplitter; import com.intellij.openapi.diff.impl.settings.DiffMergeEditorSetting; import com.intellij.openapi.diff.impl.settings.DiffMergeSettings; @@ -110,6 +112,9 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid public void customize(DiffToolbar toolbar) { ActionManager actionManager = ActionManager.getInstance(); toolbar.addAction(actionManager.getAction("DiffPanel.Toolbar")); + toolbar.addSeparator(); + toolbar.addAction(new ToggleAutoScrollAction()); + toolbar.addSeparator(); toolbar.addAction(actionManager.getAction("ContextHelp")); toolbar.addAction(getEditSourceAction()); toolbar.addSeparator(); @@ -467,10 +472,27 @@ public class DiffPanelImpl implements DiffPanelEx, ContentChangeListener, TwoSid } } + public void setAutoScrollEnabled(boolean enabled) { + myScrollSupport.setEnabled(enabled); + } + + public boolean isAutoScrollEnabled() { + return myScrollSupport.isEnabled(); + } + public void setComparisonPolicy(ComparisonPolicy comparisonPolicy) { setComparisonPolicy(comparisonPolicy, true); } + public void setHighlightMode(HighlightMode highlightMode) { + myData.setHighlightMode(highlightMode); + rediff(); + } + + public HighlightMode getHighlightMode() { + return myData.getHighlightMode(); + } + public Rediffers getDiffUpdater() { return myDiffUpdater; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java index 5446f66e50c6..d90005d70678 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/highlighting/SimpleDiffPanelState.java @@ -24,6 +24,7 @@ import com.intellij.openapi.diff.impl.fragments.FragmentList; import com.intellij.openapi.diff.impl.fragments.FragmentListImpl; import com.intellij.openapi.diff.impl.fragments.LineFragment; import com.intellij.openapi.diff.impl.processing.DiffPolicy; +import com.intellij.openapi.diff.impl.processing.HighlightMode; import com.intellij.openapi.diff.impl.processing.TextCompareProcessor; import com.intellij.openapi.diff.impl.splitter.LineBlocks; import com.intellij.openapi.project.Project; @@ -37,6 +38,7 @@ import java.util.Iterator; public abstract class SimpleDiffPanelState implements Disposable { protected ComparisonPolicy myComparisonPolicy = ComparisonPolicy.DEFAULT; protected DiffPolicy myDiffPolicy; + protected HighlightMode myHighlightMode; protected final EditorPlaceHolder myAppender1; protected final EditorPlaceHolder myAppender2; protected FragmentList myFragmentList = FragmentList.EMPTY; @@ -47,6 +49,7 @@ public abstract class SimpleDiffPanelState implements Disposable { myAppender2 = createEditorWrapper(project, changeListener, FragmentSide.SIDE2); myProject = project; myDiffPolicy = DiffPolicy.LINES_WO_FORMATTING; + myHighlightMode = HighlightMode.BY_WORD; Disposer.register(parentDisposable, this); } @@ -72,6 +75,14 @@ public abstract class SimpleDiffPanelState implements Disposable { return myComparisonPolicy; } + public HighlightMode getHighlightMode() { + return myHighlightMode; + } + + public void setHighlightMode(HighlightMode highlightMode) { + myHighlightMode = highlightMode; + } + public void dispose() { } @@ -105,7 +116,12 @@ public abstract class SimpleDiffPanelState implements Disposable { return LineBlocks.EMPTY; } - return addMarkup(new TextCompareProcessor(myComparisonPolicy, myDiffPolicy).process(myAppender1.getText(), myAppender2.getText())); + if (myHighlightMode == HighlightMode.NO_HIGHLIGHTING) { + return LineBlocks.fromLineFragments(new ArrayList()); + } + + return addMarkup(new TextCompareProcessor(myComparisonPolicy, myDiffPolicy, myHighlightMode == HighlightMode.BY_WORD) + .process(myAppender1.getText(), myAppender2.getText())); } public Project getProject() { return myProject; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java index 1555656c3865..01534b487ff5 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/processing/TextCompareProcessor.java @@ -32,28 +32,38 @@ public class TextCompareProcessor { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.processing.Processor"); private final DiffPolicy myDiffPolicy; @NotNull private final ComparisonPolicy myComparisonPolicy; + private final boolean mySearchForSubFragments; - public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, final DiffPolicy diffPolicy) { + public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, + final DiffPolicy diffPolicy, + boolean searchForSubFragments) { myComparisonPolicy = comparisonPolicy; myDiffPolicy = diffPolicy; + mySearchForSubFragments = searchForSubFragments; } - public TextCompareProcessor(ComparisonPolicy comparisonPolicy) { + public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy, final DiffPolicy diffPolicy) { + this(comparisonPolicy, diffPolicy, true); + } + + public TextCompareProcessor(@NotNull ComparisonPolicy comparisonPolicy) { this(comparisonPolicy, DiffPolicy.LINES_WO_FORMATTING); } public ArrayList process(String text1, String text2) throws FilesTooBigForDiffException { DiffFragment[] woFormattingBlocks = myDiffPolicy.buildFragments(text1, text2); - DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy). - correctAndNormalize(woFormattingBlocks); + DiffFragment[] step1lineFragments = new DiffCorrection.TrueLineBlocks(myComparisonPolicy).correctAndNormalize(woFormattingBlocks); ArrayList lineBlocks = new DiffFragmentsProcessor().process(step1lineFragments); - for (LineFragment lineBlock : lineBlocks) { - if (lineBlock.isOneSide() || lineBlock.isEqual()) continue; - String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1); - String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2); - ArrayList subFragments = findSubFragments(subText1, subText2); - lineBlock.setChildren(new ArrayList(subFragments)); - lineBlock.adjustTypeFromChildrenTypes(); + + if (mySearchForSubFragments) { + for (LineFragment lineBlock : lineBlocks) { + if (lineBlock.isOneSide() || lineBlock.isEqual()) continue; + String subText1 = lineBlock.getText(text1, FragmentSide.SIDE1); + String subText2 = lineBlock.getText(text2, FragmentSide.SIDE2); + ArrayList subFragments = findSubFragments(subText1, subText2); + lineBlock.setChildren(new ArrayList(subFragments)); + lineBlock.adjustTypeFromChildrenTypes(); + } } return lineBlocks; } diff --git a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java index ab45e1ec2ede..47ba0e817ced 100644 --- a/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java +++ b/platform/platform-impl/src/com/intellij/openapi/diff/impl/util/SyncScrollSupport.java @@ -36,6 +36,7 @@ public class SyncScrollSupport implements Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.util.SyncScrollSupport"); private boolean myDuringVerticalScroll = false; private final ArrayList myScrollers = new ArrayList(); + private boolean myEnabled = true; public void install(EditingSides[] sideContainers) { Disposer.dispose(this); @@ -58,6 +59,14 @@ public class SyncScrollSupport implements Disposable { myScrollers.clear(); } + public void setEnabled(boolean enabled) { + myEnabled = enabled; + } + + public boolean isEnabled() { + return myEnabled; + } + private void install2(Editor[] editors, EditingSides[] sideContainers) { addSlavesScroller(editors[0], new Pair(FragmentSide.SIDE1, sideContainers[0])); addSlavesScroller(editors[1], new Pair(FragmentSide.SIDE2, sideContainers[0])); @@ -100,7 +109,7 @@ public class SyncScrollSupport implements Disposable { } public void visibleAreaChanged(VisibleAreaEvent e) { - if (myDuringVerticalScroll) return; + if (!myEnabled || myDuringVerticalScroll) return; Rectangle newRectangle = e.getNewRectangle(); Rectangle oldRectangle = e.getOldRectangle(); if (newRectangle == null || oldRectangle == null) return; diff --git a/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java b/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java index 7315999171c8..923935b0645c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/FileContentQueue.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,7 +57,7 @@ public class FileContentQueue { private final Object myProceedWithProcessingLock = new Object(); private static final boolean ourAllowParallelFileReading = SystemProperties.getBooleanProperty("idea.allow.parallel.file.reading", true); - public void queue(final Collection files, @NotNull final ProgressIndicator indicator) { + public void queue(@NotNull Collection files, @NotNull final ProgressIndicator indicator) { myFilesToLoadQueue.addAll(files); final Runnable contentLoadingRunnable = new Runnable() { @Override diff --git a/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java b/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java index 2b9dce102509..f4dfb1059651 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorComboBoxEditor.java @@ -38,6 +38,7 @@ public class EditorComboBoxEditor implements ComboBoxEditor{ myTextField.setName(NAME); } + @Override public void selectAll() { myTextField.selectAll(); myTextField.requestFocus(); @@ -48,18 +49,22 @@ public class EditorComboBoxEditor implements ComboBoxEditor{ return myTextField.getEditor(); } + @Override public EditorTextField getEditorComponent() { return myTextField; } + @Override public void addActionListener(ActionListener l) { } + @Override public void removeActionListener(ActionListener l) { } + @Override public Object getItem() { return getDocument(); } @@ -68,6 +73,7 @@ public class EditorComboBoxEditor implements ComboBoxEditor{ return myTextField.getDocument(); } + @Override public void setItem(Object anObject) { myTextField.setDocument((Document)anObject); } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index 53b84612f59f..8f7600865961 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -95,7 +95,6 @@ public class AbstractPopup implements JBPopup { private boolean myCancelOnWindowDeactivation = true; private Dimension myForcedSize; private Point myForcedLocation; - private ChildFocusWatcher myFocusWatcher; private boolean myCancelKeyEnabled; private boolean myLocateByContent; protected FocusTrackback myFocusTrackback; @@ -1037,7 +1036,7 @@ public class AbstractPopup implements JBPopup { } - myFocusWatcher = new ChildFocusWatcher(myContent) { + ChildFocusWatcher focusWatcher = new ChildFocusWatcher(myContent) { @Override protected void onFocusGained(final FocusEvent event) { setWindowActive(true); @@ -1047,8 +1046,8 @@ public class AbstractPopup implements JBPopup { protected void onFocusLost(final FocusEvent event) { setWindowActive(false); } - }; + Disposer.register(this, focusWatcher); mySpeedSearchPatternField = new JTextField(); if (SystemInfo.isMac) { @@ -1058,7 +1057,7 @@ public class AbstractPopup implements JBPopup { } private Window updateMaskAndAlpha(Window window) { - if (window == null) return window; + if (window == null) return null; final WindowManagerEx wndManager = getWndManager(); if (wndManager == null) return window; @@ -1249,11 +1248,6 @@ public class AbstractPopup implements JBPopup { } myMouseOutCanceller = null; - if (myFocusWatcher != null) { - myFocusWatcher.dispose(); - myFocusWatcher = null; - } - resetWindow(); if (myFinalRunnable != null) { diff --git a/platform/platform-resources-en/src/messages/CommonBundle.properties b/platform/platform-resources-en/src/messages/CommonBundle.properties index a07d1631bad5..e027bc32a12d 100644 --- a/platform/platform-resources-en/src/messages/CommonBundle.properties +++ b/platform/platform-resources-en/src/messages/CommonBundle.properties @@ -175,4 +175,5 @@ This may lead to incorrect behaviour. Proxy should be set in Settings | HTTP Pro This JVM property is old and its usage is not recommended by Oracle.\n\ \n(Note: It could have been assigned by some code dynamically.) label.proxy.exceptions.text=Example\: *.domain.com, 192.168.* -checkbox.automatic.proxy.configuration.url=Automatic proxy configuration URL\: \ No newline at end of file +checkbox.automatic.proxy.configuration.url=Automatic proxy configuration URL\: +diff.acton.highlight.mode.action.name=Highlighting Mode \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/DiffBundle.properties b/platform/platform-resources-en/src/messages/DiffBundle.properties index cb6a0d72819b..b0515df7f6f2 100644 --- a/platform/platform-resources-en/src/messages/DiffBundle.properties +++ b/platform/platform-resources-en/src/messages/DiffBundle.properties @@ -83,3 +83,7 @@ diff.content.selected.value=Selected Value diff.clipboard.vs.value.dialog.title=Clipboard vs Selected Value diff.can.not.show.unknown=Can not show diff for unknown file type +diff.acton.highlight.mode.action.by.word=By Word +diff.acton.highlight.mode.action.by.line=By Line +diff.acton.highlight.mode.action.no.highlighting=No Highlighting +diff.acton.highlight.mode.not.available.action.name= diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index c2e5c4aafaac..ab70a8603df4 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -550,6 +550,8 @@ + + diff --git a/platform/util/src/com/intellij/openapi/diff/impl/processing/HighlightMode.java b/platform/util/src/com/intellij/openapi/diff/impl/processing/HighlightMode.java new file mode 100644 index 000000000000..441aca3517eb --- /dev/null +++ b/platform/util/src/com/intellij/openapi/diff/impl/processing/HighlightMode.java @@ -0,0 +1,20 @@ +/* + * 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.openapi.diff.impl.processing; + +public enum HighlightMode { + BY_WORD, BY_LINE, NO_HIGHLIGHTING +} diff --git a/platform/util/src/com/intellij/openapi/util/WriteExternalException.java b/platform/util/src/com/intellij/openapi/util/WriteExternalException.java index 3d61f6e3ac7d..76714142f974 100644 --- a/platform/util/src/com/intellij/openapi/util/WriteExternalException.java +++ b/platform/util/src/com/intellij/openapi/util/WriteExternalException.java @@ -15,6 +15,10 @@ */ package com.intellij.openapi.util; +/** + * Throw this exception from {@link JDOMExternalizable#writeExternal(org.jdom.Element)} method if you don't want to store any settings. + * If you simply return from the method empty '' tag will be written leading to unneeded modification of configuration files. + */ public class WriteExternalException extends Exception { public WriteExternalException() { super(); diff --git a/platform/util/src/com/intellij/util/containers/OrderedSet.java b/platform/util/src/com/intellij/util/containers/OrderedSet.java index ce03ffcba6eb..76cfc8c27480 100644 --- a/platform/util/src/com/intellij/util/containers/OrderedSet.java +++ b/platform/util/src/com/intellij/util/containers/OrderedSet.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,28 +18,26 @@ package com.intellij.util.containers; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.RandomAccess; +import java.util.Set; -public class OrderedSet extends AbstractList implements Set, RandomAccess { +// have to extend ArrayList because otherwise the spliterator() methods declared in Set and List are in conflict +public class OrderedSet extends ArrayList implements Set, RandomAccess { private final OpenTHashSet myHashSet; - private final ArrayList myElements; public OrderedSet() { this(ContainerUtil.canonicalStrategy()); } - public OrderedSet(TObjectHashingStrategy hashingStrategy) { + public OrderedSet(@NotNull TObjectHashingStrategy hashingStrategy) { this(hashingStrategy, 4); } - public OrderedSet(TObjectHashingStrategy hashingStrategy, int capacity) { + public OrderedSet(@NotNull TObjectHashingStrategy hashingStrategy, int capacity) { + super(capacity); myHashSet = new OpenTHashSet(capacity, hashingStrategy); - myElements = new ArrayList(capacity); - } - - @Override - public int size() { - return myElements.size(); } @Override @@ -50,7 +48,7 @@ public class OrderedSet extends AbstractList implements Set, RandomAcce @Override public boolean add(T o) { if (myHashSet.add(o)){ - myElements.add(o); + super.add(o); return true; } return false; @@ -59,7 +57,7 @@ public class OrderedSet extends AbstractList implements Set, RandomAcce @Override public boolean remove(Object o) { if (myHashSet.remove(o)){ - myElements.remove(o); + super.remove(o); return true; } return false; @@ -68,19 +66,7 @@ public class OrderedSet extends AbstractList implements Set, RandomAcce @Override public void clear() { myHashSet.clear(); - myElements.clear(); - } - - @NotNull - @Override - public Object[] toArray() { - return myElements.toArray(); - } - - @NotNull - @Override - public T[] toArray(@NotNull T[] a) { - return myElements.toArray(a); + super.clear(); } @Override @@ -88,11 +74,6 @@ public class OrderedSet extends AbstractList implements Set, RandomAcce throw new UnsupportedOperationException(); } - @Override - public T get(final int index) { - return myElements.get(index); - } - @Override public T set(final int index, final T element) { final T removed = remove(index); @@ -103,13 +84,13 @@ public class OrderedSet extends AbstractList implements Set, RandomAcce @Override public void add(final int index, final T element) { if (myHashSet.add(element)){ - myElements.add(index, element); + super.add(index, element); } } @Override public T remove(final int index) { - final T t = myElements.remove(index); + final T t = super.remove(index); myHashSet.remove(t); return t; } @@ -117,24 +98,12 @@ public class OrderedSet extends AbstractList implements Set, RandomAcce @Override public int indexOf(final Object o) { final int index = myHashSet.index((T)o); - return index >= 0? myElements.indexOf(myHashSet.get(index)) : -1; + return index >= 0? super.indexOf(myHashSet.get(index)) : -1; } @Override public int lastIndexOf(final Object o) { final int index = myHashSet.index((T)o); - return index >= 0 ? myElements.lastIndexOf(myHashSet.get(index)) : -1; - } - - @NotNull - @Override - public ListIterator listIterator() { - return myElements.listIterator(); - } - - @NotNull - @Override - public ListIterator listIterator(final int index) { - return myElements.listIterator(index); + return index >= 0 ? super.lastIndexOf(myHashSet.get(index)) : -1; } } diff --git a/platform/util/src/com/intellij/util/ui/UIUtil.java b/platform/util/src/com/intellij/util/ui/UIUtil.java index 1b3ad87b4a6d..b939c924968d 100644 --- a/platform/util/src/com/intellij/util/ui/UIUtil.java +++ b/platform/util/src/com/intellij/util/ui/UIUtil.java @@ -356,9 +356,9 @@ public class UIUtil { public static void setEnabled(Component component, boolean enabled, boolean recursively) { component.setEnabled(enabled); - if (component instanceof JComboBox) { + if (component instanceof JComboBox && isUnderAquaLookAndFeel()) { // On Mac JComboBox instances have children: com.apple.laf.AquaComboBoxButton and javax.swing.CellRendererPane. - // Disabling these children results in ugly UI. See WEB-10733 + // Disabling these children results in ugly UI: WEB-10733 return; } if (component instanceof JLabel) { diff --git a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java index b7ba2b988e97..d70588834481 100644 --- a/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java +++ b/platform/util/testSrc/com/intellij/util/xmlb/XmlSerializerTest.java @@ -809,6 +809,8 @@ public class XmlSerializerTest extends TestCase { public int COUNT = 3; @Attribute("name") public String name = "James"; + @Attribute("occupation") + public String occupation; } public void testBeanWithPrimitivePropertyBoundToAttribute() { final BeanWithPropertiesBoundToAttribute bean = new BeanWithPropertiesBoundToAttribute(); @@ -851,7 +853,7 @@ public class XmlSerializerTest extends TestCase { bean.STRING_V = "skip"; - assertSerializer(bean, "", "Serialization failure", null); + assertSerializer(bean, "", null); } public static class BeanWithJDOMElement { @@ -1145,13 +1147,13 @@ public class XmlSerializerTest extends TestCase { } //--------------------------------------------------------------------------------------------------- - private static void assertSerializer(Object bean, String expected, SerializationFilter filter) { - assertSerializer(bean, expected, "Serialization failure", filter); + private static Element assertSerializer(Object bean, String expected, SerializationFilter filter) { + return assertSerializer(bean, expected, "Serialization failure", filter); } private static Object doSerializerTest(String expectedText, Object bean) { try { - Element element = assertSerializer(bean, expectedText, "Serialization failure", null); + Element element = assertSerializer(bean, expectedText, null); //test deserializer diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java index 338023582e0f..8b600cbfed73 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/roots/VcsRootDetectorImpl.java @@ -37,6 +37,7 @@ public class VcsRootDetectorImpl implements VcsRootDetector { @NotNull private final Project myProject; @NotNull private final ProjectRootManager myProjectManager; @NotNull private final ProjectLevelVcsManager myVcsManager; + @NotNull private final VcsRootChecker[] myCheckers; public VcsRootDetectorImpl(@NotNull Project project, @NotNull ProjectRootManager projectRootManager, @@ -44,6 +45,7 @@ public class VcsRootDetectorImpl implements VcsRootDetector { myProject = project; myProjectManager = projectRootManager; myVcsManager = projectLevelVcsManager; + myCheckers = Extensions.getExtensions(VcsRootChecker.EXTENSION_POINT_NAME); } @NotNull @@ -53,7 +55,7 @@ public class VcsRootDetectorImpl implements VcsRootDetector { @NotNull public Collection detect(@Nullable VirtualFile startDir) { - if (startDir == null) { + if (startDir == null || myCheckers.length == 0) { return Collections.emptyList(); } @@ -140,9 +142,8 @@ public class VcsRootDetectorImpl implements VcsRootDetector { @NotNull private List getVcsListFor(@NotNull VirtualFile dir) { - VcsRootChecker[] checkers = Extensions.getExtensions(VcsRootChecker.EXTENSION_POINT_NAME); List vcsList = new ArrayList(); - for (VcsRootChecker checker : checkers) { + for (VcsRootChecker checker : myCheckers) { if (checker.isRoot(dir.getPath())) { vcsList.add(myVcsManager.findVcsByName(checker.getSupportedVcs().getName())); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java index 1b17a3a815b0..8accea1d4c36 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebugSessionImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -322,7 +322,7 @@ public class XDebugSessionImpl implements XDebugSession { return myValueMarkers; } - private static > XBreakpointType getBreakpointTypeClass(final XBreakpointHandler handler) { + private static XBreakpointType getBreakpointTypeClass(final XBreakpointHandler handler) { return XDebuggerUtil.getInstance().findBreakpointType(handler.getBreakpointTypeClass()); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java index 4fbc23431a5e..76a360f748ab 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java @@ -262,9 +262,13 @@ public class XDebuggerUtilImpl extends XDebuggerUtil { @Override @Nullable public PsiElement findContextElement(@NotNull VirtualFile virtualFile, int offset, @NotNull Project project, boolean checkXml) { + if (!virtualFile.isValid()) { + return null; + } + Document document = FileDocumentManager.getInstance().getDocument(virtualFile); - PsiFile file = PsiManager.getInstance(project).findFile(virtualFile); - if (file == null || document == null) { + PsiFile file = document == null ? null : PsiManager.getInstance(project).findFile(virtualFile); + if (file == null) { return null; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java index 90469e5ffb95..694ef28f8b37 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java @@ -60,6 +60,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { return myComboBox; } + @Override public JComponent getComponent() { return myComboBox; } @@ -70,7 +71,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { } public JComponent getEditorComponent() { - return (JComponent)myEditor.getEditorComponent(); + return myEditor.getEditorComponent(); } public void setEnabled(boolean enable) { @@ -89,13 +90,12 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { private void initEditor() { myEditor = new EditorComboBoxEditor(getProject(), myDebuggerEditorsProvider.getFileType()) { + @Override public void setItem(Object anObject) { - if (anObject == null) { - anObject = ""; - } - super.setItem(createDocument((String)anObject)); + super.setItem(createDocument(StringUtil.notNullize((String)anObject))); } + @Override public Object getItem() { return ((Document)super.getItem()).getText(); } @@ -106,6 +106,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { myComboBox.setMaximumRowCount(XDebuggerHistoryManager.MAX_RECENT_EXPRESSIONS); } + @Override protected void onHistoryChanged() { fillComboBox(); } @@ -120,6 +121,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { } } + @Override protected void doSetText(String text) { if (myComboBox.getItemCount() > 0) { myComboBox.setSelectedIndex(0); @@ -133,15 +135,18 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { } } + @Override public String getText() { final Object value = myComboBox.isPopupVisible() ? myComboBox.getPopup().getList().getSelectedValue() : myEditor.getItem(); return StringUtil.notNullize((String)value); } + @Override public JComponent getPreferredFocusedComponent() { return (JComponent)myComboBox.getEditor().getEditorComponent(); } + @Override public void selectAll() { myComboBox.getEditor().selectAll(); } diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java index 14c7535f8044..c597fc840521 100644 --- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java +++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java @@ -178,7 +178,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo } private static boolean doInjectInJava(final Project project, - final PsiElement psiElement, + @NotNull final PsiElement psiElement, PsiLanguageInjectionHost host, final String languageId) { final PsiElement target = ContextComputationProcessor.getTopLevelInjectionTarget(psiElement); @@ -245,7 +245,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo return false; } new WriteCommandAction(modifierListOwner.getProject(), modifierListOwner.getContainingFile()) { - protected void run(final Result result) throws Throwable { + protected void run(@NotNull final Result result) throws Throwable { JVMElementFactory factory = JVMElementFactories.getFactory(modifierListOwner.getLanguage(), modifierListOwner.getProject()); if (factory == null) { factory = JavaPsiFacade.getElementFactory(modifierListOwner.getProject()); @@ -484,7 +484,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo } } } - else { +// else { // todo tbd //for (InjectionPlace place : injection.getInjectionPlaces()) { // final Matcher matcher = pattern.matcher(place.getText()); @@ -492,7 +492,7 @@ public class JavaLanguageInjectionSupport extends AbstractLanguageInjectionSuppo // // } //} - } +// } result.setMethodInfos(infos); result.generatePlaces(); return result; diff --git a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java index cc8cce768f9a..d5c4b3fa8505 100644 --- a/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java +++ b/plugins/git4idea/src/git4idea/checkin/GitCheckinEnvironment.java @@ -110,22 +110,16 @@ public class GitCheckinEnvironment implements CheckinEnvironment { for (VirtualFile root : GitUtil.gitRoots(Arrays.asList(filesToCheckin))) { VirtualFile mergeMsg = root.findFileByRelativePath(GitRepositoryFiles.GIT_MERGE_MSG); VirtualFile squashMsg = root.findFileByRelativePath(GitRepositoryFiles.GIT_SQUASH_MSG); - VirtualFile normalMsg = root.findFileByRelativePath(GitRepositoryFiles.GIT_COMMIT_EDITMSG); try { - if (mergeMsg == null && squashMsg == null && normalMsg == null) { + if (mergeMsg == null && squashMsg == null) { continue; } - String encoding = GitConfigUtil.getCommitEncoding(myProject, root); - if (mergeMsg != null) { messages.add(loadMessage(mergeMsg, encoding)); } - else if (squashMsg != null) { - messages.add(loadMessage(squashMsg, encoding)); - } else { - messages.add(loadMessage(normalMsg, encoding)); + messages.add(loadMessage(squashMsg, encoding)); } } catch (IOException e) { diff --git a/plugins/gradle/gradle.iml b/plugins/gradle/gradle.iml index 6f6de2602ed6..9c852ed6ffc1 100644 --- a/plugins/gradle/gradle.iml +++ b/plugins/gradle/gradle.iml @@ -35,6 +35,7 @@ + diff --git a/plugins/gradle/lib/gradle-reporting-1.9.jar b/plugins/gradle/lib/gradle-reporting-1.9.jar new file mode 100644 index 000000000000..531552536833 Binary files /dev/null and b/plugins/gradle/lib/gradle-reporting-1.9.jar differ diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java index 03f0e66451dc..58120f90a4d4 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -187,8 +187,9 @@ public class GradleProjectResolver implements ExternalSystemProjectResolver aClass = resolverCtx.isPreviewMode() ? BasicIdeaProject.class : IdeaProject.class; ModelBuilder modelBuilder = myHelper.getModelBuilder( - resolverCtx.isPreviewMode() ? BasicIdeaProject.class : IdeaProject.class, + aClass, resolverCtx.getExternalSystemTaskId(), resolverCtx.getSettings(), resolverCtx.getConnection(), diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectImportAction.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectImportAction.java index 52c6e3d47b74..407f12c6981a 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectImportAction.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/ProjectImportAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -48,7 +48,8 @@ public class ProjectImportAction implements BuildAction aClass1 = myIsPreviewMode ? BasicIdeaProject.class : IdeaProject.class; + final IdeaProject ideaProject = controller.getModel(aClass1); if (ideaProject == null || ideaProject.getModules().isEmpty()) { return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/AlignmentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/AlignmentProvider.java index 815900804ec0..5c052f4beade 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/AlignmentProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/AlignmentProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -58,40 +58,18 @@ public class AlignmentProvider { } if (myAlignments.containsKey(set2)) { - for (Iterator iterator = set1.iterator(); iterator.hasNext(); ) { - PsiElement element = iterator.next(); - iterator.remove(); - - addInternal(set2, element); - } + addSet(set1, set2); } else { set1.addAll(set2); - for (Iterator iterator = set2.iterator(); iterator.hasNext(); ) { - PsiElement element = iterator.next(); - iterator.remove(); - - addInternal(set1, element); - } + addSet(set2, set1); } } else if (set1 != null) { - if (allowBackwardShift != null) { - assert myAllowBackwardShift.get(set1).booleanValue() == allowBackwardShift.booleanValue(); - } - if (anchor != null) { - assert myAnchor.get(set1) == anchor; - } - addInternal(set1, e2); + addElement(e2, allowBackwardShift, anchor, set1); } else if (set2 != null) { - if (allowBackwardShift != null) { - assert(myAllowBackwardShift.get(set2).booleanValue() == allowBackwardShift.booleanValue()); - } - if (anchor != null) { - assert(myAnchor.get(set2) == anchor); - } - addInternal(set2, e1); + addElement(e1, allowBackwardShift, anchor, set2); } else { final HashSet set = createHashSet(); @@ -102,6 +80,25 @@ public class AlignmentProvider { } } + private void addElement(PsiElement e, Boolean allowBackwardShift, Alignment.Anchor anchor, Set set) { + if (allowBackwardShift != null) { + assert myAllowBackwardShift.get(set).booleanValue() == allowBackwardShift.booleanValue(); + } + if (anchor != null) { + assert myAnchor.get(set) == anchor; + } + addInternal(set, e); + } + + private void addSet(Set set1, Set set2) { + for (Iterator iterator = set1.iterator(); iterator.hasNext(); ) { + PsiElement element = iterator.next(); + iterator.remove(); + + addInternal(set2, element); + } + } + private void addInternal(@NotNull Set set, @NotNull PsiElement element) { myTree.put(element, set); set.add(element); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java index c2ac05abe6f7..721e482c5c5f 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/blocks/GroovyBlockGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -301,12 +301,20 @@ public class GroovyBlockGenerator implements GroovyElementTypes { if (myContext.getSettings().ALIGN_MULTILINE_TERNARY_OPERATION) { final GrConditionalExpression conditional = (GrConditionalExpression)blockPsi; - final AlignmentProvider.Aligner aligner = myAlignmentProvider.createAligner(false); - aligner.append(conditional.getCondition()); + final AlignmentProvider.Aligner exprAligner = myAlignmentProvider.createAligner(false); + exprAligner.append(conditional.getCondition()); if (!(conditional instanceof GrElvisExpression)) { - aligner.append(conditional.getThenBranch()); + exprAligner.append(conditional.getThenBranch()); + } + exprAligner.append(conditional.getElseBranch()); + + ASTNode question = conditional.getNode().findChildByType(GroovyTokenTypes.mQUESTION); + ASTNode colon = conditional.getNode().findChildByType(GroovyTokenTypes.mCOLON); + if (question != null && colon != null) { + AlignmentProvider.Aligner questionColonAligner = myAlignmentProvider.createAligner(false); + questionColonAligner.append(question.getPsi()); + questionColonAligner.append(colon.getPsi()); } - aligner.append(conditional.getElseBranch()); } } @@ -508,7 +516,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { return blockPsi instanceof GrParameterList && myContext.getSettings().ALIGN_MULTILINE_PARAMETERS || blockPsi instanceof GrExtendsClause && myContext.getSettings().ALIGN_MULTILINE_EXTENDS_LIST || blockPsi instanceof GrThrowsClause && myContext.getSettings().ALIGN_MULTILINE_THROWS_LIST || - blockPsi instanceof GrConditionalExpression && myContext.getSettings().ALIGN_MULTILINE_TERNARY_OPERATION || blockPsi instanceof GrListOrMap && myContext.getGroovySettings().ALIGN_MULTILINE_LIST_OR_MAP; } @@ -516,7 +523,6 @@ public class GroovyBlockGenerator implements GroovyElementTypes { return blockPsi instanceof GrParameterList || blockPsi instanceof GrArgumentList || blockPsi instanceof GrAssignmentExpression || - blockPsi instanceof GrConditionalExpression || blockPsi instanceof GrExtendsClause || blockPsi instanceof GrThrowsClause || blockPsi instanceof GrListOrMap; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java index 84a6807b1594..e64154c3a14b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/formatter/processors/GroovySpacingProcessor.java @@ -370,27 +370,27 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { @Override public void visitFile(GroovyFileBase file) { if (isAfterElementOrSemi(PACKAGE_DEFINITION)) { - myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_AFTER_PACKAGE + 1, mySettings.KEEP_LINE_BREAKS, Integer.MAX_VALUE / 2); + myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_AFTER_PACKAGE + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines()); } else if (myType2 == PACKAGE_DEFINITION) { - myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_BEFORE_PACKAGE + 1, mySettings.KEEP_LINE_BREAKS, Integer.MAX_VALUE / 2); + myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_BEFORE_PACKAGE + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines()); } else if (isLeftOrRight(TYPE_DEFINITION_TYPES)) { if (myType1 == GROOVY_DOC_COMMENT) { createLF(true); } else { - myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_AROUND_CLASS + 1, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_DECLARATIONS); + myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_AROUND_CLASS + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines()); } } else if (isAfterElementOrSemi(IMPORT_STATEMENT) && myType2 != IMPORT_STATEMENT) { //after imports - myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_AFTER_IMPORTS + 1, mySettings.KEEP_LINE_BREAKS, Integer.MAX_VALUE / 2); + myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_AFTER_IMPORTS + 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines()); } else if (myType1 != IMPORT_STATEMENT && !isSemiAfter(IMPORT_STATEMENT) && myType2 == IMPORT_STATEMENT) { //before imports - myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_BEFORE_IMPORTS, mySettings.KEEP_LINE_BREAKS, Integer.MAX_VALUE / 2); + myResult = Spacing.createSpacing(0, 0, mySettings.BLANK_LINES_BEFORE_IMPORTS, mySettings.KEEP_LINE_BREAKS, keepBlankLines()); } else if (isAfterElementOrSemi(IMPORT_STATEMENT) && myType2 == IMPORT_STATEMENT) { - myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, Integer.MAX_VALUE / 2); + myResult = Spacing.createSpacing(0, 0, 1, mySettings.KEEP_LINE_BREAKS, keepBlankLines()); } else { processClassMembers(null); @@ -582,7 +582,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { @Override public void visitTypeArgumentList(GrTypeArgumentList typeArgumentList) { if (myType1 == mLT || myType2 == mGT) { - createSpaceProperty(false, true, 1); + createSpaceInCode(false); } } @@ -858,7 +858,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } private void createLazySpace() { - myResult = Spacing.createSpacing(0, Integer.MAX_VALUE, 0, mySettings.KEEP_LINE_BREAKS, mySettings.KEEP_BLANK_LINES_IN_CODE); + myResult = Spacing.createSpacing(0, Integer.MAX_VALUE, 0, mySettings.KEEP_LINE_BREAKS, keepBlankLines()); } public void visitDocTag(GrDocTag docTag) { @@ -1021,11 +1021,7 @@ public class GroovySpacingProcessor extends GroovyElementVisitor { } private void createSpaceInCode(final boolean space) { - createSpaceProperty(space, keepBlankLines()); - } - - private void createSpaceProperty(boolean space, int keepBlankLines) { - createSpaceProperty(space, mySettings.KEEP_LINE_BREAKS, keepBlankLines); + createSpaceProperty(space, mySettings.KEEP_LINE_BREAKS, keepBlankLines()); } private void createSpaceProperty(boolean space, boolean keepLineBreaks, final int keepBlankLines) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java index 2e1b0f81be05..a5383af62f6c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/java2groovy/GroovyIntroduceParameterMethodUsagesProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -270,7 +270,7 @@ public class GroovyIntroduceParameterMethodUsagesProcessor implements IntroduceP @NotNull Project project) { GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project); - final String typeText = forcedType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) ? null : forcedType.getCanonicalText(); + final String typeText = forcedType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || forcedType == PsiType.NULL ? null : forcedType.getCanonicalText(); GrParameter parameter = factory.createParameter(parameterName, typeText, parametersOwner); parameter.getModifierList().setModifierProperty(PsiModifier.FINAL, isFinal); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy index 72bb95deddbf..01cb0f735a43 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/formatter/FormatterTest.groovy @@ -713,6 +713,15 @@ print abc ?: ''' } + void testConditional2() { + groovySettings.ALIGN_MULTILINE_TERNARY_OPERATION = true + checkFormatting('''\ +print abc ? cde +:xyz''', '''\ +print abc ? cde + : xyz''') + } + void testLabelsInBasicMode() { groovySettings.indentOptions.INDENT_SIZE = 4 groovySettings.indentOptions.LABEL_INDENT_SIZE = -2 @@ -770,6 +779,8 @@ def foo() { void testSpreadArg() { doTest() } + void testExtraLines() { doTest() } + void testLabelWithDescription() { GroovyCodeStyleSettings customSettings = myTempSettings.getCustomSettings(GroovyCodeStyleSettings.class) CommonCodeStyleSettings commonSettings = myTempSettings.getCommonSettings(GroovyFileType.GROOVY_LANGUAGE) diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy index 8cc14aa1e0ee..3956cf8da7be 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -356,6 +356,25 @@ class X { print new X(2) { } +''') + } + + + void testNullType() { + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null, false, '''\ +def foo() { + def a = '4' + print a +} + +foo() +''', '''\ +def foo(anObject) { + def a = '4' + anObject +} + +foo(print(a)) ''') } } diff --git a/plugins/groovy/testdata/groovy/formatter/extraLines.test b/plugins/groovy/testdata/groovy/formatter/extraLines.test new file mode 100644 index 000000000000..1fa2e574326d --- /dev/null +++ b/plugins/groovy/testdata/groovy/formatter/extraLines.test @@ -0,0 +1,14 @@ +package abc + + + + + + + +print 1 +----- +package abc + + +print 1 \ No newline at end of file diff --git a/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties b/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties index 52b1203e06dd..1bd5aa4e0c6f 100644 --- a/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties +++ b/plugins/hg4idea/resources/org/zmlx/hg4idea/HgVcsMessages.properties @@ -52,8 +52,8 @@ hg4idea.configuration.executable.error=\"{0}\" doesn''t appear to be a valid hg hg4idea.configuration.test.label=Test hg4idea.configuration.test=&Test hg4idea.unable.to.run.hg=Unable to run hg: {0} -hg4idea.run.success.title=Hg executed successfully -hg4idea.run.failed.title=Hg execution failed +hg4idea.run.success.title=Hg Executed Successfully +hg4idea.run.failed.title=Hg Execution Failed hg4idea.command.executable.error=Error executing \"{0}\". Make sure you have setup the right executable in Mercurial configuration diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java index e808b73ee25e..61cf991c20a5 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/action/HgBranchesAction.java @@ -32,7 +32,7 @@ public class HgBranchesAction extends HgAbstractGlobalAction { @Override protected void execute(@NotNull Project project, @NotNull Collection repositories, @Nullable VirtualFile selectedRepo) { - HgRepository repository; + HgRepository repository = null; if (selectedRepo != null) { repository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(selectedRepo); } @@ -41,9 +41,6 @@ public class HgBranchesAction extends HgAbstractGlobalAction { if (selectedRoot != null) { repository = HgUtil.getRepositoryManager(project).getRepositoryForRoot(selectedRoot); } - else { - return; - } } if (repository != null) { HgBranchPopup.getInstance(project, repository).asListPopup().showInFocusCenter(); diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java index cacf3257335a..921d4cf9fbc5 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgUtil.java @@ -353,7 +353,7 @@ public abstract class HgUtil { //get file name in target revision if it was moved/renamed HgStatusCommand statCommand = new HgStatusCommand.Builder(false).copySource(true).baseRevision(vcsRevisionNumber).build(project); - Set changes = statCommand.execute(localHgFile.getRepo(), Arrays.asList(localHgFile.toFilePath())); + Set changes = statCommand.execute(localHgFile.getRepo(), Collections.singletonList(localHgFile.toFilePath())); for (HgChange change : changes) { if (change.afterFile().equals(localHgFile)) { diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java index e8cceeda7225..2f8e822190bc 100644 --- a/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java +++ b/plugins/hg4idea/src/org/zmlx/hg4idea/util/HgVersion.java @@ -70,10 +70,7 @@ public final class HgVersion implements Comparable { @NotNull private final Set myUnsupportedExtensions; public HgVersion(int major, int middle, int minor) { - myMajor = major; - myMiddle = middle; - myMinor = minor; - myUnsupportedExtensions = Collections.emptySet(); + this(major, middle, minor, Collections.emptySet()); } public HgVersion(int major, int middle, int minor, @NotNull Set unsupportedExtensions) { diff --git a/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar b/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar index 1ddf9204cf68..9400a2955c5b 100644 Binary files a/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar and b/plugins/javaFX/FxBuilderEmbedder/lib/embedder.jar differ diff --git a/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java b/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java index 025da2f708f0..fba7e4de778a 100644 --- a/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java +++ b/plugins/javaFX/FxBuilderEmbedder/src/org/jetbrains/plugins/javaFX/sceneBuilder/SceneBuilderImpl.java @@ -27,6 +27,7 @@ public class SceneBuilderImpl implements SceneBuilder { private final JFXPanel myPanel = new JFXPanel(); private EditorController myEditorController; private ChangeListener myListener; + private volatile boolean mySkipChanges; public SceneBuilderImpl(URL url, EditorCallback editorCallback) { myFileURL = url; @@ -88,7 +89,9 @@ public class SceneBuilderImpl implements SceneBuilder { myListener = new ChangeListener() { @Override public void changed(ObservableValue observable, Number oldValue, Number newValue) { - myEditorCallback.saveChanges(myEditorController.getFxmlText()); + if (!mySkipChanges) { + myEditorCallback.saveChanges(myEditorController.getFxmlText()); + } } }; @@ -103,6 +106,8 @@ public class SceneBuilderImpl implements SceneBuilder { } private void loadFile() { + mySkipChanges = true; + try { String fxmlText = FXOMDocument.readContentFromURL(myFileURL); myEditorController.setFxmlTextAndLocation(fxmlText, myFileURL); @@ -110,5 +115,8 @@ public class SceneBuilderImpl implements SceneBuilder { catch (Throwable e) { myEditorCallback.handleError(e); } + finally { + mySkipChanges = false; + } } } \ No newline at end of file diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml index d6ef063029af..ffb957bff742 100644 --- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml +++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml @@ -57,6 +57,7 @@ + diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/actions/OpenInSceneBuilderAction.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/actions/OpenInSceneBuilderAction.java index f41b9be4c614..6a56d6b60cdc 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/actions/OpenInSceneBuilderAction.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/actions/OpenInSceneBuilderAction.java @@ -17,35 +17,18 @@ package org.jetbrains.plugins.javaFX.actions; import com.intellij.CommonBundle; import com.intellij.execution.configurations.GeneralCommandLine; -import com.intellij.execution.configurations.JavaParameters; -import com.intellij.execution.configurations.PathEnvironmentVariableUtil; -import com.intellij.execution.process.OSProcessHandler; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileChooser.FileChooser; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.registry.Registry; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.ArrayUtil; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.javaFX.JavaFxSettings; -import org.jetbrains.plugins.javaFX.JavaFxSettingsConfigurable; import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; +import org.jetbrains.plugins.javaFX.sceneBuilder.SceneBuilderInfo; /** * User: anna @@ -53,84 +36,21 @@ import java.util.List; */ public class OpenInSceneBuilderAction extends AnAction { private static final Logger LOG = Logger.getInstance("#" + OpenInSceneBuilderAction.class.getName()); - public static final String ORACLE = "Oracle"; @Override public void actionPerformed(AnActionEvent e) { final VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); LOG.assertTrue(virtualFile != null); final String path = virtualFile.getPath(); - - final JavaFxSettings settings = JavaFxSettings.getInstance(); - String pathToSceneBuilder = settings.getPathToSceneBuilder(); - if (StringUtil.isEmptyOrSpaces(settings.getPathToSceneBuilder())){ - final VirtualFile sceneBuilderFile = FileChooser.chooseFile(JavaFxSettingsConfigurable.createSceneBuilderDescriptor(), e.getProject(), getPredefinedPath()); - if (sceneBuilderFile == null) return; - - pathToSceneBuilder = sceneBuilderFile.getPath(); - settings.setPathToSceneBuilder(FileUtil.toSystemIndependentName(pathToSceneBuilder)); - } - final Project project = getEventProject(e); - if (project != null && !Registry.is("scene.builder.start.executable", true)) { - final Module module = ModuleUtilCore.findModuleForFile(virtualFile, project); - if (module != null) { - try { - final JavaParameters javaParameters = new JavaParameters(); - javaParameters.configureByModule(module, JavaParameters.JDK_AND_CLASSES); - final File sceneBuilderLibsFile; - if (SystemInfo.isMac) { - sceneBuilderLibsFile = new File(new File(pathToSceneBuilder, "Contents"), "Java"); - } else if (SystemInfo.isWindows) { - File sceneBuilderRoot = new File(pathToSceneBuilder); - File sceneBuilderRootDir = sceneBuilderRoot.getParentFile(); - if (sceneBuilderRootDir == null) { - final File foundInPath = PathEnvironmentVariableUtil.findInPath(pathToSceneBuilder); - if (foundInPath != null) { - sceneBuilderRootDir = foundInPath.getParentFile(); - } - } - sceneBuilderRoot = sceneBuilderRootDir != null ? sceneBuilderRootDir.getParentFile() : null; - if (sceneBuilderRoot != null) { - final File libFile = new File(sceneBuilderRoot, "lib"); - if (libFile.isDirectory()) { - sceneBuilderLibsFile = libFile; - } - else { - final File appFile = new File(sceneBuilderRootDir, "app"); - sceneBuilderLibsFile = appFile.isDirectory() ? appFile : null; - } - } - else { - sceneBuilderLibsFile = null; - } - } else { - sceneBuilderLibsFile = new File(new File(pathToSceneBuilder).getParent(), "app"); - } - if (sceneBuilderLibsFile != null) { - final File[] sceneBuilderLibs = sceneBuilderLibsFile.listFiles(); - if (sceneBuilderLibs != null) { - for (File jarFile : sceneBuilderLibs) { - javaParameters.getClassPath().add(jarFile.getPath()); - } - javaParameters.setMainClass("com.oracle.javafx.authoring.Main"); - javaParameters.getProgramParametersList().add(path); - - final OSProcessHandler processHandler = javaParameters.createOSProcessHandler(); - final String commandLine = processHandler.getCommandLine(); - LOG.info("scene builder command line: " + commandLine); - processHandler.startNotify(); - return; - } - } - } - catch (Throwable ex) { - LOG.info(ex); - } - } + final SceneBuilderInfo info = SceneBuilderInfo.get(project, true); + if (info == SceneBuilderInfo.EMPTY) { + return; } + String pathToSceneBuilder = info.path; + if (SystemInfo.isMac) { pathToSceneBuilder += "/Contents/MacOS/scenebuilder-launcher.sh"; } @@ -152,45 +72,11 @@ public class OpenInSceneBuilderAction extends AnAction { presentation.setEnabled(false); presentation.setVisible(false); final VirtualFile virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE); - if (virtualFile != null && + if (virtualFile != null && JavaFxFileTypeFactory.isFxml(virtualFile) && e.getProject() != null) { presentation.setEnabled(true); presentation.setVisible(true); } } - - @Nullable - private static VirtualFile getPredefinedPath() { - String path = null; - if (SystemInfo.isWindows) { - final String sb11 = File.separator + "JavaFX Scene Builder 1.1" + File.separator + "JavaFX Scene Builder 1.1.exe"; - final String sb10 = File.separator + "JavaFX Scene Builder 1.0" + File.separator + "bin" + File.separator + "scenebuilder.exe"; - final List suspiciousPaths = new ArrayList(); - final String programFiles = "C:\\Program Files"; - fillPaths(programFiles, sb11, sb10, suspiciousPaths); - fillPaths(programFiles + " (x86)", sb11, sb10, suspiciousPaths); - final File sb = FileUtil.findFirstThatExist(ArrayUtil.toStringArray(suspiciousPaths)); - if (sb != null) { - path = sb.getPath(); - } - } - else if (SystemInfo.isMac) { - final File sb = FileUtil.findFirstThatExist("/Applications/JavaFX Scene Builder 1.1.app", - "/Applications/JavaFX Scene Builder 1.0.app"); - if (sb != null) { - path = sb.getPath(); - } - } - else if (SystemInfo.isUnix) { - path = "/opt/JavaFXSceneBuilder1.1/JavaFXSceneBuilder1.1"; - } - - return path != null ? LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(path)) : null; - } - - private static void fillPaths(String programFilesPath, String sb11, String sb10, List suspiciousPaths) { - suspiciousPaths.add(new File(programFilesPath, ORACLE).getPath() + sb11); - suspiciousPaths.add(new File(programFilesPath, ORACLE).getPath() + sb10); - } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java index 3d10a1c811ee..b4e2a0e9262b 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericRepositoryType.java @@ -61,8 +61,7 @@ public class GenericRepositoryType extends BaseRepositoryType this, new AsanaRepository(), new AssemblaRepository(), - new SprintlyRepository(), - new GitlabRepository() + new SprintlyRepository() ); } @@ -127,10 +126,4 @@ public class GenericRepositoryType extends BaseRepositoryType super("Sprintly", TasksIcons.Sprintly); } } - - public final class GitlabRepository extends GenericSubtype { - public GitlabRepository() { - super("Gitlab", TasksIcons.Gitlab); - } - } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/gitlab.xml b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/gitlab.xml deleted file mode 100644 index b3ffd3c21111..000000000000 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/connectors/gitlab.xml +++ /dev/null @@ -1,75 +0,0 @@ - - {id} {summary} - diff --git a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/GitlabIntegrationTest.java b/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/GitlabIntegrationTest.java deleted file mode 100644 index 7c4e2d934206..000000000000 --- a/plugins/tasks/tasks-tests/test/com/intellij/tasks/integration/GitlabIntegrationTest.java +++ /dev/null @@ -1,129 +0,0 @@ -package com.intellij.tasks.integration; - -import com.intellij.tasks.Task; -import com.intellij.tasks.TaskTestUtil; -import com.intellij.tasks.generic.GenericRepository; -import com.intellij.tasks.generic.GenericRepositoryType; -import org.jetbrains.annotations.NotNull; - -/** - * @author Mikhail Golubev - */ -public class GitlabIntegrationTest extends GenericSubtypeTestCase { - private static final String TASK_LIST_RESPONSE = "[\n" + - " {\n" + - " \"id\": 2,\n" + - " \"iid\": 2,\n" + - " \"project_id\": 1,\n" + - " \"title\": \"Drink more tea\",\n" + - " \"description\": \"It\\u0027s healthy.\",\n" + - " \"labels\": [],\n" + - " \"assignee\": {\n" + - " \"id\": 4,\n" + - " \"username\": \"deva\",\n" + - " \"email\": \"deva@somemail.com\",\n" + - " \"name\": \"John Smith\",\n" + - " \"state\": \"active\",\n" + - " \"created_at\": \"2013-11-14T12:34:37Z\"\n" + - " },\n" + - " \"author\": {\n" + - " \"id\": 1,\n" + - " \"username\": \"root\",\n" + - " \"email\": \"admin@local.host\",\n" + - " \"name\": \"Administrator\",\n" + - " \"state\": \"active\",\n" + - " \"created_at\": \"2013-11-14T12:19:43Z\"\n" + - " },\n" + - " \"state\": \"opened\",\n" + - " \"updated_at\": \"2013-11-14T12:38:51Z\",\n" + - " \"created_at\": \"2013-11-14T12:33:07Z\"\n" + - " },\n" + - " {\n" + - " \"id\": 1,\n" + - " \"iid\": 1,\n" + - " \"project_id\": 1,\n" + - " \"title\": \"Eat more bananas\",\n" + - " \"description\": \"They're tasty.\",\n" + - " \"labels\": [\n" + - " \"spam\"\n" + - " ],\n" + - " \"assignee\": {\n" + - " \"id\": 1,\n" + - " \"username\": \"root\",\n" + - " \"email\": \"admin@local.host\",\n" + - " \"name\": \"Administrator\",\n" + - " \"state\": \"active\",\n" + - " \"created_at\": \"2013-11-14T12:19:43Z\"\n" + - " },\n" + - " \"author\": {\n" + - " \"id\": 1,\n" + - " \"username\": \"root\",\n" + - " \"email\": \"admin@local.host\",\n" + - " \"name\": \"Administrator\",\n" + - " \"state\": \"active\",\n" + - " \"created_at\": \"2013-11-14T12:19:43Z\"\n" + - " },\n" + - " \"state\": \"opened\",\n" + - " \"updated_at\": \"2013-11-14T12:30:39Z\",\n" + - " \"created_at\": \"2013-11-14T12:30:39Z\"\n" + - " }\n" + - "] "; - - private static final String SINGLE_TASK_RESPONSE = "{\n" + - " \"id\": 2,\n" + - " \"iid\": 2,\n" + - " \"project_id\": 1,\n" + - " \"title\": \"Drink more tea\",\n" + - " \"description\": \"It\\u0027s healthy.\",\n" + - " \"labels\": [],\n" + - " \"assignee\": {\n" + - " \"id\": 4,\n" + - " \"username\": \"deva\",\n" + - " \"email\": \"deva@somemail.com\",\n" + - " \"name\": \"John Smith\",\n" + - " \"state\": \"active\",\n" + - " \"created_at\": \"2013-11-14T12:34:37Z\"\n" + - " },\n" + - " \"author\": {\n" + - " \"id\": 1,\n" + - " \"username\": \"root\",\n" + - " \"email\": \"admin@local.host\",\n" + - " \"name\": \"Administrator\",\n" + - " \"state\": \"active\",\n" + - " \"created_at\": \"2013-11-14T12:19:43Z\"\n" + - " },\n" + - " \"state\": \"opened\",\n" + - " \"updated_at\": \"2013-11-14T12:38:51Z\",\n" + - " \"created_at\": \"2013-11-14T12:33:07Z\"\n" + - "}"; - - private Task getTask1() { - return new TaskTestUtil.TaskBuilder("1", "Eat more bananas", myRepository) - .withDescription("They're tasty.") - .withUpdated("2013-11-14T12:30:39Z") - .withCreated("2013-11-14T12:30:39Z"); - } - - private Task getTask2() { - return new TaskTestUtil.TaskBuilder("2", "Drink more tea", myRepository) - .withDescription("It's healthy.") - .withUpdated("2013-11-14T12:38:51Z") - .withCreated("2013-11-14T12:33:07Z"); - } - - @NotNull - @Override - protected GenericRepository createRepository(GenericRepositoryType genericType) { - return (GenericRepository)genericType.new GitlabRepository().createRepository(); - } - - public void testParsingTaskList() throws Exception { - Task[] tasks = myRepository.getActiveResponseHandler().parseIssues(TASK_LIST_RESPONSE, 50); - TaskTestUtil.assertTasksEqual(new Task[]{getTask2(), getTask1()}, tasks); - } - - public void testParsingSingleTask() throws Exception { - Task task = myRepository.getActiveResponseHandler().parseIssue(SINGLE_TASK_RESPONSE); - TaskTestUtil.assertTasksEqual(getTask2(), task); - } -} diff --git a/python/helpers/pycharm/nose_utils.py b/python/helpers/pycharm/nose_utils.py index 9a6d68251cb3..a7efa08d4f4e 100644 --- a/python/helpers/pycharm/nose_utils.py +++ b/python/helpers/pycharm/nose_utils.py @@ -116,7 +116,7 @@ class TeamcityPlugin(ErrorClassPlugin, TextTestResult, TeamcityTestResult): suite = strclass(test.__class__) suite_location = "python_nosetestid://" + suite try: - from nose_helper.util import func_lineno + from nose.util import func_lineno if hasattr(test.test, "descriptor") and test.test.descriptor: suite_location = "file://" + self.test_address( diff --git a/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java b/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java index 6030afc5a158..fe51d6468fd5 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/PyInjectionUtil.java @@ -81,7 +81,8 @@ public class PyInjectionUtil { */ @NotNull public static InjectionResult registerStringLiteralInjection(@NotNull PsiElement element, @NotNull MultiHostRegistrar registrar) { - return processStringLiteral(element, registrar, "", "", Formatting.NONE); + // Assume percent formatting since the MySQL parser cannot handle Python-style substitutions + return processStringLiteral(element, registrar, "", "", Formatting.PERCENT); } private static boolean isStringLiteralPart(@NotNull PsiElement element, @Nullable PsiElement context) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java index 9c34062d2f08..6ad33d60569e 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java @@ -238,6 +238,9 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl entry : mapping.getPlainMappedParams().entrySet()) { - if (entry.getValue() == PyNamedParameterImpl.this) { - final PyExpression argument = entry.getKey(); - if (argument != null) { - final PyType type = context.getType(argument); - if (type != null) { - types.add(type); - return true; + final PyArgumentList argumentList = call.getArgumentList(); + if (argumentList != null) { + final CallArgumentsMapping mapping = argumentList.analyzeCall(resolveContext); + for (Map.Entry entry : mapping.getPlainMappedParams().entrySet()) { + if (entry.getValue() == PyNamedParameterImpl.this) { + final PyExpression argument = entry.getKey(); + if (argument != null) { + final PyType type = context.getType(argument); + if (type != null) { + types.add(type); + return true; + } } } } diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassMembersRefactoringSupport.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassMembersRefactoringSupport.java index 71f920c8399e..17588e666e25 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyClassMembersRefactoringSupport.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassMembersRefactoringSupport.java @@ -22,6 +22,7 @@ import com.intellij.refactoring.classMembers.DependentMembersCollectorBase; import com.intellij.refactoring.classMembers.MemberInfoBase; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; /** * @author Dennis.Ushakov diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java index eda33558779f..a92e3ad44a9a 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java @@ -139,6 +139,22 @@ public class PyClassRefactoringUtil { return false; } + /** + * Moves class field to another class + * @param expressions list of class fields + * @param superClass where to move them + */ + public static void moveFields(@NotNull final Collection expressions, @NotNull final PyClass superClass) { + for (final PyTargetExpression expression : expressions) { + final PyAssignmentStatement expAssignmentStatement = PsiTreeUtil.getParentOfType(expression, PyAssignmentStatement.class); + assert expAssignmentStatement != null: "Target expression has no assignment statement"; + final PyStatementList superClassStatement = superClass.getStatementList(); + PyUtil.addElementToStatementList(expAssignmentStatement.copy(), superClassStatement, true); + expAssignmentStatement.delete(); + PyPsiUtils.removeRedundantPass(superClassStatement); + } + + } public static void moveMethods(Collection methods, PyClass superClass) { if (methods.size() == 0) return; for (PsiElement e : methods) { diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyDependentMembersCollector.java b/python/src/com/jetbrains/python/refactoring/classes/PyDependentMembersCollector.java index 5c51118c0129..5efb3525d5ba 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyDependentMembersCollector.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyDependentMembersCollector.java @@ -29,6 +29,7 @@ public class PyDependentMembersCollector extends DependentMembersCollectorBase

{ - public PyMemberInfo(PyElement member) { - super(member); - final PyClass clazz = PyUtil.getContainingClassOrSelf(member); - assert clazz != null; - - if (member instanceof PyFunction) { - PyFunction function = (PyFunction)member; - displayName = buildDisplayMethodName(function); - for (PyClass aClass : clazz.getSuperClasses()) { - final PyFunction parentMethod = aClass.findMethodByName(function.getName(), true); - if (parentMethod != null) { - overrides = true; - } - } - } else if (member instanceof PyClass) { - displayName = RefactoringBundle.message("member.info.extends.0", PyClassCellRenderer.getClassText((PyClass)member)); - } - } - - private static String buildDisplayMethodName(PyFunction method) { - final StringBuilder builder = new StringBuilder(method.getName()); - builder.append("("); - final PyParameter[] arguments = method.getParameterList().getParameters(); - for (PyParameter parameter : arguments) { - builder.append(parameter.getName()); - if (arguments.length > 1 && parameter != arguments[arguments.length - 1]) { - builder.append(", "); - } - } - builder.append(")"); - return builder.toString(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof PyMemberInfo) { - return getMember().equals(((PyMemberInfo)obj).getMember()); - } - return false; - } - - @Override - public int hashCode() { - return getMember().hashCode(); - } -} diff --git a/python/src/com/jetbrains/python/refactoring/classes/PyMemberInfoStorage.java b/python/src/com/jetbrains/python/refactoring/classes/PyMemberInfoStorage.java index 5c172e63b812..ae6d769f35ab 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/PyMemberInfoStorage.java +++ b/python/src/com/jetbrains/python/refactoring/classes/PyMemberInfoStorage.java @@ -22,6 +22,8 @@ import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.refactoring.PyRefactoringUtil; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import java.util.ArrayList; @@ -60,12 +62,7 @@ public class PyMemberInfoStorage extends AbstractMemberInfoStorage temp) { - for (PyFunction function : aClass.getMethods()) { - temp.add(new PyMemberInfo(function)); - } - for (PyClass pyClass : aClass.getSuperClasses()) { - temp.add(new PyMemberInfo(pyClass)); - } + temp.addAll(MembersManager.getAllMembersCouldBeMoved(aClass)); } @Override diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java index c0bc437b9498..05dab4f7aa7f 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassDialog.java @@ -34,7 +34,7 @@ import com.jetbrains.python.PyBundle; import com.jetbrains.python.PythonLanguage; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import com.jetbrains.python.refactoring.classes.ui.UpDirectedMembersMovingDialog; import org.jetbrains.annotations.NotNull; diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHandler.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHandler.java index a68860d6e97f..8ed2fa8aef85 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHandler.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHandler.java @@ -28,7 +28,7 @@ import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyUtil; import com.jetbrains.python.refactoring.classes.PyClassMembersRefactoringSupport; import com.jetbrains.python.refactoring.classes.PyClassRefactoringHandler; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import java.util.Collection; diff --git a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java index 0d8033704728..98d016e50fa3 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java +++ b/python/src/com/jetbrains/python/refactoring/classes/extractSuperclass/PyExtractSuperclassHelper.java @@ -37,7 +37,7 @@ import com.jetbrains.python.PythonFileType; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java new file mode 100644 index 000000000000..d5ef793fb961 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java @@ -0,0 +1,57 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.intellij.psi.PsiElement; +import com.jetbrains.python.psi.PyAssignmentStatement; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.psi.PyTargetExpression; +import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * Moves class attributes up + * @author Ilya.Kazakevich + */ +class ClassFieldsManager extends MembersManager { + + ClassFieldsManager() { + super(PyTargetExpression.class); + } + + @NotNull + @Override + protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { + return new ArrayList(Collections2.filter(pyClass.getClassAttributes(), new SimpleAssignmentsOnly())); + } + + @Override + protected void moveMembers(@NotNull final PyClass from, @NotNull final PyClass to, @NotNull final Collection members) { + PyClassRefactoringUtil.moveFields(members, to); + } + + @NotNull + @Override + public PyMemberInfo apply(@NotNull final PyElement input) { + return new PyMemberInfo(input, true, input.getText(), false, this); //TODO: Check overrides + } + + private static class SimpleAssignmentsOnly implements Predicate { + //Support only simplest cases like CLASS_VAR = 42. + //Tuples (CLASS_VAR_1, CLASS_VAR_2) = "spam", "eggs" are not supported by now + @Override + public boolean apply(@Nullable final PyTargetExpression input) { + if (input == null) { + return false; //Filter out empties (which probably would never be here) + } + final PsiElement parent = input.getParent(); + return (parent != null) && PyAssignmentStatement.class.isAssignableFrom(parent.getClass()); + } + } +} diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java new file mode 100644 index 000000000000..93701ce13eb6 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MembersManager.java @@ -0,0 +1,141 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Collections2; +import com.google.common.collect.Multimap; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.TestOnly; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * Moves members between classes via its plugins (managers). + * To move members use {@link #getAllMembersCouldBeMoved(com.jetbrains.python.psi.PyClass)} and {@link #moveMembers(com.jetbrains.python.psi.PyClass, com.jetbrains.python.psi.PyClass, java.util.Collection)} + * To add new manager, extend this class and add it to {@link #MANAGERS} + * + * @author Ilya.Kazakevich + */ +public abstract class MembersManager implements Function { + /** + * List of managers. Class delegates all logic to them. + */ + private static final Collection> MANAGERS = + Arrays.asList(new MethodsManager(), new SuperClassesManager(), new ClassFieldsManager()); + private static final PyMemberExtractor PY_MEMBER_EXTRACTOR = new PyMemberExtractor(); + + @NotNull + private final Class myExpectedClass; + + protected MembersManager(@NotNull final Class expectedClass) { + myExpectedClass = expectedClass; + } + + /** + * Get all members that could be moved out of certain class + * + * @param pyClass class to find members + * @return list of members could be moved + */ + @NotNull + public static List getAllMembersCouldBeMoved(@NotNull final PyClass pyClass) { + final List result = new ArrayList(); + + for (final MembersManager manager : MANAGERS) { + result.addAll(Collections2.transform(manager.getMembersCouldBeMoved(pyClass), manager)); + } + return result; + } + + + /** + * Moves members from one class to another + * + * @param from source + * @param to destination + * @param memberInfos members to move + */ + public static void moveAllMembers(@NotNull final PyClass from, + @NotNull final PyClass to, + @NotNull final Collection memberInfos) { + final Multimap, PyMemberInfo> managerToMember = ArrayListMultimap.create(); + //Collect map (manager)->(list_of_memebers) + for (final PyMemberInfo memberInfo : memberInfos) { + managerToMember.put(memberInfo.getMembersManager(), memberInfo); + } + //Move members via manager + for (final MembersManager membersManager : managerToMember.keySet()) { + moveSafely(from, to, membersManager, Collections2.transform(managerToMember.get(membersManager), PY_MEMBER_EXTRACTOR)); + } + PyClassRefactoringUtil.insertPassIfNeeded(from); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) //We check classes at runtime + private static void moveSafely(@NotNull final PyClass from, + @NotNull final PyClass to, + @NotNull final MembersManager manager, + @NotNull final Collection elementsToMove) { + for (final PyElement pyElement : elementsToMove) { + Preconditions.checkArgument(manager.myExpectedClass.isAssignableFrom(pyElement.getClass()), + String.format("Manager %s expected %s but got %s", manager, manager.myExpectedClass, pyElement)); + } + + manager.moveMembers(from, to, (Collection)elementsToMove); + } + + /** + * Finds member in class. It is here only for backward compatibility with some tests. + */ + //TODO: mark deprecated? + @TestOnly + @NotNull + public static PyMemberInfo findMember(@NotNull final PyClass pyClass, @NotNull final PyElement pyElement) { + for (final PyMemberInfo pyMemberInfo : getAllMembersCouldBeMoved(pyClass)) { + if (pyMemberInfo.getMember().equals(pyElement)) { + return pyMemberInfo; + } + } + throw new IllegalArgumentException(String.format("Element %s not found in class %s or can't be moved", pyElement, pyClass)); + } + + /** + * Get list of elements certain plugin could move out of the class + * + * @param pyClass class with members + * @return list of members + */ + @NotNull + protected abstract List getMembersCouldBeMoved(@NotNull PyClass pyClass); + + /** + * Moves element from one class to another + * + * @param from source + * @param to destination + * @param members collection of memebrs to move + */ + protected abstract void moveMembers(@NotNull PyClass from, @NotNull PyClass to, @NotNull Collection members); + + //TODO: Doc + @SuppressWarnings("NullableProblems") //IDEA-120100 + @NotNull + @Override + public abstract PyMemberInfo apply(@NotNull PyElement input); + + private static class PyMemberExtractor implements Function { + @SuppressWarnings("NullableProblems") //IDEA-120100 + @Override + public PyElement apply(@NotNull final PyMemberInfo input) { + return input.getMember(); + } + } +} + + diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java new file mode 100644 index 000000000000..720b420b62ab --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java @@ -0,0 +1,70 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.jetbrains.python.psi.*; +import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +/** + * Plugin that moves class methods + * + * @author Ilya.Kazakevich + */ +class MethodsManager extends MembersManager { + + MethodsManager() { + super(PyFunction.class); + } + + @NotNull + @Override + protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { + return Arrays.asList(pyClass.getMethods()); + } + + @Override + protected void moveMembers(@NotNull final PyClass from, @NotNull final PyClass to, @NotNull final Collection members) { + PyClassRefactoringUtil.moveMethods(members, to); + } + + @NotNull + @Override + public PyMemberInfo apply(@NotNull final PyElement input) { + //TODO: Use generics to prevent casting in each subclass + final PyFunction pyFunction = (PyFunction)input; + //TODO: Support static and classmethod functions + return new PyMemberInfo(input, false, buildDisplayMethodName(pyFunction), isOverrides(pyFunction), this); + } + + @Nullable + private static Boolean isOverrides(final PyFunction pyFunction) { + final PyClass clazz = PyUtil.getContainingClassOrSelf(pyFunction); + assert clazz != null : "Refactoring called on function, not method: " + pyFunction; + for (final PyClass parentClass : clazz.getSuperClasses()) { + final PyFunction parentMethod = parentClass.findMethodByName(pyFunction.getName(), true); + if (parentMethod != null) { + return true; + } + } + return null; + } + + @NotNull + private static String buildDisplayMethodName(@NotNull final PyFunction pyFunction) { + final StringBuilder builder = new StringBuilder(pyFunction.getName()); + builder.append('('); + final PyParameter[] arguments = pyFunction.getParameterList().getParameters(); + for (final PyParameter parameter : arguments) { + builder.append(parameter.getName()); + if (arguments.length > 1 && parameter != arguments[arguments.length - 1]) { + builder.append(", "); + } + } + builder.append(')'); + return builder.toString(); + } +} diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMemberInfo.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMemberInfo.java new file mode 100644 index 000000000000..210326f28e81 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/PyMemberInfo.java @@ -0,0 +1,67 @@ +/* + * Copyright 2000-2013 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.jetbrains.python.refactoring.classes.membersManager; + +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.jetbrains.python.psi.PyElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Dennis.Ushakov + */ +public class PyMemberInfo extends MemberInfoBase { + @NotNull + private final MembersManager myMembersManager; + + /** + * @param member element itself + * @param isStatic is it static or not? + * @param displayName element display name + * @param overrides does it overrides something? TRUE if is overriden, FALSE if implemented, null if not implemented or overriden + * TODO: use primitive instead? "Implemeneted" has nothing to do with python duck-typing + * @param membersManager manager that knows how to handle this member + */ + PyMemberInfo(@NotNull final PyElement member, + final boolean isStatic, + @NotNull final String displayName, + @Nullable final Boolean overrides, + @NotNull final MembersManager membersManager) { + super(member); + this.isStatic = isStatic; + this.displayName = displayName; + this.overrides = overrides; + myMembersManager = membersManager; + } + + @NotNull + MembersManager getMembersManager() { + return myMembersManager; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof PyMemberInfo) { + return getMember().equals(((PyMemberInfo)obj).getMember()); + } + return false; + } + + @Override + public int hashCode() { + return getMember().hashCode(); + } +} diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java new file mode 100644 index 000000000000..0caf927c9751 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/SuperClassesManager.java @@ -0,0 +1,74 @@ +package com.jetbrains.python.refactoring.classes.membersManager; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.google.common.collect.Sets; +import com.intellij.psi.PsiNamedElement; +import com.intellij.refactoring.RefactoringBundle; +import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; +import com.jetbrains.python.refactoring.classes.ui.PyClassCellRenderer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +/** + * Plugin that moves superclasses from one class to another + * + * @author Ilya.Kazakevich + */ +class SuperClassesManager extends MembersManager { + SuperClassesManager() { + super(PyClass.class); + } + + private static final NameExtractor NAME_EXTRACTOR = new NameExtractor(); + private static final NameFilter NAME_FILTER = new NameFilter(); + + @NotNull + @Override + protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { + return Arrays.asList(pyClass.getSuperClasses()); + } + + @Override + protected void moveMembers(@NotNull final PyClass from, @NotNull final PyClass to, @NotNull final Collection members) { + final Set superClassesToMove = + Sets.newHashSet(Collections2.filter(Collections2.transform(members, NAME_EXTRACTOR), NAME_FILTER)); + + for (final PyElement member : members) { + superClassesToMove.add(member.getName()); + } + + PyClassRefactoringUtil.moveSuperclasses(from, superClassesToMove, to); + //TODO: Use generics! + PyClassRefactoringUtil.insertImport(to, new ArrayList(members)); + } + + @NotNull + @Override + public PyMemberInfo apply(@NotNull final PyElement input) { + final String name = RefactoringBundle.message("member.info.extends.0", PyClassCellRenderer.getClassText((PyClass)input)); + //TODO: Check for "overrides" + return new PyMemberInfo(input, false, name, false, this); + } + + private static class NameExtractor implements Function { + @SuppressWarnings("NullableProblems") //We sure collection has no null + @Nullable + @Override + public String apply(@NotNull final PyElement input) { + return input.getName(); + } + } + + private static class NameFilter implements Predicate { + @Override + public boolean apply(@Nullable final String input) { + return input != null; + } + } +} diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/package-info.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/package-info.java new file mode 100644 index 000000000000..b730fd4e3c06 --- /dev/null +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/package-info.java @@ -0,0 +1,12 @@ +/** + * Incapsulates knowledge about class members that could be moved to some other class. + * To use (get list of members to move or actually move them) use {@link com.jetbrains.python.refactoring.classes.membersManager.MembersManager#getAllMembersCouldBeMoved(com.jetbrains.python.psi.PyClass)} + * and {@link com.jetbrains.python.refactoring.classes.membersManager.MembersManager#moveAllMembers(com.jetbrains.python.psi.PyClass, com.jetbrains.python.psi.PyClass, java.util.Collection)} + * + * This class delegates its behaviour to its managers (some kind of plugins). There is one for each member type (one for method, one for field etc). + * You need to extend {@link com.jetbrains.python.refactoring.classes.membersManager.MembersManager} to add some. See its javadoc for more info. + * + * + * @author Ilya.Kazakevich + */ +package com.jetbrains.python.refactoring.classes.membersManager; \ No newline at end of file diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PullUpViewSwingImpl.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PullUpViewSwingImpl.java index 7707faab3f00..b0c38d31c8fa 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PullUpViewSwingImpl.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PullUpViewSwingImpl.java @@ -26,7 +26,7 @@ import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.ui.PyClassCellRenderer; import com.jetbrains.python.refactoring.classes.ui.PyMemberSelectionPanel; import com.jetbrains.python.refactoring.classes.ui.PyMemberSelectionTable; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpConflictsUtil.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpConflictsUtil.java index 8d68255f1a1a..c1f5eeaa4240 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpConflictsUtil.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpConflictsUtil.java @@ -21,7 +21,7 @@ import com.intellij.refactoring.util.RefactoringUIUtil; import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import java.util.Collection; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpHelper.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpHelper.java index 0046ba2eef92..37f3718b84ed 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpHelper.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpHelper.java @@ -17,49 +17,31 @@ package com.jetbrains.python.refactoring.classes.pullUp; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.PsiNamedElement; import com.intellij.refactoring.RefactoringBundle; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; -import java.util.*; +import java.util.Collection; /** * @author Dennis.Ushakov */ -public class PyPullUpHelper { - private static final Logger LOG = Logger.getInstance(PyPullUpHelper.class.getName()); - private PyPullUpHelper() {} +public final class PyPullUpHelper { + + private PyPullUpHelper() { + } public static PyElement pullUp(final PyClass clazz, final Collection selectedMemberInfos, final PyClass superClass) { - final Set superClasses = new HashSet(); - final Set extractedClasses = new HashSet(); - final List methods = new ArrayList(); - for (PyMemberInfo member : selectedMemberInfos) { - final PyElement element = member.getMember(); - if (element instanceof PyFunction) methods.add((PyFunction)element); - else if (element instanceof PyClass) { - superClasses.add(element.getName()); - extractedClasses.add((PyClass)element); - } - else LOG.error("unmatched member class " + element.getClass()); - } - + CommandProcessor.getInstance().executeCommand(clazz.getProject(), new Runnable() { + @Override public void run() { ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override public void run() { - // move methods - PyClassRefactoringUtil.moveMethods(methods, superClass); - - // move superclasses declarations - PyClassRefactoringUtil.moveSuperclasses(clazz, superClasses, superClass); - PyClassRefactoringUtil.insertImport(superClass, extractedClasses); - PyClassRefactoringUtil.insertPassIfNeeded(clazz); + MembersManager.moveAllMembers(clazz, superClass, selectedMemberInfos); } }); } diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterImpl.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterImpl.java index 8ab80cf5603a..99295d9f607e 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterImpl.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterImpl.java @@ -25,7 +25,7 @@ import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import org.jetbrains.annotations.NotNull; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpView.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpView.java index 1f935ee8de1d..856b072ef236 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpView.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpView.java @@ -21,7 +21,7 @@ import com.intellij.refactoring.classMembers.MemberInfoModel; import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import java.util.Collection; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownConflicts.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownConflicts.java index c159b2f27f00..7e4f93c5493e 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownConflicts.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownConflicts.java @@ -25,7 +25,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.resolve.PyResolveContext; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import java.util.ArrayList; import java.util.Collection; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownDialog.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownDialog.java index 2235c574f9a8..73790938911f 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownDialog.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownDialog.java @@ -23,7 +23,7 @@ import com.intellij.refactoring.classMembers.UsedByDependencyMemberInfoModel; import com.intellij.refactoring.ui.RefactoringDialog; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import com.jetbrains.python.refactoring.classes.ui.PyMemberSelectionPanel; diff --git a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java index 1164c691eea8..ec321f7f5999 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pushDown/PyPushDownProcessor.java @@ -34,7 +34,7 @@ import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.psi.search.PyClassInheritorsSearch; import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import java.util.*; diff --git a/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionPanel.java b/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionPanel.java index 7ee075424936..330575b9eabc 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionPanel.java +++ b/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionPanel.java @@ -19,7 +19,7 @@ import com.intellij.refactoring.classMembers.MemberInfoModel; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.ScrollPaneFactory; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import org.jetbrains.annotations.NotNull; import javax.swing.*; diff --git a/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionTable.java b/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionTable.java index 11d3e4285b7c..e34cd591d343 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionTable.java +++ b/python/src/com/jetbrains/python/refactoring/classes/ui/PyMemberSelectionTable.java @@ -22,7 +22,7 @@ import com.intellij.refactoring.ui.AbstractMemberSelectionTable; import com.intellij.ui.RowIcon; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyFunction; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import javax.swing.*; import java.util.List; diff --git a/python/src/com/jetbrains/python/refactoring/classes/ui/UpDirectedMembersMovingDialog.java b/python/src/com/jetbrains/python/refactoring/classes/ui/UpDirectedMembersMovingDialog.java index 7ac313d57101..81794643bb59 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/ui/UpDirectedMembersMovingDialog.java +++ b/python/src/com/jetbrains/python/refactoring/classes/ui/UpDirectedMembersMovingDialog.java @@ -23,7 +23,7 @@ import com.intellij.refactoring.util.CommonRefactoringUtil; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyUtil; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import javax.swing.*; import java.awt.*; diff --git a/python/src/com/jetbrains/python/run/PythonRunConfigurationProducer.java b/python/src/com/jetbrains/python/run/PythonRunConfigurationProducer.java index c14bde2030b4..581776880816 100644 --- a/python/src/com/jetbrains/python/run/PythonRunConfigurationProducer.java +++ b/python/src/com/jetbrains/python/run/PythonRunConfigurationProducer.java @@ -17,6 +17,7 @@ package com.jetbrains.python.run; import com.intellij.execution.Location; import com.intellij.execution.actions.ConfigurationContext; +import com.intellij.execution.actions.ConfigurationFromContext; import com.intellij.execution.actions.RunConfigurationProducer; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; @@ -94,4 +95,8 @@ public class PythonRunConfigurationProducer extends RunConfigurationProducer.) is treated as method. + * member that starts with dash (#) is treated as attribute. * It is treated parent class otherwise * @return member or null if not found */ @NotNull protected PyElement findMember(@NotNull String className, @NotNull String memberName) { - boolean findMethod = memberName.contains("."); - PyElement result = (findMethod ? findMethod(className, memberName.substring(1)) : findClass(memberName)); + final PyElement result; + //TODO: Get rid of this chain of copy pastes + if (memberName.contains(".")) { + result = findMethod(className, memberName.substring(1)); + } + else if (memberName.contains("#")) { + result = findField(className, memberName.substring(1)); + } + else { + result = findClass(memberName); + } Assert.assertNotNull(String.format("No member %s found in class %s", memberName, className), result); return result; } + private PyElement findField(final String className, final String memberName) { + return findClass(className).findClassAttribute(memberName, false); + } + private PyFunction findMethod(final String className, final String name) { final PyClass clazz = findClass(className); return clazz.findMethodByName(name, false); diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyExtractSuperclassTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyExtractSuperclassTest.java index baab81cc5062..d143e966e077 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyExtractSuperclassTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyExtractSuperclassTest.java @@ -24,6 +24,8 @@ import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.refactoring.classes.extractSuperclass.PyExtractSuperclassHelper; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import java.io.File; import java.util.ArrayList; @@ -53,7 +55,7 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { final List members = new ArrayList(); for (String memberName : membersName) { final PyElement member = findMember(className, memberName); - members.add(new PyMemberInfo(member)); + members.add(MembersManager.findMember(clazz, member)); } new WriteCommandAction.Simple(myFixture.getProject()) { @@ -81,7 +83,7 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { final PyClass clazz = findClass(className); final List members = new ArrayList(); final PyElement member = findMember(className, ".foo"); - members.add(new PyMemberInfo(member)); + members.add(MembersManager.findMember(clazz, member)); final VirtualFile base_dir = myFixture.getFile().getVirtualFile().getParent(); new WriteCommandAction.Simple(myFixture.getProject()) { @@ -124,7 +126,7 @@ public class PyExtractSuperclassTest extends PyClassRefactoringTest { final PyClass clazz = findClass(className); final List members = new ArrayList(); final PyElement member = findMember(className, ".foo"); - members.add(new PyMemberInfo(member)); + members.add(MembersManager.findMember(clazz, member)); final VirtualFile base_dir = myFixture.getFile().getVirtualFile().getParent(); new WriteCommandAction.Simple(myFixture.getProject()) { diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyPullUpTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyPullUpTest.java index 881dac2a9766..c1bb6d033216 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyPullUpTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyPullUpTest.java @@ -17,6 +17,7 @@ package com.jetbrains.python.refactoring.classes; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; import com.jetbrains.python.refactoring.classes.pullUp.PyPullUpHelper; import java.util.Collections; @@ -49,6 +50,13 @@ public class PyPullUpTest extends PyClassRefactoringTest { doHelperTest("Child", "Spam", "Parent_1"); } + public void testMoveClassAttributesSimple() { + doHelperTest("Child", "#CLASS_VAR", "Parent"); + } + public void testMoveClassAttributesNoPass() { + doHelperTest("Child2", "#CLASS_VAR", "Parent2"); + } + public void testMultiFile() { // PY-2810 doMultiFileTest(); } @@ -76,6 +84,6 @@ public class PyPullUpTest extends PyClassRefactoringTest { final PyClass clazz = findClass(className); final PyElement member = findMember(className, memberName); final PyClass superClass = findClass(superClassName); - PyPullUpHelper.pullUp(clazz, Collections.singleton(new PyMemberInfo(member)), superClass); + PyPullUpHelper.pullUp(clazz, Collections.singleton(MembersManager.findMember(clazz, member)), superClass); } } diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyPushDownTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyPushDownTest.java index 72c3bfded44a..480e3a4b4bf7 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyPushDownTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyPushDownTest.java @@ -18,6 +18,8 @@ package com.jetbrains.python.refactoring.classes; import com.intellij.openapi.command.WriteCommandAction; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; +import com.jetbrains.python.refactoring.classes.membersManager.MembersManager; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.pushDown.PyPushDownProcessor; import java.util.ArrayList; @@ -55,7 +57,7 @@ public class PyPushDownTest extends PyClassRefactoringTest { final List members = new ArrayList(); for (String memberName : membersName) { final PyElement member = findMember(className, memberName); - members.add(new PyMemberInfo(member)); + members.add(MembersManager.findMember(clazz, member)); } final PyPushDownProcessor processor = new PyPushDownProcessor(myFixture.getProject(), clazz, members); diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java index 02092d208518..e8b7ed671b86 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/pullUp/PyPullUpPresenterTest.java @@ -7,7 +7,7 @@ import com.intellij.refactoring.classMembers.MemberInfoModel; import com.jetbrains.python.fixtures.PyTestCase; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; -import com.jetbrains.python.refactoring.classes.PyMemberInfo; +import com.jetbrains.python.refactoring.classes.membersManager.PyMemberInfo; import com.jetbrains.python.refactoring.classes.PyMemberInfoStorage; import org.easymock.Capture; import org.easymock.EasyMock; @@ -102,6 +102,7 @@ public class PyPullUpPresenterTest extends PyTestCase { @SuppressWarnings("unchecked") Matcher>> matcher = Matchers .containsInAnyOrder( Pair.create("date", true), + Pair.create("CLASS_FIELD", true), Pair.create("SubParent1", false), Pair.create("foo", false), Pair.create("bar", true)); diff --git a/python/testSrc/python-community-tests.iml b/python/testSrc/python-community-tests.iml index b4cc2764d3aa..6511d8860c87 100644 --- a/python/testSrc/python-community-tests.iml +++ b/python/testSrc/python-community-tests.iml @@ -15,6 +15,7 @@ +