From 4534d02ff6acee9299b3d15f92fde8715db13bce Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 5 Oct 2016 16:28:23 +0200 Subject: [PATCH 01/27] deprecate CompletionProgressIndicator to prevent external usages multiplying --- .../codeInsight/completion/CompletionProgressIndicator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java index 12e2e2851221..6ea9e784118e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java @@ -85,8 +85,9 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.TimeUnit; /** - * @author peter + * Please don't use this class directly from plugins */ +@Deprecated public class CompletionProgressIndicator extends ProgressIndicatorBase implements CompletionProcess, Disposable { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.CompletionProgressIndicator"); private final Editor myEditor; From 5ce6b6a893b3297f81fa713b82c5d3e8cfe0bc3d Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 5 Oct 2016 16:42:03 +0200 Subject: [PATCH 02/27] IDEA-161588 If you paste code with statically imported ambiguous methods copied from another Java file, IDEA should remember the "static imports" and add them automatically like it does for classes --- .../impl/quickfix/StaticImportMemberFix.java | 12 ++++++------ .../JavaCopyPasteReferenceProcessor.java | 17 +++++++++++++++-- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMemberFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMemberFix.java index 48d9d24ad0e5..0134261cbf03 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMemberFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/StaticImportMemberFix.java @@ -24,17 +24,13 @@ import com.intellij.codeInsight.hint.HintManager; import com.intellij.codeInsight.hint.QuestionAction; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInspection.HintAction; -import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.impl.LaterInvocator; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiJavaFile; -import com.intellij.psi.PsiMember; +import com.intellij.psi.*; import com.intellij.psi.util.FileTypeUtils; import com.intellij.psi.util.PsiUtil; import org.jetbrains.annotations.NotNull; @@ -79,7 +75,11 @@ public abstract class StaticImportMemberFix implements Inte && !(candidates == null ? candidates = getMembersToImport(false) : candidates).isEmpty() ; } - + + public final List getMembersToImport() { + return getMembersToImport(false); + } + @NotNull protected abstract List getMembersToImport(boolean applicableOnly); public static boolean isExcluded(PsiMember method) { diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java index 70460bfca8ea..4f0247b60b24 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java @@ -17,11 +17,14 @@ package com.intellij.codeInsight.editorActions; import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix; +import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportConstantFix; +import com.intellij.codeInsight.daemon.impl.quickfix.StaticImportMethodFix; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -105,8 +108,7 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor if (CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY) { for (int i = 0; i < refs.length; i++) { - PsiJavaCodeReferenceElement ref = refs[i]; - if (ref != null && new ImportClassFix(ref).getClassesToImport().size() <= 1) { + if (isUnambiguous(refs[i])) { refs[i] = null; } } @@ -115,6 +117,17 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor return refs; } + private static boolean isUnambiguous(@Nullable PsiJavaCodeReferenceElement ref) { + if (ref == null) return false; + + PsiElement parent = ref.getParent(); + if (parent instanceof PsiMethodCallExpression) { + return new StaticImportMethodFix((PsiMethodCallExpression)parent).getMembersToImport().size() <= 1; + } + + return new ImportClassFix(ref).getClassesToImport().size() + new StaticImportConstantFix(ref).getMembersToImport().size() <= 1; + } + @Override protected void restoreReferences(ReferenceData[] referenceData, PsiJavaCodeReferenceElement[] refs) { From 3876645460d3c8a5ac633c8415496152b22356eb Mon Sep 17 00:00:00 2001 From: "vadim.lomshakov" Date: Wed, 5 Oct 2016 17:45:59 +0300 Subject: [PATCH 03/27] fixed SearchAgainAction/SearchBackAction availability: if EditorSearchSession isn't opened, these actions won't be available --- .../intellij/ide/actions/SearchAgainAction.java | 14 +++++++++----- .../com/intellij/ide/actions/SearchBackAction.java | 12 ++++++++---- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java index 65403b76b9a5..746068aea363 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java @@ -16,6 +16,7 @@ package com.intellij.ide.actions; +import com.intellij.find.EditorSearchSession; import com.intellij.find.FindManager; import com.intellij.find.FindUtil; import com.intellij.ide.IdeBundle; @@ -63,11 +64,14 @@ public class SearchAgainAction extends AnAction implements DumbAware { public void update(AnActionEvent event){ Presentation presentation = event.getPresentation(); Project project = event.getData(CommonDataKeys.PROJECT); - if (project == null) { - presentation.setEnabled(false); + presentation.setEnabled(false); + if (project == null) return; - } - FileEditor editor = event.getData(PlatformDataKeys.FILE_EDITOR); - presentation.setEnabled(editor instanceof TextEditor); + final FileEditor editor = event.getData(PlatformDataKeys.FILE_EDITOR); + if (!(editor instanceof TextEditor)) + return; + + final EditorSearchSession search = EditorSearchSession.get(event.getData(PlatformDataKeys.EDITOR)); + presentation.setEnabled(search != null); } } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java index 978471cef90f..b5eeb5295879 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java @@ -16,6 +16,7 @@ package com.intellij.ide.actions; +import com.intellij.find.EditorSearchSession; import com.intellij.find.FindManager; import com.intellij.find.FindUtil; import com.intellij.ide.IdeBundle; @@ -59,11 +60,14 @@ public class SearchBackAction extends AnAction implements DumbAware { public void update(AnActionEvent event){ Presentation presentation = event.getPresentation(); Project project = event.getData(CommonDataKeys.PROJECT); - if (project == null) { - presentation.setEnabled(false); + presentation.setEnabled(false); + if (project == null) return; - } final FileEditor editor = event.getData(PlatformDataKeys.FILE_EDITOR); - presentation.setEnabled(editor instanceof TextEditor); + if (!(editor instanceof TextEditor)) + return; + + final EditorSearchSession search = EditorSearchSession.get(event.getData(PlatformDataKeys.EDITOR)); + presentation.setEnabled(search != null); } } From 25c1158f7c27e22de4af3bea4c4f574cd2c972df Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Wed, 5 Oct 2016 19:07:07 +0300 Subject: [PATCH 04/27] [vcs-log] lower maximum graph width to reduce space on the left for the very large graphs --- .../com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java index ffe43ec4bb99..0591dd7ac0bb 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java @@ -37,7 +37,7 @@ import java.util.Map; public class GraphCommitCellRenderer extends ColoredTableCellRenderer { private static final Logger LOG = Logger.getInstance(GraphCommitCellRenderer.class); - private static final int MAX_GRAPH_WIDTH = 10; + private static final int MAX_GRAPH_WIDTH = 6; private static final int VERTICAL_PADDING = JBUI.scale(7); From 039501e89d5405b0bbc461e18351c24efea94c1a Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Wed, 5 Oct 2016 19:12:02 +0300 Subject: [PATCH 05/27] IDEA-162025 Unexpected focus-effect painting in ComboBox with custom JPanel-based editor --- .../intellij/ui/ComboBoxCompositeEditor.java | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/ComboBoxCompositeEditor.java b/platform/platform-impl/src/com/intellij/ui/ComboBoxCompositeEditor.java index 9cba1bb1351c..510e6bd8a5bb 100644 --- a/platform/platform-impl/src/com/intellij/ui/ComboBoxCompositeEditor.java +++ b/platform/platform-impl/src/com/intellij/ui/ComboBoxCompositeEditor.java @@ -21,6 +21,7 @@ import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.util.function.BiConsumer; +import java.util.function.BiFunction; import static java.awt.GridBagConstraints.CENTER; @@ -41,12 +42,18 @@ public class ComboBoxCompositeEditor extends JPanel imp } private BiConsumer myOnSetItemHandler = null; + private BiFunction myOnGetItemHandler = null; public ComboBoxCompositeEditor onSetItem (BiConsumer onSetItemHandler) { myOnSetItemHandler = onSetItemHandler; return this; } + public ComboBoxCompositeEditor onGetItem (BiFunction onGetItemHandler) { + myOnGetItemHandler = onGetItemHandler; + return this; + } + public interface EditorComponent { void setItem(I anObject); I getItem(); @@ -75,10 +82,14 @@ public class ComboBoxCompositeEditor extends JPanel imp abstract void addActionListener(F component, ActionListener l) ; abstract void removeActionListener(F component, ActionListener l) ; + + abstract I getItem(F component, I item); } private ComboBoxCompositeEditorStrategy editorTextFieldStrategy = new ComboBoxCompositeEditorStrategy () { - BiConsumer defaultOnSetHandler = (anObject, component) -> (component).setText((anObject == null) ? "" : anObject.toString()); + + BiConsumer defaultOnSetHandler = (anObject, component) -> component.setText((anObject == null) ? "" : anObject.toString()); + public void setItem(F component, I anObject) { if (myOnSetItemHandler == null) { defaultOnSetHandler.accept(anObject, (EditorTextField)component); @@ -87,6 +98,14 @@ public class ComboBoxCompositeEditor extends JPanel imp } } + public I getItem(F component, I anObject) { + if (myOnGetItemHandler == null) { + return anObject; + } else { + return myOnGetItemHandler.apply(anObject, component); + } + } + public void selectAll(JComponent component) { ((EditorTextField)component).selectAll(); } @@ -100,7 +119,7 @@ public class ComboBoxCompositeEditor extends JPanel imp } }; - private ComboBoxCompositeEditorStrategy jTextFieldStrategy = new ComboBoxCompositeEditorStrategy(){ + private ComboBoxCompositeEditorStrategy jTextFieldStrategy = new ComboBoxCompositeEditorStrategy() { BiConsumer defaultOnSetHandler = (anObject, component) -> component.setText((anObject ==null) ? "" : anObject.toString()); @@ -112,6 +131,14 @@ public class ComboBoxCompositeEditor extends JPanel imp } } + public I getItem(F component, I anObject) { + if (myOnGetItemHandler == null) { + return anObject; + } else { + return myOnGetItemHandler.apply(anObject, component); + } + } + public void selectAll(JComponent component) { ((JTextField)component).selectAll(); } @@ -162,7 +189,7 @@ public class ComboBoxCompositeEditor extends JPanel imp } public I getItem() { - return myItem; + return strategy.getItem((F)components[focusableComponentIndex], myItem); } @Override From 99405d6a9e5a5d91af43b9dd9c365189a2664b5a Mon Sep 17 00:00:00 2001 From: Alexander Kass Date: Wed, 5 Oct 2016 19:14:52 +0300 Subject: [PATCH 06/27] DBE: modality state issue in CheckRegExp IDEA-161948, IDEA-161946 --- .../src/org/intellij/lang/regexp/intention/CheckRegExpForm.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java index 51fc45789200..242dae54255b 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/intention/CheckRegExpForm.java @@ -157,7 +157,7 @@ public class CheckRegExpForm { myRootPanel.revalidate(); Balloon balloon = JBPopupFactory.getInstance().getParentBalloonFor(myRootPanel); if (balloon != null) balloon.revalidate(); - }, ModalityState.current()); + }); } @TestOnly From 21e4651a64bed7b5b5050deb697a812b92363287 Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Wed, 5 Oct 2016 19:15:37 +0300 Subject: [PATCH 07/27] [groovy] transformations: add ability to check inheritance of currently transformed class --- .../transformations/TransformationContext.java | 7 +++++++ .../TransformationContextImpl.java | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContext.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContext.java index 4f4a924a583f..ddaebc48144e 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContext.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContext.java @@ -87,6 +87,13 @@ public interface TransformationContext { return getAnnotation(fqn) != null; } + default boolean isInheritor(@NotNull String fqn) { + PsiClass baseClass = getPsiFacade().findClass(fqn, getResolveScope()); + return baseClass != null && isInheritor(baseClass); + } + + boolean isInheritor(@NotNull PsiClass baseClass); + @NotNull Collection findMethodsByName(@NotNull String name, boolean checkBases); diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java index 726003266e4e..87b1bc329af5 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/TransformationContextImpl.java @@ -122,6 +122,21 @@ public class TransformationContextImpl implements TransformationContext { return PsiImplUtil.getAnnotation(getCodeClass(), fqn); } + @Override + public boolean isInheritor(@NotNull PsiClass baseClass) { + if (getManager().areElementsEquivalent(getCodeClass(), baseClass)) return false; + if (getCodeClass().isInterface() && !baseClass.isInterface()) return false; + + for (PsiClassType superType : getSuperTypes()) { + PsiClass superClass = superType.resolve(); + if (superClass == null) continue; + if (getManager().areElementsEquivalent(superClass, baseClass)) return true; + if (superClass.isInheritor(baseClass, true)) return true; + } + + return false; + } + @NotNull @Override public Collection findMethodsByName(@NotNull String name, boolean checkBases) { From 5b0ac530c873222804646cdb8b70ee6165c6175b Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 5 Oct 2016 16:41:04 +0200 Subject: [PATCH 08/27] highlight static imports with 'overloads' if all of the same type (IDEA-161999) --- .../daemon/impl/analysis/HighlightVisitorImpl.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 1a648d2a1aed..d9d81f92a0c5 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -732,7 +732,18 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh } } if (!myHolder.hasErrorResults()) { - final PsiElement resolved = results.length == 1 ? results[0].getElement() : null; + PsiElement resolved = results.length >= 1 ? results[0].getElement() : null; + if (results.length > 1) { + for (int i = 1; i < results.length; i++) { + final PsiElement element = results[i].getElement(); + if (resolved instanceof PsiMethod && !(element instanceof PsiMethod) || + resolved instanceof PsiVariable && !(element instanceof PsiVariable) || + resolved instanceof PsiClass && !(element instanceof PsiClass)) { + resolved = null; + break; + } + } + } final TextAttributesScheme colorsScheme = myHolder.getColorsScheme(); if (resolved instanceof PsiClass) { myHolder.add(HighlightNamesUtil.highlightClassName((PsiClass)resolved, ref, colorsScheme)); From 12f2c4dea0523e80baca730837a1dbf5fd598240 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 5 Oct 2016 17:01:36 +0200 Subject: [PATCH 09/27] clear sorted refs after inspections are finished (IDEA-162072) --- .../com/intellij/codeInspection/reference/RefManagerImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java index 22a1c4a067a3..4df677907bd0 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java @@ -344,6 +344,10 @@ public class RefManagerImpl extends RefManager { public void inspectionReadActionFinished() { myIsInProcess = false; if (myScope != null) myScope.invalidate(); + + synchronized (myRefTable) { + mySortedRefs = null; + } } public void startOfflineView() { From c622fe2f624d3e3e56be2453ce0aeb192caa7167 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 5 Oct 2016 17:28:03 +0200 Subject: [PATCH 10/27] read action EA-89337 - assert: TreeElement.getStartOffsetInParent --- .../codeInsight/navigation/ImplementationSearcher.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java index c2cb9fc29874..de1b87b9e592 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/navigation/ImplementationSearcher.java @@ -19,6 +19,7 @@ package com.intellij.codeInsight.navigation; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.TargetElementUtil; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbService; @@ -68,7 +69,7 @@ public class ImplementationSearcher { if (elements.length > 0) { if (!includeSelfAlways) return filterElements(element, elements, offset); final PsiElement[] all; - if (element.getTextRange() != null) { + if (ReadAction.compute(() -> element.getTextRange()) != null) { all = new PsiElement[elements.length + 1]; all[0] = element; System.arraycopy(elements, 0, all, 1, elements.length); From de249923e6b9b78d1eb85f17e8d66ad1abc07a41 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 5 Oct 2016 18:02:49 +0200 Subject: [PATCH 11/27] tests: set fraction to 1.0 in case of undefined total --- .../testframework/sm/runner/ui/SMTestRunnerResultsForm.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java index 8b3de586c61e..aa6a5aa35f5d 100644 --- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java +++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java @@ -712,7 +712,10 @@ public class SMTestRunnerResultsForm extends TestResultsPanel private void updateProgressOnTestDone() { int doneTestCount = myFinishedTestCount; // update progress - if (myTotalTestCount != 0 && !isUndefined()) { + if (isUndefined()) { + myStatusLine.setFraction(1.0); + } + else if (myTotalTestCount != 0) { // if total is set myStatusLine.setFraction((double) doneTestCount / myTotalTestCount); } From 354277c1b6a672251be3b1431c80bd935ab9fc28 Mon Sep 17 00:00:00 2001 From: Mikhail Golubev Date: Wed, 5 Oct 2016 19:34:50 +0300 Subject: [PATCH 12/27] PyUtil#runWithProgress() doesn't call Application#invokeAndWait() since ProgressManager does it internally anyway. Also I've added javadoc describing possible pitfall when launching a task with a modal progress dialog from the write action. --- .../src/com/jetbrains/python/psi/PyUtil.java | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index c009d86d4396..cc47620fcd49 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -28,7 +28,7 @@ import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.ASTFactory; import com.intellij.lang.ASTNode; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; +import com.intellij.openapi.application.impl.ApplicationImpl; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; @@ -862,26 +862,31 @@ public class PyUtil { return result; } + /** + * This method is allowed to be called from any thread, but in general you should not set {@code modal=true} if you're calling it + * from the write action, because in this case {@code function} will be executed right in the current thread (presumably EDT) + * without any progress whatsoever to avoid possible deadlock. + * + * @see ApplicationImpl#runProcessWithProgressSynchronously(Runnable, String, boolean, Project, JComponent, String) + */ public static void runWithProgress(@Nullable Project project, @Nls(capitalization = Nls.Capitalization.Title) @NotNull String title, boolean modal, boolean canBeCancelled, @NotNull final Consumer function) { - ApplicationManager.getApplication().invokeAndWait(() -> { - if (modal) { - ProgressManager.getInstance().run(new Task.Modal(project, title, canBeCancelled) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - function.consume(indicator); - } - }); - } - else { - ProgressManager.getInstance().run(new Task.Backgroundable(project, title, canBeCancelled) { - @Override - public void run(@NotNull ProgressIndicator indicator) { - function.consume(indicator); - } - }); - } - }, ModalityState.current()); + if (modal) { + ProgressManager.getInstance().run(new Task.Modal(project, title, canBeCancelled) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + function.consume(indicator); + } + }); + } + else { + ProgressManager.getInstance().run(new Task.Backgroundable(project, title, canBeCancelled) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + function.consume(indicator); + } + }); + } } /** From 0a7fa12188218575a040f18815a3bf4c3ad864cf Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 5 Oct 2016 20:00:42 +0300 Subject: [PATCH 13/27] IDEA-162067 diff: do not register DiffPsiFileType via FileTypeFactory --- .../src/com/intellij/diff/contents/DiffPsiFileType.java | 7 ------- .../platform-resources/src/META-INF/PlatformExtensions.xml | 1 - 2 files changed, 8 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java b/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java index 83d0ee6f84fe..c5c6b29f14eb 100644 --- a/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java +++ b/platform/diff-impl/src/com/intellij/diff/contents/DiffPsiFileType.java @@ -85,13 +85,6 @@ public class DiffPsiFileType extends LanguageFileType implements FileTypeIdentif } - public static class TypeFactory extends FileTypeFactory { - @Override - public void createFileTypes(@NotNull FileTypeConsumer consumer) { - consumer.consume(INSTANCE); - } - } - public static class Substitutor extends LanguageSubstitutor { @Nullable @Override diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index af355de3126a..d295e219fef4 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -107,7 +107,6 @@ - From 32525be44f79a50f91fdcf85fa92aa67d7448097 Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Wed, 5 Oct 2016 19:28:36 +0300 Subject: [PATCH 14/27] [Parameter Hints Manager] add report and disable action to context menu --- .../actions/ToggleInlineHintsAction.kt | 51 +++++++++++++++++++ .../ParameterHintsPresentationManager.java | 6 +++ .../reporting/ReportExcessiveInlineHint.kt | 6 +-- .../src/messages/ActionsBundle.properties | 2 + .../src/idea/LangActions.xml | 7 ++- resources/src/META-INF/IdeaPlugin.xml | 3 -- 6 files changed, 68 insertions(+), 7 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/analysis/actions/ToggleInlineHintsAction.kt rename java/java-impl/src/com/intellij/reporting/ReportMissingOrExcessiveInlineHint.kt => platform/lang-impl/src/com/intellij/reporting/ReportExcessiveInlineHint.kt (95%) diff --git a/platform/lang-impl/src/com/intellij/analysis/actions/ToggleInlineHintsAction.kt b/platform/lang-impl/src/com/intellij/analysis/actions/ToggleInlineHintsAction.kt new file mode 100644 index 000000000000..fd0d138d0e76 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/analysis/actions/ToggleInlineHintsAction.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2016 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.analysis.actions + +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer +import com.intellij.openapi.actionSystem.AnAction +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.editor.ex.EditorSettingsExternalizable +import com.intellij.openapi.fileEditor.FileEditorManager +import com.intellij.openapi.project.ProjectManager +import com.intellij.psi.PsiManager + +class ToggleInlineHintsAction: AnAction() { + + override fun update(e: AnActionEvent) { + e.presentation.isEnabled = true + + val isShow = EditorSettingsExternalizable.getInstance().isShowParameterNameHints + e.presentation.text = if (isShow) "Hide parameter name hints" else "Show parameter name hints" + } + + override fun actionPerformed(e: AnActionEvent) { + val settings = EditorSettingsExternalizable.getInstance() + val before = settings.isShowParameterNameHints + settings.isShowParameterNameHints = !before + + ProjectManager.getInstance().openProjects.forEach { + val psiManager = PsiManager.getInstance(it) + val daemonCodeAnalyzer = DaemonCodeAnalyzer.getInstance(it) + val fileEditorManager = FileEditorManager.getInstance(it) + + fileEditorManager.selectedFiles.forEach { + psiManager.findFile(it)?.let { daemonCodeAnalyzer.restart(it) } + } + } + } + +} \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ParameterHintsPresentationManager.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ParameterHintsPresentationManager.java index 8763a0fc746e..960557466c6f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ParameterHintsPresentationManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/ParameterHintsPresentationManager.java @@ -159,6 +159,12 @@ public class ParameterHintsPresentationManager implements Disposable { updateState(editor, newText); } + @Nullable + @Override + public String getContextMenuGroupId() { + return "ParameterNameHints"; + } + private void updateState(Editor editor, String text) { FontMetrics metrics = getFontMetrics(editor).metrics; startWidth = doCalcWidth(myText, metrics); diff --git a/java/java-impl/src/com/intellij/reporting/ReportMissingOrExcessiveInlineHint.kt b/platform/lang-impl/src/com/intellij/reporting/ReportExcessiveInlineHint.kt similarity index 95% rename from java/java-impl/src/com/intellij/reporting/ReportMissingOrExcessiveInlineHint.kt rename to platform/lang-impl/src/com/intellij/reporting/ReportExcessiveInlineHint.kt index 3e06f1ae1231..d18d9dc48230 100644 --- a/java/java-impl/src/com/intellij/reporting/ReportMissingOrExcessiveInlineHint.kt +++ b/platform/lang-impl/src/com/intellij/reporting/ReportExcessiveInlineHint.kt @@ -31,13 +31,13 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.util.TextRange import java.io.File -class ReportMissingOrExcessiveInlineHint : AnAction() { +class ReportExcessiveInlineHint : AnAction() { - private val text = "Report Missing or Excessive Inline Hint" + private val text = "Report Excessive Inline Hint" private val description = "Text line at caret will be anonymously reported to our servers" companion object { - private val LOG = Logger.getInstance(ReportMissingOrExcessiveInlineHint::class.java) + private val LOG = Logger.getInstance(ReportExcessiveInlineHint::class.java) } init { diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index f00ecb4f51d1..af16c4e70ff2 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -416,6 +416,8 @@ action.ShowSiblings.text=Show Siblings action.ShowSiblings.description=Show a popup window with the symbol siblings content action.ParameterInfo.text=_Parameter Info action.ParameterInfo.description=Show parameters of the method call at caret +action.ToggleInlineHintsAction.text=Toggle parameter name hints +action.ToggleInlineHintsAction.description=Toggle parameter name hints action.ExpressionTypeInfo.text=_Expression Type action.ExpressionTypeInfo.description=Show type of the selected expression action.EditorContextInfo.text=_Context Info diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index cac3ae55220b..9a2c145584f2 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -298,7 +298,12 @@ - + + + + + + diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 7cc48c65c979..2e0249035038 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -1828,9 +1828,6 @@ - - - From 0bc941e055c7d961420fc74790bd8ae0f04639fc Mon Sep 17 00:00:00 2001 From: Yaroslav Lepenkin Date: Wed, 5 Oct 2016 20:20:07 +0300 Subject: [PATCH 15/27] uppercasify --- .../com/intellij/analysis/actions/ToggleInlineHintsAction.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/analysis/actions/ToggleInlineHintsAction.kt b/platform/lang-impl/src/com/intellij/analysis/actions/ToggleInlineHintsAction.kt index fd0d138d0e76..828e0b26eac7 100644 --- a/platform/lang-impl/src/com/intellij/analysis/actions/ToggleInlineHintsAction.kt +++ b/platform/lang-impl/src/com/intellij/analysis/actions/ToggleInlineHintsAction.kt @@ -29,7 +29,7 @@ class ToggleInlineHintsAction: AnAction() { e.presentation.isEnabled = true val isShow = EditorSettingsExternalizable.getInstance().isShowParameterNameHints - e.presentation.text = if (isShow) "Hide parameter name hints" else "Show parameter name hints" + e.presentation.text = if (isShow) "Hide Parameter Name Hints" else "Show Parameter Name Hints" } override fun actionPerformed(e: AnActionEvent) { From 8202092acc570a31768be296b745973898661135 Mon Sep 17 00:00:00 2001 From: Aleksey Pivovarov Date: Wed, 5 Oct 2016 20:26:23 +0300 Subject: [PATCH 16/27] IDEA-162135 diff: do not pass editor-specific data context if there are no editor in focus --- .../diff/tools/holders/TextEditorHolder.java | 20 ++++++++++++++++--- .../util/side/TwosideTextDiffViewer.java | 4 ---- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/platform/diff-impl/src/com/intellij/diff/tools/holders/TextEditorHolder.java b/platform/diff-impl/src/com/intellij/diff/tools/holders/TextEditorHolder.java index 9971ef08d351..8172e35d4640 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/holders/TextEditorHolder.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/holders/TextEditorHolder.java @@ -19,9 +19,13 @@ import com.intellij.diff.DiffContext; import com.intellij.diff.contents.DiffContent; import com.intellij.diff.contents.DocumentContent; import com.intellij.diff.util.DiffUtil; +import com.intellij.ide.DataManager; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.registry.Registry; +import com.intellij.ui.components.panels.Wrapper; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,9 +34,19 @@ import java.awt.event.FocusListener; public class TextEditorHolder extends EditorHolder { @NotNull protected final EditorEx myEditor; + @NotNull protected final Wrapper myPanel; - public TextEditorHolder(@NotNull EditorEx editor) { + public TextEditorHolder(@Nullable Project project, @NotNull EditorEx editor) { myEditor = editor; + myPanel = new Wrapper(myEditor.getComponent()); + + DataManager.registerDataProvider(myPanel, (dataId) -> { + if (project != null && !project.isDisposed() && Registry.is("diff.enable.psi.highlighting")) { + final Object o = FileEditorManager.getInstance(project).getData(dataId, editor, editor.getCaretModel().getCurrentCaret()); + if (o != null) return o; + } + return null; + }); } @NotNull @@ -48,7 +62,7 @@ public class TextEditorHolder extends EditorHolder { @NotNull @Override public JComponent getComponent() { - return myEditor.getComponent(); + return myPanel; } @Override @@ -70,7 +84,7 @@ public class TextEditorHolder extends EditorHolder { public static TextEditorHolder create(@Nullable Project project, @NotNull DocumentContent content) { EditorEx editor = DiffUtil.createEditor(content.getDocument(), project, false, true); DiffUtil.configureEditor(editor, content, project); - return new TextEditorHolder(editor); + return new TextEditorHolder(project, editor); } public static class TextEditorHolderFactory extends EditorHolderFactory { diff --git a/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java b/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java index d7750be9e7b6..4b97639f734b 100644 --- a/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java +++ b/platform/diff-impl/src/com/intellij/diff/tools/util/side/TwosideTextDiffViewer.java @@ -354,10 +354,6 @@ public abstract class TwosideTextDiffViewer extends TwosideDiffViewer Date: Wed, 5 Oct 2016 20:24:43 +0200 Subject: [PATCH 17/27] Cleanup (IDEA-CR-13779) --- .../src/org/jetbrains/jps/ProjectPaths.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java index 3fef298f8819..4d21510ad72b 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java +++ b/jps/jps-builders/src/org/jetbrains/jps/ProjectPaths.java @@ -74,9 +74,6 @@ public class ProjectPaths { else if (classpathPart == ClasspathPart.AFTER_JDK) { enumerator = enumerator.satisfying(new AfterJavaSdkItemFilter(module)); } - else if (classpathPart == ClasspathPart.MODULE_PATH) { - enumerator = enumerator.satisfying(new ModuleSourceElementsFilter()); - } JpsJavaDependenciesRootsEnumerator rootsEnumerator = enumerator.classes(); if (excludeMainModuleOutput) { rootsEnumerator = rootsEnumerator.withoutSelfModuleOutput(); @@ -181,7 +178,7 @@ public class ProjectPaths { return StringUtil.isEmpty(sourceDirName)? outputDir : new File(outputDir, sourceDirName); } - private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK, MODULE_PATH} + private enum ClasspathPart {WHOLE, BEFORE_JDK, AFTER_JDK} private static class BeforeJavaSdkItemFilter implements Condition { private JpsModule myModule; @@ -220,13 +217,4 @@ public class ProjectPaths { return mySdkFound; } } - - private static class ModuleSourceElementsFilter implements Condition { - private ModuleSourceElementsFilter() { } - - @Override - public boolean value(JpsDependencyElement dependency) { - return dependency instanceof JpsModuleDependency || dependency instanceof JpsModuleSourceDependency; - } - } } \ No newline at end of file From 3a22960b61798ac7aa8f1ebcfd49c35543557834 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Wed, 5 Oct 2016 21:01:29 +0200 Subject: [PATCH 18/27] [java] filtering out non-Java directories in "Create module-info.java" action (EA-88041) --- .../intellij/ide/actions/CreateModuleInfoAction.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java b/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java index 429487ca4e52..ebc24ac743f7 100644 --- a/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java +++ b/java/java-impl/src/com/intellij/ide/actions/CreateModuleInfoAction.java @@ -52,7 +52,7 @@ public class CreateModuleInfoAction extends CreateFromTemplateActionBase { DataContext ctx = e.getDataContext(); boolean available = Optional.ofNullable(LangDataKeys.IDE_VIEW.getData(ctx)) .map(view -> getTargetDirectory(ctx, view)) - .filter(dir -> JavaDirectoryService.getInstance().isSourceRoot(dir) && PsiUtil.isLanguageLevel9OrHigher(dir)) + .filter(PsiUtil::isLanguageLevel9OrHigher) .map(ModuleUtilCore::findModuleForPsiElement) .map(module -> FilenameIndex.getVirtualFilesByName(module.getProject(), MODULE_INFO_FILE, module.getModuleScope(false)).isEmpty()) .orElse(false); @@ -63,7 +63,15 @@ public class CreateModuleInfoAction extends CreateFromTemplateActionBase { @Override protected PsiDirectory getTargetDirectory(DataContext dataContext, IdeView view) { PsiDirectory[] directories = view.getDirectories(); - return directories.length == 1 ? directories[0] : null; + if (directories.length == 1) { + PsiDirectory directory = directories[0]; + JavaDirectoryService service = JavaDirectoryService.getInstance(); + if (service.isSourceRoot(directory) && service.getPackage(directory) != null) { + return directory; + } + } + + return null; } @Override From 0200ca7b50302e4164334bff6cf2aabf9a91ed04 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 5 Oct 2016 21:15:10 +0200 Subject: [PATCH 19/27] IDEA-161588 If you paste code with statically imported ambiguous methods copied from another Java file, IDEA should remember the "static imports" and add them automatically like it does for classes add tests, honor ADD_MEMBER_IMPORTS_ON_THE_FLY setting (IDEA-CR-14253) --- .../JavaCopyPasteReferenceProcessor.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java index 4f0247b60b24..d7dea455820a 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java @@ -106,7 +106,8 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor } } - if (CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY) { + if (CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY || + CodeInsightSettings.getInstance().ADD_MEMBER_IMPORTS_ON_THE_FLY) { for (int i = 0; i < refs.length; i++) { if (isUnambiguous(refs[i])) { refs[i] = null; @@ -122,10 +123,16 @@ public class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor PsiElement parent = ref.getParent(); if (parent instanceof PsiMethodCallExpression) { - return new StaticImportMethodFix((PsiMethodCallExpression)parent).getMembersToImport().size() <= 1; + return CodeInsightSettings.getInstance().ADD_MEMBER_IMPORTS_ON_THE_FLY && + new StaticImportMethodFix((PsiMethodCallExpression)parent).getMembersToImport().size() <= 1; } - - return new ImportClassFix(ref).getClassesToImport().size() + new StaticImportConstantFix(ref).getMembersToImport().size() <= 1; + + int constCount = new StaticImportConstantFix(ref).getMembersToImport().size(); + int classCount = new ImportClassFix(ref).getClassesToImport().size(); + if (constCount + classCount > 1) return false; + if (constCount + classCount == 0) return true; + return constCount == 1 ? CodeInsightSettings.getInstance().ADD_MEMBER_IMPORTS_ON_THE_FLY + : CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY; } @Override From 4400928b1681d3f59d3255a723500a3af5c2775a Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Wed, 5 Oct 2016 21:52:49 +0200 Subject: [PATCH 20/27] Exit with 0, if ide can successfully transfer the control from second instance to the first one. --- native/WinLauncher/WinLauncher/WinLauncher.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/native/WinLauncher/WinLauncher/WinLauncher.cpp b/native/WinLauncher/WinLauncher/WinLauncher.cpp index 9399e9391b75..373fc7dce30b 100644 --- a/native/WinLauncher/WinLauncher/WinLauncher.cpp +++ b/native/WinLauncher/WinLauncher/WinLauncher.cpp @@ -900,7 +900,8 @@ int APIENTRY _tWinMain(HINSTANCE hInstance, return 0; } - if (!CheckSingleInstance()) return 1; + //it's OK to return 0 here, because the control is transferred to the first instance + if (!CheckSingleInstance()) return 0; if (nativesplash = wcsstr(lpCmdLine, _T("/nativesplash")) != NULL) StartSplashProcess(); From 5c64ab7498476bc6cbf0af349fdbf00d864736ad Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 5 Oct 2016 18:09:10 +0300 Subject: [PATCH 21/27] FileIndex: javadoc corrected --- .../com/intellij/openapi/roots/FileIndex.java | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java b/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java index d2182f033471..0d8def9d6273 100644 --- a/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java +++ b/platform/projectModel-api/src/com/intellij/openapi/roots/FileIndex.java @@ -30,7 +30,7 @@ import java.util.Set; */ public interface FileIndex { /** - * Iterates all files and directories in the content. + * Iterates all files and directories under content roots skipping excluded and ignored files and directories. * * @param iterator the iterator receiving the files. * @return false if files processing was stopped ({@link ContentIterator#processFile(VirtualFile)} returned false) @@ -38,8 +38,8 @@ public interface FileIndex { boolean iterateContent(@NotNull ContentIterator iterator); /** - * Iterates all files and directories in the content under directory dir (including the directory itself). - * Does not iterate anything if dir is not in the content. + * Iterates all files and directories in the content under directory dir (including the directory itself) skipping excluded + * and ignored files and directories. Does not iterate anything if dir is not in the content. * * @param dir the directory the contents of which is iterated. * @param iterator the iterator receiving the files. @@ -48,17 +48,14 @@ public interface FileIndex { boolean iterateContentUnderDirectory(@NotNull VirtualFile dir, @NotNull ContentIterator iterator); /** - * Returns true if fileOrDir is a file or directory under a content root of this - * project or module. - * - * @param fileOrDir the file or directory to check. - * @return true if the file or directory belongs to a content root, false otherwise. + * Returns {@code true} if {@code fileOrDir} is a file or directory under a content root of this project or module and not excluded or + * ignored. */ boolean isInContent(@NotNull VirtualFile fileOrDir); /** - * Returns true if file is a source file which belongs to sources of the content. - * (Returns true for both source and test source).

+ * Returns {@code true} if {@code fileOrDir} is a file located under a sources, tests or resources root and not excluded or ignored. + *

* Note that sometimes a file can belong to the content and be a source file but not belong to sources of the content. * This happens if sources of some library are located under the content (so they belong to the project content but not as sources). * @@ -68,16 +65,12 @@ public interface FileIndex { boolean isContentSourceFile(@NotNull VirtualFile file); /** - * Returns true if fileOrDir is a file or directory from the content source. - * (Returns true for both source and test source). - * - * @param fileOrDir the file or directory to check. - * @return true if the file or directory belongs to a source or test source root, false otherwise. + * Returns {@code true} if {@code fileOrDir} is a file or directory located under a sources, tests or resources root and not excluded or ignored. */ boolean isInSourceContent(@NotNull VirtualFile fileOrDir); /** - * Returns true if fileOrDir is a file or directory from the test content source + * Returns true if {@code fileOrDir} is a file or directory located under a test sources or resources root and not excluded or ignored. *

* Use this method when you really need to check whether the file is under test roots according to project configuration. *

@@ -92,10 +85,7 @@ public interface FileIndex { boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir); /** - * Returns true if fileOrDir is a file or directory from the source root which have - * - * @param fileOrDir the file or directory to check. - * @return true if the file or directory belongs to a source root of one of specified types, false otherwise + * Returns {@code true} if {@code fileOrDir} is a file or directory located under a source root of type from {@code rootTypes} set and not excluded or ignored */ boolean isUnderSourceRootOfType(@NotNull VirtualFile fileOrDir, @NotNull Set> rootTypes); } From 823f8cbc440ea2ae7184b387d65bc8277aad0992 Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 5 Oct 2016 18:09:26 +0300 Subject: [PATCH 22/27] ArtifactBuildTaskProvider: javadoc added --- .../builders/artifacts/ArtifactBuildTaskProvider.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java b/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java index 5d0ff6cc85c6..84972eb29617 100644 --- a/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java +++ b/jps/jps-builders/src/org/jetbrains/jps/builders/artifacts/ArtifactBuildTaskProvider.java @@ -22,6 +22,10 @@ import org.jetbrains.jps.model.artifact.JpsArtifact; import java.util.List; /** + * Allows to perform additional tasks when artifacts are built. Implementations of this class are registered as Java services, by creating + * a file META-INF/services/org.jetbrains.jps.builders.artifacts.ArtifactBuildTaskProvider containing the qualified name of your + * implementation class. + * * @author nik */ public abstract class ArtifactBuildTaskProvider { @@ -38,6 +42,13 @@ public abstract class ArtifactBuildTaskProvider { } } + /** + * Returns list of tasks which need to be executed during {@code buildPhase} when {@code artifact} is building. Firstly tasks returned for + * {@link ArtifactBuildPhase#PRE_PROCESSING PRE_PROCESSING} are executed, then files specified in the artifact layout are copied to the output directory. + * If all files in the artifact output were up to date, i.e. no copying was performed, the build finishes. Otherwise all tasks returned for + * {@link ArtifactBuildPhase#FINISHING_BUILD FINISHING_BUILD} are executed and then all tasks returned for + * {@link ArtifactBuildPhase#POST_PROCESSING POST_PROCESSING} are executed. + */ @NotNull public abstract List createArtifactBuildTasks(@NotNull JpsArtifact artifact, @NotNull ArtifactBuildPhase buildPhase); } From e9ab28ff71db366b316eb7408457e202ef047583 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 6 Oct 2016 11:06:28 +0300 Subject: [PATCH 23/27] project view: don't show duplicated nodes for content roots located under excluded roots (IDEA-162102) --- .../contentRootUnderExcluded/B.txt | 0 .../contentRootUnderExcluded/exc/excluded.txt | 0 .../contentRootUnderExcluded/exc/gen/A.java | 0 .../projectView/ProjectTreeStructureTest.java | 50 ++++++++++++++----- .../projectView/BaseProjectViewTestCase.java | 12 ++++- .../nodes/ProjectViewDirectoryHelper.java | 23 +++++++-- .../impl/nodes/ProjectViewModuleNode.java | 14 +----- .../impl/nodes/ProjectViewProjectNode.java | 7 ++- .../projectView/TestProjectTreeStructure.java | 13 ++++- 9 files changed, 82 insertions(+), 37 deletions(-) create mode 100644 java/java-tests/testData/projectView/contentRootUnderExcluded/B.txt create mode 100644 java/java-tests/testData/projectView/contentRootUnderExcluded/exc/excluded.txt create mode 100644 java/java-tests/testData/projectView/contentRootUnderExcluded/exc/gen/A.java diff --git a/java/java-tests/testData/projectView/contentRootUnderExcluded/B.txt b/java/java-tests/testData/projectView/contentRootUnderExcluded/B.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/projectView/contentRootUnderExcluded/exc/excluded.txt b/java/java-tests/testData/projectView/contentRootUnderExcluded/exc/excluded.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testData/projectView/contentRootUnderExcluded/exc/gen/A.java b/java/java-tests/testData/projectView/contentRootUnderExcluded/exc/gen/A.java new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java index 46fb031dd4bd..5eecadf0d209 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/ProjectTreeStructureTest.java @@ -142,20 +142,44 @@ public class ProjectTreeStructureTest extends BaseProjectViewTestCase { ModuleManagerImpl.getInstanceImpl(myProject).setModuleGroupPath(module, new String[]{"modules"}); PsiTestUtil.addContentRoot(module, mainModuleRoot.findFileByRelativePath("src/com/package1/p2/p3")); - TestProjectTreeStructure structure = new TestProjectTreeStructure(myProject, getTestRootDisposable()); - structure.setShowLibraryContents(false); + myStructure.setShowLibraryContents(false); + myStructure.hideExcludedFiles(); - String structureContent = PlatformTestUtil.print(structure, structure.getRootElement(), 0, null, 10, ' ', myPrintInfo).toString(); + assertStructureEqual("Project\n" + + " nested_module.iml\n" + + " noDuplicateModules\n" + + " src\n" + + " com\n" + + " package1\n" + + " Test.java\n" + + " testNoDuplicateModules.iml\n"); + } - Assert.assertFalse(structureContent.contains("modules")); - assertEquals("Project\n" + - " noDuplicateModules\n" + - " src\n" + - " com\n" + - " package1\n" + - " Test.java\n" + - " nested_module.iml\n" + - " testNoDuplicateModules.iml\n", - structureContent); + public void testContentRootUnderExcluded() { + VirtualFile mainModuleRoot = ModuleRootManager.getInstance(myModule).getContentRoots()[0]; + + PsiTestUtil.addExcludedRoot(myModule, mainModuleRoot.findFileByRelativePath("exc")); + + PsiTestUtil.addContentRoot(myModule, mainModuleRoot.findFileByRelativePath("exc/gen")); + + myStructure.setShowLibraryContents(false); + + assertStructureEqual("Project\n" + + " contentRootUnderExcluded\n" + + " B.txt\n" + + " exc\n" + + " excluded.txt\n" + + " gen\n" + + " A.java\n" + + " testContentRootUnderExcluded.iml\n"); + + myStructure.hideExcludedFiles(); + assertStructureEqual("Project\n" + + " Module\n" + + " contentRootUnderExcluded\n" + + " B.txt\n" + + " gen\n" + + " A.java\n" + + " testContentRootUnderExcluded.iml\n"); } } diff --git a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java index 70fec7bcf19f..0c6d1f8fa17d 100644 --- a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java +++ b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java @@ -65,9 +65,17 @@ public abstract class BaseProjectViewTestCase extends TestSourceBasedTestCase { return myStructure; } - private void assertStructureEqual(PsiDirectory root, String expected, int maxRowCount, AbstractTreeStructure structure) { + private void assertStructureEqual(PsiDirectory root, String expected, int maxRowCount, AbstractProjectTreeStructure structure) { assertNotNull(root); - PsiDirectoryNode rootNode = new PsiDirectoryNode(myProject, root, (ViewSettings)structure); + PsiDirectoryNode rootNode = new PsiDirectoryNode(myProject, root, structure); + assertStructureEqual(expected, maxRowCount, rootNode); + } + + protected void assertStructureEqual(String expected) { + assertStructureEqual(expected, -1, myStructure.getRootElement()); + } + + private void assertStructureEqual(String expected, int maxRowCount, Object rootNode) { ProjectViewTestUtil.assertStructureEqual(myStructure, expected, maxRowCount, PlatformTestUtil.createComparator(myPrintInfo), rootNode, myPrintInfo); } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java index 127d4a64a2ff..d2f584560bb7 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewDirectoryHelper.java @@ -42,6 +42,7 @@ import com.intellij.psi.*; import com.intellij.psi.search.PsiElementProcessor; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.FontUtil; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -212,6 +213,19 @@ public class ProjectViewDirectoryHelper { return topLevelContentRoots; } + public List getTopLevelModuleRoots(Module module, ViewSettings settings) { + return ContainerUtil.filter(ModuleRootManager.getInstance(module).getContentRoots(), root -> { + if (!shouldBeShown(root, settings)) return false; + VirtualFile parent = root.getParent(); + if (parent == null) return true; + DirectoryInfo info = myIndex.getInfoForFile(parent); + if (!module.equals(info.getModule())) return true; + //show inner content root separately only if it won't be shown under outer content root + return info.isExcluded() && !shouldShowExcludedFiles(settings); + }); + } + + private static boolean isFileInContent(ProjectFileIndex index, VirtualFile file) { while (file != null) { if (index.isInContent(file)) { @@ -260,12 +274,11 @@ public class ProjectViewDirectoryHelper { private boolean shouldBeShown(VirtualFile dir, ViewSettings settings) { DirectoryInfo directoryInfo = myIndex.getInfoForFile(dir); - if (directoryInfo.isInProject()) return true; + return directoryInfo.isInProject() || shouldShowExcludedFiles(settings) && directoryInfo.isExcluded(); + } - if (!Registry.is("ide.hide.excluded.files") && settings instanceof ProjectViewSettings && ((ProjectViewSettings)settings).isShowExcludedFiles()) { - return directoryInfo.isExcluded(); - } - return false; + private static boolean shouldShowExcludedFiles(ViewSettings settings) { + return !Registry.is("ide.hide.excluded.files") && settings instanceof ProjectViewSettings && ((ProjectViewSettings)settings).isShowExcludedFiles(); } // used only for non-flatten packages mode diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java index 1b51e33c0353..9da0e81d4765 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewModuleNode.java @@ -46,15 +46,11 @@ public class ProjectViewModuleNode extends AbstractModuleNode { if (module == null || module.isDisposed()) { // module has been disposed return Collections.emptyList(); } - ModuleRootManager rootManager = ModuleRootManager.getInstance(module); - ModuleFileIndex moduleFileIndex = rootManager.getFileIndex(); - final VirtualFile[] contentRoots = rootManager.getContentRoots(); - final List children = new ArrayList<>(contentRoots.length + 1); + final List contentRoots = ProjectViewDirectoryHelper.getInstance(myProject).getTopLevelModuleRoots(module, getSettings()); + final List children = new ArrayList<>(contentRoots.size()); final PsiManager psiManager = PsiManager.getInstance(module.getProject()); for (final VirtualFile contentRoot : contentRoots) { - if (!moduleFileIndex.isInContent(contentRoot)) continue; - if (contentRoot.isDirectory()) { PsiDirectory directory = psiManager.findDirectory(contentRoot); if (directory != null) { @@ -68,12 +64,6 @@ public class ProjectViewModuleNode extends AbstractModuleNode { } } } - - /* - if (getSettings().isShowLibraryContents()) { - children.add(new LibraryGroupNode(getProject(), new LibraryGroupElement(getValue()), getSettings())); - } - */ return children; } diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java index 2e41e8db07e1..f89abd9b0b33 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/nodes/ProjectViewProjectNode.java @@ -22,7 +22,6 @@ import com.intellij.ide.util.treeView.AbstractTreeNode; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.io.FileUtil; @@ -125,9 +124,9 @@ public class ProjectViewProjectNode extends AbstractProjectNode { @Override protected AbstractTreeNode createModuleGroup(final Module module) throws InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException { - final VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots(); - if (roots.length == 1) { - final PsiDirectory psi = PsiManager.getInstance(myProject).findDirectory(roots[0]); + List roots = ProjectViewDirectoryHelper.getInstance(myProject).getTopLevelModuleRoots(module, getSettings()); + if (roots.size() == 1) { + final PsiDirectory psi = PsiManager.getInstance(myProject).findDirectory(roots.get(0)); if (psi != null) { return new PsiDirectoryNode(myProject, psi, getSettings()); } diff --git a/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java b/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java index a1bd02b83d5c..eee966b1386b 100644 --- a/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java +++ b/platform/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java @@ -15,6 +15,7 @@ */ package com.intellij.projectView; +import com.intellij.ide.projectView.ProjectViewSettings; import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure; import com.intellij.ide.projectView.impl.AbstractProjectViewPSIPane; import com.intellij.openapi.Disposable; @@ -25,7 +26,8 @@ import com.intellij.psi.PsiElement; import com.intellij.testFramework.ProjectViewTestUtil; import org.junit.Assert; -public class TestProjectTreeStructure extends AbstractProjectTreeStructure implements Disposable { +public class TestProjectTreeStructure extends AbstractProjectTreeStructure implements Disposable, ProjectViewSettings { + private boolean myShowExcludedFiles = true; protected boolean myShowMembers = false; protected boolean myHideEmptyMiddlePackages; protected boolean myFlattenPackages; @@ -74,6 +76,11 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple return myShowLibraryContents; } + @Override + public boolean isShowExcludedFiles() { + return myShowExcludedFiles; + } + @Override public boolean isShowModules() { return true; @@ -91,6 +98,10 @@ public class TestProjectTreeStructure extends AbstractProjectTreeStructure imple myFlattenPackages = flattenPackages; } + public void hideExcludedFiles() { + myShowExcludedFiles = false; + } + public void setShowLibraryContents(boolean showLibraryContents) { myShowLibraryContents = showLibraryContents; } From 9aeb6bc8e5da61a4dc90589008901084ba674228 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 6 Oct 2016 10:32:13 +0200 Subject: [PATCH 24/27] revert and restore iteration over selected usages in the editor --- .../ide/actions/SearchAgainAction.java | 22 ++++++------------- .../ide/actions/SearchBackAction.java | 20 +++++------------ 2 files changed, 13 insertions(+), 29 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java index 746068aea363..31933bc613f8 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchAgainAction.java @@ -16,21 +16,16 @@ package com.intellij.ide.actions; -import com.intellij.find.EditorSearchSession; import com.intellij.find.FindManager; import com.intellij.find.FindUtil; import com.intellij.ide.IdeBundle; -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.actionSystem.*; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; import com.intellij.openapi.fileEditor.ex.IdeDocumentHistory; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; public class SearchAgainAction extends AnAction implements DumbAware { @@ -64,14 +59,11 @@ public class SearchAgainAction extends AnAction implements DumbAware { public void update(AnActionEvent event){ Presentation presentation = event.getPresentation(); Project project = event.getData(CommonDataKeys.PROJECT); - presentation.setEnabled(false); - if (project == null) + if (project == null) { + presentation.setEnabled(false); return; - final FileEditor editor = event.getData(PlatformDataKeys.FILE_EDITOR); - if (!(editor instanceof TextEditor)) - return; - - final EditorSearchSession search = EditorSearchSession.get(event.getData(PlatformDataKeys.EDITOR)); - presentation.setEnabled(search != null); + } + FileEditor editor = event.getData(PlatformDataKeys.FILE_EDITOR); + presentation.setEnabled(editor instanceof TextEditor); } } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java index b5eeb5295879..3676234bdccf 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchBackAction.java @@ -16,20 +16,15 @@ package com.intellij.ide.actions; -import com.intellij.find.EditorSearchSession; import com.intellij.find.FindManager; import com.intellij.find.FindUtil; import com.intellij.ide.IdeBundle; -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.actionSystem.*; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.fileEditor.FileEditor; import com.intellij.openapi.fileEditor.TextEditor; -import com.intellij.openapi.project.Project; import com.intellij.openapi.project.DumbAware; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; public class SearchBackAction extends AnAction implements DumbAware { @@ -60,14 +55,11 @@ public class SearchBackAction extends AnAction implements DumbAware { public void update(AnActionEvent event){ Presentation presentation = event.getPresentation(); Project project = event.getData(CommonDataKeys.PROJECT); - presentation.setEnabled(false); - if (project == null) + if (project == null) { + presentation.setEnabled(false); return; + } final FileEditor editor = event.getData(PlatformDataKeys.FILE_EDITOR); - if (!(editor instanceof TextEditor)) - return; - - final EditorSearchSession search = EditorSearchSession.get(event.getData(PlatformDataKeys.EDITOR)); - presentation.setEnabled(search != null); + presentation.setEnabled(editor instanceof TextEditor); } } From 07f1ec121e519ced5e7c7d1dc0d2b99df2bc00e5 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Thu, 6 Oct 2016 11:51:51 +0300 Subject: [PATCH 25/27] IDEA-162062 Move Statement: Scope of shifted block changes fix for Python use cases --- .../moveUpDown/MoverWrapper.java | 173 +++++++++--------- python/testData/mover/class_afterUp.py | 2 +- .../testData/mover/lastComment1_afterDown.py | 2 +- 3 files changed, 89 insertions(+), 88 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/MoverWrapper.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/MoverWrapper.java index 00bab74b4f6d..0b641a7756dc 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/MoverWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/MoverWrapper.java @@ -54,96 +54,97 @@ class MoverWrapper { assert myInfo.toMove2 != null; myMover.beforeMove(editor, myInfo, myIsDown); final Document document = editor.getDocument(); - - final int start = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.startLine); - final int end = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.endLine); - String textToInsert = document.getCharsSequence().subSequence(start, end).toString(); - if (!StringUtil.endsWithChar(textToInsert,'\n')) textToInsert += '\n'; - - final int start2 = document.getLineStartOffset(myInfo.toMove2.startLine); - final int end2 = StatementUpDownMover.getLineStartSafeOffset(document,myInfo.toMove2.endLine); - String textToInsert2 = document.getCharsSequence().subSequence(start2, end2).toString(); - if (!StringUtil.endsWithChar(textToInsert2,'\n')) textToInsert2 += '\n'; - - TextRange range = new TextRange(start, end); - TextRange range2 = new TextRange(start2, end2); - if (range.intersectsStrict(range2) && !range.equals(range2)) { - LOGGER.error("Wrong move ranges requested by " + myMover, - new Attachment("ranges.txt", - start + ":" + end + "(" + textToInsert + ")\n" + start2 + ":" + end2 + "(" + textToInsert2 + ")")); - return; - } - - myInfo.range1 = document.createRangeMarker(start, end); - myInfo.range2 = document.createRangeMarker(start2, end2); - if (myInfo.range1.getStartOffset() < myInfo.range2.getStartOffset()) { - myInfo.range1.setGreedyToLeft(true); - myInfo.range1.setGreedyToRight(false); - myInfo.range2.setGreedyToLeft(true); - myInfo.range2.setGreedyToRight(true); - } - else { - myInfo.range1.setGreedyToLeft(true); - myInfo.range1.setGreedyToRight(true); - myInfo.range2.setGreedyToLeft(true); - myInfo.range2.setGreedyToRight(false); - } - - final CaretModel caretModel = editor.getCaretModel(); - final int caretRelativePos = caretModel.getOffset() - start; - final SelectionModel selectionModel = editor.getSelectionModel(); - final int selectionStart = selectionModel.getSelectionStart(); - final int selectionEnd = selectionModel.getSelectionEnd(); - final boolean hasSelection = selectionModel.hasSelection(); - - // to prevent flicker - caretModel.moveToOffset(0); - - // There is a possible case that the user performs, say, method move. It's also possible that one (or both) of moved methods - // are folded. We want to preserve their states then. The problem is that folding processing is based on PSI element pointers - // and the pointers behave as following during move up/down: - // method1() {} - // method2() {} - // Pointer for the fold region from method1 points to 'method2()' now and vice versa (check range markers processing on - // document change for further information). I.e. information about fold regions statuses holds the data swapped for - // 'method1' and 'method2'. Hence, we want to apply correct 'collapsed' status. - final FoldRegion topRegion = findTopLevelRegionInRange(editor, myInfo.range1); - final FoldRegion bottomRegion = findTopLevelRegionInRange(editor, myInfo.range2); - - document.insertString(myInfo.range1.getStartOffset(), textToInsert2); - document.deleteString(myInfo.range1.getStartOffset()+textToInsert2.length(), myInfo.range1.getEndOffset()); - - document.insertString(myInfo.range2.getStartOffset(), textToInsert); - int s = myInfo.range2.getStartOffset() + textToInsert.length(); - int e = myInfo.range2.getEndOffset(); - if (e > s) { - document.deleteString(s, e); - } - final Project project = file.getProject(); - PsiDocumentManager.getInstance(project).commitAllDocuments(); + if (!myInfo.toMove.equals(myInfo.toMove2)) { // some movers (e.g. PyStatementMover) perform actual moving inside beforeMove/afterMove + final int start = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.startLine); + final int end = StatementUpDownMover.getLineStartSafeOffset(document, myInfo.toMove.endLine); + String textToInsert = document.getCharsSequence().subSequence(start, end).toString(); + if (!StringUtil.endsWithChar(textToInsert,'\n')) textToInsert += '\n'; - // Swap fold regions status if necessary. - if (topRegion != null && bottomRegion != null) { - CodeFoldingManager.getInstance(project).updateFoldRegions(editor); - editor.getFoldingModel().runBatchFoldingOperation(() -> { - FoldRegion newTopRegion = findTopLevelRegionInRange(editor, myInfo.range1); - if (newTopRegion != null) { - newTopRegion.setExpanded(bottomRegion.isExpanded()); - } + final int start2 = document.getLineStartOffset(myInfo.toMove2.startLine); + final int end2 = StatementUpDownMover.getLineStartSafeOffset(document,myInfo.toMove2.endLine); + String textToInsert2 = document.getCharsSequence().subSequence(start2, end2).toString(); + if (!StringUtil.endsWithChar(textToInsert2,'\n')) textToInsert2 += '\n'; - FoldRegion newBottomRegion = findTopLevelRegionInRange(editor, myInfo.range2); - if (newBottomRegion != null) { - newBottomRegion.setExpanded(topRegion.isExpanded()); - } - }); + TextRange range = new TextRange(start, end); + TextRange range2 = new TextRange(start2, end2); + if (range.intersectsStrict(range2) && !range.equals(range2)) { + LOGGER.error("Wrong move ranges requested by " + myMover, + new Attachment("ranges.txt", + start + ":" + end + "(" + textToInsert + ")\n" + start2 + ":" + end2 + "(" + textToInsert2 + ")")); + return; + } + + myInfo.range1 = document.createRangeMarker(start, end); + myInfo.range2 = document.createRangeMarker(start2, end2); + if (myInfo.range1.getStartOffset() < myInfo.range2.getStartOffset()) { + myInfo.range1.setGreedyToLeft(true); + myInfo.range1.setGreedyToRight(false); + myInfo.range2.setGreedyToLeft(true); + myInfo.range2.setGreedyToRight(true); + } + else { + myInfo.range1.setGreedyToLeft(true); + myInfo.range1.setGreedyToRight(true); + myInfo.range2.setGreedyToLeft(true); + myInfo.range2.setGreedyToRight(false); + } + + final CaretModel caretModel = editor.getCaretModel(); + final int caretRelativePos = caretModel.getOffset() - start; + final SelectionModel selectionModel = editor.getSelectionModel(); + final int selectionStart = selectionModel.getSelectionStart(); + final int selectionEnd = selectionModel.getSelectionEnd(); + final boolean hasSelection = selectionModel.hasSelection(); + + // to prevent flicker + caretModel.moveToOffset(0); + + // There is a possible case that the user performs, say, method move. It's also possible that one (or both) of moved methods + // are folded. We want to preserve their states then. The problem is that folding processing is based on PSI element pointers + // and the pointers behave as following during move up/down: + // method1() {} + // method2() {} + // Pointer for the fold region from method1 points to 'method2()' now and vice versa (check range markers processing on + // document change for further information). I.e. information about fold regions statuses holds the data swapped for + // 'method1' and 'method2'. Hence, we want to apply correct 'collapsed' status. + final FoldRegion topRegion = findTopLevelRegionInRange(editor, myInfo.range1); + final FoldRegion bottomRegion = findTopLevelRegionInRange(editor, myInfo.range2); + + document.insertString(myInfo.range1.getStartOffset(), textToInsert2); + document.deleteString(myInfo.range1.getStartOffset()+textToInsert2.length(), myInfo.range1.getEndOffset()); + + document.insertString(myInfo.range2.getStartOffset(), textToInsert); + int s = myInfo.range2.getStartOffset() + textToInsert.length(); + int e = myInfo.range2.getEndOffset(); + if (e > s) { + document.deleteString(s, e); + } + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + // Swap fold regions status if necessary. + if (topRegion != null && bottomRegion != null) { + CodeFoldingManager.getInstance(project).updateFoldRegions(editor); + editor.getFoldingModel().runBatchFoldingOperation(() -> { + FoldRegion newTopRegion = findTopLevelRegionInRange(editor, myInfo.range1); + if (newTopRegion != null) { + newTopRegion.setExpanded(bottomRegion.isExpanded()); + } + + FoldRegion newBottomRegion = findTopLevelRegionInRange(editor, myInfo.range2); + if (newBottomRegion != null) { + newBottomRegion.setExpanded(topRegion.isExpanded()); + } + }); + } + + if (hasSelection) { + restoreSelection(editor, selectionStart, selectionEnd, start, end, myInfo.range2.getStartOffset()); + } + + caretModel.moveToOffset(myInfo.range2.getStartOffset() + caretRelativePos); } - - if (hasSelection) { - restoreSelection(editor, selectionStart, selectionEnd, start, end, myInfo.range2.getStartOffset()); - } - - caretModel.moveToOffset(myInfo.range2.getStartOffset() + caretRelativePos); myMover.afterMove(editor, file, myInfo, myIsDown); PsiDocumentManager.getInstance(project).commitDocument(document); if (myInfo.indentTarget) { diff --git a/python/testData/mover/class_afterUp.py b/python/testData/mover/class_afterUp.py index 7864db22ba35..710862786d3c 100644 --- a/python/testData/mover/class_afterUp.py +++ b/python/testData/mover/class_afterUp.py @@ -4,4 +4,4 @@ if condition: class C: pass class B(Exception): - b=1 + b=1 \ No newline at end of file diff --git a/python/testData/mover/lastComment1_afterDown.py b/python/testData/mover/lastComment1_afterDown.py index b6ff87fd824b..4c6a890dbcad 100644 --- a/python/testData/mover/lastComment1_afterDown.py +++ b/python/testData/mover/lastComment1_afterDown.py @@ -3,4 +3,4 @@ def f(): a = 1 else: a = 2 -#comment +#comment \ No newline at end of file From c61d90531d8b1c374cb80f286c550d453ff2dfea Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 6 Oct 2016 12:41:18 +0300 Subject: [PATCH 26/27] project view: added action to mark a directory under excluded root as a new content root to cancel exclusion (IDEA-162102) --- .../actions/MarkAsContentRootAction.kt | 51 +++++++++++++++++++ .../actions/MarkRootActionBase.java | 6 ++- .../src/messages/ActionsBundle.properties | 2 + resources/src/idea/RichPlatformActions.xml | 1 + 4 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkAsContentRootAction.kt diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkAsContentRootAction.kt b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkAsContentRootAction.kt new file mode 100644 index 000000000000..2228bb399437 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkAsContentRootAction.kt @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2016 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.ide.projectView.actions + +import com.intellij.ide.projectView.impl.ProjectRootsUtil +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.CommonDataKeys +import com.intellij.openapi.project.DumbAwareAction +import com.intellij.openapi.roots.ModuleRootManager +import com.intellij.openapi.roots.ProjectRootManager + +/** + * @author nik + */ +class MarkAsContentRootAction : DumbAwareAction() { + override fun update(e: AnActionEvent) { + val files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) + val module = MarkRootActionBase.getModule(e, files) + if (module == null || files == null) { + e.presentation.isEnabledAndVisible = false + return + } + val fileIndex = ProjectRootManager.getInstance(module.project).fileIndex + e.presentation.isEnabledAndVisible = files.all { + it.isDirectory && fileIndex.isExcluded(it) && ProjectRootsUtil.findExcludeFolder(module, it) == null + } + } + + override fun actionPerformed(e: AnActionEvent) { + val files = e.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY) ?: return + val module = MarkRootActionBase.getModule(e, files) ?: return + val model = ModuleRootManager.getInstance(module).modifiableModel + files.forEach { + model.addContentEntry(it) + } + MarkRootActionBase.commitModel(module, model) + } +} diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java index 4e7683e180b5..0c5d26fdaf15 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkRootActionBase.java @@ -77,6 +77,10 @@ public abstract class MarkRootActionBase extends DumbAwareAction { modifyRoots(file, entry); } } + commitModel(module, model); + } + + static void commitModel(@NotNull Module module, ModifiableRootModel model) { DumbService.allowStartingDumbModeInside(DumbModePermission.MAY_START_BACKGROUND, () -> ApplicationManager.getApplication().runWriteAction(() -> { model.commit(); @@ -148,7 +152,7 @@ public abstract class MarkRootActionBase extends DumbAwareAction { } @Nullable - private static Module getModule(@NotNull AnActionEvent e, @Nullable VirtualFile[] files) { + static Module getModule(@NotNull AnActionEvent e, @Nullable VirtualFile[] files) { if (files == null) return null; Module module = e.getData(LangDataKeys.MODULE); if (module == null) { diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index af16c4e70ff2..0e44f01f5673 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -1476,6 +1476,8 @@ group.Vcs.Browse.text=Browse VCS Repository action.Graph.print.reset=Reset action.MarkExcludeRoot.text=Excluded action.UnmarkRoot.text=Unmark Root +action.MarkAsContentRoot.text=Cancel Exclusion +action.MarkAsContentRoot.description=Cancel exclusion for the selected directory to make its files processable by IDE's actions action.CreateLibraryFromFile.text=Add as Library... action.ImportModuleFromImlFile.text=Import Module action.ImportModuleFromImlFile.description=Import iml file as a module to the project diff --git a/resources/src/idea/RichPlatformActions.xml b/resources/src/idea/RichPlatformActions.xml index 8b01f1bc4930..f45f64028afc 100644 --- a/resources/src/idea/RichPlatformActions.xml +++ b/resources/src/idea/RichPlatformActions.xml @@ -390,6 +390,7 @@ + From c4dea478166642cd19fa079738763f41bf19b47d Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Thu, 6 Oct 2016 12:54:49 +0300 Subject: [PATCH 27/27] IDEA-162128 Strange cursor position after press 'End' when edit javadoc --- java/java-impl/src/com/intellij/javadoc/JavadocHelper.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/java/java-impl/src/com/intellij/javadoc/JavadocHelper.java b/java/java-impl/src/com/intellij/javadoc/JavadocHelper.java index 9d192a1fecb4..b96d77cac98f 100644 --- a/java/java-impl/src/com/intellij/javadoc/JavadocHelper.java +++ b/java/java-impl/src/com/intellij/javadoc/JavadocHelper.java @@ -107,16 +107,15 @@ public class JavadocHelper { } final CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getInstance(psiFile.getProject()).getCurrentSettings(); - final int indentSize = codeStyleSettings.getIndentSize(psiFile.getFileType()); int column; if (codeStyleSettings.JD_ALIGN_PARAM_COMMENTS) { column = Math.max(descriptionStartColumn, parameterNameEndColumn); if (column <= parameterNameEndColumn) { - column = parameterNameEndColumn + indentSize; + column = parameterNameEndColumn + 1; } } else { - column = anchor.parameterNameEndPosition.column + indentSize; + column = anchor.parameterNameEndPosition.column + 1; } return new LogicalPosition(anchor.parameterNameEndPosition.line, column); }