From 2a0ae003c15ba8ba606307f360e43b3afcdb48cb Mon Sep 17 00:00:00 2001 From: Valentina Kiryushkina Date: Mon, 11 Apr 2016 16:28:39 +0300 Subject: [PATCH 01/64] Add scrolling for study swing panel --- .../com/jetbrains/edu/learning/ui/StudySwingToolWindow.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudySwingToolWindow.java b/python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudySwingToolWindow.java index f076c9e4e14e..ef66218d3398 100644 --- a/python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudySwingToolWindow.java +++ b/python/educational-core/student/src/com/jetbrains/edu/learning/ui/StudySwingToolWindow.java @@ -14,11 +14,13 @@ * limitations under the License. */ package com.jetbrains.edu.learning.ui; + import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.project.Project; import com.intellij.ui.BrowserHyperlinkListener; import com.intellij.ui.ColorUtil; +import com.intellij.ui.components.JBScrollPane; import com.intellij.util.ui.UIUtil; import javax.swing.*; @@ -37,6 +39,7 @@ public class StudySwingToolWindow extends StudyToolWindow { @Override public JComponent createTaskInfoPanel(String taskText, Project project) { myTaskTextPane = new JTextPane(); + final JBScrollPane scrollPane = new JBScrollPane(myTaskTextPane); myTaskTextPane.setContentType(new HTMLEditorKit().getContentType()); final EditorColorsScheme editorColorsScheme = EditorColorsManager.getInstance().getGlobalScheme(); int fontSize = editorColorsScheme.getEditorFontSize(); @@ -56,7 +59,7 @@ public class StudySwingToolWindow extends StudyToolWindow { myTaskTextPane.setBorder(new EmptyBorder(20, 20, 0, 10)); myTaskTextPane.setText(taskText); myTaskTextPane.addHyperlinkListener(BrowserHyperlinkListener.INSTANCE); - return myTaskTextPane; + return scrollPane; } public void setTaskText(String text) { From c21a4c154f1454f9d0cee50dfc91ee211327e483 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 12 Apr 2016 14:12:02 +0300 Subject: [PATCH 02/64] optimisation --- .../visibility/AccessCanBeTightenedInspection.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/AccessCanBeTightenedInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/AccessCanBeTightenedInspection.java index 465279bbc5d6..b5c52c42d4c1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/AccessCanBeTightenedInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/visibility/AccessCanBeTightenedInspection.java @@ -147,7 +147,7 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool { final PsiPackage memberPackage = memberDirectory == null ? null : JavaDirectoryService.getInstance().getPackage(memberDirectory); log(member.getName()+ ": checking effective level for "+member); - UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> { + boolean proceed = UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> { PsiElement element = info.getElement(); if (element == null) return true; PsiFile psiFile = info.getFile(); @@ -156,7 +156,7 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool { return handleUsage(member, memberClass, memberFile, maxLevel, memberPackage, element, psiFile, foundUsage); }); - if (member instanceof PsiClass && ((PsiClass)member).isInterface()) { + if (proceed && member instanceof PsiClass && LambdaUtil.isFunctionalClass((PsiClass)member)) { // there can be lambda implementing this interface implicitly FunctionalExpressionSearch.search((PsiClass)member).forEach(functionalExpression -> { PsiFile psiFile = functionalExpression.getContainingFile(); From f360cd9a4aa37befa1e7611676dff593891e6572 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 12 Apr 2016 13:20:28 +0200 Subject: [PATCH 03/64] download Kotlin from 1.0.1 branch --- build/scripts/download_kotlin.gant | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/download_kotlin.gant b/build/scripts/download_kotlin.gant index 63d9bc039c7e..6b7e58c30aec 100644 --- a/build/scripts/download_kotlin.gant +++ b/build/scripts/download_kotlin.gant @@ -26,7 +26,7 @@ import static org.jetbrains.jps.idea.IdeaProjectLoader.guessHome includeTargets << new File("${guessHome(this)}/build/scripts/utils.gant") -String kotlinBuildConfigurationOnPublicTeamCity = "Kotlin_Rc_Idea142branch150versionNoTests" +String kotlinBuildConfigurationOnPublicTeamCity = "Kotlin_101andRc_Idea142branch150versionNoTests" target('default': 'Ensures that build/kotlinc directory contains JARs from Kotlin plugin compatible with current IDEA sources. These JARs are used by build scripts.') { def communityHome = guessHome(this) From 34fa9f79f00277fdbf50042aa89fb213e7f8d288 Mon Sep 17 00:00:00 2001 From: Eugene Kudelevsky Date: Tue, 12 Apr 2016 14:52:34 +0300 Subject: [PATCH 04/64] Revert setting default hostname verifier of HttpsURLConnection For some reason It breaks authentication through client SSL certificate --- .../src/com/intellij/util/net/ssl/CertificateManager.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java index 32f37e24c797..de7ac7d1b5e0 100644 --- a/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java +++ b/platform/platform-api/src/com/intellij/util/net/ssl/CertificateManager.java @@ -131,10 +131,7 @@ public class CertificateManager implements PersistentStateComponent Date: Tue, 12 Apr 2016 14:41:22 +0300 Subject: [PATCH 05/64] changed Collection to Iterable --- .../psi/impl/search/HighlightingCaches.java | 5 ++--- .../search/JavaClassInheritorsSearcher.java | 18 ++++++------------ .../search/JavaOverridingMethodsSearcher.java | 4 ++-- 3 files changed, 10 insertions(+), 17 deletions(-) diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/HighlightingCaches.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/HighlightingCaches.java index 94ee67becd3a..72aed9ebf3d7 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/HighlightingCaches.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/HighlightingCaches.java @@ -25,7 +25,6 @@ import com.intellij.psi.impl.PsiManagerImpl; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentMap; @@ -57,9 +56,9 @@ class HighlightingCaches { // baseClass -> (list of direct subclasses, isInheritor flag array) final Map, AtomicIntegerArray>> DIRECT_SUB_CLASSES = createWeakCache(); // baseClass -> all sub classes transitively, including anonymous - final ConcurrentMap> ALL_SUB_CLASSES = createWeakCache(); + final ConcurrentMap> ALL_SUB_CLASSES = createWeakCache(); // baseMethod -> all overriding methods - final Map> OVERRIDING_METHODS = createWeakCache(); + final Map> OVERRIDING_METHODS = createWeakCache(); @NotNull private ConcurrentMap createWeakCache() { diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java index ccc430fc3344..9dc4d1ee0d44 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaClassInheritorsSearcher.java @@ -38,7 +38,6 @@ import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.HashSetQueue; import org.jetbrains.annotations.NotNull; -import java.util.AbstractCollection; import java.util.Collection; import java.util.Iterator; import java.util.concurrent.ConcurrentMap; @@ -86,7 +85,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase cached = getOrComputeSubClasses(project, parameters.getClassToProcess()); + Iterable cached = getOrComputeSubClasses(project, parameters.getClassToProcess()); for (final PsiClass subClass : cached) { ProgressManager.checkCanceled(); @@ -102,9 +101,9 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase getOrComputeSubClasses(@NotNull Project project, @NotNull PsiClass baseClass) { - ConcurrentMap> CACHE = HighlightingCaches.getInstance(project).ALL_SUB_CLASSES; - Collection cached = CACHE.get(baseClass); + private static Iterable getOrComputeSubClasses(@NotNull Project project, @NotNull PsiClass baseClass) { + ConcurrentMap> CACHE = HighlightingCaches.getInstance(project).ALL_SUB_CLASSES; + Iterable cached = CACHE.get(baseClass); if (cached == null) { cached = computeAllSubClasses(project, baseClass); // it's almost empty now, no big deal // make sure concurrent calls of this method always return the same collection to avoid expensive duplicate work @@ -115,7 +114,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase computeAllSubClasses(@NotNull Project project, @NotNull PsiClass baseClass) { + private static Iterable computeAllSubClasses(@NotNull Project project, @NotNull PsiClass baseClass) { return new AllSubClassesLazyCollection(project, baseClass); } @@ -188,7 +187,7 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase)() -> baseClass.hasModifierProperty(PsiModifier.FINAL)); } - private static class AllSubClassesLazyCollection extends AbstractCollection { + private static class AllSubClassesLazyCollection implements Iterable { // Computes all sub classes of the 'baseClass' transitively by calling DirectClassInheritorsSearch repeatedly. // Already computed subclasses in this collection. // There are two iterators maintained for this collection: @@ -235,11 +234,6 @@ public class JavaClassInheritorsSearcher extends QueryExecutorBase candidatesToFindSubclassesIterator; // guarded by lock private void findNextSubclasses() { diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java index 33817855456b..c8dd2eb2483f 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaOverridingMethodsSearcher.java @@ -54,7 +54,7 @@ public class JavaOverridingMethodsSearcher implements QueryExecutor cached = HighlightingCaches.getInstance(project).OVERRIDING_METHODS.get(method); + Iterable cached = HighlightingCaches.getInstance(project).OVERRIDING_METHODS.get(method); if (cached == null) { cached = compute(method, project); HighlightingCaches.getInstance(project).OVERRIDING_METHODS.put(method, cached); @@ -112,7 +112,7 @@ public class JavaOverridingMethodsSearcher implements QueryExecutor compute(@NotNull PsiMethod method, @NotNull Project project) { + private static Iterable compute(@NotNull PsiMethod method, @NotNull Project project) { Collection result = new LinkedHashSet<>(); Application application = ApplicationManager.getApplication(); From bddb453946da867fe9b3b6ad29746e643208bc12 Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Tue, 12 Apr 2016 15:34:45 +0300 Subject: [PATCH 06/64] IDEA-151147 Splash screen: license info is aligned differently on Windows and Mac OS --- platform/platform-impl/src/com/intellij/ui/Splash.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/Splash.java b/platform/platform-impl/src/com/intellij/ui/Splash.java index 2df4853d4b5f..f4cca64aa7b5 100644 --- a/platform/platform-impl/src/com/intellij/ui/Splash.java +++ b/platform/platform-impl/src/com/intellij/ui/Splash.java @@ -185,7 +185,7 @@ public class Splash extends JDialog implements StartupProgress { if (Registry.is("ide.new.about")) { ApplicationInfo info = getAppInfo(); if (info instanceof ApplicationInfoImpl) { - offsetX = Math.max(offsetX, ((ApplicationInfoImpl)info).getProgressX()); + offsetX = Math.max(offsetX, uiScale(((ApplicationInfoImpl)info).getProgressX())); offsetY = ((ApplicationInfoImpl)info).getLicenseOffsetY(); } else { return false; From cb2ad019a6f6991eda8982650b3e523fb6c26b09 Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Tue, 12 Apr 2016 15:41:27 +0300 Subject: [PATCH 07/64] IDEA-154550 Unreadable disabled text in selected tree line --- .../intellij/openapi/vfs/encoding/EncodingFileTreeTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/EncodingFileTreeTable.java b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/EncodingFileTreeTable.java index bbb53e327534..3b52f3c54882 100644 --- a/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/EncodingFileTreeTable.java +++ b/platform/lang-impl/src/com/intellij/openapi/vfs/encoding/EncodingFileTreeTable.java @@ -71,7 +71,7 @@ class EncodingFileTreeTable extends AbstractFileTreeTable { setText(encodingText + (failReason == null ? "" : " (" + failReason + ")")); } - setEnabled(enabled); + setEnabled(enabled || isSelected); // do not use grayed text on selected row return this; } }); From e71085ae02fb4d55845e08b801f9dcf68980f40f Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Tue, 12 Apr 2016 14:30:36 +0300 Subject: [PATCH 08/64] Reference hyperlink preview --- .../openapi/options/colors/pages/GeneralColorsPage.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java index 1071b412ac9f..0327f604c1c0 100644 --- a/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java +++ b/platform/lang-impl/src/com/intellij/openapi/options/colors/pages/GeneralColorsPage.java @@ -46,6 +46,7 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett "//TODO: Visit JB Web resources:\n"+ "JetBrains Home Page: http://www.jetbrains.com\n" + "JetBrains Developer Community: https://www.jetbrains.com/devnet\n" + + "ReferenceHyperlink\n" + "\n" + "Search:\n" + " result = \"text, text, text\";\n" + @@ -145,6 +146,7 @@ public class GeneralColorsPage implements ColorSettingsPage, InspectionColorSett ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("todo", CodeInsightColors.TODO_DEFAULT_ATTRIBUTES); ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("hyperlink", CodeInsightColors.HYPERLINK_ATTRIBUTES); ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("hyperlink_f", CodeInsightColors.FOLLOWED_HYPERLINK_ATTRIBUTES); + ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("ref_hyperlink", EditorColors.REFERENCE_HYPERLINK_COLOR); ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("wrong_ref", CodeInsightColors.WRONG_REFERENCES_ATTRIBUTES); ADDITIONAL_HIGHLIGHT_DESCRIPTORS.put("deprecated", CodeInsightColors.DEPRECATED_ATTRIBUTES); From 415eba66304b66653e791c71db394d6c43a56498 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Tue, 12 Apr 2016 15:28:53 +0300 Subject: [PATCH 09/64] Add hyperlink colors from a base scheme --- .../eclipse/importer/colors/EclipseColorSchemeImporter.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/colors/EclipseColorSchemeImporter.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/colors/EclipseColorSchemeImporter.java index 06468197c6cd..7c0dc077b112 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/colors/EclipseColorSchemeImporter.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/colors/EclipseColorSchemeImporter.java @@ -89,7 +89,11 @@ public class EclipseColorSchemeImporter implements SchemeImporter Date: Tue, 12 Apr 2016 15:40:34 +0300 Subject: [PATCH 10/64] Set console background upon import --- .../idea/eclipse/importer/colors/EclipseThemeOptionHandler.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/colors/EclipseThemeOptionHandler.java b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/colors/EclipseThemeOptionHandler.java index 93c5e05de91b..b77309cbd6f9 100644 --- a/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/colors/EclipseThemeOptionHandler.java +++ b/plugins/eclipse/src/org/jetbrains/idea/eclipse/importer/colors/EclipseThemeOptionHandler.java @@ -15,6 +15,7 @@ */ package org.jetbrains.idea.eclipse.importer.colors; +import com.intellij.execution.ui.ConsoleViewContentType; import com.intellij.ide.highlighter.JavaHighlightingColors; import com.intellij.openapi.editor.DefaultLanguageHighlighterColors; import com.intellij.openapi.editor.HighlighterColors; @@ -71,6 +72,7 @@ public class EclipseThemeOptionHandler implements EclipseThemeReader.OptionHandl if (BACKGROUND_TAG.equals(name)) { updateAttributes(HighlighterColors.TEXT, attributes); myColorsScheme.setColor(EditorColors.GUTTER_BACKGROUND, attributes.getBackgroundColor()); + myColorsScheme.setColor(ConsoleViewContentType.CONSOLE_BACKGROUND_KEY, attributes.getBackgroundColor()); } else if (FOREGROUND_TAG.equals(name)) { updateAttributes(HighlighterColors.TEXT, attributes); From 3b9b43e7ed7a2349460192e24fbcaedae120fb25 Mon Sep 17 00:00:00 2001 From: Sergey Ignatov Date: Tue, 12 Apr 2016 15:50:10 +0300 Subject: [PATCH 11/64] [find usage popup/dialog] gray a bit repeated files --- .../com/intellij/find/impl/FindDialog.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index 7b02fa8cfb6b..c7dfea8a92a7 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -53,6 +53,7 @@ import com.intellij.openapi.progress.util.ReadTask; import com.intellij.openapi.project.DumbAwareAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.*; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.registry.Registry; @@ -93,6 +94,8 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; +import static com.intellij.ui.SimpleTextAttributes.STYLE_PLAIN; + public class FindDialog extends DialogWrapper { private static final Logger LOG = Logger.getInstance("#com.intellij.find.impl.FindDialog"); @@ -1679,6 +1682,9 @@ public class FindDialog extends DialogWrapper { } }; private final ColoredTableCellRenderer myFileAndLineNumber = new ColoredTableCellRenderer() { + private final SimpleTextAttributes REPEATED_FILE_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, new JBColor(0xCCCCCC, 0x5E5E5E)); + private final SimpleTextAttributes ORDINAL_ATTRIBUTES = new SimpleTextAttributes(STYLE_PLAIN, new JBColor(0x999999, 0x999999)); + @Override protected void customizeCellRenderer(JTable table, Object value, boolean selected, boolean hasFocus, int row, int column) { if (value instanceof UsageInfo2UsageAdapter) { @@ -1687,11 +1693,22 @@ public class FindDialog extends DialogWrapper { // line number / file info VirtualFile file = usageAdapter.getFile(); String uniqueVirtualFilePath = myOmitFileExtension ? file.getNameWithoutExtension() : file.getName(); - append(uniqueVirtualFilePath + " " + text[0].getText(), SimpleTextAttributes.GRAYED_ATTRIBUTES); + VirtualFile prevFile = findPrevFile(table, row, column); + SimpleTextAttributes attributes = Comparing.equal(file, prevFile) ? REPEATED_FILE_ATTRIBUTES : ORDINAL_ATTRIBUTES; + append(uniqueVirtualFilePath, attributes); + append(" " + text[0].getText(), ORDINAL_ATTRIBUTES); } setBorder(null); } + + @Nullable + private VirtualFile findPrevFile(@NotNull JTable table, int row, int column) { + if (row <= 0) return null; + Object prev = table.getValueAt(row - 1, column); + return prev instanceof UsageInfo2UsageAdapter ? ((UsageInfo2UsageAdapter)prev).getFile() : null; + } }; + private static final int MARGIN = 2; private final boolean myOmitFileExtension; private final boolean myUseBold; From 266fa76001b1235c979225013291f11454b182a1 Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 12 Apr 2016 12:29:52 +0200 Subject: [PATCH 12/64] fallback jdk path as system-intedependent name --- .../impl/src/com/intellij/compiler/server/BuildManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index 4acb533d5409..c817a35e8f77 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -1156,7 +1156,7 @@ public class BuildManager implements Disposable { cmdLine.addParameter("-D" + PathManager.PROPERTY_PLUGINS_PATH + "=" + PathManager.getPluginsPath()); cmdLine.addParameter("-D" + GlobalOptions.LOG_DIR_OPTION + "=" + FileUtil.toSystemIndependentName(getBuildLogDirectory().getAbsolutePath())); - cmdLine.addParameter("-D" + GlobalOptions.FALLBACK_JDK_HOME + "=" + SystemProperties.getJavaHome()); + cmdLine.addParameter("-D" + GlobalOptions.FALLBACK_JDK_HOME + "=" + FileUtil.toSystemIndependentName(SystemProperties.getJavaHome())); cmdLine.addParameter("-D" + GlobalOptions.FALLBACK_JDK_VERSION + "=" + SystemProperties.getJavaVersion()); final File workDirectory = getBuildSystemDirectory(); From e5ea07635ba1fc5e85af4d820218b66ea5a3ae2e Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Tue, 12 Apr 2016 12:47:25 +0200 Subject: [PATCH 13/64] better error diagnostics --- .../impl/src/com/intellij/compiler/server/BuildManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java index c817a35e8f77..a9c6135446e2 100644 --- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java +++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java @@ -1463,7 +1463,7 @@ public class BuildManager implements Disposable { String text; synchronized (this) { - if (myStoredLength > 2048) { + if (myStoredLength > 16384) { return; } text = event.getText(); From 94f52c4ae7447f7edce87f22fd4dcdd98a8416f7 Mon Sep 17 00:00:00 2001 From: "Dmitry.Krasilschikov" Date: Tue, 12 Apr 2016 16:06:46 +0300 Subject: [PATCH 14/64] #RUBY-17947 customize file reference extended completion --- .../reference/impl/providers/FileReferenceSet.java | 4 ++++ .../completion/FilePathCompletionContributor.java | 8 ++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java index 2d10ceb873be..a8c583904a5e 100644 --- a/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java +++ b/platform/analysis-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceSet.java @@ -503,4 +503,8 @@ public class FileReferenceSet { public void setEmptyPathAllowed(boolean emptyPathAllowed) { myEmptyPathAllowed = emptyPathAllowed; } + + public boolean supportsExtendedCompletion() { + return true; + } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java index 4a34e9460718..8071b97d6fe6 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/FilePathCompletionContributor.java @@ -241,14 +241,18 @@ public class FilePathCompletionContributor extends CompletionContributor { final PsiMultiReference multiReference = (PsiMultiReference)original; for (PsiReference reference : multiReference.getReferences()) { if (reference instanceof FileReference) { - return Pair.create((FileReference) reference, false); + if (((FileReference)reference).getFileReferenceSet().supportsExtendedCompletion()) { + return Pair.create((FileReference)reference, false); + } } } } else if (original instanceof FileReferenceOwner) { final PsiFileReference fileReference = ((FileReferenceOwner)original).getLastFileReference(); if (fileReference instanceof FileReference) { - return Pair.create((FileReference) fileReference, true); + if (((FileReference)fileReference).getFileReferenceSet().supportsExtendedCompletion()) { + return Pair.create((FileReference) fileReference, true); + } } } From e172cb539ecbcfe847e3075f86b197d2db02a0ca Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 12 Apr 2016 16:17:19 +0300 Subject: [PATCH 15/64] external build: follow IDEA's behavior and add 'module-source' dependency if it's missing in iml file generated by third-party tool (IDEA-152998) --- .../module/JpsModuleRootModelSerializer.java | 5 +++++ .../missingModuleSourcesOrderEntry.iml | 8 ++++++++ .../missingModuleSourcesOrderEntry.ipr | 12 ++++++++++++ .../serialization/JpsProjectSerializationTest.java | 9 +++++++++ 4 files changed, 34 insertions(+) create mode 100644 jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.iml create mode 100644 jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.ipr diff --git a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java index 211d8d1a5bbd..4c1fbf0e6ffc 100644 --- a/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java +++ b/jps/model-serialization/src/org/jetbrains/jps/model/serialization/module/JpsModuleRootModelSerializer.java @@ -91,10 +91,12 @@ public class JpsModuleRootModelSerializer { dependenciesList.clear(); final JpsElementFactory elementFactory = JpsElementFactory.getInstance(); UniqueNameGenerator nameGenerator = new UniqueNameGenerator(); + boolean moduleSourceAdded = false; for (Element orderEntry : getChildren(rootModelComponent, ORDER_ENTRY_TAG)) { String type = orderEntry.getAttributeValue(TYPE_ATTRIBUTE); if (SOURCE_FOLDER_TYPE.equals(type)) { dependenciesList.addModuleSourceDependency(); + moduleSourceAdded = true; } else if (JDK_TYPE.equals(type)) { String sdkName = orderEntry.getAttributeValue(JDK_NAME_ATTRIBUTE); @@ -140,6 +142,9 @@ public class JpsModuleRootModelSerializer { loadModuleDependencyProperties(dependency, orderEntry); } } + if (!moduleSourceAdded) { + dependenciesList.addModuleSourceDependency(); + } for (JpsModelSerializerExtension extension : JpsModelSerializerExtension.getExtensions()) { extension.loadRootModel(module, rootModelComponent); diff --git a/jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.iml b/jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.iml new file mode 100644 index 000000000000..088307e94146 --- /dev/null +++ b/jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.iml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.ipr b/jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.ipr new file mode 100644 index 000000000000..bad34659d510 --- /dev/null +++ b/jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.ipr @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java index ae80493e3e3f..506c6fcc7f27 100644 --- a/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java +++ b/jps/model-serialization/testSrc/org/jetbrains/jps/model/serialization/JpsProjectSerializationTest.java @@ -179,6 +179,15 @@ public class JpsProjectSerializationTest extends JpsSerializationTestCase { doTestSaveModule(module, projectPath + "resourceRoots.iml"); } + public void testMissingModuleSourcesOrderEntry() { + loadProject("/jps/model-serialization/testData/missingModuleSourcesOrderEntry/missingModuleSourcesOrderEntry.ipr"); + JpsModule module = assertOneElement(myProject.getModules()); + List dependencies = module.getDependenciesList().getDependencies(); + assertEquals(2, dependencies.size()); + assertInstanceOf(dependencies.get(0), JpsSdkDependency.class); + assertInstanceOf(dependencies.get(1), JpsModuleSourceDependency.class); + } + private static void checkResourceRoot(JpsModuleSourceRoot root, boolean forGenerated, String relativeOutput) { assertSame(JavaResourceRootType.RESOURCE, root.getRootType()); JavaResourceRootProperties properties = root.getProperties(JavaResourceRootType.RESOURCE); From cc745e6324e7fddff12ad431190efe44560965a7 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 12 Apr 2016 15:21:51 +0200 Subject: [PATCH 16/64] Allow to close Shortcut panel by pressing two times Esc --- .../impl/ui/ShortcutFilteringPanel.java | 28 ++++++++++++++----- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutFilteringPanel.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutFilteringPanel.java index 96e4979bbe19..f00cffce4f55 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutFilteringPanel.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutFilteringPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -16,6 +16,7 @@ package com.intellij.openapi.keymap.impl.ui; import com.intellij.icons.AllIcons; +import com.intellij.ide.IdeEventQueue; import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.actionSystem.MouseShortcut; import com.intellij.openapi.actionSystem.Shortcut; @@ -26,14 +27,13 @@ import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.ui.components.panels.VerticalLayout; import com.intellij.util.ui.JBUI; -import java.awt.BorderLayout; -import java.awt.Component; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import javax.swing.JLabel; -import javax.swing.JPanel; +import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import java.awt.*; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; /** * @author Sergey.Malenkov @@ -146,6 +146,20 @@ final class ShortcutFilteringPanel extends JPanel { .setCancelKeyEnabled(false) .setMovable(true) .createPopup(); + IdeEventQueue.getInstance().addPostprocessor(new IdeEventQueue.EventDispatcher() { + boolean isEscWasPressed = false; + @Override + public boolean dispatch(AWTEvent e) { + if (e instanceof KeyEvent && e.getID() == KeyEvent.KEY_PRESSED) { + boolean isEsc = ((KeyEvent)e).getKeyCode() == KeyEvent.VK_ESCAPE; + if (isEscWasPressed && isEsc) { + myPopup.cancel(); + } + isEscWasPressed = isEsc; + } + return false; + } + }, myPopup); } myPopup.showUnderneathOf(component); } From 8dfb3f2771fa18577bed0d79687438741e5c7ca5 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 12 Apr 2016 15:22:06 +0200 Subject: [PATCH 17/64] cleanup --- .../keymap/impl/ui/ShortcutTextField.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutTextField.java b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutTextField.java index faf1dbc7e431..4c1ff440dca3 100644 --- a/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutTextField.java +++ b/platform/platform-impl/src/com/intellij/openapi/keymap/impl/ui/ShortcutTextField.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -56,14 +56,13 @@ public final class ShortcutTextField extends JTextField { protected void processKeyEvent(KeyEvent e) { if (e.getID() == KeyEvent.KEY_PRESSED) { int keyCode = e.getKeyCode(); - if ( - keyCode == KeyEvent.VK_SHIFT || - keyCode == KeyEvent.VK_ALT || - keyCode == KeyEvent.VK_CONTROL || - keyCode == KeyEvent.VK_ALT_GRAPH || - keyCode == KeyEvent.VK_META || - absolutelyUnknownKey(e) - ){ + + if (keyCode == KeyEvent.VK_SHIFT || + keyCode == KeyEvent.VK_ALT || + keyCode == KeyEvent.VK_CONTROL || + keyCode == KeyEvent.VK_ALT_GRAPH || + keyCode == KeyEvent.VK_META || + absolutelyUnknownKey(e)) { return; } setKeyStroke(KeyStrokeAdapter.getDefaultKeyStroke(e)); From d58fd8d232378bcf7e07ddf6e24b3620d7684192 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Tue, 12 Apr 2016 15:38:51 +0200 Subject: [PATCH 18/64] check for null PsiClass.getContainingFile() when filtering dependencies in OrderEntryFix (EA-81471) --- .../codeInsight/daemon/impl/quickfix/OrderEntryFix.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java index 0ffe3732748b..cdd8e6814326 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/OrderEntryFix.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -163,7 +163,8 @@ public abstract class OrderEntryFix implements IntentionAction, LocalQuickFix { PsiFile fromFile = element.getContainingFile(); List result = new ArrayList(); for (PsiClass psiClass : classes) { - if (dependencyValidationManager.getViolatorDependencyRule(fromFile, psiClass.getContainingFile()) == null) { + PsiFile containingFile = psiClass.getContainingFile(); + if (containingFile != null && dependencyValidationManager.getViolatorDependencyRule(fromFile, containingFile) == null) { result.add(psiClass); } } From 7deb8a2680c935522cb6d1fad61c8da0904a17e9 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 12 Apr 2016 16:02:26 +0200 Subject: [PATCH 19/64] Fix running pty process with spaces in path on Windows (PY-18221) --- lib/pty4j-0.6.jar | Bin 53942 -> 58005 bytes lib/src/pty4j-0.6-src.jar | Bin 34728 -> 37172 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/lib/pty4j-0.6.jar b/lib/pty4j-0.6.jar index 950ab6129ad4d632b2e42126db5d0a38fdc33857..7b3f5f2d9d6d784e4debe1a1a585b6151c1fbc99 100644 GIT binary patch delta 42934 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 Ij{HXb4+^UZVE_OC delta 39098 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 diff --git a/lib/src/pty4j-0.6-src.jar b/lib/src/pty4j-0.6-src.jar index b6ef30cdc34ba50156cb2a7088f768fa492b4e05..794c220ea4c8bc8dcede0132b836423afa6af0a3 100644 GIT binary patch delta 26955 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 From ffcd868039ac9b62f9f2d4d771c47d6375d28bfa Mon Sep 17 00:00:00 2001 From: nik Date: Tue, 12 Apr 2016 17:06:36 +0300 Subject: [PATCH 20/64] build scripts: ignore patch number of metadata version when checking Kotlin class-files compatibility (Kotlin 1.0.2 builds produce 1.1.1 version which is compatible with 1.1.0 version produced by Kotlin 1.0.1) --- build/scripts/download_kotlin.gant | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/build/scripts/download_kotlin.gant b/build/scripts/download_kotlin.gant index 6b7e58c30aec..b383fade563c 100644 --- a/build/scripts/download_kotlin.gant +++ b/build/scripts/download_kotlin.gant @@ -190,7 +190,7 @@ private String readKotlinClassVersionOfCompiledClasses() { } } -private String readKotlinClassFileVersion(InputStream classFileStream) { +private static String readKotlinClassFileVersion(InputStream classFileStream) { def reader = new ClassReader(classFileStream) String kotlinBytecodeVersion = null String kotlinMetaDataVersion = null @@ -209,7 +209,8 @@ private String readKotlinClassFileVersion(InputStream classFileStream) { return new AnnotationVisitor(Opcodes.ASM5) { void visit(String name, Object value) { if (name == "mv") { - kotlinMetaDataVersion = (value as Integer[]).join(".") + //strip patch number of metadata version because changes in patch updates are forward and backward compatible + kotlinMetaDataVersion = (value as Integer[]).toList().dropRight(1).join(".") } else if (name == "bv") { kotlinBytecodeVersion = (value as Integer[]).join(".") From 55e9cd93bc6231e51af5e58687355294b588740f Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 12 Apr 2016 16:27:02 +0200 Subject: [PATCH 21/64] Enable passing tests --- .../com/intellij/execution/PtyCommandLineTest.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/execution/PtyCommandLineTest.java b/platform/platform-tests/testSrc/com/intellij/execution/PtyCommandLineTest.java index cfcbbb27f61c..48451ba92aef 100644 --- a/platform/platform-tests/testSrc/com/intellij/execution/PtyCommandLineTest.java +++ b/platform/platform-tests/testSrc/com/intellij/execution/PtyCommandLineTest.java @@ -37,16 +37,6 @@ public class PtyCommandLineTest extends GeneralCommandLineTest { return cmd; } - @Override - public void unicodePath() { - assumeFalse(SystemInfo.isWindows); - } - - @Override - public void unicodeClassPath() { - assumeFalse(SystemInfo.isWindows); - } - @Override public void passingArgumentsToJavaApp() { assumeFalse(SystemInfo.isWindows); From 106dec046af821affd882fb1530ce51d92fa1525 Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Tue, 12 Apr 2016 16:28:03 +0200 Subject: [PATCH 22/64] OC-11493 Emoji in Build Settings is converted to ASCII: do not convert surrogate pairs to \uXXXX format when escaping strings --- .../com/intellij/openapi/util/text/StringUtil.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index 456a0ac0d5c0..d7c129700dc5 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -579,6 +579,16 @@ public class StringUtil extends StringUtilRt { @Nullable String additionalChars, boolean escapeSlash, @NotNull @NonNls StringBuilder buffer) { + return escapeStringCharacters(length, str, additionalChars, escapeSlash, true, buffer); + } + + @NotNull + public static StringBuilder escapeStringCharacters(int length, + @NotNull String str, + @Nullable String additionalChars, + boolean escapeSlash, + boolean escapeUnicode, + @NotNull @NonNls StringBuilder buffer) { char prev = 0; for (int idx = 0; idx < length; idx++) { char ch = str.charAt(idx); @@ -610,7 +620,7 @@ public class StringUtil extends StringUtilRt { else if (additionalChars != null && additionalChars.indexOf(ch) > -1 && (escapeSlash || prev != '\\')) { buffer.append("\\").append(ch); } - else if (!isPrintableUnicode(ch)) { + else if (escapeUnicode && !isPrintableUnicode(ch)) { CharSequence hexCode = StringUtilRt.toUpperCase(Integer.toHexString(ch)); buffer.append("\\u"); int paddingCount = 4 - hexCode.length(); From 26786f10747fa15dcef0d0b841a0559d4bd98ec9 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 12 Apr 2016 12:33:12 +0200 Subject: [PATCH 23/64] logging for EA-81421 - assert: PsiDiamondTypeUtil.areTypeArgumentsRedundant --- .../src/com/intellij/psi/impl/PsiDiamondTypeUtil.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java index c449aa665f99..d9b0c797a3ae 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java @@ -195,7 +195,9 @@ public class PsiDiamondTypeUtil { final PsiFile fileCopy = (PsiFile)containingFile.copy(); copy = fileCopy.findElementAt(offset); if (method != null && method.getContainingFile() == containingFile) { - method = PsiTreeUtil.getParentOfType(fileCopy.findElementAt(method.getTextOffset()), PsiMethod.class); + final PsiElement startMethodElementInCopy = fileCopy.findElementAt(method.getTextOffset()); + method = PsiTreeUtil.getParentOfType(startMethodElementInCopy, PsiMethod.class); + LOG.assertTrue(method != null, startMethodElementInCopy); } } final PsiCallExpression exprCopy = PsiTreeUtil.getParentOfType(copy, PsiCallExpression.class, false); From 9f746bed33643ee96560b3f77839b940956a92ec Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 12 Apr 2016 12:39:01 +0200 Subject: [PATCH 24/64] EA-81353 - assert: PsiManagerImpl.fireEvent --- .../typeMigration/TypeMigrationVariableTypeFixProvider.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java index c16ea7f0c04b..b61cf5bd524a 100644 --- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java +++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java @@ -8,6 +8,7 @@ import com.intellij.codeInsight.FileModificationService; import com.intellij.codeInsight.daemon.impl.quickfix.VariableTypeFix; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider; +import com.intellij.openapi.application.WriteAction; import com.intellij.openapi.command.undo.UndoUtil; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; @@ -74,7 +75,7 @@ public class TypeMigrationVariableTypeFixProvider implements ChangeVariableTypeQ final TypeMigrationRules rules = new TypeMigrationRules(); rules.setBoundScope(GlobalSearchScope.projectScope(project)); TypeMigrationProcessor.runHighlightingTypeMigration(project, editor, rules, variable, targetType, optimizeImports); - JavaCodeStyleManager.getInstance(project).shortenClassReferences(variable); + WriteAction.run(() -> JavaCodeStyleManager.getInstance(project).shortenClassReferences(variable)); UndoUtil.markPsiFileForUndo(variable.getContainingFile()); } catch (IncorrectOperationException e) { From 89f5ad0a396e023091b45dacf7ab0b05c2549b03 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 12 Apr 2016 12:49:38 +0200 Subject: [PATCH 25/64] logging for EA-81243 - assert: ProblemDescriptorBase. --- .../src/com/intellij/codeInspection/ProblemDescriptorBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java index 3ac277c96d8e..d0e642abae10 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ProblemDescriptorBase.java @@ -67,7 +67,7 @@ public class ProblemDescriptorBase extends CommonProblemDescriptorImpl implement LOG.assertTrue(endElementRange != null, endElement); if (startElementRange.getStartOffset() >= endElementRange.getEndOffset()) { if (!(startElement instanceof PsiFile && endElement instanceof PsiFile)) { - LOG.error("Empty PSI elements should not be passed to createDescriptor. Start: " + startElement + ", end: " + endElement); + LOG.error("Empty PSI elements should not be passed to createDescriptor. Start: " + startElement + ", end: " + endElement + ", startContainingFile: " + startContainingFile); } } From 7db6ca94f7992736653b401575f7afea6028f67e Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 12 Apr 2016 13:54:53 +0200 Subject: [PATCH 26/64] @NotNull --- .../moveClassesOrPackages/MoveDirectoryWithClassesHelper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java index c354dddf5c15..30acd20da80e 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveDirectoryWithClassesHelper.java @@ -121,9 +121,9 @@ public abstract class MoveDirectoryWithClassesHelper { } private static class MyUsageInfo extends UsageInfo { - private final PsiFileSystemItem myFile; + private final @NotNull PsiFileSystemItem myFile; - public MyUsageInfo(@NotNull PsiReference reference, PsiFileSystemItem file) { + public MyUsageInfo(@NotNull PsiReference reference, @NotNull PsiFileSystemItem file) { super(reference); myFile = file; } From f0b218fc5cc7138fe5ad843f6857241cf0e4b2f1 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 12 Apr 2016 16:24:47 +0200 Subject: [PATCH 27/64] pull setter to the common class --- .../intellij/refactoring/changeSignature/JavaParameterInfo.java | 1 + .../intellij/refactoring/changeSignature/ParameterInfoImpl.java | 1 + .../groovy/refactoring/changeSignature/GrParameterInfo.java | 1 + 3 files changed, 3 insertions(+) diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterInfo.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterInfo.java index 99a9f63a431d..bc5740508172 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterInfo.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaParameterInfo.java @@ -41,4 +41,5 @@ public interface JavaParameterInfo extends ParameterInfo { boolean isVarargType(); + default void setType(@Nullable PsiType type) {} } diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java index ecb68903d1da..9bc2bba3b570 100644 --- a/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java +++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/ParameterInfoImpl.java @@ -124,6 +124,7 @@ public class ParameterInfoImpl implements JavaParameterInfo { } } + @Override public void setType(PsiType type) { myType = CanonicalTypes.createTypeWrapper(type); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java index deb6f2f47faf..a9fca573c9e1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrParameterInfo.java @@ -155,6 +155,7 @@ public class GrParameterInfo implements JavaParameterInfo { myName = newName; } + @Override public void setType(@Nullable PsiType type) { myTypeWrapper = type == null ? null : CanonicalTypes.createTypeWrapper(type); } From 503c2c1d1a35104cce8dc15eeb43afbe3ebe9c8b Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 12 Apr 2016 16:32:40 +0200 Subject: [PATCH 28/64] abstract method call in constructor: don't warn inside lambda body --- .../siyeh/ig/psiutils/MethodCallUtils.java | 2 +- .../AbstractMethodCallInConstructor.java | 13 ++++++++ ...MethodCallInConstructorInspectionTest.java | 31 +++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/abstract_method_call_in_constructor/AbstractMethodCallInConstructor.java create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/initialization/AbstractMethodCallInConstructorInspectionTest.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/MethodCallUtils.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/MethodCallUtils.java index 35da41e6d8c5..66e29475b579 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/MethodCallUtils.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/psiutils/MethodCallUtils.java @@ -150,7 +150,7 @@ public class MethodCallUtils { } public static boolean isCallDuringObjectConstruction(PsiMethodCallExpression expression) { - final PsiMember member = PsiTreeUtil.getParentOfType(expression, PsiMethod.class, PsiClassInitializer.class, PsiField.class); + final PsiMember member = PsiTreeUtil.getParentOfType(expression, PsiMember.class, true, PsiClass.class, PsiLambdaExpression.class); if (member == null) { return false; } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/abstract_method_call_in_constructor/AbstractMethodCallInConstructor.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/abstract_method_call_in_constructor/AbstractMethodCallInConstructor.java new file mode 100644 index 000000000000..88ad0be72eda --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/initialization/abstract_method_call_in_constructor/AbstractMethodCallInConstructor.java @@ -0,0 +1,13 @@ +abstract class A { + public A() { + Runnable r = () -> foo(); + Runnable r1 = new Runnable() { + public void run() { + foo(); + } + }; + + } + + abstract void foo(); +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/initialization/AbstractMethodCallInConstructorInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/initialization/AbstractMethodCallInConstructorInspectionTest.java new file mode 100644 index 000000000000..26c16148c326 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/initialization/AbstractMethodCallInConstructorInspectionTest.java @@ -0,0 +1,31 @@ +/* + * 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.siyeh.ig.initialization; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.siyeh.ig.LightInspectionTestCase; + +public class AbstractMethodCallInConstructorInspectionTest extends LightInspectionTestCase { + + public void testAbstractMethodCallInConstructor() { + doTest(); + } + + @Override + protected InspectionProfileEntry getInspection() { + return new AbstractMethodCallInConstructorInspection(); + } +} From fd89d8fd49fd9b2511a340f110944696184be85f Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Tue, 12 Apr 2016 16:46:11 +0200 Subject: [PATCH 29/64] erase types to avoid red code caused by kotlin --- .../src/org/jetbrains/debugger/VariablesHost.java | 2 +- .../xdebugger/impl/breakpoints/XBreakpointUtil.java | 10 +++++----- .../impl/breakpoints/XLineBreakpointManager.java | 6 ++++-- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/VariablesHost.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/VariablesHost.java index a0f189409166..746016d690cf 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/VariablesHost.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/VariablesHost.java @@ -34,7 +34,7 @@ public abstract class VariablesHost { @NotNull @Override - public Promise> load(@NotNull VariablesHost host) { + public Promise load(@NotNull VariablesHost host) { return host.valueManager.isObsolete() ? ValueManager.Companion.reject() : host.load(); } }; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointUtil.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointUtil.java index f1c6d7a35144..9e70f0f94202 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointUtil.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointUtil.java @@ -133,11 +133,11 @@ public class XBreakpointUtil { * - if folded, checks if line breakpoints could be toggled inside folded text */ @NotNull - public static Promise toggleLineBreakpoint(@NotNull Project project, - @NotNull XSourcePosition position, - @Nullable Editor editor, - boolean temporary, - boolean moveCarret) { + public static Promise toggleLineBreakpoint(@NotNull Project project, + @NotNull XSourcePosition position, + @Nullable Editor editor, + boolean temporary, + boolean moveCarret) { int lineStart = position.getLine(); VirtualFile file = position.getFile(); // for folded text check each line and find out type with the biggest priority diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java index dcbaf0d6b44a..e889d6c4ad71 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointManager.java @@ -52,10 +52,12 @@ import com.intellij.util.ui.update.Update; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.breakpoints.SuspendPolicy; import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XLineBreakpoint; import com.intellij.xdebugger.impl.XSourcePositionImpl; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import gnu.trove.TIntHashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.concurrency.Promise; import java.awt.event.MouseEvent; import java.util.Collection; @@ -280,8 +282,8 @@ public class XLineBreakpointManager { if (line >= 0 && line < document.getLineCount() && file != null) { ActionManagerEx.getInstanceEx().fireBeforeActionPerformed(IdeActions.ACTION_TOGGLE_LINE_BREAKPOINT, e.getMouseEvent()); - XBreakpointUtil - .toggleLineBreakpoint(myProject, XSourcePositionImpl.create(file, line), editor, mouseEvent.isAltDown(), false) + final Promise lineBreakpoint = XBreakpointUtil.toggleLineBreakpoint(myProject, XSourcePositionImpl.create(file, line), editor, mouseEvent.isAltDown(), false); + lineBreakpoint .done(breakpoint -> { if (!mouseEvent.isAltDown() && mouseEvent.isShiftDown() && breakpoint != null) { breakpoint.setSuspendPolicy(SuspendPolicy.NONE); From 0dd323adc8b785ada50fdea40c5d601db085a6bb Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Tue, 12 Apr 2016 17:48:49 +0300 Subject: [PATCH 30/64] make sure correct new font size is advertized in font-changed editor event --- .../src/com/intellij/openapi/editor/impl/EditorImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index b355a31e636e..529699f4b361 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -1080,7 +1080,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi * @param fontSize new font size * @param zoomCenter zoom point, relative to viewport */ - private void setFontSize(final int fontSize, @Nullable Point zoomCenter) { + private void setFontSize(int fontSize, @Nullable Point zoomCenter) { int oldFontSize = myScheme.getEditorFontSize(); Rectangle visibleArea = myScrollingModel.getVisibleArea(); @@ -1091,6 +1091,7 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi int intraLineOffset = zoomCenterAbsolute.y % oldLineHeight; myScheme.setEditorFontSize(fontSize); + fontSize = myScheme.getEditorFontSize(); // resulting font size might be different due to applied min/max limits myPropertyChangeSupport.firePropertyChange(PROP_FONT_SIZE, oldFontSize, fontSize); // Update vertical scroll bar bounds if necessary (we had a problem that use increased editor font size and it was not possible // to scroll to the bottom of the document). From 498b0d6d3d7a789b19046060eceba6f43d4d82b6 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 12 Apr 2016 16:52:40 +0200 Subject: [PATCH 31/64] EA-79407 (ISE: CvsContentRevision.getRevisionNumber) --- .../changeBrowser/CvsContentRevision.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/CvsContentRevision.java b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/CvsContentRevision.java index a329c60cd6b4..d1403b0851a1 100644 --- a/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/CvsContentRevision.java +++ b/plugins/cvs/cvs-plugin/src/com/intellij/cvsSupport2/changeBrowser/CvsContentRevision.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -29,6 +29,7 @@ import com.intellij.cvsSupport2.cvsExecution.CvsOperationExecutorCallback; import com.intellij.cvsSupport2.cvshandlers.CommandCvsHandler; import com.intellij.cvsSupport2.cvsoperations.cvsContent.GetFileContentOperation; import com.intellij.cvsSupport2.cvsoperations.dateOrRevision.RevisionOrDate; +import com.intellij.cvsSupport2.history.CvsRevisionNumber; import com.intellij.openapi.cvsIntegration.CvsResult; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; @@ -65,6 +66,7 @@ public class CvsContentRevision implements ByteBackedContentRevision { myProject = project; } + @Override @Nullable public String getContent() throws VcsException { byte[] content = getContentAsBytes(); @@ -96,14 +98,20 @@ public class CvsContentRevision implements ByteBackedContentRevision { return myContent; } + @Override @NotNull public FilePath getFile() { return myLocalFile; } + @Override @NotNull public VcsRevisionNumber getRevisionNumber() { - return myRevision.getCvsRevisionNumber(); + final CvsRevisionNumber cvsRevisionNumber = myRevision.getCvsRevisionNumber(); + if (cvsRevisionNumber == null) { + return VcsRevisionNumber.NULL; + } + return cvsRevisionNumber; } @Override @NonNls From 42a880fdfa66771158edba89b6bae51cf9124e90 Mon Sep 17 00:00:00 2001 From: Dmitry Trofimov Date: Tue, 12 Apr 2016 17:05:10 +0200 Subject: [PATCH 32/64] Fix cmd line processing according to IDEA-CR-9232 --- lib/pty4j-0.6.jar | Bin 58005 -> 57988 bytes lib/src/pty4j-0.6-src.jar | Bin 37172 -> 37154 bytes .../execution/PtyCommandLineTest.java | 15 --------------- 3 files changed, 15 deletions(-) diff --git a/lib/pty4j-0.6.jar b/lib/pty4j-0.6.jar index 7b3f5f2d9d6d784e4debe1a1a585b6151c1fbc99..af105c2ff1ef82f7ba22aaab0ac9d09222aead8b 100644 GIT binary patch delta 2859 zcmY+Gc{o&k8^?zsV_(NE*^_;b$I{rdPNA`cN28%^AsSm#mPnQ|gS>WGl6|QsB>Pg9 z7?Z7;Fp^}Qw2)D+bGqK^y`J;O`JC_fci-Rp{QkSM2cU@qP!6Oml!*-jfk7ZQQXX(9 zGDfC6&}(Eo`d*VidgFN+lmHkrXaNXk&;U@$p!vs?!iPk|{uOc5Ac0qA4$<47Z<2rk zuUC~k2A)TzaawNq>_|n!Wy-_(Hq**YsWWhzb7`s{Y&P(Jxwy!)T{*_03^tmnlzg_JR@8QJ^XH5cSd zF>~P%w%0n$3+&SI+xPlBs9VuIdOOctZ}N0=59~@HZlaX8_ZR8d-~9cVJ7{J-=-yeL zm>s9k11)9~)DAoA{gMpfI~Y#Cto;``xje%-RlBu8#TbO?JO9_C-&Z!05`=z!jF1T$ zUp*jqAXwAql6YlMjS7Lbwivk$uY~=t*O~K`ZjhVp0xVPwqov&JzOP}tbruFUda*tA z>WzN((Ck>kS4ko##aMa?xsg_5h}Xs(U>n3*5+bY}oiObRa>IQXcYNa&XT8=Y)9<(f zOrb;3$bCLh9j8~LzC_|cn>k@qzi{bY6K2%G4P!I1%8Hb-)xABiMBqCJCtYOEy2*j{w4hGyqt>SRmp!7(Y z20;#wH&^k|UJ5^@`qVdl?>1GK?mxkCa3=bfJa+p|v$^j1?Go9OyV#r(Mr=0NAND^c zNlanN9Jhx`MDD{j73Ur?8{wywp9t6b1yc42!a38aU)2>>Ab0mX)g#cS^N%-UEW`+5 z{dIcTmxn*>=E*MUe2N+zzg7~Brbxez8pGUC_&P#b;HyzbmT|EyzoxT|8o29o#So}M*L&IOS!zuX6KUSBm>zlD!Zj;u5kzwHBTcHp#uUNuF|rx8FDS| z?&>`5+TZPtm9{h)a$m$%{8g-?xm>bUJLG(r>fWuQB;qHnP&D&I8XEyPsCMl9-jtoY9_DesEqytHFoG!rKCRi_=l3l*o+r`Lv7U+ptGD(;;yejvJhx5(-~F1qiFrXjcW&LaE8 zgjhz8(lR)dEO9+gBgJgo&qao783s?K+#^R7P=qx4)r_0|O7#&n_y}2!9SF7h%=DXX zh}sqW#=hJUe!q5k_z?|n-Eq6A#|YG_E> zDft2pp%D?)9IcDK0(bs=8)q-w!m_vR6Sz$Kk3Db8a@=0pbKS<@oO`#;e$e~HQy`}A zB^3HA!vp7Ur)^(uo_gqqT+!0C^4G(ltZ&6y*8mb#iTWk zbnttE4;KOJsw>z&8mqi;8InKOBpRh=6(fa6yDWE%|Na-Tm%RF(M#_FS$iGmj0S zDpjOLi{TwCm_sF;T9=o8)jU*<=r0LBrrV*vu+#>%@Jih1L`8OQtJ@izaL#Qb7@mFc z%O=&FYW`U?QQGovzo5)wshpOKEWzBSiwvCQxUuT}hGntfv6g7rA%a!AH}pe3{EVTT zL=En(6wTNzo`fPU$&^pK>$oS0de0SyE6-OYCz9@Zbix?mAn*Y45PZK*g-O z3WE66ALKg?hhAEdM!j1Dj=w#oXQ<`v-Q9w71-r9}%)j_!+QdIVs#}y{KGjd+U#d%(`x5mBn%GCYDs){x7@&gf9n_q)8}93Jk@3T4W-ZUzIOO(xvzY;^rXZT z-=l~o-^wn5+*<*a9nUQ5TLwd%6BUrek3Ogroe>cw?Eb<%C;dGWq%8xZ0Q7(B82-zo z{?R^$S0RQSEeiNjqAq|r;$Hv+r_2C&Od$XiO_>6q{xRo>;&?NXB;fdxi~*FBtO0D1 zECJ}g1$$%OIs$6+tt$Ze>GJ@hr$KXM8VM+g8FK*W89M+?GtK~5W}N_BoV5i|J$nuS zef9zX=Q*&wVh;WPor{4Yh?k$Y0gl7wT>!kAcLN~%?h=5McVHgnoe!YSkij82WHg`- z$QS@<3fR|9u>cgqdoaxYJ$R|y_u%C1Kd@Q=+Y1-$fy#{qu+MA}EXiL4e|2jSEHPgK a$L1}8VJk~cod4RY@D@~?V^fomqvyYL$VKx2 delta 2877 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 H00000hSnZh delta 1161 zcmV;41a|wPq5`y{0t`?~0|W{H00;m8Gk=i`DFQNou{RQClR8xpvsq@n91$#jj7WVV z(sl;~000CJ001PDA9op(K!Xy0<2De!>sL&CSj$0Hae$s`xX5mj1zMnW&;(r+%^nzu zwwaYkfu!uXUH|tE^)e|@cJ{EmSRrS=d4FVb5`QHt3bDwdTnJ60lCK#u3W=mB7_j-5t8q-`e!TrbgQp8j#&*5i(#vjTf2__yUQN;}T?Rb1gaDTN#suJG-U zQKypuqjh~tb4g=VOe&OrDtIUC5H%QI{qx0CCnG$$fOd!S4U>XrlP6OED9K6@*S;vsyfZpAK?o!&`p+n zkgK+9yj|h=*>90De!yvn*AUv|1+-h6((Td(%kyw_BZ@TPV-$wQ<}3 zuDn^-3mi7d652bd+m3OKok|j~w$;Y(uV%gDy|c5oD@#*F-{Ai7B9!vIBJAzqak<5A z&h7-MVMd9we_= zv#cU~Wzg5fvNQm{%wY=OzJaymRivY>e7bL| z?Gco{H4WW=3&*GpTs1Bm)C|zHHdB8VoR>OT@^=n&e%~;}%*l9xz@amv^;?}F9<3*az;PUcual1Ha#km4ng7zP3 zcnaUXs+ybV7<%t9`yJpGBm2R7kKbe9<}TS1rauXPX(gU(lq_<5_xdVOQs)e2(Bn!3 zGtG8`Hz6{duL0eeF!azWoSD}2kwfz;s|AO~%B;t=xfmmrQksWX)9G~R5*kc~JuC-T zoRgEGHDT4#zPPLxQkv2gNh{AE@NT5mi|G%c0c(-rzb#k{*ik+5zLu;Ml}6t<;R#h* zie2a#o#!|eiXPZ#AN&tcO928D0}22D2mk;xf0I#%IRY|&vy6vd2a_L;5VQM^%K;87 bevC+cBGPsT1ONa850li8NCs7h00000uGcKL diff --git a/platform/platform-tests/testSrc/com/intellij/execution/PtyCommandLineTest.java b/platform/platform-tests/testSrc/com/intellij/execution/PtyCommandLineTest.java index 48451ba92aef..d3cb2bc5ae0c 100644 --- a/platform/platform-tests/testSrc/com/intellij/execution/PtyCommandLineTest.java +++ b/platform/platform-tests/testSrc/com/intellij/execution/PtyCommandLineTest.java @@ -36,19 +36,4 @@ public class PtyCommandLineTest extends GeneralCommandLineTest { return cmd; } - - @Override - public void passingArgumentsToJavaApp() { - assumeFalse(SystemInfo.isWindows); - } - - @Override - public void passingArgumentsToJavaAppThroughWinShell() { - assumeFalse(SystemInfo.isWindows); - } - - @Override - public void passingArgumentsToJavaAppThroughCmdScriptAndWinShell() { - assumeFalse(SystemInfo.isWindows); - } } \ No newline at end of file From fb584669bbda9bfd6fbf1e5fa4bef849838012f1 Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Tue, 12 Apr 2016 18:04:49 +0300 Subject: [PATCH 33/64] IDEA-153807 Welcome screen notifications --- .../src/ide/notification/errorEvents.png | Bin 241 -> 467 bytes .../src/ide/notification/errorEvents@2x.png | Bin 425 -> 918 bytes .../ide/notification/errorEvents@2x_dark.png | Bin 0 -> 392 bytes .../src/ide/notification/errorEvents_dark.png | Bin 0 -> 221 bytes .../icons/src/ide/notification/infoEvents.png | Bin 241 -> 461 bytes .../src/ide/notification/infoEvents@2x.png | Bin 425 -> 928 bytes .../ide/notification/infoEvents@2x_dark.png | Bin 0 -> 392 bytes .../src/ide/notification/infoEvents_dark.png | Bin 0 -> 221 bytes .../icons/src/ide/notification/noEvents.png | Bin 308 -> 292 bytes .../src/ide/notification/noEvents@2x.png | Bin 606 -> 548 bytes .../src/ide/notification/noEvents@2x_dark.png | Bin 0 -> 547 bytes .../src/ide/notification/noEvents_dark.png | Bin 0 -> 290 bytes .../src/ide/notification/warningEvents.png | Bin 241 -> 477 bytes .../src/ide/notification/warningEvents@2x.png | Bin 425 -> 919 bytes .../notification/warningEvents@2x_dark.png | Bin 0 -> 949 bytes .../ide/notification/warningEvents_dark.png | Bin 0 -> 220 bytes .../impl/IdeNotificationArea.java | 37 ++++++++---------- .../impl/actions/NotificationTestAction.java | 20 +++++++++- .../impl/ui/NotificationsUtil.java | 18 ++++----- .../openapi/wm/impl/ToolWindowImpl.java | 7 +++- 20 files changed, 48 insertions(+), 34 deletions(-) create mode 100644 platform/icons/src/ide/notification/errorEvents@2x_dark.png create mode 100644 platform/icons/src/ide/notification/errorEvents_dark.png create mode 100644 platform/icons/src/ide/notification/infoEvents@2x_dark.png create mode 100644 platform/icons/src/ide/notification/infoEvents_dark.png create mode 100644 platform/icons/src/ide/notification/noEvents@2x_dark.png create mode 100644 platform/icons/src/ide/notification/noEvents_dark.png create mode 100644 platform/icons/src/ide/notification/warningEvents@2x_dark.png create mode 100644 platform/icons/src/ide/notification/warningEvents_dark.png diff --git a/platform/icons/src/ide/notification/errorEvents.png b/platform/icons/src/ide/notification/errorEvents.png index 8fe04b8971c0acb0e9dc0b7f82de9450bf5976ba..d271acd2e6e4986d66efe17823c62d8261d7f43e 100644 GIT binary patch delta 442 zcmV;r0Y(1t0n-DJBYy#!Nkl$3aia{gc{}*B7LPFRY(b&EoKu5s@SiDT8y56f-)zwrCid2#%swj4< zg&g#F;2Z&u^Yda*BA%}WmE|AeQ`n_%M%+iOh&usvfDin?Ab);=bET>{=6JDR0(Fp) zphI#L=mBgTAjBGBR~N-Lv?7EcAtCl3@vjJ+e4-uuupL5hX%ezl1g_uUVnG!^Fg}ey ztM7tgcBeyu_KX70g+O0`%_2|=N-XEMsxxR$JA;~HXZd|=H{%u5TZm6xJs`5IPdH0^ z%<3L2V-F^)j(@zG4C_7%19|bmY5Ly87+2;(%`ujn19BteV3mLk0z#UTlcJGm@D_Af zjwpnBT!;g$sb4r$d*+p^L6MaqkoD}<@1-r>t!V!Z delta 214 zcmV;{04e{|1MvZnBYyz6Nkl^!vzy@#w@jVhW!!XEO+#mxA$j}VK1t0@XQeeO- zkOAK*FyIHsfFBeX@R3q4oTM}m3t`cCpA60SV9`iULi&K5kWXM(0f-M1X}~ui=0rCD zmYF<}GShD${tCo*fcPhxAzs)Fz=tJ(xDkk-Lk*ZnssS*}2E@@oybQz#0EZxwS@S%O Q?f?J)07*qoM6N<$g5h#n1^@s6 diff --git a/platform/icons/src/ide/notification/errorEvents@2x.png b/platform/icons/src/ide/notification/errorEvents@2x.png index 7450904c5d576a8e42b47e6540f9416891998697..42d5517b0965a9b843b024287bb99ea23b9c0dad 100644 GIT binary patch delta 896 zcmV-`1AqLf1C|GnBYyxHbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU# zI7vi7RCwCNS3PJ{K@i^AdkP_iiK2+27zqXuZA1b|VG#l%M6gMMRu&P|R9d97Qcw$j zz(&$&BgVo)iP$8VLO~>rpr8pNScqDvAOw{bl4!7c#iJM34Gcn5zPb}D8063MJaB&l3=Vr>L(1L!$)X^wW*_2cVLVu+HO5}Qx`6-K87OhIL5nMsn0bB_btQ|!AJtn_Y2fRk|3>Ap_Fvle3 zdJgR(qIv`Zc)ov5i8K_;T8L!c@v7kD0J%L2?tfCS>=Q#|0g)I6i6Q7Wm$Nu=jSIH+ z>2t+2bsEWM!A&G2a+LhuV@hv9wJ9;lLlEhLo-d|6R}26SD3FS({Y%irqSJBscR0N7 zX#j~}xDoBeQG7NM64XUfC!;^Hk{c{^6OBXoVGoW`J-YX~4-;cHmaCjUqR8&Tzk-hf zPY-B=)ksQy57 zjzeeuiaR@>0t^74 WY$t%;z<^r-0000#OHzdH4y)T;@40ykX$ZQ zEm7tYQosbnQ9yhgi2sv_k3;n`k?R0UAihe5#pw7d)GVSMzzoFIK>V8umc#IGsF}=! z9Ka65o2Y0pI^G1e1FHi-uG>gM%VBsUa!4RMpq37n!*D&i1Anxk*@<2b0NJIB?0_wF zv>b-Fz#O0q#D53C0slaDgB(yX0G7jW1;_!r2G9Y!Kn{31fDU*Ha=?!Pbij{+cEI<6 zj)MCGoe0+rbT&)_IY13sDA3#TZ$Kx9g`DOazGcU4nXgkU8RZu diff --git a/platform/icons/src/ide/notification/errorEvents@2x_dark.png b/platform/icons/src/ide/notification/errorEvents@2x_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..dc0d8b8eb0c6ac77c765f077a3550794bb98afef GIT binary patch literal 392 zcmV;30eAk1P)D7d+*xK;cQ6mf7B(N#hb99=qCT!f;Fli(j94#iOf2R8=`f=dSxI_MyX zh&XhxlSokX{64tAQBvB&<{l28C4{^mxl8W7=w>61G)4a*z#!(Zi*wxJ4c~aj6Y8j9 z4P*TZFp3JEVLbfc5=(yxu!^Q<;Vf5}_6ab8lRgx7$uh;g1Q@oj&g4LrrPM9JQBK8E zvT0X31z60vc&deotN@Kb0mN~8fcb#M#TO>s0Q-Rhh%Gn3wL*XkH$YP%z^fY|Q3#M| z2l&)pf|m9sY-oRmRm~rfSl0X%OOG(1br^{$t>akKv>K9BMWZEi9fWR5+uhqXzvs5R zj0cYbvX2hC+*9%$OyrZ9!6r_f!Nh&&BX%%k@88BphX8VYHpFN)jy)SL>nvCZIU5$R mZa3i>Zt;Sm{%~rHQS}Q$dE=IhzTRj60000}1TTGTa=)mbF9>DM@ zO~H=qNPfc)eu4cgk7^xaxQ-m!!IQx9s7m1<>yiH-ACx=D^qp# zsh4TF2g}%liGQo>?VLzfbpi6Ca*-TuVu9ykAx`>D@*u0XObBTAOpcUxh`!%K0Lx)Q zXo%gHCSf%BMTc@`uB^Eh1Pq~8GLO--cwp-!Mx&MF&4N%6aL|VwA>Smmhr3d{ykW3Ml2|JSxYxOD)Pd$Pa5ro2!$N;kGw3w;e7< e2xJN!hUpV;+-A;nu3z5(0000^!vzy@#w@jVhW!!XEO+#mxA$j}VK1t0@XQeeO- zkOAK*FyIHsfFBeX@R3q4oTM}m3t`cCpA60SV9`iULi&K5kWXM(0f-M1X}~ui=0rCD zmYF<}GShD${tCo*fcPhxAzs)Fz=tJ(xDkk-Lk*ZnssS*}2E@@oybQz#07S%LS;+Dh Q(f|Me07*qoM6N<$f&e911poj5 diff --git a/platform/icons/src/ide/notification/infoEvents@2x.png b/platform/icons/src/ide/notification/infoEvents@2x.png index c9fb87e2400d06b48f41900dba79090a2a63d40f..fb467e8e03012fca47ec473e3c0f1efc83e7cf54 100644 GIT binary patch delta 907 zcmV;619beU1E2?xBYyxHbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU# zLPhY=J+(pU(ZAcCN%g$hEz+j-+RZ)W%QE`NI$4{!J7Uf%rN%=f)F zZ|CjF^Up7eW+L%tKirmb#k?`bH|)oVRwZl(Y5}Ekpw=b?qytO{7-w0@v_vM%0+)dU zQ-QJr7P=312-Ev8-UGV{+6i3-=y%w!z8;zgQxys}Kq6y|$oM0n~~98Q7DU z-qv7!3G*e`?SJ@gANDw5Bq%8+a*Z@S5tKTn3{i>K@G}SlRyqik@yx>VANk2zDr1} zL+%PUd=c#w1q;CU2wyuafwhH#3kF_qQUr?h+!ZKWEn))r_p3N?a%#-)xIigHDce$LvUGf=@0CWsvCO!_Egm&;LI@9eSu>#y5ulK%;{$i2~J_#MWh|Yq@ zoPSQ+3Lb|Wwwwk}E+S9jkB;;(bS8PDZGi|?pMUWTaKnWN-|0$&yCbN*B9{?~QII$a z{btBBr`k>Hz2>uxw7?pl=~U~v@N1ZvjfYK&#!moVmn3hXyB`bted*rqf0(RGW%&ne zc7Ge~Nqj#Nl0L%U3s}>^1dI>6;3!;0MShL`D<-wtZ^LE@CmJQ3Yi|arQ|KQ9=#Dtq z?Y!3d2cmNXIv=(joRS3l44uH}1o}N7HDKQZpxqen2AR9K4aUQqz(rlQFQK&*kBQVe hnO7b7SNSWz0056YeV@RghX4Qo07*qoL#OHzdH4y)T;@40ykX$ZQ zEm7tYQosbnQ9yhgi2sv_k3;n`k?R0UAihe5#pw7d)GVSMzzoFIK>V8umc#IGsF}=! z9Ka65o2Y0pI^G1e1FHi-uG>gM%VBsUa!4RMpq37n!*D&i1Anxk*@<2b0NJIB?0_wF zv>b-Fz#O0q#D53C0slaDgB(yX0G7jW1;_!r2G9Y!Kn{31fDU*Ha=?!Pbij{+cEI<6 zj)MCGoe0+rbT&)_IY13sDA3#TZ$Kx9g`DOazGcU4nXgk$mEZ$NieM>%g`I_hXk#U$&_WOi zk|KqvL_$Q@|G*wB;X<;Q+ri@39LLSa?cVK7w0*l5X^Q?sfMG16hzmU89pCuCEACOj zCME_IU>pV1U_AWb3faE|SVP0JaFQF$`2-ll=>Q75WSQ3c2{3A3ok@W#ORiUda!SQx zvT0Yl1z1kGc&v%3qyW`G0mMmXfK0&R;tSJmfWyE6#I76QP9eah8=#>Opza1}DFkR~ z2WV?AK~sAZR<%FFisp|`SiOyrZ9#}3Y%!Nh&&3l1=1@88E~mjH5oA;f4liINSMbQUayoDFBN mWjEnD9`J?@{o&LYqv{txwM2!gxYI}g0000}1pRf)&DM@ zO~H=qNPfc)eu4cgk7^xaxQ-m!!IQx9s7m1<>yiH-ACx=D^qp_A literal 0 HcmV?d00001 diff --git a/platform/icons/src/ide/notification/noEvents.png b/platform/icons/src/ide/notification/noEvents.png index 0cbeeed2a9fb06c34dfa092a44763238593f49fc..da816bfad5c796c396b966e806454688acb949c1 100644 GIT binary patch delta 265 zcmV+k0rvj10;B?vB!BBkL_t(|+G8jvC}5xjqYEeiaWfDf1>!eA{0E3%0`Wc|E(Ky? zTm~=#aXk?K0^%AVwt^~V24XQFb_C)sAbtnL;n)nA2*gu?Se$^9?Sc3o5N9A8-~_~b zftZy@f9nD9PaxKU8L$C}Lr4s~93WlR zU=j_80^+SO1Dt_)4+*gV!iRy_hMaT&!UjNm9$!kVMoNhwIes9nfF^NJ=&JznZKxis zd7%XxG}T~MEnYR&UA-Qf%?I6#m8#h7s_NYhf#rzUi f`yn=QAkPo5OA_ORv-?|_00000NkvXXu0mjf+Z%sd diff --git a/platform/icons/src/ide/notification/noEvents@2x.png b/platform/icons/src/ide/notification/noEvents@2x.png index 9ef60cceccdbe5a7422b7e21509f21e9292e325e..e6aea9da012bb2b6e033161936eab78f012df0ba 100644 GIT binary patch delta 524 zcmV+n0`vXe1f&FzBYy$wNkl=!*kn%S3;p8X;E zC^h>!mOr>}Wk&bV`6dO@}{R9Y$ z`H*N(!`zXSKg|lk48_Inlzta9n)x;?0sTzEEpQI*L9hD9sitX4`2-hBE4dIupOgRq O002ovP6b4+LSTZuYwA$| delta 582 zcmV-M0=fO91l|OYBYy%VNklAHiWPg`)lYeWV1{`StZ^1GM zf+~;=Qb{)Zf*f!8S3Y{!v^}!PufPZW<`%agtZns_>^V}y>v7Q_`{YK}-_i;Y%`2HL2( zC5;OR?M+CEv!j0KhqRz+I+e-p6G!B@Z+$4X!1yhhPB zM-x!bLGPf*hV8b*`JaIICjkKtn6PorhihvkQa}|uj%_}4d}5VzrGQy>%s6oJtufZH z6mZ1GY6k?gGS;pX5I%6S91!4Tta~Zom5m+;1b7(hRh57g#(Gngf(&sUC@I2H#tNv~ zhNFz-S8))z#SPh{;wbhDkC5Q>Wn@%;kTD9JzK-P&?mKBnB-7DSY{rtcnG9m2t_Spi zl8C+$&Nu&8Q+fs#*d8{ea(o@@M;Gp=QS_Iy{gO7{v@IV3*A^`KvT#2J8=#i+9kQ+8 z>chm?GG$Cl19`RKL%bze^40I7p{oyPqQ5D`wRWBQpR0S6o8Ho3g5DOrD7>I4iNe3Wo z0L16cN^9T9EPrD5SpwaXU1L{|4f2Af5%psn`r4 ogq47}1c-M4@nuk8GEkbG0YXQ$Lj{cl*#H0l07*qoM6N<$f-X^N)c^nh literal 0 HcmV?d00001 diff --git a/platform/icons/src/ide/notification/warningEvents.png b/platform/icons/src/ide/notification/warningEvents.png index 7a26967479337954b405db0bfd553043fc01167f..cc57f81d9406c9c4a3b5fe6f361d3bff61779c9f 100644 GIT binary patch delta 452 zcmV;#0XzQj0o?&^^eKAjy@q;jHeBOn<-Zk7NJ~c)@=T@g&YC z9uj(+6#FLdm{ddulBa+Qz<&WkTuvJ{iuvkA2th(Z=s)655jc58J7cwW2*IvK$n_#{ zU51MeC4gYK836%YFlIMb6UetHaA}*G65v(@?zV$$#r$dp`DSNOO6Y8x0Xx4jsBR(L ze07blqrPZv-G8h0pc{M8V08o4hq$omV~{(qBA(Ap42iM`iN&9m-(he$rE@W^aUteA z5c2t|o9N>$IItX35UODJl})s!zHq2|mdd4s27v%uQSb5Pn%i-<+)tk?DVqf$Colt7 z8NdP<@h1#y*533_-kAPsA?D?5WPmSLU8AQHq)$07*qoM6N<$f>f?l0RR91 diff --git a/platform/icons/src/ide/notification/warningEvents@2x.png b/platform/icons/src/ide/notification/warningEvents@2x.png index acd4f27c739e3e78b55b70936554914ad8c48bd8..4e6d79899a50106caa929a428c0e5e3552a56c2f 100644 GIT binary patch delta 897 zcmV-{1AhFe1D6MoBYyxHbVXQnQ*UN;cVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU# zIY~r8RCwCNS3PJ{K@i^E_aX!f6Gah4ArcHC+K32AArb;2M6gMM))CZHHrH7xXd?(V zk|t@ySXd|#EpnJb!6J=?pb0h>q833A4(`33^_%@UHsS8LyMNq0=a|gC*_ZvknVtQ4 za`Wvq(M+Udm9AZ<-vnz6RJ1K=Gf)OpO4?^7opt@v0y_NOa09ygjZ`hvz{cI9ZCNe9U%nw*kra1u_rXWO}Cei{U;sHG0 zg6lfEkG7gp#(xAb6M2|x^O{L8nMR@lIH$NTQC5+GDWv`jTzA_6_hU%}FrFrAxi6LP z5YPxuV?zQp@Kka1{doBq9+%K}Kgp5pXC!u`7U4KM-R`f{xbTHN;xE$U>z_0TM zqQ_!MByteJ-ix!qr7;G3S`;8|V-vjYkHkfISrjB(@BmC2SO9z~Ca~u}5ZD(JC=%G73$Ut20Q#p$aKf1l=)d7OXC_~Z01xU<$M3aO03IKT z0@sLMYk%S+d(F6WTPU!3*~wL^?Z^Sf;4TC7g2DNxaC>Bvgw4GT_bGXB; zxOLiHaF+$*MmYwrZA6|#HPbW+U9zcalSoK&BY$w|+JiB;or35#%L7!9iJ2@n(;)II z6iy&hj}ZH~y0ctc4dk~(Za-hFy@W3c75sI#Vjd7R@f<`(su|seUC%54*}>80s@W@p zR#`J^=kY&JG{tM)gTaTZ=LuXuZi*-avV~7G&fZy^;iG8q(S6c=n25d6?)D8}3uxcR z4SFlbdnJT&2VniEcj45%o99%4UI6irx)lPQ6r7tYa|rDl0KbZdWA@|C6VW+sB9m8; zsnw1MGy@MiT&Q-NZefPuA9MEr8bXZ>A#3~5UrKuk9##7W>_+Sh|0hka4uTftp8x{@ XPl7h`b+f?W00000NkvXXu0mjfx!{~E delta 400 zcmV;B0dM}72dM*)BYy#KNkl0J2LL*#TSV zXgLgTfjK}Ki2n|N1O9>R205T&04#^$3XlVK4WI*dfgJF303GlYFXIuWiL=xmqFLa&bN>F9v0foza~ zTF#94nq-@4Xn*-ZAZ8=fC}jcS9vbD0LQTnE$_&Qm9fCpkrPjS;kGf32eC*AH#V9W5#C*Xb#2t(XciRl6u&QKVU%>+*x4of); zo(>{U;x|YP#W7F0TCI?XkFYVgb~bfp!CeWm0~*f7ilq^hrKed5T(){{z9Kr0nO`kYR{zC#qc z-cp)=_;C8$gPri4O0oohlvB_jc;+Vb7CsyV^S-ck?+rgp)+aj}#_I>Nd>8grHje8@ zT)2e8Mw=hKA?@egHUAzQJYMU*Ge0J~J?K4k4XvU3a> zoLv=xJn&?~CEXr?yP^G1oCBx}CF(+7Z9-YbqE>=ux_trb0#|+M&o#}h+6ewp{s=Gt X3m7c;d~7=*00000NkvXXu0mjfd4sXt literal 0 HcmV?d00001 diff --git a/platform/icons/src/ide/notification/warningEvents_dark.png b/platform/icons/src/ide/notification/warningEvents_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..3b0a345f219bd922a049f3881b297adedaa93e27 GIT binary patch literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`i#=T&Ln>}1S8TBBY82|xTflJS ztV4}R$9;y6@(OjFM}9Z#5b0Np5K5VRonxJkt=KBK1Ke?La-3fvaAHd!|HAtK=lw+=DPNA^$T@jRNwpty$Rh^oUL<_>*k!_-L07DgA(u20NQ S#is+E%i!ti=d#Wzp$Pzua8BI- literal 0 HcmV?d00001 diff --git a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java index 021646b39ba6..79e434340247 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java @@ -23,16 +23,18 @@ import com.intellij.notification.EventLog; import com.intellij.notification.LogModel; import com.intellij.notification.Notification; import com.intellij.notification.NotificationType; +import com.intellij.notification.impl.ui.NotificationsUtil; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.wm.CustomStatusBarWidget; import com.intellij.openapi.wm.IconLikeCustomStatusBarWidget; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.ToolWindow; import com.intellij.ui.ClickListener; +import com.intellij.ui.JBColor; import com.intellij.ui.LayeredIcon; +import com.intellij.ui.SimpleColoredComponent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -125,15 +127,17 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget } private LayeredIcon createIconWithNotificationCount(ArrayList notifications) { + return createIconWithNotificationCount(this, getMaximumType(notifications), notifications.size()); + } + + @NotNull + public static LayeredIcon createIconWithNotificationCount(JComponent component, NotificationType type, int size) { LayeredIcon icon = new LayeredIcon(2); - NotificationType type = getMaximumType(notifications); - Icon statusIcon = getPendingNotificationsIcon(AllIcons.Ide.Notification.NoEvents, type); - icon.setIcon(statusIcon, 0); - int size = notifications.size(); + icon.setIcon(getPendingNotificationsIcon(AllIcons.Ide.Notification.NoEvents, type), 0); if (size > 0) { //noinspection UseJBColor - Color textColor = type == NotificationType.ERROR ? Color.white : Color.black; - icon.setIcon(new TextIcon(this, size < 10 ? String.valueOf(size) : "9+", textColor), 1); + Color textColor = type == NotificationType.ERROR ? new JBColor(Color.white, new Color(0xF2F2F2)) : new Color(0x333333); + icon.setIcon(new TextIcon(component, size < 10 ? String.valueOf(size) : "9+", textColor), 1); } return icon; } @@ -181,12 +185,14 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget private final JComponent myComponent; private final Color myTextColor; private final int myWidth; + private final Font myFont; public TextIcon(JComponent component, @NotNull String str, @NotNull Color textColor) { myStr = str; myComponent = component; myTextColor = textColor; - myWidth = myComponent.getFontMetrics(calcFont()).stringWidth(myStr); + myFont = new Font(NotificationsUtil.getFontName(), Font.BOLD, 9); + myWidth = myComponent.getFontMetrics(myFont).stringWidth(myStr) + 1; } @Override @@ -217,13 +223,10 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget Font originalFont = g.getFont(); Color originalColor = g.getColor(); - g.setFont(calcFont()); + g.setFont(myFont); x += (getIconWidth() - myWidth) / 2; - y += getIconHeight() / 2 + g.getFontMetrics().getDescent(); - if (!SystemInfo.isLinux && myStr.length() > 1) { - x++; - } + y += SimpleColoredComponent.getTextBaseLine(g.getFontMetrics(), getIconHeight()); g.setColor(myTextColor); g.drawString(myStr, x, y); @@ -232,14 +235,6 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget g.setColor(originalColor); } - private Font calcFont() { - float size = (float)getIconHeight() * 3 / 5; - if (myStr.length() > 1) { - size--; - } - return myComponent.getFont().deriveFont(size); - } - @Override public int getIconWidth() { return AllIcons.Ide.Notification.NoEvents.getIconWidth(); diff --git a/platform/platform-impl/src/com/intellij/notification/impl/actions/NotificationTestAction.java b/platform/platform-impl/src/com/intellij/notification/impl/actions/NotificationTestAction.java index 5a44d0a1a731..95fae4f3f789 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/actions/NotificationTestAction.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/actions/NotificationTestAction.java @@ -175,6 +175,9 @@ public class NotificationTestAction extends AnAction implements DumbAware { notification.setActions(StringUtil.split(value, ",")); } } + else if (line.startsWith("Type:")) { + notification.setType(StringUtil.substringAfter(line, ":")); + } else if (line.startsWith("Sticky:")) { notification.setSticky("true".equals(StringUtil.substringAfter(line, ":"))); } @@ -200,6 +203,7 @@ public class NotificationTestAction extends AnAction implements DumbAware { private String mySubtitle; private List myContent; private List myActions; + private NotificationType myType = NotificationType.INFORMATION; private boolean mySticky; private boolean myAddListener; @@ -218,10 +222,10 @@ public class NotificationTestAction extends AnAction implements DumbAware { String content = myContent == null ? "" : StringUtil.join(myContent, "\n"); if (icon == null) { myNotification = - new Notification(displayId, StringUtil.notNullize(myTitle), content, NotificationType.INFORMATION, getListener()); + new Notification(displayId, StringUtil.notNullize(myTitle), content, myType, getListener()); } else { - myNotification = new Notification(displayId, icon, myTitle, mySubtitle, content, NotificationType.INFORMATION, getListener()); + myNotification = new Notification(displayId, icon, myTitle, mySubtitle, content, myType, getListener()); if (myActions != null) { for (String action : myActions) { myNotification.addAction(new MyAnAction(action)); @@ -268,6 +272,18 @@ public class NotificationTestAction extends AnAction implements DumbAware { mySticky = sticky; } + public void setType(@Nullable String type) { + if ("info".equals(type)) { + myType = NotificationType.INFORMATION; + } + else if ("error".equals(type)) { + myType = NotificationType.ERROR; + } + else if ("warn".equals(type)) { + myType = NotificationType.WARNING; + } + } + @Override public void hyperlinkUpdate(@NotNull Notification notification, @NotNull HyperlinkEvent event) { if (MessageDialogBuilder.yesNo("Notification Listener", event.getDescription() + " Expire?").is()) { diff --git a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java index 1a3f8698f3ce..ad2a40882e31 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/ui/NotificationsUtil.java @@ -124,18 +124,18 @@ public class NotificationsUtil { @Nullable public static String getFontStyle() { - String fontName = null; + String fontName = getFontName(); + return StringUtil.isEmpty(fontName) ? null : "font-family:" + fontName + ";"; + } + + @Nullable + public static String getFontName() { UISettings uiSettings = UISettings.getInstance(); if (uiSettings.OVERRIDE_NONIDEA_LAF_FONTS) { - fontName = uiSettings.FONT_FACE; + return uiSettings.FONT_FACE; } - else { - Pair systemFontData = UIUtil.getSystemFontData(); - if (systemFontData != null) { - fontName = systemFontData.first; - } - } - return StringUtil.isEmpty(fontName) ? null : "font-family:" + fontName + ";"; + Pair systemFontData = UIUtil.getSystemFontData(); + return systemFontData == null ? null : systemFontData.first; } @Nullable diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java index 63287d96a8dc..c579afd0d46c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/ToolWindowImpl.java @@ -18,6 +18,7 @@ package com.intellij.openapi.wm.impl; import com.intellij.ide.UiActivity; import com.intellij.ide.UiActivityMonitor; import com.intellij.ide.impl.ContentManagerWatcher; +import com.intellij.notification.EventLog; import com.intellij.openapi.actionSystem.ActionGroup; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.application.ApplicationManager; @@ -393,8 +394,10 @@ public final class ToolWindowImpl implements ToolWindowEx { public final void setIcon(final Icon icon) { ApplicationManager.getApplication().assertIsDispatchThread(); final Icon oldIcon = getIcon(); - if (oldIcon != icon && icon != null && !(icon instanceof LayeredIcon) && (icon.getIconHeight() != JBUI.scale(13) || icon.getIconWidth() != JBUI.scale(13))) { - LOG.warn("ToolWindow icons should be 13x13. Please fix ToolWindow (ID: " + getId() + ") or icon " + icon); + if (!EventLog.LOG_TOOL_WINDOW_ID.equals(getId())) { + if (oldIcon != icon && icon != null && !(icon instanceof LayeredIcon) && (icon.getIconHeight() != JBUI.scale(13) || icon.getIconWidth() != JBUI.scale(13))) { + LOG.warn("ToolWindow icons should be 13x13. Please fix ToolWindow (ID: " + getId() + ") or icon " + icon); + } } //getSelectedContent().setIcon(icon); myIcon = icon; From ce793e41f0934267c7f137e590c2c51dd51783ee Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Tue, 12 Apr 2016 18:42:30 +0300 Subject: [PATCH 34/64] [vcs-log] minor: rename GraphCommitCellRender -> GraphCommitCellRenderer --- .../intellij/vcs/log/ui/frame/VcsLogGraphTable.java | 6 +++--- ...mitCellRender.java => GraphCommitCellRenderer.java} | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) rename platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/{GraphCommitCellRender.java => GraphCommitCellRenderer.java} (96%) diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java index f2b582be401e..f07f73083965 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/frame/VcsLogGraphTable.java @@ -55,7 +55,7 @@ import com.intellij.vcs.log.ui.VcsLogColorManager; import com.intellij.vcs.log.ui.VcsLogColorManagerImpl; import com.intellij.vcs.log.ui.VcsLogUiImpl; import com.intellij.vcs.log.ui.render.GraphCommitCell; -import com.intellij.vcs.log.ui.render.GraphCommitCellRender; +import com.intellij.vcs.log.ui.render.GraphCommitCellRenderer; import com.intellij.vcs.log.ui.tables.GraphTableModel; import com.intellij.vcs.log.util.VcsUserUtil; import gnu.trove.TIntHashSet; @@ -92,7 +92,7 @@ public class VcsLogGraphTable extends JBTable implements DataProvider, CopyProvi @NotNull private final VcsLogDataManager myLogDataManager; @NotNull private final MyDummyTableCellEditor myDummyEditor = new MyDummyTableCellEditor(); @NotNull private final TableCellRenderer myDummyRenderer = new DefaultTableCellRenderer(); - @NotNull private final GraphCommitCellRender myGraphCommitCellRenderer; + @NotNull private final GraphCommitCellRenderer myGraphCommitCellRenderer; private boolean myColumnsSizeInitialized = false; @Nullable private Selection mySelection = null; @@ -109,7 +109,7 @@ public class VcsLogGraphTable extends JBTable implements DataProvider, CopyProvi super(new GraphTableModel(initialDataPack, logDataManager, ui)); myUi = ui; myLogDataManager = logDataManager; - myGraphCommitCellRenderer = new GraphCommitCellRender(logDataManager, myGraphCellPainter, this); + myGraphCommitCellRenderer = new GraphCommitCellRenderer(logDataManager, myGraphCellPainter, this); setDefaultRenderer(VirtualFile.class, new RootCellRenderer(myUi)); setDefaultRenderer(GraphCommitCell.class, myGraphCommitCellRenderer); diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java similarity index 96% rename from platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java rename to platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java index cfe770837ec1..b9c53dd5ce63 100644 --- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRender.java +++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/render/GraphCommitCellRenderer.java @@ -24,9 +24,9 @@ import java.util.Collections; import java.util.List; import java.util.Map; -public class GraphCommitCellRender extends ColoredTableCellRenderer { +public class GraphCommitCellRenderer extends ColoredTableCellRenderer { - private static final Logger LOG = Logger.getInstance(GraphCommitCellRender.class); + private static final Logger LOG = Logger.getInstance(GraphCommitCellRenderer.class); @NotNull private final VcsLogDataManager myDataManager; @NotNull private final GraphCellPainter myPainter; @@ -39,9 +39,9 @@ public class GraphCommitCellRender extends ColoredTableCellRenderer { @NotNull private Font myFont; private int myHeight; - public GraphCommitCellRender(@NotNull VcsLogDataManager dataManager, - @NotNull GraphCellPainter painter, - @NotNull VcsLogGraphTable table) { + public GraphCommitCellRenderer(@NotNull VcsLogDataManager dataManager, + @NotNull GraphCellPainter painter, + @NotNull VcsLogGraphTable table) { myDataManager = dataManager; myPainter = painter; myGraphTable = table; From 978ba17c85ca1ce77b29cdbd7e4d4f00d230a8e5 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Tue, 12 Apr 2016 18:53:14 +0300 Subject: [PATCH 35/64] do not highlight errors in return statements in debugger code fragments --- .../engine/evaluation/DefaultCodeFragmentFactory.java | 2 ++ .../codeInsight/daemon/impl/analysis/HighlightUtil.java | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java index 830ecbb70a63..a69cd899f960 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java @@ -18,6 +18,7 @@ package com.intellij.debugger.engine.evaluation; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionService; import com.intellij.codeInsight.completion.JavaCompletionUtil; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.codeinsight.RuntimeTypeEvaluator; import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder; @@ -75,6 +76,7 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory { fragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE); //noinspection HardCodedStringLiteral fragment.putUserData(KEY, "DebuggerComboBoxEditor.IS_DEBUGGER_EDITOR"); + fragment.putUserData(HighlightUtil.DISABLE_RETURN_CHECK_IN_CODE_FRAGMENT, true); fragment.putCopyableUserData(JavaCompletionUtil.DYNAMIC_TYPE_EVALUATOR, new PairFunction() { public PsiType fun(PsiExpression expression, CompletionParameters parameters) { if (!RuntimeTypeEvaluator.isSubtypeable(expression)) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index c061dba79582..0cda6140d70e 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -87,6 +87,8 @@ public class HighlightUtil extends HighlightUtilBase { @NonNls private static final String SERIAL_PERSISTENT_FIELDS_FIELD_NAME = "serialPersistentFields"; private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance(); + public static final Key DISABLE_RETURN_CHECK_IN_CODE_FRAGMENT = Key.create("DISABLE_RETURN_CHECK_IN_CODE_FRAGMENT"); + private HighlightUtil() { } static { @@ -594,6 +596,9 @@ public class HighlightUtil extends HighlightUtilBase { } parent = parent.getParent(); } + if (parent instanceof PsiCodeFragment && parent.getUserData(DISABLE_RETURN_CHECK_IN_CODE_FRAGMENT) != null) { + return null; + } String description; HighlightInfo errorResult = null; if (method == null && lambda != null) { From 04fd0905dd7740c4ce40b3700e23f094d42e7e2e Mon Sep 17 00:00:00 2001 From: Dmitry Avdeev Date: Tue, 12 Apr 2016 20:01:46 +0300 Subject: [PATCH 36/64] property used from Android restored --- resources-en/src/messages/QuickFixBundle.properties | 1 + 1 file changed, 1 insertion(+) diff --git a/resources-en/src/messages/QuickFixBundle.properties b/resources-en/src/messages/QuickFixBundle.properties index 10115b7fd7b2..091b95496c7e 100644 --- a/resources-en/src/messages/QuickFixBundle.properties +++ b/resources-en/src/messages/QuickFixBundle.properties @@ -223,6 +223,7 @@ orderEntry.fix.add.library.to.classpath=Add library ''{0}'' to classpath orderEntry.fix.family.add.library.to.classpath=Add library to classpath orderEntry.fix.circular.dependency.warning=Adding dependency on module ''{0}'' will introduce circular dependency between modules ''{1}'' and ''{2}''.\nAdd dependency anyway? orderEntry.fix.title.circular.dependency.warning=Circular Dependency Warning +orderEntry.fix.add.junit.jar.to.classpath=Add JUnit to classpath static.import.method.text=Static import method static.import.method.choose.method.to.import=Choose Method to Import From c01c7bafa4056f8baf04c2d4018da90f7021b2d7 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 12 Apr 2016 19:13:53 +0200 Subject: [PATCH 37/64] + withBackground(Color) --- platform/util/src/com/intellij/ui/components/JBPanel.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/platform/util/src/com/intellij/ui/components/JBPanel.java b/platform/util/src/com/intellij/ui/components/JBPanel.java index fb0101033965..fc6b6fee1860 100644 --- a/platform/util/src/com/intellij/ui/components/JBPanel.java +++ b/platform/util/src/com/intellij/ui/components/JBPanel.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -18,6 +18,7 @@ package com.intellij.ui.components; import com.intellij.util.ui.JBFont; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.components.JBComponent; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.border.Border; @@ -75,6 +76,11 @@ public class JBPanel extends JPanel implements JBComponent return (T)this; } + public T withBackground(@Nullable Color background) { + setBackground(background); + return (T)this; + } + public T withPreferredWidth(int width) { myPreferredWidth = width; return (T)this; From a17661e973a52ba2efef9a38771e571234962fe9 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Tue, 12 Apr 2016 19:23:35 +0200 Subject: [PATCH 38/64] cleanup --- .../ide/actions/SearchEverywhereAction.java | 71 +++++++++---------- 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index c133972de151..eb0d172a52a5 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -162,7 +162,6 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA private Map myConfigurables = new HashMap(); private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, ApplicationManager.getApplication()); - private Alarm myUpdateAlarm = new Alarm(ApplicationManager.getApplication()); private JBList myList; private JCheckBox myNonProjectCheckBox; private AnActionEvent myActionEvent; @@ -932,33 +931,36 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA final Object value = myList.getSelectedValue(); if (CommonDataKeys.PSI_ELEMENT.is(dataId) && value instanceof PsiElement) { return value; - } else if (CommonDataKeys.VIRTUAL_FILE.is(dataId) && value instanceof VirtualFile) { + } + if (CommonDataKeys.VIRTUAL_FILE.is(dataId) && value instanceof VirtualFile) { return value; - } else if (CommonDataKeys.NAVIGATABLE.is(dataId)) { - if (value instanceof Navigatable) return value; - if (value instanceof ChooseRunConfigurationPopup.ItemWrapper) { - final Object config = ((ChooseRunConfigurationPopup.ItemWrapper)value).getValue(); - if (config instanceof RunnerAndConfigurationSettings) { - return new Navigatable() { - @Override - public void navigate(boolean requestFocus) { - Executor executor = findExecutor((RunnerAndConfigurationSettings)config); - RunDialog.editConfiguration(project, (RunnerAndConfigurationSettings)config, "Edit Configuration", executor); - } - - @Override - public boolean canNavigate() { - return true; - } - - @Override - public boolean canNavigateToSource() { - return true; - } - }; + } + if (CommonDataKeys.NAVIGATABLE.is(dataId)) { + if (value instanceof Navigatable) return value; + if (value instanceof ChooseRunConfigurationPopup.ItemWrapper) { + final Object config = ((ChooseRunConfigurationPopup.ItemWrapper)value).getValue(); + if (config instanceof RunnerAndConfigurationSettings) { + return new Navigatable() { + @Override + public void navigate(boolean requestFocus) { + Executor executor = findExecutor((RunnerAndConfigurationSettings)config); + RunDialog.editConfiguration(project, (RunnerAndConfigurationSettings)config, "Edit Configuration", executor); } - } - } else if (PlatformDataKeys.SEARCH_INPUT_TEXT.is(dataId)) { + + @Override + public boolean canNavigate() { + return true; + } + + @Override + public boolean canNavigateToSource() { + return true; + } + }; + } + } + } + if (PlatformDataKeys.SEARCH_INPUT_TEXT.is(dataId)) { return myPopupField == null ? null : myPopupField.getText(); } return null; @@ -1076,7 +1078,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA private class MyListRenderer extends ColoredListCellRenderer { ColoredListCellRenderer myLocation = new ColoredListCellRenderer() { @Override - protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) { + protected void customizeCellRenderer(@NotNull JList list, Object value, int index, boolean selected, boolean hasFocus) { setPaintFocusBorder(false); append(myLocationString, SimpleTextAttributes.GRAYED_ATTRIBUTES); setIcon(myLocationIcon); @@ -1193,7 +1195,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } @Override - protected void customizeCellRenderer(JList list, final Object value, int index, final boolean selected, boolean hasFocus) { + protected void customizeCellRenderer(@NotNull JList list, final Object value, int index, final boolean selected, boolean hasFocus) { setPaintFocusBorder(false); setIcon(EmptyIcon.ICON_16); ApplicationManager.getApplication().runReadAction(new Runnable() { @@ -1241,7 +1243,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA } } - append(templatePresentation.getText()); + append(String.valueOf(templatePresentation.getText())); if (actionWithParentGroup != null) { final String groupName = actionWithParentGroup.getGroupName(); if (!StringUtil.isEmpty(groupName)) { @@ -2663,16 +2665,13 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA JLabel titleLabel = new JLabel(titleText); titleLabel.setFont(getTitleFont()); titleLabel.setForeground(UIUtil.getLabelDisabledForeground()); - final Color bg = UIUtil.getListBackground(); SeparatorComponent separatorComponent = new SeparatorComponent(titleLabel.getPreferredSize().height / 2, new JBColor(Gray._220, Gray._80), null); - JPanel result = new JPanel(new BorderLayout(5, 10)); - result.add(titleLabel, BorderLayout.WEST); - result.add(separatorComponent, BorderLayout.CENTER); - result.setBackground(bg); - - return result; + return JBUI.Panels.simplePanel(5, 10) + .addToCenter(separatorComponent) + .addToLeft(titleLabel) + .withBackground(UIUtil.getListBackground()); } private enum HistoryType {PSI, FILE, SETTING, ACTION, RUN_CONFIGURATION} From db9b2f8f824286cc599aafa185bfbadb44f286bd Mon Sep 17 00:00:00 2001 From: Alexander Lobas Date: Tue, 12 Apr 2016 22:38:36 +0300 Subject: [PATCH 39/64] IDEA-153807 Welcome screen notifications --- .../src/com/intellij/notification/impl/IdeNotificationArea.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java index 79e434340247..c5319fcf9bc9 100644 --- a/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java +++ b/platform/platform-impl/src/com/intellij/notification/impl/IdeNotificationArea.java @@ -192,7 +192,7 @@ public class IdeNotificationArea extends JLabel implements CustomStatusBarWidget myComponent = component; myTextColor = textColor; myFont = new Font(NotificationsUtil.getFontName(), Font.BOLD, 9); - myWidth = myComponent.getFontMetrics(myFont).stringWidth(myStr) + 1; + myWidth = myComponent.getFontMetrics(myFont).stringWidth(myStr); } @Override From 4b69564638cb8d9139fc336c9651078d7b931203 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Tue, 12 Apr 2016 22:47:59 +0300 Subject: [PATCH 40/64] inspection tool window: extract popup action group to LangActions.xml + extract Exclude/Include actions to reusable ones --- .../ui/InspectionResultsView.java | 195 ++++-------------- .../ui/QuickFixPreviewDecorator.java | 11 +- .../ui/actions/EditSettingsAction.java | 90 ++++++++ .../ui/actions/InspectionViewActionBase.java | 67 ++++++ .../InspectionsOptionsToolbarAction.java | 122 +---------- .../actions/KeyAwareInspectionViewAction.java | 134 ++++++++++++ .../ui/actions/QuickFixesActionGroup.java | 46 +++++ .../ui/actions/SuppressActionWrapper.java | 125 +++++------ .../ide/actions/TreeNodeExclusionAction.java | 122 +++++++++++ .../openapi/actionSystem/IdeActions.java | 2 + .../src/messages/InspectionsBundle.properties | 2 - .../src/idea/LangActions.xml | 21 ++ 12 files changed, 595 insertions(+), 342 deletions(-) create mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/actions/EditSettingsAction.java create mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionViewActionBase.java create mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/actions/KeyAwareInspectionViewAction.java create mode 100644 platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesActionGroup.java create mode 100644 platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java index 3d9eca458109..f19cdf153680 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -32,6 +32,7 @@ import com.intellij.diff.util.DiffUtil; import com.intellij.icons.AllIcons; import com.intellij.ide.*; import com.intellij.ide.actions.ContextHelpAction; +import com.intellij.ide.actions.TreeNodeExclusionAction; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; @@ -55,7 +56,6 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.wm.ToolWindowId; import com.intellij.openapi.wm.ToolWindowManager; import com.intellij.pom.Navigatable; -import com.intellij.profile.codeInspection.InspectionProjectProfileManager; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; @@ -119,8 +119,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren @NotNull private final InspectionRVContentProvider myProvider; - private AnAction myIncludeAction; - private AnAction myExcludeAction; + private final TreeNodeExclusionAction.ExclusionHandler myExclusionHandler; private EditorEx myPreviewEditor; private InspectionTreeLoadingProgressAware myLoadingProgressPreview; private final ExcludedInspectionTreeNodesManager myExcludedInspectionTreeNodesManager = new ExcludedInspectionTreeNodesManager(); @@ -151,6 +150,41 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } }); add(mySplitter, BorderLayout.CENTER); + myExclusionHandler = new TreeNodeExclusionAction.ExclusionHandler() { + @Override + public boolean isNodeExcluded(@NotNull InspectionTreeNode node) { + return node.isResolved(myExcludedInspectionTreeNodesManager); + } + + @Override + public void excludeNode(@NotNull InspectionTreeNode node, boolean isExcluded) { + if (isExcluded) { + node.ignoreElement(myExcludedInspectionTreeNodesManager); + } else { + node.amnesty(myExcludedInspectionTreeNodesManager); + } + } + + @Override + public boolean isActionEnabled(boolean isExcludeAction) { + return isExcludeAction || !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS; + } + + @Override + public void updateUiWhenActionWasPerformed(boolean isExcludeAction) { + if (isExcludeAction && myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS) { + update(); + } + else { + myTree.queueUpdate(); + } + } + + @Override + public boolean isValid() { + return !isDisposed(); + } + }; createActionsToolbar(); } @@ -177,13 +211,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } }); - myTree.addMouseListener(new PopupHandler() { - @Override - public void invokePopup(Component comp, int x, int y) { - popupInvoked(comp, x, y); - } - }); - + PopupHandler.installPopupHandler(myTree, IdeActions.INSPECTION_TOOL_WINDOW_TREE_POPUP, ActionPlaces.CODE_INSPECTION); SmartExpander.installOn(myTree); } @@ -244,64 +272,13 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren @SuppressWarnings({"NonStaticInitializer"}) private JComponent createRightActionsToolbar() { - myIncludeAction = new AnAction(InspectionsBundle.message("inspections.result.view.include.action.text")) { - { - registerCustomShortcutSet(CommonShortcuts.INSERT, myTree); - } - - @Override - public void actionPerformed(AnActionEvent e) { - final TreePath[] paths = myTree.getSelectionPaths(); - if (paths != null) { - for (TreePath path : paths) { - ((InspectionTreeNode)path.getLastPathComponent()).amnesty(myExcludedInspectionTreeNodesManager); - } - } - myTree.queueUpdate(); - } - - @Override - public void update(final AnActionEvent e) { - final TreePath[] paths = myTree.getSelectionPaths(); - e.getPresentation().setEnabled(paths != null && paths.length > 0 && - !myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS); - } - }; - - myExcludeAction = new AnAction(InspectionsBundle.message("inspections.result.view.exclude.action.text")) { - { - registerCustomShortcutSet(CommonShortcuts.getDelete(), myTree); - } - - @Override - public void actionPerformed(final AnActionEvent e) { - final TreePath[] paths = myTree.getSelectionPaths(); - if (paths != null) { - for (TreePath path : paths) { - ((InspectionTreeNode)path.getLastPathComponent()).ignoreElement(myExcludedInspectionTreeNodesManager); - } - } - if (myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS) { - InspectionResultsView.this.update(); - } else { - myTree.queueUpdate(); - } - } - - @Override - public void update(final AnActionEvent e) { - final TreePath[] path = myTree.getSelectionPaths(); - e.getPresentation().setEnabled(path != null && path.length > 0); - } - }; - DefaultActionGroup specialGroup = new DefaultActionGroup(); specialGroup.add(myGlobalInspectionContext.getUIOptions().createGroupBySeverityAction(this)); specialGroup.add(myGlobalInspectionContext.getUIOptions().createGroupByDirectoryAction(this)); specialGroup.add(myGlobalInspectionContext.getUIOptions().createFilterResolvedItemsAction(this)); specialGroup.add(myGlobalInspectionContext.getUIOptions().createShowOutdatedProblemsAction(this)); specialGroup.add(myGlobalInspectionContext.getUIOptions().createShowDiffOnlyAction(this)); - specialGroup.add(new EditSettingsAction()); + specialGroup.add(ActionManager.getInstance().getAction("EditInspectionSettings")); specialGroup.add(new InvokeQuickFixAction(this)); specialGroup.add(new InspectionsOptionsToolbarAction(this)); return createToolbar(specialGroup); @@ -785,6 +762,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren public Object getData(String dataId) { if (PlatformDataKeys.HELP_ID.is(dataId)) return HELP_ID; if (DATA_KEY.is(dataId)) return this; + if (TreeNodeExclusionAction.EXCLUSION_HANDLER.is(dataId)) return myExclusionHandler; if (myTree == null) return null; TreePath[] paths = myTree.getSelectionPaths(); @@ -895,48 +873,6 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren return PsiUtilCore.toPsiElementArray(psiElements); } - private void popupInvoked(Component component, int x, int y) { - final TreePath path = myTree.getLeadSelectionPath(); - - if (path == null) return; - - final DefaultActionGroup actions = new DefaultActionGroup(); - final ActionManager actionManager = ActionManager.getInstance(); - actions.add(actionManager.getAction(IdeActions.ACTION_EDIT_SOURCE)); - actions.add(actionManager.getAction(IdeActions.ACTION_FIND_USAGES)); - - actions.add(myIncludeAction); - actions.add(myExcludeAction); - - actions.addSeparator(); - - final InspectionToolWrapper toolWrapper = myTree.getSelectedToolWrapper(); - if (toolWrapper != null) { - final QuickFixAction[] quickFixes = myProvider.getQuickFixes(toolWrapper, myTree); - if (quickFixes != null) { - for (QuickFixAction quickFix : quickFixes) { - actions.add(quickFix); - } - } - final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName()); - if (key == null) return; //e.g. DummyEntryPointsTool - - //options - actions.addSeparator(); - actions.add(new EditSettingsAction()); - final List options = new InspectionsOptionsToolbarAction(this).createActions(); - for (AnAction action : options) { - actions.add(action); - } - } - - actions.addSeparator(); - actions.add(actionManager.getAction(IdeActions.GROUP_VERSION_CONTROLS)); - - final ActionPopupMenu menu = actionManager.createActionPopupMenu(ActionPlaces.CODE_INSPECTION, actions); - menu.getComponent().show(component, x, y); - } - @NotNull public InspectionTree getTree() { return myTree; @@ -962,24 +898,6 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren return rerun; } - private InspectionProfile guessProfileToSelect(final InspectionProjectProfileManager profileManager) { - final Set profiles = new HashSet(); - final RefEntity[] selectedElements = myTree.getSelectedElements(); - for (RefEntity selectedElement : selectedElements) { - if (selectedElement instanceof RefElement) { - final RefElement refElement = (RefElement)selectedElement; - final PsiElement element = refElement.getElement(); - if (element != null) { - profiles.add(profileManager.getInspectionProfile()); - } - } - } - if (profiles.isEmpty()) { - return (InspectionProfile)profileManager.getProjectProfileImpl(); - } - return profiles.iterator().next(); - } - public boolean isProfileDefined() { return myInspectionProfile != null && myInspectionProfile.isEditable(); } @@ -1045,39 +963,6 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } } - private class EditSettingsAction extends AnAction { - private EditSettingsAction() { - super(InspectionsBundle.message("inspection.action.edit.settings"), InspectionsBundle.message("inspection.action.edit.settings"), - AllIcons.General.Settings); - } - - @Override - public void actionPerformed(AnActionEvent e) { - final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(myProject); - final InspectionToolWrapper toolWrapper = myTree.getSelectedToolWrapper(); - InspectionProfile inspectionProfile = myInspectionProfile; - final boolean profileIsDefined = isProfileDefined(); - if (!profileIsDefined) { - inspectionProfile = guessProfileToSelect(profileManager); - } - - if (toolWrapper != null) { - final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName()); //do not search for dead code entry point tool - if (key != null) { - if (new EditInspectionToolsSettingsAction(key) - .editToolSettings(myProject, (InspectionProfileImpl)inspectionProfile, profileIsDefined) - && profileIsDefined) { - updateCurrentProfile(); - } - return; - } - } - if (EditInspectionToolsSettingsAction.editToolSettings(myProject, inspectionProfile, profileIsDefined, null) && profileIsDefined) { - updateCurrentProfile(); - } - } - } - public void updateCurrentProfile() { final String name = myInspectionProfile.getName(); myInspectionProfile = (InspectionProfile)myInspectionProfile.getProfileManager().getProfile(name); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixPreviewDecorator.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixPreviewDecorator.java index 38e0999ab18c..b576d4c848a1 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixPreviewDecorator.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixPreviewDecorator.java @@ -20,6 +20,7 @@ import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.ex.QuickFixAction; import com.intellij.codeInspection.ui.actions.SuppressActionWrapper; import com.intellij.icons.AllIcons; +import com.intellij.ide.DataManager; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.diagnostic.Logger; @@ -100,8 +101,6 @@ public class QuickFixPreviewDecorator extends JPanel implements InspectionTreeLo private void fillPanel(@Nullable QuickFixAction[] fixes, CommonProblemDescriptor[] descriptors) { if (myFoldings != null) myFoldings.appendFoldings(descriptors); - InspectionTree tree = myView.getTree(); - Project project = myView.getProject(); boolean hasFixes = fixes != null && fixes.length != 0; int problemCount = descriptors.length; boolean multipleDescriptors = problemCount > 1; @@ -114,7 +113,7 @@ public class QuickFixPreviewDecorator extends JPanel implements InspectionTreeLo if (hasFixes) { actions.addAll(createFixActions(fixes, multipleDescriptors)); } - actions.add(createSuppressionCombo(myWrapper, tree.getSelectionPaths(), project)); + actions.add(createSuppressionCombo(myView)); final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, actions, true); final JComponent component = toolbar.getComponent(); toolbar.setTargetComponent(this); @@ -144,10 +143,8 @@ public class QuickFixPreviewDecorator extends JPanel implements InspectionTreeLo label.append(problemsCount + " problems:"); } - private static AnAction createSuppressionCombo(@NotNull final InspectionToolWrapper toolWrapper, - @NotNull final TreePath[] paths, - @NotNull final Project project) { - final AnAction[] suppressors = new SuppressActionWrapper(project, toolWrapper, paths).getChildren(null); + private static AnAction createSuppressionCombo(InspectionResultsView view) { + final AnAction[] suppressors = new SuppressActionWrapper().getChildren(AnActionEvent.createFromDataContext(ActionPlaces.CODE_INSPECTION, null, DataManager.getInstance().getDataContext(view))); final ComboBoxAction action = new ComboBoxAction() { { getTemplatePresentation().setText("Suppress"); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/EditSettingsAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/EditSettingsAction.java new file mode 100644 index 000000000000..1ef8f39aaa8a --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/EditSettingsAction.java @@ -0,0 +1,90 @@ +/* + * 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.codeInspection.ui.actions; + +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInspection.InspectionProfile; +import com.intellij.codeInspection.InspectionsBundle; +import com.intellij.codeInspection.ex.EditInspectionToolsSettingsAction; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.codeInspection.ex.InspectionToolWrapper; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.codeInspection.ui.InspectionResultsView; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import com.intellij.psi.PsiElement; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Dmitry Batkovich + */ +public class EditSettingsAction extends InspectionViewActionBase { + public EditSettingsAction() { + super(InspectionsBundle.message("inspection.action.edit.settings"), + InspectionsBundle.message("inspection.action.edit.settings"), + AllIcons.General.Settings); + } + + @Override + public void actionPerformed(AnActionEvent e) { + final InspectionResultsView view = getView(e); + final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(view.getProject()); + final InspectionToolWrapper toolWrapper = view.getTree().getSelectedToolWrapper(); + InspectionProfile inspectionProfile = view.getCurrentProfile(); + final boolean profileIsDefined = view.isProfileDefined(); + if (!profileIsDefined) { + inspectionProfile = guessProfileToSelect(view, profileManager); + } + + if (toolWrapper != null) { + final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName()); //do not search for dead code entry point tool + if (key != null) { + if (new EditInspectionToolsSettingsAction(key) + .editToolSettings(view.getProject(), (InspectionProfileImpl)inspectionProfile, profileIsDefined) + && profileIsDefined) { + view.updateCurrentProfile(); + } + return; + } + } + if (EditInspectionToolsSettingsAction.editToolSettings(view.getProject(), inspectionProfile, profileIsDefined, null) && profileIsDefined) { + view.updateCurrentProfile(); + } + } + + private static InspectionProfile guessProfileToSelect(final InspectionResultsView view, + final InspectionProjectProfileManager profileManager) { + final Set profiles = new HashSet(); + final RefEntity[] selectedElements = view.getTree().getSelectedElements(); + for (RefEntity selectedElement : selectedElements) { + if (selectedElement instanceof RefElement) { + final RefElement refElement = (RefElement)selectedElement; + final PsiElement element = refElement.getElement(); + if (element != null) { + profiles.add(profileManager.getInspectionProfile()); + } + } + } + if (profiles.isEmpty()) { + return (InspectionProfile)profileManager.getProjectProfileImpl(); + } + return profiles.iterator().next(); + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionViewActionBase.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionViewActionBase.java new file mode 100644 index 000000000000..6139b7f5219d --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionViewActionBase.java @@ -0,0 +1,67 @@ +/* + * 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.codeInspection.ui.actions; + +import com.intellij.codeInspection.ui.InspectionResultsView; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; + +/** + * @author Dmitry Batkovich + */ +public abstract class InspectionViewActionBase extends AnAction { + public InspectionViewActionBase(@Nullable String text, @Nullable String description, @Nullable Icon icon) { + super(text, description, icon); + } + + public InspectionViewActionBase(String name) { + super(name); + } + + @Override + public final void update(AnActionEvent e) { + final InspectionResultsView view = getView(e); + final boolean enabled = view != null && isEnabled(view); + final Presentation presentation = e.getPresentation(); + if (hideIfDisabled()) { + presentation.setEnabledAndVisible(enabled); + } + else { + presentation.setEnabled(enabled); + } + } + + protected boolean isEnabled(@NotNull InspectionResultsView view) { + return true; + } + + protected boolean hideIfDisabled() { + return false; + } + + public static InspectionResultsView getView(@Nullable AnActionEvent event) { + if (event == null) { + return null; + } + final InspectionResultsView view = InspectionResultsView.DATA_KEY.getData(event.getDataContext()); + return view == null || view.isDisposed() ? null : view; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionsOptionsToolbarAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionsOptionsToolbarAction.java index 1d4635bf07c8..ff3c80f7db31 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionsOptionsToolbarAction.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionsOptionsToolbarAction.java @@ -1,38 +1,16 @@ package com.intellij.codeInspection.ui.actions; -import com.intellij.CommonBundle; -import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInspection.InspectionsBundle; -import com.intellij.codeInspection.ModifiableModel; -import com.intellij.codeInspection.actions.RunInspectionIntention; -import com.intellij.codeInspection.ex.DisableInspectionToolAction; -import com.intellij.codeInspection.ex.InspectionProfileImpl; import com.intellij.codeInspection.ex.InspectionToolWrapper; -import com.intellij.codeInspection.reference.RefElement; -import com.intellij.codeInspection.reference.RefEntity; import com.intellij.codeInspection.ui.InspectionResultsView; -import com.intellij.codeInspection.ui.InspectionTree; import com.intellij.icons.AllIcons; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.DefaultActionGroup; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.ui.popup.ListPopup; -import com.intellij.profile.codeInspection.InspectionProjectProfileManager; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - /** * User: anna * Date: 11-Jan-2006 @@ -47,15 +25,12 @@ public class InspectionsOptionsToolbarAction extends AnAction { @Override public void actionPerformed(AnActionEvent e) { - final DefaultActionGroup options = new DefaultActionGroup(); - final List actions = createActions(); - for (AnAction action : actions) { - options.add(action); - } - final DataContext dataContext = e.getDataContext(); final ListPopup popup = JBPopupFactory.getInstance() - .createActionGroupPopup(getSelectedToolWrapper().getDisplayName(), options, dataContext, - JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false); + .createActionGroupPopup(getSelectedToolWrapper().getDisplayName(), + (ActionGroup)ActionManager.getInstance().getAction("InspectionsOptions"), + e.getDataContext(), + JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, + false); InspectionResultsView.showPopup(e, popup); } @@ -86,89 +61,4 @@ public class InspectionsOptionsToolbarAction extends AnAction { private static String getToolOptions(@Nullable final InspectionToolWrapper toolWrapper) { return InspectionsBundle.message("inspections.view.options.title", toolWrapper != null ? toolWrapper.getDisplayName() : ""); } - - public List createActions() { - final List result = new ArrayList(); - final InspectionTree tree = myView.getTree(); - final InspectionToolWrapper toolWrapper = tree.getSelectedToolWrapper(); - if (toolWrapper == null) return result; - final HighlightDisplayKey key = HighlightDisplayKey.find(toolWrapper.getShortName()); - if (key == null) return result; - - result.add(new DisableInspectionAction(key)); - - result.add(new AnAction(InspectionsBundle.message("run.inspection.on.file.intention.text")) { - @Override - public void actionPerformed(final AnActionEvent e) { - final PsiElement psiElement = getPsiElement(tree); - assert psiElement != null; - new RunInspectionIntention(toolWrapper).invoke(myView.getProject(), null, psiElement.getContainingFile()); - } - - @Override - public void update(AnActionEvent e) { - e.getPresentation().setEnabled(getPsiElement(tree) != null); - } - - @Nullable - private PsiElement getPsiElement(InspectionTree tree) { - final RefEntity[] selectedElements = tree.getSelectedElements(); - - final PsiElement psiElement; - if (selectedElements.length > 0 && selectedElements[0] instanceof RefElement) { - psiElement = ((RefElement)selectedElements[0]).getElement(); - } - else { - psiElement = null; - } - return psiElement; - } - }); - - result.add(new SuppressActionWrapper(myView.getProject(), toolWrapper, tree.getSelectionPaths())); - - - return result; - } - - private class DisableInspectionAction extends AnAction { - private final HighlightDisplayKey myKey; - - public DisableInspectionAction(final HighlightDisplayKey key) { - super(DisableInspectionToolAction.NAME); - myKey = key; - } - - @Override - public void actionPerformed(final AnActionEvent e) { - try { - if (myView.isProfileDefined()) { - final ModifiableModel model = myView.getCurrentProfile().getModifiableModel(); - model.disableTool(myKey.toString(), myView.getProject()); - model.commit(); - myView.updateCurrentProfile(); - } else { - final RefEntity[] selectedElements = myView.getTree().getSelectedElements(); - final Set files = new HashSet(); - final Project project = myView.getProject(); - final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(project); - for (RefEntity selectedElement : selectedElements) { - if (selectedElement instanceof RefElement) { - final PsiElement element = ((RefElement)selectedElement).getElement(); - files.add(element); - } - } - ModifiableModel model = ((InspectionProfileImpl)profileManager.getProjectProfileImpl()).getModifiableModel(); - for (PsiElement element : files) { - model.disableTool(myKey.toString(), element); - } - model.commit(); - DaemonCodeAnalyzer.getInstance(project).restart(); - } - } - catch (IOException e1) { - Messages.showErrorDialog(myView.getProject(), e1.getMessage(), CommonBundle.getErrorTitle()); - } - } - } } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/KeyAwareInspectionViewAction.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/KeyAwareInspectionViewAction.java new file mode 100644 index 000000000000..7757e27d1ce5 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/KeyAwareInspectionViewAction.java @@ -0,0 +1,134 @@ +/* + * 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.codeInspection.ui.actions; + +import com.intellij.CommonBundle; +import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; +import com.intellij.codeInspection.InspectionsBundle; +import com.intellij.codeInspection.ModifiableModel; +import com.intellij.codeInspection.actions.RunInspectionIntention; +import com.intellij.codeInspection.ex.DisableInspectionToolAction; +import com.intellij.codeInspection.ex.InspectionProfileImpl; +import com.intellij.codeInspection.ex.InspectionToolWrapper; +import com.intellij.codeInspection.reference.RefElement; +import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.codeInspection.ui.InspectionResultsView; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.Messages; +import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +/** + * @author Dmitry Batkovich + */ +public abstract class KeyAwareInspectionViewAction extends InspectionViewActionBase { + public KeyAwareInspectionViewAction(String name) { + super(name); + } + + @Override + protected boolean isEnabled(@NotNull InspectionResultsView view) { + final InspectionToolWrapper wrapper = view.getTree().getSelectedToolWrapper(); + return wrapper != null && HighlightDisplayKey.find(wrapper.getShortName()) != null; + } + + @Override + public void actionPerformed(AnActionEvent e) { + final InspectionResultsView view = getView(e); + final HighlightDisplayKey key = HighlightDisplayKey.find(view.getTree().getSelectedToolWrapper().getShortName()); + actionPerformed(view, key); + } + + protected abstract void actionPerformed(@NotNull InspectionResultsView view, @NotNull HighlightDisplayKey key); + + public static class DisableInspection extends KeyAwareInspectionViewAction { + public DisableInspection() { + super(DisableInspectionToolAction.NAME); + } + + @Override + protected void actionPerformed(@NotNull InspectionResultsView view, @NotNull HighlightDisplayKey key) { + try { + if (view.isProfileDefined()) { + final ModifiableModel model = view.getCurrentProfile().getModifiableModel(); + model.disableTool(key.toString(), view.getProject()); + model.commit(); + view.updateCurrentProfile(); + } else { + final RefEntity[] selectedElements = view.getTree().getSelectedElements(); + final Set files = new HashSet(); + final Project project = view.getProject(); + final InspectionProjectProfileManager profileManager = InspectionProjectProfileManager.getInstance(project); + for (RefEntity selectedElement : selectedElements) { + if (selectedElement instanceof RefElement) { + final PsiElement element = ((RefElement)selectedElement).getElement(); + files.add(element); + } + } + ModifiableModel model = ((InspectionProfileImpl)profileManager.getProjectProfileImpl()).getModifiableModel(); + for (PsiElement element : files) { + model.disableTool(key.toString(), element); + } + model.commit(); + DaemonCodeAnalyzer.getInstance(project).restart(); + } + } + catch (IOException e1) { + Messages.showErrorDialog(view.getProject(), e1.getMessage(), CommonBundle.getErrorTitle()); + } + } + } + + public static class RunInspectionOn extends KeyAwareInspectionViewAction { + public RunInspectionOn() { + super(InspectionsBundle.message("run.inspection.on.file.intention.text")); + } + + @Override + protected boolean isEnabled(@NotNull InspectionResultsView view) { + return super.isEnabled(view) && getPsiElement(view) != null; + } + + @Override + protected void actionPerformed(@NotNull InspectionResultsView view, @NotNull HighlightDisplayKey key) { + final PsiElement psiElement = getPsiElement(view); + assert psiElement != null; + new RunInspectionIntention(key).invoke(view.getProject(), null, psiElement.getContainingFile()); + } + + @Nullable + private static PsiElement getPsiElement(InspectionResultsView view) { + final RefEntity[] selectedElements = view.getTree().getSelectedElements(); + + final PsiElement psiElement; + if (selectedElements.length > 0 && selectedElements[0] instanceof RefElement) { + psiElement = ((RefElement)selectedElements[0]).getElement(); + } + else { + psiElement = null; + } + return psiElement; + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesActionGroup.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesActionGroup.java new file mode 100644 index 000000000000..1793d20a1346 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesActionGroup.java @@ -0,0 +1,46 @@ +/* + * 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.codeInspection.ui.actions; + +import com.intellij.codeInspection.ex.InspectionToolWrapper; +import com.intellij.codeInspection.ex.QuickFixAction; +import com.intellij.codeInspection.ui.InspectionResultsView; +import com.intellij.openapi.actionSystem.ActionGroup; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import static com.intellij.codeInspection.ui.actions.InspectionViewActionBase.getView; + +/** + * @author Dmitry Batkovich + */ +public class QuickFixesActionGroup extends ActionGroup { + @NotNull + @Override + public AnAction[] getChildren(@Nullable AnActionEvent e) { + final InspectionResultsView view = getView(e); + if (view == null) { + return AnAction.EMPTY_ARRAY; + } + final InspectionToolWrapper wrapper = view.getTree().getSelectedToolWrapper(); + if (wrapper == null) return AnAction.EMPTY_ARRAY; + + final QuickFixAction[] fixes = view.getProvider().getQuickFixes(wrapper, view.getTree()); + return fixes == null ? AnAction.EMPTY_ARRAY : fixes; + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java index 3b0399299785..d8cb876136d0 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java @@ -20,19 +20,18 @@ */ package com.intellij.codeInspection.ui.actions; +import com.intellij.codeInsight.daemon.HighlightDisplayKey; import com.intellij.codeInspection.*; import com.intellij.codeInspection.ex.GlobalInspectionContextImpl; import com.intellij.codeInspection.ex.InspectionManagerEx; import com.intellij.codeInspection.ex.InspectionToolWrapper; import com.intellij.codeInspection.reference.RefElement; import com.intellij.codeInspection.reference.RefEntity; +import com.intellij.codeInspection.ui.InspectionResultsView; import com.intellij.codeInspection.ui.InspectionTreeNode; import com.intellij.codeInspection.ui.ProblemDescriptionNode; import com.intellij.codeInspection.ui.RefElementNode; -import com.intellij.openapi.actionSystem.ActionGroup; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.Separator; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.diagnostic.Logger; @@ -51,43 +50,27 @@ import org.jetbrains.annotations.Nullable; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.util.Arrays; +import java.util.Collections; import java.util.Comparator; import java.util.Set; +import static com.intellij.codeInspection.ui.actions.InspectionViewActionBase.getView; + public class SuppressActionWrapper extends ActionGroup { - private final Project myProject; - private final InspectionManagerEx myManager; - private final Set myNodesToSuppress = new HashSet(); - private final InspectionToolWrapper myToolWrapper; private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.actions.SuppressActionWrapper"); - public SuppressActionWrapper(@NotNull final Project project, - @NotNull final InspectionToolWrapper toolWrapper, - @NotNull final TreePath... paths) { + public SuppressActionWrapper() { super(InspectionsBundle.message("suppress.inspection.problem"), false); - myProject = project; - myManager = (InspectionManagerEx)InspectionManager.getInstance(myProject); - for (TreePath path : paths) { - final Object node = path.getLastPathComponent(); - if (!(node instanceof TreeNode)) continue; - TreeUtil.traverse((TreeNode)node, new TreeUtil.Traverse() { - @Override - public boolean accept(final Object node) { //fetch leaves - final InspectionTreeNode n = (InspectionTreeNode)node; - if (n.isLeaf()) { - myNodesToSuppress.add(n); - } - return true; - } - }); - } - myToolWrapper = toolWrapper; } @Override @NotNull public AnAction[] getChildren(@Nullable final AnActionEvent e) { - final SuppressIntentionAction[] suppressActions = InspectionManagerEx.getSuppressActions(myToolWrapper); + final InspectionResultsView view = getView(e); + if (view == null) return AnAction.EMPTY_ARRAY; + final InspectionToolWrapper wrapper = view.getTree().getSelectedToolWrapper(); + if (wrapper == null) return AnAction.EMPTY_ARRAY; + final SuppressIntentionAction[] suppressActions = InspectionManagerEx.getSuppressActions(wrapper); if (suppressActions == null || suppressActions.length == 0) return new SuppressTreeAction[0]; final AnAction[] actions = new AnAction[suppressActions.length + 1]; for (int i = 0; i < suppressActions.length; i++) { @@ -108,18 +91,19 @@ public class SuppressActionWrapper extends ActionGroup { return actions; } - private boolean suppress(@NotNull final PsiElement element, - final CommonProblemDescriptor descriptor, - final SuppressIntentionAction action, - final RefEntity refEntity) { + private static boolean suppress(@NotNull final PsiElement element, + final CommonProblemDescriptor descriptor, + final SuppressIntentionAction action, + @NotNull final RefEntity refEntity, InspectionToolWrapper wrapper) { if (action instanceof SuppressIntentionActionFromFix && !(descriptor instanceof ProblemDescriptor)) { - LOG.info("local suppression fix for specific problem descriptor: " + myToolWrapper.getTool().getClass().getName()); + LOG.info("local suppression fix for specific problem descriptor: " + wrapper.getTool().getClass().getName()); } - final PsiModificationTracker tracker = PsiManager.getInstance(myProject).getModificationTracker(); + final Project project = element.getProject(); + final PsiModificationTracker tracker = PsiManager.getInstance(project).getModificationTracker(); ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - PsiDocumentManager.getInstance(myProject).commitAllDocuments(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); try { final long startModificationCount = tracker.getModificationCount(); @@ -131,15 +115,15 @@ public class SuppressActionWrapper extends ActionGroup { container = element; } - if (action.isAvailable(myProject, null, element)) { - action.invoke(myProject, null, element); + if (action.isAvailable(project, null, element)) { + action.invoke(project, null, element); } if (startModificationCount != tracker.getModificationCount()) { - final Set globalInspectionContexts = myManager.getRunningContexts(); + final Set globalInspectionContexts = ((InspectionManagerEx)InspectionManager.getInstance(element.getProject())).getRunningContexts(); for (GlobalInspectionContextImpl context : globalInspectionContexts) { - context.ignoreElement(myToolWrapper.getTool(), container); + context.ignoreElement(wrapper.getTool(), container); if (descriptor != null) { - context.getPresentation(myToolWrapper).ignoreCurrentElementProblem(refEntity, descriptor); + context.getPresentation(wrapper).ignoreCurrentElementProblem(refEntity, descriptor); } } } @@ -152,12 +136,6 @@ public class SuppressActionWrapper extends ActionGroup { return true; } - @Override - public void update(final AnActionEvent e) { - super.update(e); - e.getPresentation().setEnabled(InspectionManagerEx.getSuppressActions(myToolWrapper) != null); - } - private static Pair getContentToSuppress(InspectionTreeNode node) { RefElement refElement = null; CommonProblemDescriptor descriptor = null; @@ -177,7 +155,7 @@ public class SuppressActionWrapper extends ActionGroup { return Pair.create(element, descriptor); } - public class SuppressTreeAction extends AnAction { + public static class SuppressTreeAction extends KeyAwareInspectionViewAction { private final SuppressIntentionAction mySuppressAction; public SuppressTreeAction(final SuppressIntentionAction suppressAction) { @@ -186,14 +164,16 @@ public class SuppressActionWrapper extends ActionGroup { } @Override - public void actionPerformed(final AnActionEvent e) { + protected void actionPerformed(@NotNull InspectionResultsView view, @NotNull HighlightDisplayKey key) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + Project project = view.getProject(); + CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { - for (InspectionTreeNode node : myNodesToSuppress) { + final InspectionToolWrapper wrapper = view.getTree().getSelectedToolWrapper(); + for (InspectionTreeNode node : getNodesToSuppress(view)) { final Pair content = getContentToSuppress(node); if (content.first == null) break; final PsiElement element = content.first; @@ -203,13 +183,13 @@ public class SuppressActionWrapper extends ActionGroup { } else if (node instanceof ProblemDescriptionNode) { refEntity = ((ProblemDescriptionNode)node).getElement(); } - if (!suppress(element, content.second, mySuppressAction, refEntity)) break; + if (!suppress(element, content.second, mySuppressAction, refEntity, wrapper)) break; } - final Set globalInspectionContexts = myManager.getRunningContexts(); + final Set globalInspectionContexts = ((InspectionManagerEx)InspectionManager.getInstance(project)).getRunningContexts(); for (GlobalInspectionContextImpl context : globalInspectionContexts) { context.refreshViews(); } - CommandProcessor.getInstance().markCurrentCommandAsGlobal(myProject); + CommandProcessor.getInstance().markCurrentCommandAsGlobal(project); } }, getTemplatePresentation().getText(), null); } @@ -217,25 +197,46 @@ public class SuppressActionWrapper extends ActionGroup { } @Override - public void update(final AnActionEvent e) { - super.update(e); - if (!isAvailable()) e.getPresentation().setVisible(false); - } - - public boolean isAvailable() { - for (InspectionTreeNode node : myNodesToSuppress) { + protected boolean isEnabled(@NotNull InspectionResultsView view) { + for (InspectionTreeNode node : getNodesToSuppress(view)) { final Pair content = getContentToSuppress(node); if (content.first == null) continue; final PsiElement element = content.first; - if (mySuppressAction.isAvailable(myProject, null, element)) { + if (mySuppressAction.isAvailable(view.getProject(), null, element)) { return true; } } return false; } + @Override + protected boolean hideIfDisabled() { + return true; + } + public boolean isSuppressAll() { return mySuppressAction.isSuppressAll(); } } + + private static Set getNodesToSuppress(@NotNull InspectionResultsView view) { + final TreePath[] paths = view.getTree().getSelectionPaths(); + if (paths == null) return Collections.emptySet(); + final Set result = new HashSet<>(); + for (TreePath path : paths) { + final Object node = path.getLastPathComponent(); + if (!(node instanceof TreeNode)) continue; + TreeUtil.traverse((TreeNode)node, new TreeUtil.Traverse() { + @Override + public boolean accept(final Object node) { //fetch leaves + final InspectionTreeNode n = (InspectionTreeNode)node; + if (n.isLeaf()) { + result.add(n); + } + return true; + } + }); + } + return result; + } } diff --git a/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java b/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java new file mode 100644 index 000000000000..b0b1b88bb751 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java @@ -0,0 +1,122 @@ +/* + * 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.actions; + +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.diagnostic.Logger; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import javax.swing.tree.MutableTreeNode; +import javax.swing.tree.TreePath; +import java.awt.*; + +/** + * @author Dmitry Batkovich. + */ +public class TreeNodeExclusionAction extends AnAction { + private final static Logger LOG = Logger.getInstance(TreeNodeExclusionAction.class); + + public static final DataKey EXCLUSION_HANDLER = DataKey.create("tree.exclusion.handler"); + + private final boolean myIsExclude; + + public interface ExclusionHandler { + boolean isNodeExcluded(@NotNull T node); + + void excludeNode(@NotNull T node, boolean isExcluded); + + boolean isActionEnabled(boolean isExcludeAction); + + void updateUiWhenActionWasPerformed(boolean isExcludeAction); + + boolean isValid(); + } + + public static class Exclude extends TreeNodeExclusionAction { + public Exclude() { + super(true); + } + } + + public static class Include extends TreeNodeExclusionAction { + public Include() { + super(false); + } + } + + private TreeNodeExclusionAction(boolean isExclude) { + myIsExclude = isExclude; + copyShortcutFrom(ActionManager.getInstance().getAction(myIsExclude ? "$Delete" : "EditorToggleInsertState")); + } + + @Override + public void update(AnActionEvent e) { + final ExclusionHandler exclusionProcessor = EXCLUSION_HANDLER.getData(e.getDataContext()); + if (exclusionProcessor == null || !exclusionProcessor.isValid()) { + e.getPresentation().setEnabledAndVisible(false); + return; + } + final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext()); + final Presentation presentation = e.getPresentation(); + if (!(component instanceof JTree) || !exclusionProcessor.isActionEnabled(myIsExclude)) { + presentation.setEnabledAndVisible(false); + return; + } + JTree tree = (JTree) component; + final TreePath[] selection = tree.getSelectionPaths(); + if (selection == null) { + presentation.setEnabledAndVisible(false); + return; + } + boolean isEnabled = false; + for (TreePath path : selection) { + final T node = (T)path.getLastPathComponent(); + final Boolean isNodeExcluded = exclusionProcessor.isNodeExcluded(node); + if (myIsExclude != isNodeExcluded) { + isEnabled = true; + break; + } + } + presentation.setEnabledAndVisible(isEnabled); + String text = getActionText(); + if (selection.length > 1) { + text += " All"; + } + presentation.setText(text); + } + + @Override + public void actionPerformed(AnActionEvent e) { + final JTree tree = (JTree)PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext()); + LOG.assertTrue(tree != null); + final TreePath[] paths = tree.getSelectionPaths(); + LOG.assertTrue(paths != null); + final ExclusionHandler exclusionProcessor = EXCLUSION_HANDLER.getData(e.getDataContext()); + LOG.assertTrue(exclusionProcessor != null); + for (TreePath path : paths) { + final T node = (T)path.getLastPathComponent(); + if (Boolean.valueOf(myIsExclude) != exclusionProcessor.isNodeExcluded(node)) { + exclusionProcessor.excludeNode(node, myIsExclude); + } + } + exclusionProcessor.updateUiWhenActionWasPerformed(myIsExclude); + } + + private String getActionText() { + return myIsExclude ? "Exclude" : "Include"; + } +} diff --git a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java index 3cb240e070ca..4d427ed51591 100644 --- a/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java +++ b/platform/platform-api/src/com/intellij/openapi/actionSystem/IdeActions.java @@ -326,4 +326,6 @@ public interface IdeActions { String ACTION_MARK_ALL_NOTIFICATIONS_AS_READ = "MarkNotificationsAsRead"; String ACTION_SWITCHER = "Switcher"; + + @NonNls String INSPECTION_TOOL_WINDOW_TREE_POPUP = "InspectionToolWindow.TreePopup"; } diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index f4343273e879..4d5ab4a342f4 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -656,8 +656,6 @@ parsing.inspections.dump.progress.title=Parsing inspections XML dump suppress.inspection.problem=Suppress inspections.view.options.title=Inspection {0} options -inspections.result.view.exclude.action.text=Exclude -inspections.result.view.include.action.text=Include xml.suppressable.for.tag.title=Suppress for tag xml.suppressable.for.file.title=Suppress for file xml.suppressable.all.for.file.title=Suppress all for file diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 780094342e27..48961974ba6b 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -988,5 +988,26 @@ + + + + + > + + + + + + + + + + + + + + + + From c6a35c6daa776387f025c936453308cfe1f50f45 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 12 Apr 2016 22:48:51 +0200 Subject: [PATCH 41/64] no animated scrolling in usages preview (IDEA-154342) --- .../src/com/intellij/usages/impl/UsagePreviewPanel.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/usageView/src/com/intellij/usages/impl/UsagePreviewPanel.java b/platform/usageView/src/com/intellij/usages/impl/UsagePreviewPanel.java index 7c56b4a0a9f4..c7d756a39ca5 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsagePreviewPanel.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsagePreviewPanel.java @@ -207,6 +207,7 @@ public class UsagePreviewPanel extends UsageContextPanelBase { settings.setAdditionalColumnsCount(0); settings.setAdditionalLinesCount(0); settings.setVirtualSpace(true); + settings.setAnimatedScrolling(false); } @Override From 10271c741bcf7bbe7836d3eaf320e6a36d34d0ad Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Tue, 12 Apr 2016 22:09:42 +0300 Subject: [PATCH 42/64] [vcs-log] minor: NotNull annotations --- .../log/graph/impl/print/AbstractPrintElementGenerator.java | 6 ++++-- .../impl/print/elements/PrintElementWithGraphElement.java | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementGenerator.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementGenerator.java index 1a48f05100f5..71df4dc77589 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementGenerator.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementGenerator.java @@ -93,14 +93,16 @@ public abstract class AbstractPrintElementGenerator implements PrintElementGener return result; } - private SimplePrintElementImpl createSimplePrintElement(int rowIndex, SimpleRowElement rowElement) { + @NotNull + private SimplePrintElementImpl createSimplePrintElement(int rowIndex, @NotNull SimpleRowElement rowElement) { return new SimplePrintElementImpl(rowIndex, rowElement.myPosition, rowElement.myElement, myPrintElementManager); } + @NotNull private EdgePrintElementImpl createEdgePrintElement(int rowIndex, @NotNull ShortEdge shortEdge, @NotNull EdgePrintElement.Type type, - @NotNull boolean hasArrow) { + boolean hasArrow) { int positionInCurrentRow, positionInOtherRow; if (type == EdgePrintElement.Type.DOWN) { positionInCurrentRow = shortEdge.myUpPosition; diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/PrintElementWithGraphElement.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/PrintElementWithGraphElement.java index b1f93f358360..510137a86386 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/PrintElementWithGraphElement.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/elements/PrintElementWithGraphElement.java @@ -64,6 +64,7 @@ public abstract class PrintElementWithGraphElement implements PrintElement { return myPrintElementManager.isSelected(this); } + @NotNull public static PrintElementWithGraphElement converted(@NotNull PrintElementWithGraphElement element, @NotNull GraphElement convertedGraphElement) { return new PrintElementWithGraphElement(element.getRowIndex(), element.getPositionInCurrentRow(), convertedGraphElement, From 91589fa9e0509e860925d1a194c422c4b0dd6969 Mon Sep 17 00:00:00 2001 From: Julia Beliaeva Date: Tue, 12 Apr 2016 22:12:59 +0300 Subject: [PATCH 43/64] [vcs-log] minor: rename method toPrintElementWithGraphElement -> withGraphElement --- .../vcs/log/graph/api/printer/PrintElementGenerator.java | 2 +- .../intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java | 2 +- .../vcs/log/graph/impl/print/AbstractPrintElementGenerator.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/printer/PrintElementGenerator.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/printer/PrintElementGenerator.java index 1ed689cde270..9411f82cb21d 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/printer/PrintElementGenerator.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/api/printer/PrintElementGenerator.java @@ -28,5 +28,5 @@ public interface PrintElementGenerator { Collection getPrintElements(int visibleRow); @NotNull - PrintElementWithGraphElement toPrintElementWithGraphElement(@NotNull PrintElement printElement); + PrintElementWithGraphElement withGraphElement(@NotNull PrintElement printElement); } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java index b05fcba42334..7e2f5d915188 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/facade/VisibleGraphImpl.java @@ -205,7 +205,7 @@ public class VisibleGraphImpl implements VisibleGraph { private LinearGraphAction convert(@NotNull GraphAction graphAction) { PrintElementWithGraphElement printElement = null; if (graphAction.getAffectedElement() != null) { - printElement = myPrintElementGenerator.toPrintElementWithGraphElement(graphAction.getAffectedElement()); + printElement = myPrintElementGenerator.withGraphElement(graphAction.getAffectedElement()); } return new LinearGraphActionImpl(printElement, graphAction.getType()); } diff --git a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementGenerator.java b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementGenerator.java index 71df4dc77589..569632bd44bf 100644 --- a/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementGenerator.java +++ b/platform/vcs-log/graph/src/com/intellij/vcs/log/graph/impl/print/AbstractPrintElementGenerator.java @@ -118,7 +118,7 @@ public abstract class AbstractPrintElementGenerator implements PrintElementGener @NotNull @Override - public PrintElementWithGraphElement toPrintElementWithGraphElement(@NotNull PrintElement printElement) { + public PrintElementWithGraphElement withGraphElement(@NotNull PrintElement printElement) { if (printElement instanceof PrintElementWithGraphElement) { return (PrintElementWithGraphElement)printElement; } From df0ce66716ea28b2f8423ba8b6a605ce2614dc14 Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Tue, 12 Apr 2016 23:52:24 +0300 Subject: [PATCH 44/64] IDEA-81363 'triangular' logic doesn't work if one initially moves mouse over the menu item in 'wrong' direction. After that submenu would disappear quickly and not user-friendly. --- .../openapi/actionSystem/impl/ActionMenu.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java index 2b42a7297f65..12a81b8df6d4 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java @@ -359,6 +359,10 @@ public final class ActionMenu extends JMenu { private SingleAlarm myCallbackAlarm; private MouseEvent myEventToRedispatch; + private long myLastEventTime = 0L; + private boolean myInBounds = false; + private SingleAlarm myCheckAlarm; + private UsabilityHelper(Component component) { myCallbackAlarm = new SingleAlarm(new Runnable() { @Override @@ -370,6 +374,17 @@ public final class ActionMenu extends JMenu { } } }, 50, this); + myCheckAlarm = new SingleAlarm(new Runnable() { + @Override + public void run() { + if (myLastEventTime > 0 && System.currentTimeMillis() - myLastEventTime > 1500) { + if (!myInBounds && myCallbackAlarm != null && !myCallbackAlarm.isDisposed()) { + myCallbackAlarm.request(); + } + } + myCheckAlarm.request(); + } + }, 100, this); myComponent = component; PointerInfo info = MouseInfo.getPointerInfo(); myLastMousePoint = info != null ? info.getLocation() : null; @@ -410,17 +425,19 @@ public final class ActionMenu extends JMenu { Point point = ((MouseEvent)e).getLocationOnScreen(); Rectangle bounds = myComponent.getBounds(); bounds.setLocation(myComponent.getLocationOnScreen()); - - myCallbackAlarm.cancel(); - boolean isMouseMovingTowardsSubmenu = bounds.contains(point) || new Polygon( + myInBounds = bounds.contains(point); + boolean isMouseMovingTowardsSubmenu = myInBounds || new Polygon( new int[]{myLastMousePoint.x, myUpperTargetPoint.x, myLowerTargetPoint.x}, new int[]{myLastMousePoint.y, myUpperTargetPoint.y, myLowerTargetPoint.y}, 3).contains(point); myEventToRedispatch = (MouseEvent)e; + myLastEventTime = System.currentTimeMillis(); if (!isMouseMovingTowardsSubmenu) { myCallbackAlarm.request(); + } else { + myCallbackAlarm.cancel(); } myLastMousePoint = point; return true; From eb84df0d2385703d49fd1d6ba27498e81b609048 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 12 Apr 2016 23:00:00 +0200 Subject: [PATCH 45/64] "Find in path"-Action // Previous searches popdown conflicts with live preview (IDEA-154525) --- platform/lang-impl/src/com/intellij/find/impl/FindDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java index c7dfea8a92a7..0ed1020218de 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindDialog.java @@ -400,7 +400,7 @@ public class FindDialog extends DialogWrapper { component.getActionMap().put(newActionKey, new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { - if(isResultsPreviewTabActive()) { + if(isResultsPreviewTabActive() && !component.isPopupVisible()) { newAction.run(); return; } From 5e8ee4c6863a1fe70c6db8d888d9213445cd41ee Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Tue, 12 Apr 2016 23:24:12 +0200 Subject: [PATCH 46/64] drop inmemory caches for unsaved documents on low memory (IDEA-153382) --- .../com/intellij/psi/stubs/StubIndexImpl.java | 2 +- .../util/indexing/FileBasedIndexImpl.java | 2 +- .../intellij/util/indexing/MapReduceIndex.java | 8 ++++++++ .../util/indexing/MemoryIndexStorage.java | 16 ++++++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java index a295767004a8..84ce4d8c5183 100644 --- a/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/stubs/StubIndexImpl.java @@ -148,7 +148,7 @@ public class StubIndexImpl extends StubIndex implements ApplicationComponent, Pe extension instanceof StringStubIndexExtension && ((StringStubIndexExtension)extension).traceKeyHashToVirtualFileMapping() ); - final MemoryIndexStorage memStorage = new MemoryIndexStorage(storage); + final MemoryIndexStorage memStorage = new MemoryIndexStorage(storage, indexKey); MyIndex index = new MyIndex<>(new IndexExtension() { @NotNull @Override diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index cb08da424c04..e7682bc88d34 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -388,7 +388,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { } state.registerIndex(name, - createIndex(extension, new MemoryIndexStorage(storage)), + createIndex(extension, new MemoryIndexStorage(storage, name)), new FileBasedIndex.InputFilter() { @Override diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java index d3a7ca988288..436802bccbc6 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MapReduceIndex.java @@ -76,6 +76,14 @@ public class MapReduceIndex implements UpdatableIndex)myStorage).clearCaches(); + } finally { + getWriteLock().unlock(); + } + } flush(); } catch (StorageException e) { LOG.info(e); diff --git a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java index 6055feb67a0a..8b8503bf1765 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/MemoryIndexStorage.java @@ -36,6 +36,7 @@ public class MemoryIndexStorage implements IndexStorage @NotNull private final IndexStorage myBackendStorage; private final List myListeners = ContainerUtil.createLockFreeCopyOnWriteList(); + private final ID myIndexId; private boolean myBufferingEnabled; public interface BufferingStateListener { @@ -45,7 +46,12 @@ public class MemoryIndexStorage implements IndexStorage } public MemoryIndexStorage(@NotNull IndexStorage backend) { + this(backend, null); + } + + public MemoryIndexStorage(@NotNull IndexStorage backend, ID indexId) { myBackendStorage = backend; + myIndexId = indexId; } @NotNull @@ -85,6 +91,16 @@ public class MemoryIndexStorage implements IndexStorage } } + void clearCaches() { + if (myMap.size() == 0) return; + String message = "Dropping caches for " + (myIndexId != null ? myIndexId:this) + ", number of items:" + myMap.size(); + FileBasedIndexImpl.LOG.info(message); + + for(ChangeTrackingValueContainer v:myMap.values()) { + v.dropMergedData(); + } + } + @Override public void close() throws StorageException { myBackendStorage.close(); From 6bdfe468c41d1d26fdd5778f2a32b2369333b2e9 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 13 Apr 2016 07:08:53 +0300 Subject: [PATCH 47/64] inspection tool window: tree exclusion default text --- .../src/com/intellij/ide/actions/TreeNodeExclusionAction.java | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java b/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java index b0b1b88bb751..80f4de7fe1b8 100644 --- a/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java +++ b/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java @@ -60,6 +60,7 @@ public class TreeNodeExclusionAction extends AnAction private TreeNodeExclusionAction(boolean isExclude) { myIsExclude = isExclude; + getTemplatePresentation().setText(getActionText()); copyShortcutFrom(ActionManager.getInstance().getAction(myIsExclude ? "$Delete" : "EditorToggleInsertState")); } From f43e6b3ed80ebc61c4650541a95ccd8bda51f86a Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 13 Apr 2016 07:20:29 +0300 Subject: [PATCH 48/64] inspection tool window: tree exclusion action - do not need update text if disabled --- .../intellij/ide/actions/TreeNodeExclusionAction.java | 11 ++++++----- platform/platform-resources/src/idea/LangActions.xml | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java b/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java index 80f4de7fe1b8..91480b084920 100644 --- a/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java +++ b/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java @@ -61,7 +61,6 @@ public class TreeNodeExclusionAction extends AnAction private TreeNodeExclusionAction(boolean isExclude) { myIsExclude = isExclude; getTemplatePresentation().setText(getActionText()); - copyShortcutFrom(ActionManager.getInstance().getAction(myIsExclude ? "$Delete" : "EditorToggleInsertState")); } @Override @@ -93,11 +92,13 @@ public class TreeNodeExclusionAction extends AnAction } } presentation.setEnabledAndVisible(isEnabled); - String text = getActionText(); - if (selection.length > 1) { - text += " All"; + if (isEnabled) { + String text = getActionText(); + if (selection.length > 1) { + text += " All"; + } + presentation.setText(text); } - presentation.setText(text); } @Override diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 48961974ba6b..22172ed32733 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -991,7 +991,7 @@ - + > From ffdd1380f710c1a9754f870bfaf6fcf9d84f9cda Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 13 Apr 2016 10:04:17 +0300 Subject: [PATCH 49/64] inspection tool window: proper insert "of" when tabs.size == 1 --- .../ex/InspectionManagerEx.java | 19 ++++++++++++------- .../src/messages/InspectionsBundle.properties | 2 -- .../src/messages/UIBundle.properties | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java index 0e5bd5c69ef5..b46e55ecc3fd 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ex/InspectionManagerEx.java @@ -72,6 +72,8 @@ public class InspectionManagerEx extends InspectionManagerBase { toolWindow.setIcon(AllIcons.Toolwindows.ToolWindowInspection); new ContentManagerWatcher(toolWindow, contentManager); contentManager.addContentManagerListener(new ContentManagerAdapter() { + private static final String PREFIX = "of "; + @Override public void contentAdded(ContentManagerEvent event) { handleContentSizeChanged(); @@ -84,16 +86,19 @@ public class InspectionManagerEx extends InspectionManagerBase { private void handleContentSizeChanged() { final int count = contentManager.getContentCount(); - String newStripeTitle = null; if (count == 1) { - newStripeTitle = InspectionsBundle.message("inspection.tool.window.stripe.title.single.content"); + final Content content = contentManager.getContent(0); + final String displayName = content.getDisplayName(); + if (!content.getDisplayName().startsWith(PREFIX)) { + content.setDisplayName(PREFIX + displayName); + } } else if (count > 1) { - newStripeTitle = InspectionsBundle.message("inspection.tool.window.stripe.title.multiple.content"); - } - final String stripeTitle = toolWindow.getStripeTitle(); - if (newStripeTitle != null && !stripeTitle.equals(newStripeTitle)) { - toolWindow.setStripeTitle(newStripeTitle); + for (Content content : contentManager.getContents()) { + if (content.getDisplayName().startsWith(PREFIX)) { + content.setDisplayName(content.getDisplayName().substring(PREFIX.length())); + } + } } } }); diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index 4d5ab4a342f4..7e617bd06883 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -710,5 +710,3 @@ todo.comment.problem.descriptor=TODO comment #ref #loc long.line.display.name=Line is longer than allowed by code style inspection.default.annotation.param=Default annotation parameter value -inspection.tool.window.stripe.title.single.content=Inspection Results of -inspection.tool.window.stripe.title.multiple.content=Inspection Results diff --git a/platform/platform-resources-en/src/messages/UIBundle.properties b/platform/platform-resources-en/src/messages/UIBundle.properties index 73a3770f0b8e..013a21d00003 100644 --- a/platform/platform-resources-en/src/messages/UIBundle.properties +++ b/platform/platform-resources-en/src/messages/UIBundle.properties @@ -51,7 +51,7 @@ tool.window.name.run=Run tool.window.name.find=Find tool.window.name.cvs=CVS tool.window.name.hierarchy=Hierarchy -tool.window.name.inspection=Inspection +tool.window.name.inspection=Inspection Results tool.window.name.todo=TODO tool.window.name.dependency.viewer=Dependency Viewer tool.window.name.version.control=Version Control From 94b60ae68a3b858f378208ec2bcefc297c3bb584 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 13 Apr 2016 10:18:57 +0300 Subject: [PATCH 50/64] inspection tool window: use compact action group --- .../codeInspection/ui/QuickFixPreviewDecorator.java | 2 +- .../ui/actions/InspectionViewActionBase.java | 11 +---------- .../ui/actions/SuppressActionWrapper.java | 7 +------ platform/platform-resources/src/idea/LangActions.xml | 2 +- 4 files changed, 4 insertions(+), 18 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixPreviewDecorator.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixPreviewDecorator.java index b576d4c848a1..72ec034701a2 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixPreviewDecorator.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/QuickFixPreviewDecorator.java @@ -154,7 +154,7 @@ public class QuickFixPreviewDecorator extends JPanel implements InspectionTreeLo @NotNull @Override protected DefaultActionGroup createPopupActionGroup(JComponent button) { - DefaultActionGroup group = new DefaultActionGroup(); + DefaultActionGroup group = new DefaultCompactActionGroup(); group.addAll(suppressors); return group; } diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionViewActionBase.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionViewActionBase.java index 6139b7f5219d..d95cb42c2414 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionViewActionBase.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/InspectionViewActionBase.java @@ -41,22 +41,13 @@ public abstract class InspectionViewActionBase extends AnAction { final InspectionResultsView view = getView(e); final boolean enabled = view != null && isEnabled(view); final Presentation presentation = e.getPresentation(); - if (hideIfDisabled()) { - presentation.setEnabledAndVisible(enabled); - } - else { - presentation.setEnabled(enabled); - } + presentation.setEnabled(enabled); } protected boolean isEnabled(@NotNull InspectionResultsView view) { return true; } - protected boolean hideIfDisabled() { - return false; - } - public static InspectionResultsView getView(@Nullable AnActionEvent event) { if (event == null) { return null; diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java index d8cb876136d0..576bab57e023 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/SuppressActionWrapper.java @@ -56,7 +56,7 @@ import java.util.Set; import static com.intellij.codeInspection.ui.actions.InspectionViewActionBase.getView; -public class SuppressActionWrapper extends ActionGroup { +public class SuppressActionWrapper extends ActionGroup implements CompactActionGroup { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.actions.SuppressActionWrapper"); public SuppressActionWrapper() { @@ -209,11 +209,6 @@ public class SuppressActionWrapper extends ActionGroup { return false; } - @Override - protected boolean hideIfDisabled() { - return true; - } - public boolean isSuppressAll() { return mySuppressAction.isSuppressAll(); } diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index 22172ed32733..e71eeef5de21 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -994,7 +994,7 @@ > - + From 017a96da264b166d3be04c70d9b79b1bcb5ca3de Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Wed, 13 Apr 2016 10:26:36 +0300 Subject: [PATCH 51/64] IDEA-154578 Unable to save settings (please restart IntelliJ Idea) --- .../folding/impl/DocumentFoldingInfo.java | 9 ++- .../openapi/util/text/StringUtil.java | 59 +++++++++++++++++++ .../intellij/util/text/StringUtilTest.java | 10 ++++ 3 files changed, 75 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java index 2f91efed0e73..0acf48f30609 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java @@ -33,6 +33,7 @@ import com.intellij.openapi.fileEditor.impl.text.CodeFoldingState; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.util.containers.ContainerUtil; @@ -67,7 +68,8 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { @NonNls private static final String EXPANDED_ATT = "expanded"; @NonNls private static final String MARKER_TAG = "marker"; @NonNls private static final String DATE_ATT = "date"; - @NonNls private static final String PLACEHOLDER_ATT = "placeholder"; + @NonNls private static final String PLACEHOLDER_OLD_ATT = "placeholder"; + @NonNls private static final String PLACEHOLDER_ATT = "ph"; DocumentFoldingInfo(@NotNull Project project, @NotNull Document document) { myProject = project; @@ -274,7 +276,7 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { String signature = Integer.valueOf(marker.getStartOffset()) + ":" + Integer.valueOf(marker.getEndOffset()); e.setAttribute(SIGNATURE_ATT, signature); String placeHolderText = fi == null ? DEFAULT_PLACEHOLDER : fi.placeHolder; - e.setAttribute(PLACEHOLDER_ATT, placeHolderText); + e.setAttribute(PLACEHOLDER_ATT, StringUtil.escapeIllegalXmlChars(placeHolderText)); element.addContent(e); } } @@ -331,7 +333,8 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { if (start < 0 || end >= document.getTextLength() || start > end) continue; RangeMarker marker = document.createRangeMarker(start, end); myRangeMarkers.add(marker); - String placeHolderText = e.getAttributeValue(PLACEHOLDER_ATT); + String placeHolderText = StringUtil.unescapeIllegalXmlChars(e.getAttributeValue(PLACEHOLDER_ATT)); + if (placeHolderText == null) e.getAttributeValue(PLACEHOLDER_OLD_ATT); if (placeHolderText == null) placeHolderText = DEFAULT_PLACEHOLDER; FoldingInfo fi = new FoldingInfo(placeHolderText, expanded); marker.putUserData(FOLDING_INFO_KEY, fi); diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index d7c129700dc5..b6f5ab65a0e3 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -24,6 +24,7 @@ import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.CharArrayUtil; import com.intellij.util.text.CharSequenceSubSequence; import com.intellij.util.text.StringFactory; +import org.jdom.Verifier; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -2194,6 +2195,64 @@ public class StringUtil extends StringUtilRt { } } + /** + * Some characters are illegal in XML even as numerical character references. This method performs escaping of them + * in a custom format, which is supposed to be unescaped on retrieving from XML using {@link #unescapeIllegalXmlChars(String)}. + * Resulting text can be part of XML version 1.0 document. + * + * @see https://www.w3.org/International/questions/qa-controls + * @see Verifier#isXMLCharacter(int) + */ + public static String escapeIllegalXmlChars(@NotNull String text) { + StringBuilder b = null; + int lastPos = 0; + for (int i = 0; i < text.length(); i++) { + int c = text.codePointAt(i); + if (Character.isSupplementaryCodePoint(c)) { + //noinspection AssignmentToForLoopParameter + i++; + } + if (c == '#' || !Verifier.isXMLCharacter(c)) { + if (b == null) b = new StringBuilder(text.length() + 5); // assuming there's one 'large' char (e.g. 0xFFFF) to escape numerically + b.append(text, lastPos, i).append('#'); + if (c != '#') b.append(Integer.toHexString(c)); + b.append('#'); + lastPos = i + 1; + } + } + return b == null ? text : b.append(text, lastPos, text.length()).toString(); + } + + /** + * @see #escapeIllegalXmlChars(String) + */ + public static String unescapeIllegalXmlChars(@NotNull String text) { + StringBuilder b = null; + int lastPos = 0; + for (int i = 0; i < text.length(); i++) { + int c = text.charAt(i); + if (c == '#') { + int numberEnd = text.indexOf('#', i + 1); + if (numberEnd > 0) { + int charCode; + try { + charCode = numberEnd == (i + 1) ? '#' : Integer.parseInt(text.substring(i + 1, numberEnd), 16); + } + catch (NumberFormatException e) { + continue; + } + if (b == null) b = new StringBuilder(text.length()); + b.append(text, lastPos, i); + b.append((char) charCode); + //noinspection AssignmentToForLoopParameter + i = numberEnd; + lastPos = i + 1; + } + } + } + return b == null ? text : b.append(text, lastPos, text.length()).toString(); + } + public static void quote(@NotNull final StringBuilder builder) { quote(builder, '\"'); } diff --git a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java index f8136aebdde0..0d37f66d1db2 100644 --- a/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/text/StringUtilTest.java @@ -19,6 +19,7 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.LineSeparator; import com.intellij.xml.util.XmlStringUtil; +import org.jdom.Verifier; import org.junit.Test; import java.nio.CharBuffer; @@ -492,4 +493,13 @@ public class StringUtilTest { assertEquals(3, StringUtil.lastIndexOf("axaxa", 'x', 0, 5)); assertEquals(2, StringUtil.lastIndexOf("abcd", 'c', -42, 99)); // #IDEA-144968 } + + @Test + public void testEscapingIllegalXmlChars() { + for (String s : new String[]{"ab\n\0\r\tde", "\\abc\1\2\3\uFFFFdef"}) { + String escapedText = StringUtil.escapeIllegalXmlChars(s); + assertNull(Verifier.checkCharacterData(escapedText)); + assertEquals(s, StringUtil.unescapeIllegalXmlChars(escapedText)); + } + } } From a69953836caafef31fe99fa81788c90cf42c052d Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Wed, 13 Apr 2016 10:37:09 +0300 Subject: [PATCH 52/64] remove fallback logic (following fix for IDEA-154578) this is for master only - assuming that it's ok to loose folding state information for recently opened files when migrating to a newer IDE version --- .../intellij/codeInsight/folding/impl/DocumentFoldingInfo.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java index 0acf48f30609..d60f4bc3ae9d 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java @@ -68,7 +68,6 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { @NonNls private static final String EXPANDED_ATT = "expanded"; @NonNls private static final String MARKER_TAG = "marker"; @NonNls private static final String DATE_ATT = "date"; - @NonNls private static final String PLACEHOLDER_OLD_ATT = "placeholder"; @NonNls private static final String PLACEHOLDER_ATT = "ph"; DocumentFoldingInfo(@NotNull Project project, @NotNull Document document) { @@ -334,7 +333,6 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { RangeMarker marker = document.createRangeMarker(start, end); myRangeMarkers.add(marker); String placeHolderText = StringUtil.unescapeIllegalXmlChars(e.getAttributeValue(PLACEHOLDER_ATT)); - if (placeHolderText == null) e.getAttributeValue(PLACEHOLDER_OLD_ATT); if (placeHolderText == null) placeHolderText = DEFAULT_PLACEHOLDER; FoldingInfo fi = new FoldingInfo(placeHolderText, expanded); marker.putUserData(FOLDING_INFO_KEY, fi); From bc0826f4e0ddaa5e2f70b78542d3896be3a53df0 Mon Sep 17 00:00:00 2001 From: "Egor.Ushakov" Date: Wed, 13 Apr 2016 11:33:59 +0300 Subject: [PATCH 53/64] do not highlight errors in return statements in debugger code fragments - avoid user data keys (IDEA-CR-10075) --- .../engine/evaluation/DefaultCodeFragmentFactory.java | 2 -- .../codeInsight/daemon/impl/analysis/HighlightUtil.java | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java index a69cd899f960..830ecbb70a63 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/DefaultCodeFragmentFactory.java @@ -18,7 +18,6 @@ package com.intellij.debugger.engine.evaluation; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionService; import com.intellij.codeInsight.completion.JavaCompletionUtil; -import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.codeinsight.RuntimeTypeEvaluator; import com.intellij.debugger.engine.evaluation.expression.EvaluatorBuilder; @@ -76,7 +75,6 @@ public class DefaultCodeFragmentFactory extends CodeFragmentFactory { fragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE); //noinspection HardCodedStringLiteral fragment.putUserData(KEY, "DebuggerComboBoxEditor.IS_DEBUGGER_EDITOR"); - fragment.putUserData(HighlightUtil.DISABLE_RETURN_CHECK_IN_CODE_FRAGMENT, true); fragment.putCopyableUserData(JavaCompletionUtil.DYNAMIC_TYPE_EVALUATOR, new PairFunction() { public PsiType fun(PsiExpression expression, CompletionParameters parameters) { if (!RuntimeTypeEvaluator.isSubtypeable(expression)) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java index 0cda6140d70e..0e0cc7d63a3c 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java @@ -87,8 +87,6 @@ public class HighlightUtil extends HighlightUtilBase { @NonNls private static final String SERIAL_PERSISTENT_FIELDS_FIELD_NAME = "serialPersistentFields"; private static final QuickFixFactory QUICK_FIX_FACTORY = QuickFixFactory.getInstance(); - public static final Key DISABLE_RETURN_CHECK_IN_CODE_FRAGMENT = Key.create("DISABLE_RETURN_CHECK_IN_CODE_FRAGMENT"); - private HighlightUtil() { } static { @@ -596,7 +594,7 @@ public class HighlightUtil extends HighlightUtilBase { } parent = parent.getParent(); } - if (parent instanceof PsiCodeFragment && parent.getUserData(DISABLE_RETURN_CHECK_IN_CODE_FRAGMENT) != null) { + if (parent instanceof PsiCodeFragment) { return null; } String description; From ce2dec4ee18cdfb435b093dc35605bfcbf6a6fa9 Mon Sep 17 00:00:00 2001 From: Dmitry Batrak Date: Wed, 13 Apr 2016 11:44:33 +0300 Subject: [PATCH 54/64] fix problem with unexpected null value (following fix for IDEA-154578) --- .../codeInsight/folding/impl/DocumentFoldingInfo.java | 5 +++-- .../util/src/com/intellij/openapi/util/text/StringUtil.java | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java index d60f4bc3ae9d..bbd78f6372f1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/DocumentFoldingInfo.java @@ -332,8 +332,9 @@ class DocumentFoldingInfo implements JDOMExternalizable, CodeFoldingState { if (start < 0 || end >= document.getTextLength() || start > end) continue; RangeMarker marker = document.createRangeMarker(start, end); myRangeMarkers.add(marker); - String placeHolderText = StringUtil.unescapeIllegalXmlChars(e.getAttributeValue(PLACEHOLDER_ATT)); - if (placeHolderText == null) placeHolderText = DEFAULT_PLACEHOLDER; + String placeholderAttributeValue = e.getAttributeValue(PLACEHOLDER_ATT); + String placeHolderText = placeholderAttributeValue == null ? DEFAULT_PLACEHOLDER + : StringUtil.unescapeIllegalXmlChars(placeholderAttributeValue); FoldingInfo fi = new FoldingInfo(placeHolderText, expanded); marker.putUserData(FOLDING_INFO_KEY, fi); } diff --git a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java index b6f5ab65a0e3..b65c9d5ef958 100644 --- a/platform/util/src/com/intellij/openapi/util/text/StringUtil.java +++ b/platform/util/src/com/intellij/openapi/util/text/StringUtil.java @@ -2203,6 +2203,7 @@ public class StringUtil extends StringUtilRt { * @see https://www.w3.org/International/questions/qa-controls * @see Verifier#isXMLCharacter(int) */ + @NotNull public static String escapeIllegalXmlChars(@NotNull String text) { StringBuilder b = null; int lastPos = 0; @@ -2226,6 +2227,7 @@ public class StringUtil extends StringUtilRt { /** * @see #escapeIllegalXmlChars(String) */ + @NotNull public static String unescapeIllegalXmlChars(@NotNull String text) { StringBuilder b = null; int lastPos = 0; From 5beacf0b13df15afaed9b18933e0f6cc79c5dc30 Mon Sep 17 00:00:00 2001 From: "Maxim.Mossienko" Date: Wed, 13 Apr 2016 12:10:33 +0200 Subject: [PATCH 55/64] contentsChanged event for file outside indexablesets doesn't add the file for filesToBeIndexed --- .../util/indexing/FileBasedIndexImpl.java | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index e7682bc88d34..fc5d7f81bc97 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -1791,8 +1791,8 @@ public class FileBasedIndexImpl extends FileBasedIndex { clearUpToDateStateForPsiIndicesOfUnsavedDocuments(file); - // the file is for sure not a dir and it was previously indexed by at least one index AND it belongs to some update set - if (!isTooLarge(file) && getIndexableSetForFile(file) != null) myChangedFilesCollector.scheduleForUpdate(file); + // the file is for sure not a dir and it was previously indexed by at least one index + if (!isTooLarge(file)) myChangedFilesCollector.scheduleForUpdate(file); } } else if (!fileIndexedStatesToUpdate.isEmpty()) { // file was removed, its data should be (lazily) wiped for every index @@ -1854,10 +1854,10 @@ public class FileBasedIndexImpl extends FileBasedIndex { } } - if (scheduleForUpdate) { - if (resetStamp) IndexingStamp.flushCache(fileId); - myChangedFilesCollector.scheduleForUpdate(file); - } + if (scheduleForUpdate) { + if (resetStamp) IndexingStamp.flushCache(fileId); + myChangedFilesCollector.scheduleForUpdate(file); + } if (!myUpToDateIndicesForUnsavedOrTransactedDocuments.isEmpty()) { clearUpToDateStateForPsiIndicesOfUnsavedDocuments(file); @@ -1922,6 +1922,12 @@ public class FileBasedIndexImpl extends FileBasedIndex { } void scheduleForUpdate(VirtualFile file) { + if (!(file instanceof DeletedVirtualFileStub)) { + IndexableFileSet setForFile = getIndexableSetForFile(file); + if (setForFile == null) { + return; + } + } final int fileId = Math.abs(getIdMaskingNonIdBasedFile(file)); final VirtualFile previousVirtualFile = myFilesToUpdate.put(fileId, file); From 908611534782b254d7016e09bddbb74e8c958602 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 13 Apr 2016 11:25:17 +0200 Subject: [PATCH 56/64] method ref: type parameter instantiation (IDEA-154645) --- .../impl/source/tree/java/MethodReferenceResolver.java | 4 +++- .../lambda/newMethodRef/TypeParameterInstantiation.java | 8 ++++++++ .../daemon/lambda/NewMethodRefHighlightingTest.java | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/TypeParameterInstantiation.java diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java index 785cb7e57d4d..8d40e2914d9c 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/MethodReferenceResolver.java @@ -54,7 +54,9 @@ public class MethodReferenceResolver implements ResolveCache.PolyVariantContextR final PsiElement element = reference.getReferenceNameElement(); final boolean isConstructor = reference.isConstructor(); if (element instanceof PsiIdentifier || isConstructor) { - if (isConstructor && (containingClass.isEnum() || containingClass.hasModifierProperty(PsiModifier.ABSTRACT))) { + if (isConstructor && (containingClass.isEnum() || + containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || + containingClass instanceof PsiTypeParameter)) { return JavaResolveResult.EMPTY_ARRAY; } final PsiType functionalInterfaceType = getInterfaceType(reference); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/TypeParameterInstantiation.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/TypeParameterInstantiation.java new file mode 100644 index 000000000000..8c2124022fa9 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/TypeParameterInstantiation.java @@ -0,0 +1,8 @@ + +import java.util.function.Supplier; + +class Test { + { + Supplier aNew = T::new; + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java index 5a2a9368959f..c140584b90ae 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java @@ -506,6 +506,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testTypeParameterInstantiation() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } From 7c49161bc47bcb786bb6bd01dedcd087dbff7995 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 13 Apr 2016 11:39:24 +0200 Subject: [PATCH 57/64] pull up: init abstract state for member if checkbox is disabled (IDEA-154608) --- .../src/com/intellij/refactoring/memberPullUp/PullUpDialog.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java index 779711b15e74..6f454ed3f563 100644 --- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpDialog.java @@ -156,8 +156,8 @@ public class PullUpDialog extends PullUpDialogBase Date: Wed, 13 Apr 2016 12:26:32 +0200 Subject: [PATCH 58/64] lang parameter table panel extracted: SimpleParameterTablePanel for parameters without types --- .../refactoring/util/VariableData.java | 20 +- .../IntroduceParameterObjectDialog.java | 2 +- .../refactoring/util/ParameterTablePanel.java | 335 ++++------------ .../util/AbstractVariableData.java | 34 ++ .../AbstactExtractMethodDialog.form | 2 +- .../AbstractExtractMethodDialog.java | 22 +- .../AbstractParameterTablePanel.java | 238 ------------ .../extractMethod/AbstractVariableData.java | 31 +- .../extractMethod/ExtractMethodDecorator.java | 11 +- .../extractMethod/ExtractMethodSettings.java | 9 +- .../extractMethod/SimpleDuplicatesFinder.java | 12 +- .../util/AbstractParameterTablePanel.java | 244 ++++++++++++ .../util/SimpleParameterTablePanel.java | 24 ++ .../extract/ExtractInfoHelperBase.java | 2 +- .../refactoring/extract/ExtractUtil.java | 8 +- .../extract/GrParameterTablePanel.java | 46 +++ .../refactoring/extract/ParameterInfo.java | 42 +-- .../extract/ParameterTablePanel.java | 357 ------------------ .../method/GroovyExtractMethodDialog.java | 6 +- .../method/GroovyExtractMethodHandler.java | 2 +- .../parameter/GrIntroduceParameterDialog.java | 12 +- .../extractmethod/PyExtractMethodUtil.java | 9 +- 22 files changed, 513 insertions(+), 955 deletions(-) create mode 100644 platform/analysis-impl/src/com/intellij/refactoring/util/AbstractVariableData.java delete mode 100644 platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractParameterTablePanel.java create mode 100644 platform/lang-impl/src/com/intellij/refactoring/util/AbstractParameterTablePanel.java create mode 100644 platform/lang-impl/src/com/intellij/refactoring/util/SimpleParameterTablePanel.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/GrParameterTablePanel.java delete mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ParameterTablePanel.java diff --git a/java/java-analysis-impl/src/com/intellij/refactoring/util/VariableData.java b/java/java-analysis-impl/src/com/intellij/refactoring/util/VariableData.java index bcb4e271d545..d367ceb0e768 100644 --- a/java/java-analysis-impl/src/com/intellij/refactoring/util/VariableData.java +++ b/java/java-analysis-impl/src/com/intellij/refactoring/util/VariableData.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * 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. @@ -18,23 +18,27 @@ package com.intellij.refactoring.util; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; -public class VariableData { +public class VariableData extends AbstractVariableData { public final PsiVariable variable; public PsiType type; - public String name; - public boolean passAsParameter; public VariableData(@NotNull PsiVariable var) { variable = var; type = var.getType(); } - public VariableData(@NotNull PsiVariable var, @NotNull PsiType type) { + public VariableData(@Nullable PsiVariable var, PsiType type) { variable = var; - if (type instanceof PsiLambdaParameterType || type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType) { - type = PsiType.getJavaLangObject(var.getManager(), GlobalSearchScope.allScope(var.getProject())); + if (var != null) { + if (type instanceof PsiLambdaParameterType || type instanceof PsiLambdaExpressionType || type instanceof PsiMethodReferenceType) { + type = PsiType.getJavaLangObject(var.getManager(), GlobalSearchScope.allScope(var.getProject())); + } + this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType(); + } + else { + this.type = type; } - this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType(); } } diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java index 4a1482c390a4..fa89c769b200 100644 --- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java +++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java @@ -259,7 +259,7 @@ public class IntroduceParameterObjectDialog extends RefactoringDialog { protected JComponent createCenterPanel() { sourceMethodTextField.setEditable(false); - final ParameterTablePanel paramsPanel = new ParameterTablePanel(myProject, parameterInfo, sourceMethod) { + final ParameterTablePanel paramsPanel = new ParameterTablePanel(myProject, parameterInfo) { protected void updateSignature() {} protected void doEnterAction() {} diff --git a/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java b/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java index b12da0bcbd7a..6210e347f1f7 100644 --- a/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java +++ b/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java @@ -15,100 +15,59 @@ */ package com.intellij.refactoring.util; +import com.intellij.lang.LanguageNamesValidation; +import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; import com.intellij.psi.*; import com.intellij.refactoring.ui.TypeSelector; import com.intellij.refactoring.ui.TypeSelectorManager; import com.intellij.refactoring.ui.TypeSelectorManagerImpl; -import com.intellij.ui.BooleanTableCellRenderer; import com.intellij.ui.ListCellRendererWrapper; -import com.intellij.ui.TableUtil; -import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.components.JBComboBoxLabel; import com.intellij.ui.components.editors.JBComboBoxTableCellEditorComponent; -import com.intellij.ui.table.JBTable; -import com.intellij.util.Function; import com.intellij.util.ui.AbstractTableCellEditor; -import com.intellij.util.ui.EditableModel; -import org.jetbrains.annotations.NonNls; +import com.intellij.util.ui.ColumnInfo; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.TableCellEditor; import javax.swing.table.TableColumn; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; import java.util.ArrayList; +import java.util.function.Predicate; -/** - * @author Konstantin Bulenkov - */ -public abstract class ParameterTablePanel extends JPanel { - private final Project myProject; - private final VariableData[] myVariableData; - private final TypeSelector[] myParameterTypeSelectors; - private final JBTable myTable; - private final MyTableModel myTableModel; - private final JComboBox myTypeRendererCombo; +public abstract class ParameterTablePanel extends AbstractParameterTablePanel { - public VariableData[] getVariableData() { - return myVariableData; + private TypeSelector[] myParameterTypeSelectors; + private JComboBox myTypeRendererCombo; + + public ParameterTablePanel(Project project, + VariableData[] variableData, + PsiElement... scopeElements) { + this(paramName -> LanguageNamesValidation.INSTANCE.forLanguage(JavaLanguage.INSTANCE).isIdentifier(paramName, project)); + init(variableData, project, scopeElements); } - protected abstract void updateSignature(); - - protected abstract void doEnterAction(); - - protected abstract void doCancelAction(); - - protected boolean areTypesDirected() { - return true; + public ParameterTablePanel(Predicate parameterNameValidator) { + super(new PassParameterColumnInfo(), + new TypeColumnInfo(), + new NameColumnInfo(parameterNameValidator)); } - public ParameterTablePanel(Project project, VariableData[] variableData, final PsiElement... scopeElements) { - super(new BorderLayout()); - myProject = project; - myVariableData = variableData; - - myTableModel = new MyTableModel(); - myTable = new JBTable(myTableModel); - DefaultCellEditor defaultEditor = (DefaultCellEditor)myTable.getDefaultEditor(Object.class); - defaultEditor.setClickCountToStart(1); - - - myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - myTable.setCellSelectionEnabled(true); - TableColumn checkboxColumn = myTable.getColumnModel().getColumn(MyTableModel.CHECKMARK_COLUMN); - TableUtil.setupCheckboxColumn(checkboxColumn); - checkboxColumn.setCellRenderer(new CheckBoxTableCellRenderer()); - myTable.getColumnModel().getColumn(MyTableModel.PARAMETER_NAME_COLUMN).setCellRenderer(new DefaultTableCellRenderer() { - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - VariableData data = getVariableData()[row]; - setText(data.name); - return this; - } - }); + public void init(VariableData[] variableData, Project project, PsiElement... scopeElements) { + super.init(variableData); myParameterTypeSelectors = new TypeSelector[getVariableData().length]; for (int i = 0; i < myParameterTypeSelectors.length; i++) { - final PsiVariable variable = getVariableData()[i].variable; - final PsiExpression[] occurrences = findVariableOccurrences(scopeElements, variable); - final TypeSelectorManager manager = new TypeSelectorManagerImpl(myProject, getVariableData()[i].type, occurrences, areTypesDirected()) { - @Override - protected boolean isUsedAfter() { - return ParameterTablePanel.this.isUsedAfter(variable); - } - }; - myParameterTypeSelectors[i] = manager.getTypeSelector(); + final VariableData data = variableData[i]; + final TypeSelector selector = createSelector(project, data, scopeElements); + myParameterTypeSelectors[i] = selector; getVariableData()[i].type = myParameterTypeSelectors[i].getSelectedType(); //reverse order } - myTypeRendererCombo = new JComboBox(getVariableData()); + myTypeRendererCombo = new ComboBox(getVariableData()); myTypeRendererCombo.setOpaque(true); myTypeRendererCombo.setBorder(null); myTypeRendererCombo.setRenderer(new ListCellRendererWrapper() { @@ -121,7 +80,7 @@ public abstract class ParameterTablePanel extends JPanel { }); - final TableColumn typeColumn = myTable.getColumnModel().getColumn(MyTableModel.PARAMETER_TYPE_COLUMN); + final TableColumn typeColumn = myTable.getColumnModel().getColumn(1); typeColumn.setCellEditor(new AbstractTableCellEditor() { TypeSelector myCurrentSelector; final JBComboBoxTableCellEditorComponent myEditorComponent = new JBComboBoxTableCellEditorComponent(); @@ -139,12 +98,7 @@ public abstract class ParameterTablePanel extends JPanel { myEditorComponent.setCell(table, row, column); myEditorComponent.setOptions(myParameterTypeSelectors[row].getTypes()); myEditorComponent.setDefaultValue(getVariableData()[row].type); - myEditorComponent.setToString(new Function() { - @Override - public String fun(Object o) { - return ((PsiType)o).getPresentableText(); - } - }); + myEditorComponent.setToString(o -> ((PsiType)o).getPresentableText()); myCurrentSelector = myParameterTypeSelectors[row]; return myEditorComponent; @@ -152,96 +106,40 @@ public abstract class ParameterTablePanel extends JPanel { }); - - myTable.getColumnModel().getColumn(MyTableModel.PARAMETER_TYPE_COLUMN).setCellRenderer(new DefaultTableCellRenderer() { + myTable.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() { private final JBComboBoxLabel myLabel = new JBComboBoxLabel(); - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - myLabel.setText(String.valueOf(value)); + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + myLabel.setText(((PsiType)value).getPresentableText()); myLabel.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); myLabel.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground()); if (isSelected) { myLabel.setSelectionIcon(); - } else { + } + else { myLabel.setRegularIcon(); } return myLabel; } }); + } - myTable.setPreferredScrollableViewportSize(new Dimension(250, myTable.getRowHeight() * 5)); - myTable.setShowGrid(false); - myTable.setIntercellSpacing(new Dimension(0, 0)); - @NonNls final InputMap inputMap = myTable.getInputMap(); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); - @NonNls final ActionMap actionMap = myTable.getActionMap(); - actionMap.put("enable_disable", new AbstractAction() { - public void actionPerformed(ActionEvent e) { - if (myTable.isEditing()) return; - int[] rows = myTable.getSelectedRows(); - if (rows.length > 0) { - boolean valueToBeSet = false; - for (int row : rows) { - if (!getVariableData()[row].passAsParameter) { - valueToBeSet = true; - break; - } - } - for (int row : rows) { - getVariableData()[row].passAsParameter = valueToBeSet; - } - myTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]); - TableUtil.selectRows(myTable, rows); + protected TypeSelector createSelector(final Project project, final VariableData data, PsiElement[] scopeElements) { + final PsiVariable variable = data.variable; + final PsiExpression[] occurrences = findVariableOccurrences(scopeElements, variable); + final TypeSelectorManager manager = + new TypeSelectorManagerImpl(project, data.type, occurrences, areTypesDirected()) { + @Override + protected boolean isUsedAfter() { + return ParameterTablePanel.this.isUsedAfter(variable); } - } - }); - //// F2 should edit the name - //inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "edit_parameter_name"); - //actionMap.put("edit_parameter_name", new AbstractAction() { - // public void actionPerformed(ActionEvent e) { - // if (!myTable.isEditing()) { - // int row = myTable.getSelectedRow(); - // if (row >= 0 && row < myTableModel.getRowCount()) { - // TableUtil.editCellAt(myTable, row, MyTableModel.PARAMETER_NAME_COLUMN); - // } - // } - // } - //}); - - //// make ENTER work when the table has focus - //inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "invokeImpl"); - //actionMap.put("invokeImpl", new AbstractAction() { - // public void actionPerformed(ActionEvent e) { - // TableCellEditor editor = myTable.getCellEditor(); - // if (editor != null) { - // editor.stopCellEditing(); - // } - // else { - // doEnterAction(); - // } - // } - //}); - - // make ESCAPE work when the table has focus - actionMap.put("doCancel", new AbstractAction() { - public void actionPerformed(ActionEvent e) { - TableCellEditor editor = myTable.getCellEditor(); - if (editor != null) { - editor.stopCellEditing(); - } - else { - doCancelAction(); - } - } - }); - - - JPanel listPanel = ToolbarDecorator.createDecorator(myTable).disableAddAction().disableRemoveAction().createPanel(); - add(listPanel, BorderLayout.CENTER); - - if (getVariableData().length > 1) { - myTable.getSelectionModel().setSelectionInterval(0, 0); - } + }; + return manager.getTypeSelector(); } protected boolean isUsedAfter(PsiVariable variable) { @@ -263,141 +161,40 @@ public abstract class ParameterTablePanel extends JPanel { return result.toArray(new PsiExpression[result.size()]); } - - public void setEnabled(boolean enabled) { - myTable.setEnabled(enabled); - super.setEnabled(enabled); + @Override + protected void exchangeRows(int row, int targetRow, VariableData currentItem) { + super.exchangeRows(row, targetRow, currentItem); + TypeSelector currentSelector = myParameterTypeSelectors[row]; + myParameterTypeSelectors[row] = myParameterTypeSelectors[targetRow]; + myParameterTypeSelectors[targetRow] = currentSelector; + myTypeRendererCombo.setModel(new DefaultComboBoxModel(getVariableData())); } - private class MyTableModel extends AbstractTableModel implements EditableModel { - public static final int CHECKMARK_COLUMN = 0; - public static final int PARAMETER_TYPE_COLUMN = 1; - public static final int PARAMETER_NAME_COLUMN = 2; + private static class TypeColumnInfo extends ColumnInfo { - public int getRowCount() { - return getVariableData().length; - } - - public int getColumnCount() { - return 3; - } - - public Object getValueAt(int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: { - return getVariableData()[rowIndex].passAsParameter; - } - case PARAMETER_NAME_COLUMN: { - return getVariableData()[rowIndex].name; - } - case PARAMETER_TYPE_COLUMN: { - return getVariableData()[rowIndex].type.getPresentableText(); - } - } - assert false; - return null; - } - - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: { - getVariableData()[rowIndex].passAsParameter = ((Boolean)aValue).booleanValue(); - fireTableRowsUpdated(rowIndex, rowIndex); - myTable.getSelectionModel().setSelectionInterval(rowIndex, rowIndex); - updateSignature(); - break; - } - case PARAMETER_NAME_COLUMN: { - VariableData data = getVariableData()[rowIndex]; - String name = (String)aValue; - if (PsiNameHelper.getInstance(myProject).isIdentifier(name)) { - data.name = name; - } - updateSignature(); - break; - } - case PARAMETER_TYPE_COLUMN: { - VariableData data = getVariableData()[rowIndex]; - data.type = (PsiType)aValue; - updateSignature(); - break; - } - } + public TypeColumnInfo() { + super("Type"); } @Override - public String getColumnName(int column) { - switch (column) { - case CHECKMARK_COLUMN: return ""; - case PARAMETER_TYPE_COLUMN: return "Type"; - case PARAMETER_NAME_COLUMN: return "Name"; - } - return ""; + public void setValue(VariableData data, PsiType value) { + data.type = value; } - public boolean isCellEditable(int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: - return isEnabled(); - case PARAMETER_NAME_COLUMN: - return isEnabled() && getVariableData()[rowIndex].passAsParameter; - case PARAMETER_TYPE_COLUMN: - return isEnabled() && getVariableData()[rowIndex].passAsParameter && !(myParameterTypeSelectors[rowIndex].getComponent() instanceof JLabel); - default: - return false; - } - } - - public Class getColumnClass(int columnIndex) { - if (columnIndex == CHECKMARK_COLUMN) { - return Boolean.class; - } - return super.getColumnClass(columnIndex); + @Nullable + @Override + public PsiType valueOf(VariableData data) { + return data.type; } @Override - public void addRow() { - throw new IllegalAccessError("Not implemented"); + public Class getColumnClass() { + return PsiType.class; } @Override - public void removeRow(int index) { - throw new IllegalAccessError("Not implemented"); - } - - @Override - public void exchangeRows(int row, int targetRow) { - if (row < 0 || row >= getVariableData().length) return; - if (targetRow < 0 || targetRow >= getVariableData().length) return; - - final VariableData currentItem = getVariableData()[row]; - getVariableData()[row] = getVariableData()[targetRow]; - getVariableData()[targetRow] = currentItem; - - TypeSelector currentSelector = myParameterTypeSelectors[row]; - myParameterTypeSelectors[row] = myParameterTypeSelectors[targetRow]; - myParameterTypeSelectors[targetRow] = currentSelector; - - myTypeRendererCombo.setModel(new DefaultComboBoxModel(getVariableData())); - - myTableModel.fireTableRowsUpdated(Math.min(targetRow, row), Math.max(targetRow, row)); - myTable.getSelectionModel().setSelectionInterval(targetRow, targetRow); - updateSignature(); - } - - @Override - public boolean canExchangeRows(int row, int targetRow) { - if (row < 0 || row >= getVariableData().length) return false; - if (targetRow < 0 || targetRow >= getVariableData().length) return false; + public boolean isCellEditable(VariableData data) { return true; } } - - private class CheckBoxTableCellRenderer extends BooleanTableCellRenderer { - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component rendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - rendererComponent.setEnabled(ParameterTablePanel.this.isEnabled()); - return rendererComponent; - } - } } diff --git a/platform/analysis-impl/src/com/intellij/refactoring/util/AbstractVariableData.java b/platform/analysis-impl/src/com/intellij/refactoring/util/AbstractVariableData.java new file mode 100644 index 000000000000..3723525b56be --- /dev/null +++ b/platform/analysis-impl/src/com/intellij/refactoring/util/AbstractVariableData.java @@ -0,0 +1,34 @@ +/* + * 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.refactoring.util; + +public class AbstractVariableData { + public String originalName; + public String name; + public boolean passAsParameter; + + public String getName() { + return name; + } + + public String getOriginalName() { + return originalName; + } + + public boolean isPassAsParameter() { + return passAsParameter; + } +} diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstactExtractMethodDialog.form b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstactExtractMethodDialog.form index 1de53ad6f31b..bb971d7b95eb 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstactExtractMethodDialog.form +++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstactExtractMethodDialog.form @@ -48,7 +48,7 @@ - + diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractMethodDialog.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractMethodDialog.java index 1fc9dc3e7fcc..bbca1a5cba1c 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractMethodDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractMethodDialog.java @@ -23,6 +23,8 @@ import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.ui.Messages; import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.ui.MethodSignatureComponent; +import com.intellij.refactoring.util.AbstractVariableData; +import com.intellij.refactoring.util.SimpleParameterTablePanel; import com.intellij.ui.DocumentAdapter; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; @@ -36,7 +38,7 @@ import java.util.Map; public class AbstractExtractMethodDialog extends DialogWrapper implements ExtractMethodSettings { private JPanel myContentPane; - private AbstractParameterTablePanel myParametersPanel; + private SimpleParameterTablePanel myParametersPanel; private JTextField myMethodNameTextField; private MethodSignatureComponent mySignaturePreviewTextArea; private JTextArea myOutputVariablesTextArea; @@ -90,10 +92,9 @@ public class AbstractExtractMethodDialog extends DialogWrapper implements Extrac }); - myVariableData = createVariableData(myArguments); + myVariableData = createVariableDataByNames(myArguments); myVariablesMap = createVariableMap(myVariableData); - myParametersPanel.setVariableData(myVariableData); - myParametersPanel.init(); + myParametersPanel.init(myVariableData); updateOutputVariables(); updateSignature(); @@ -105,7 +106,7 @@ public class AbstractExtractMethodDialog extends DialogWrapper implements Extrac return myMethodNameTextField; } - public static AbstractVariableData[] createVariableData(final List args) { + public static AbstractVariableData[] createVariableDataByNames(final List args) { final AbstractVariableData[] datas = new AbstractVariableData[args.size()]; for (int i = 0; i < args.size(); i++) { final AbstractVariableData data = new AbstractVariableData(); @@ -118,6 +119,11 @@ public class AbstractExtractMethodDialog extends DialogWrapper implements Extrac return datas; } + @Deprecated + public static com.intellij.refactoring.extractMethod.AbstractVariableData[] createVariableData(final List args) { + return com.intellij.refactoring.extractMethod.AbstractVariableData.copy(createVariableDataByNames(args)); + } + public static Map createVariableMap(final AbstractVariableData[] data) { final HashMap map = new HashMap(); for (AbstractVariableData variableData : data) { @@ -158,7 +164,7 @@ public class AbstractExtractMethodDialog extends DialogWrapper implements Extrac } private void createUIComponents() { - myParametersPanel = new AbstractParameterTablePanel(myValidator){ + myParametersPanel = new SimpleParameterTablePanel(myValidator::isValidName) { @Override protected void doCancelAction() { AbstractExtractMethodDialog.this.doCancelAction(); @@ -197,7 +203,7 @@ public class AbstractExtractMethodDialog extends DialogWrapper implements Extrac } private void updateSignature() { - mySignaturePreviewTextArea.setSignature(myDecorator.createMethodPreview(getMethodName(), myVariableData)); + mySignaturePreviewTextArea.setSignature(myDecorator.createMethodSignature(getMethodName(), myVariableData)); } private void updateOkStatus() { @@ -210,7 +216,7 @@ public class AbstractExtractMethodDialog extends DialogWrapper implements Extrac } @Override - public AbstractVariableData[] getVariableData() { + public AbstractVariableData[] getAbstractVariableData() { return myVariableData; } diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractParameterTablePanel.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractParameterTablePanel.java deleted file mode 100644 index c62a9cb3dc26..000000000000 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractParameterTablePanel.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2000-2015 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.refactoring.extractMethod; - -import com.intellij.ui.TableUtil; -import com.intellij.ui.ToolbarDecorator; -import com.intellij.ui.table.JBTable; -import com.intellij.util.ui.EditableModel; -import com.intellij.util.ui.JBUI; -import org.jetbrains.annotations.NonNls; - -import javax.swing.*; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; - -/** - * @author oleg - * It`s a modified copy of com.intellij.refactoring.util.ParameterTablePanel - */ -public abstract class AbstractParameterTablePanel extends JPanel { - private AbstractVariableData[] myVariableData; - - private JBTable myTable; - private MyTableModel myTableModel; - private final ExtractMethodValidator myValidator; - - protected abstract void updateSignature(); - - protected abstract void doEnterAction(); - - protected abstract void doCancelAction(); - - public void setVariableData(AbstractVariableData[] variableData) { - myVariableData = variableData; - } - - public AbstractParameterTablePanel(final ExtractMethodValidator validator) { - super(new BorderLayout()); - myValidator = validator; - } - - public void init() { - myTableModel = new MyTableModel(); - myTable = new JBTable(myTableModel); - DefaultCellEditor defaultEditor = (DefaultCellEditor)myTable.getDefaultEditor(Object.class); - defaultEditor.setClickCountToStart(1); - - myTable.setTableHeader(null); - myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - TableUtil.setupCheckboxColumn(myTable, MyTableModel.CHECKMARK_COLUMN); - myTable.getColumnModel().getColumn(MyTableModel.PARAMETER_NAME_COLUMN).setCellRenderer(new DefaultTableCellRenderer() { - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - AbstractVariableData data = myVariableData[row]; - setText(data.name); - return this; - } - }); - - - myTable.setPreferredScrollableViewportSize(new Dimension(250, myTable.getRowHeight() * 5)); - myTable.setShowGrid(false); - myTable.setIntercellSpacing(JBUI.emptySize()); - @NonNls final InputMap inputMap = myTable.getInputMap(); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); - @NonNls final ActionMap actionMap = myTable.getActionMap(); - actionMap.put("enable_disable", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - if (myTable.isEditing()) return; - int[] rows = myTable.getSelectedRows(); - if (rows.length > 0) { - boolean valueToBeSet = false; - for (int row : rows) { - if (!myVariableData[row].passAsParameter) { - valueToBeSet = true; - break; - } - } - for (int row : rows) { - myVariableData[row].passAsParameter = valueToBeSet; - } - myTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]); - TableUtil.selectRows(myTable, rows); - } - } - }); - // F2 should edit the name - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "edit_parameter_name"); - actionMap.put("edit_parameter_name", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - if (!myTable.isEditing()) { - int row = myTable.getSelectedRow(); - if (row >= 0 && row < myTableModel.getRowCount()) { - TableUtil.editCellAt(myTable, row, MyTableModel.PARAMETER_NAME_COLUMN); - } - } - } - }); - - JPanel listPanel = ToolbarDecorator.createDecorator(myTable).disableAddAction().disableRemoveAction().createPanel(); - add(listPanel, BorderLayout.CENTER); - - if (myVariableData.length > 1) { - myTable.getSelectionModel().setSelectionInterval(0, 0); - } - } - - @Override - public void setEnabled(boolean enabled) { - myTable.setEnabled(enabled); - super.setEnabled(enabled); - } - - public AbstractVariableData[] getVariableData() { - return myVariableData; - } - - private class MyTableModel extends AbstractTableModel implements EditableModel { - public static final int CHECKMARK_COLUMN = 0; - public static final int PARAMETER_NAME_COLUMN = 1; - - @Override - public int getRowCount() { - return myVariableData.length; - } - - @Override - public int getColumnCount() { - return 2; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: { - return myVariableData[rowIndex].passAsParameter; - } - case PARAMETER_NAME_COLUMN: { - return myVariableData[rowIndex].name; - } - } - assert false; - return null; - } - - @Override - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: { - myVariableData[rowIndex].passAsParameter = ((Boolean)aValue).booleanValue(); - fireTableRowsUpdated(rowIndex, rowIndex); - myTable.getSelectionModel().setSelectionInterval(rowIndex, rowIndex); - updateSignature(); - break; - } - case PARAMETER_NAME_COLUMN: { - AbstractVariableData data = myVariableData[rowIndex]; - String name = (String)aValue; - if (myValidator.isValidName(name)) { - data.name = name; - } - updateSignature(); - break; - } - } - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: - return isEnabled(); - case PARAMETER_NAME_COLUMN: - return isEnabled() && myVariableData[rowIndex].passAsParameter; - default: - return false; - } - } - - @Override - public Class getColumnClass(int columnIndex) { - if (columnIndex == CHECKMARK_COLUMN) { - return Boolean.class; - } - return super.getColumnClass(columnIndex); - } - - @Override - public void addRow() { - throw new IllegalAccessError("Not implemented"); - } - - @Override - public void removeRow(int index) { - throw new IllegalAccessError("Not implemented"); - } - - @Override - public void exchangeRows(int row, int targetRow) { - if (row < 0 || row >= getVariableData().length) return; - if (targetRow < 0 || targetRow >= getVariableData().length) return; - - final AbstractVariableData currentItem = getVariableData()[row]; - getVariableData()[row] = getVariableData()[targetRow]; - getVariableData()[targetRow] = currentItem; - - myTableModel.fireTableRowsUpdated(Math.min(targetRow, row), Math.max(targetRow, row)); - myTable.getSelectionModel().setSelectionInterval(targetRow, targetRow); - updateSignature(); - } - - @Override - public boolean canExchangeRows(int row, int targetRow) { - if (row < 0 || row >= getVariableData().length) return false; - if (targetRow < 0 || targetRow >= getVariableData().length) return false; - return true; - } - } -} diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractVariableData.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractVariableData.java index e6346120a48c..31fb4cb9f51b 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractVariableData.java +++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/AbstractVariableData.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2010 JetBrains s.r.o. + * 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. @@ -16,22 +16,23 @@ package com.intellij.refactoring.extractMethod; /** -* @author oleg +* Would be deleted during 2016.2 EAP! */ -public class AbstractVariableData { - public String originalName; - public String name; - public boolean passAsParameter; - - public String getName() { - return name; +@Deprecated +public class AbstractVariableData extends com.intellij.refactoring.util.AbstractVariableData { + public static AbstractVariableData copy(com.intellij.refactoring.util.AbstractVariableData data) { + final AbstractVariableData cdata = new AbstractVariableData(); + cdata.passAsParameter = data.passAsParameter; + cdata.name = data.name; + cdata.originalName = data.originalName; + return cdata; } - public String getOriginalName() { - return originalName; - } - - public boolean isPassAsParameter() { - return passAsParameter; + public static AbstractVariableData[] copy(com.intellij.refactoring.util.AbstractVariableData[] data) { + final AbstractVariableData[] cdata = new AbstractVariableData[data.length]; + for (int i = 0; i < data.length; i++) { + cdata[i] = copy(data[i]); + } + return cdata; } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDecorator.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDecorator.java index e4826ece5f72..9443fb44f0de 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDecorator.java +++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDecorator.java @@ -15,9 +15,18 @@ */ package com.intellij.refactoring.extractMethod; +import com.intellij.refactoring.util.AbstractVariableData; + /** * @author oleg */ public interface ExtractMethodDecorator { - String createMethodPreview(String methodName, AbstractVariableData[] variableDatas); + default String createMethodSignature(String methodName, AbstractVariableData[] variableDatas) { + return createMethodPreview(methodName, com.intellij.refactoring.extractMethod.AbstractVariableData.copy(variableDatas)); + } + + @Deprecated + default String createMethodPreview(String methodName, com.intellij.refactoring.extractMethod.AbstractVariableData[] variableDatas) { + return null; + } } diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSettings.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSettings.java index 6a9dcc4d155b..d47533a00ed2 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSettings.java +++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodSettings.java @@ -15,10 +15,17 @@ */ package com.intellij.refactoring.extractMethod; +import com.intellij.refactoring.util.AbstractVariableData; + /** * @author oleg */ public interface ExtractMethodSettings { String getMethodName(); - AbstractVariableData[] getVariableData(); + AbstractVariableData[] getAbstractVariableData(); + + @Deprecated + default com.intellij.refactoring.extractMethod.AbstractVariableData[] getVariableData() { + return com.intellij.refactoring.extractMethod.AbstractVariableData.copy(getAbstractVariableData()); + } } \ No newline at end of file diff --git a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java index 1a09a761986f..241daf23293f 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java +++ b/platform/lang-impl/src/com/intellij/refactoring/extractMethod/SimpleDuplicatesFinder.java @@ -8,6 +8,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiRecursiveElementWalkingVisitor; import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.util.AbstractVariableData; import com.intellij.util.containers.HashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -27,9 +28,18 @@ public class SimpleDuplicatesFinder { public static final Key PARAMETER = Key.create("PARAMETER"); private final Collection myOutputVariables; + @Deprecated public SimpleDuplicatesFinder(@NotNull final PsiElement statement1, @NotNull final PsiElement statement2, - AbstractVariableData[] variableData, Collection variables) { + com.intellij.refactoring.extractMethod.AbstractVariableData[] variableData, + Collection variables) { + this(statement1, statement2, variables, variableData); + } + + public SimpleDuplicatesFinder(@NotNull final PsiElement statement1, + @NotNull final PsiElement statement2, + Collection variables, + AbstractVariableData[] variableData) { myOutputVariables = variables; myParameters = new HashSet(); for (AbstractVariableData data : variableData) { diff --git a/platform/lang-impl/src/com/intellij/refactoring/util/AbstractParameterTablePanel.java b/platform/lang-impl/src/com/intellij/refactoring/util/AbstractParameterTablePanel.java new file mode 100644 index 000000000000..769046fe29a5 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/util/AbstractParameterTablePanel.java @@ -0,0 +1,244 @@ +/* + * 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.refactoring.util; + +import com.intellij.ui.BooleanTableCellRenderer; +import com.intellij.ui.TableUtil; +import com.intellij.ui.ToolbarDecorator; +import com.intellij.ui.table.JBTable; +import com.intellij.util.ui.ColumnInfo; +import com.intellij.util.ui.EditableModel; +import com.intellij.util.ui.ListTableModel; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.KeyEvent; +import java.util.Arrays; +import java.util.function.Predicate; + +public abstract class AbstractParameterTablePanel

extends JPanel { + private P[] myParameterData; + + protected final JBTable myTable; + private final MyTableModel myTableModel; + + public P[] getVariableData() { + return myParameterData; + } + + protected abstract void updateSignature(); + + protected abstract void doEnterAction(); + + protected abstract void doCancelAction(); + + protected boolean areTypesDirected() { + return true; + } + + public AbstractParameterTablePanel(P[] parameterData, + ColumnInfo... columnInfos) { + this(columnInfos); + init(parameterData); + } + + public AbstractParameterTablePanel(ColumnInfo... columnInfos) { + super(new BorderLayout()); + myTableModel = new MyTableModel(columnInfos); + myTable = new JBTable(myTableModel); + + for (int i = 0; i < columnInfos.length; i++) { + if (columnInfos[i] instanceof PassParameterColumnInfo) { + TableUtil.setupCheckboxColumn(myTable, i); + } + } + + DefaultCellEditor defaultEditor = (DefaultCellEditor)myTable.getDefaultEditor(Object.class); + defaultEditor.setClickCountToStart(1); + + + myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + myTable.setCellSelectionEnabled(true); + + myTable.setPreferredScrollableViewportSize(new Dimension(250, myTable.getRowHeight() * 5)); + myTable.setShowGrid(false); + myTable.setIntercellSpacing(new Dimension(0, 0)); + @NonNls final InputMap inputMap = myTable.getInputMap(); + inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); + @NonNls final ActionMap actionMap = myTable.getActionMap(); + actionMap.put("enable_disable", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + if (myTable.isEditing()) return; + int[] rows = myTable.getSelectedRows(); + if (rows.length > 0) { + boolean valueToBeSet = false; + for (int row : rows) { + if (!getVariableData()[row].isPassAsParameter()) { + valueToBeSet = true; + break; + } + } + for (int row : rows) { + getVariableData()[row].passAsParameter = valueToBeSet; + } + myTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]); + TableUtil.selectRows(myTable, rows); + } + } + }); + + // make ESCAPE work when the table has focus + actionMap.put("doCancel", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + TableCellEditor editor = myTable.getCellEditor(); + if (editor != null) { + editor.stopCellEditing(); + } + else { + doCancelAction(); + } + } + }); + + + JPanel listPanel = ToolbarDecorator.createDecorator(myTable).disableAddAction().disableRemoveAction().createPanel(); + add(listPanel, BorderLayout.CENTER); + + + myTableModel.addTableModelListener(e -> updateSignature()); + } + + public void init(P[] parameterData) { + myParameterData = parameterData; + myTableModel.setItems(Arrays.asList(parameterData)); + if (parameterData.length > 1) { + myTable.getSelectionModel().setSelectionInterval(0, 0); + } + } + + + public void setEnabled(boolean enabled) { + myTable.setEnabled(enabled); + super.setEnabled(enabled); + } + + public static class NameColumnInfo extends ColumnInfo { + private final Predicate myNameValidator; + + public NameColumnInfo(Predicate nameValidator) { + super("Name"); + myNameValidator = nameValidator; + } + + @Nullable + @Override + public String valueOf(AbstractVariableData data) { + return data.getName(); + } + + @Override + public void setValue(AbstractVariableData data, String value) { + if (myNameValidator.test(value)) { + data.name = value; + } + } + + @Override + public boolean isCellEditable(AbstractVariableData data) { + return true; + } + } + + public static class PassParameterColumnInfo extends ColumnInfo { + public PassParameterColumnInfo() { + super(""); + } + + @Nullable + @Override + public TableCellRenderer getRenderer(AbstractVariableData data) { + return new BooleanTableCellRenderer(); + } + + @Nullable + @Override + public Boolean valueOf(AbstractVariableData data) { + return data.isPassAsParameter(); + } + + @Override + public void setValue(AbstractVariableData data, Boolean value) { + data.passAsParameter = value; + } + + @Override + public boolean isCellEditable(AbstractVariableData data) { + return true; + } + + @Override + public Class getColumnClass() { + return Boolean.class; + } + } + + private class MyTableModel extends ListTableModel implements EditableModel { + public MyTableModel(@NotNull ColumnInfo... columnInfos) { + super(columnInfos); + } + + @Override + public void addRow() { + throw new IllegalAccessError("Not implemented"); + } + + @Override + public void removeRow(int index) { + throw new IllegalAccessError("Not implemented"); + } + + @Override + public void exchangeRows(int row, int targetRow) { + if (row < 0 || row >= getVariableData().length) return; + if (targetRow < 0 || targetRow >= getVariableData().length) return; + + final P currentItem = getVariableData()[row]; + AbstractParameterTablePanel.this.exchangeRows(row, targetRow, currentItem); + + myTableModel.fireTableRowsUpdated(Math.min(targetRow, row), Math.max(targetRow, row)); + myTable.getSelectionModel().setSelectionInterval(targetRow, targetRow); + updateSignature(); + } + + @Override + public boolean canExchangeRows(int row, int targetRow) { + if (row < 0 || row >= getVariableData().length) return false; + if (targetRow < 0 || targetRow >= getVariableData().length) return false; + return true; + } + } + + protected void exchangeRows(int row, int targetRow, P currentItem) { + getVariableData()[row] = getVariableData()[targetRow]; + getVariableData()[targetRow] = currentItem; + } +} diff --git a/platform/lang-impl/src/com/intellij/refactoring/util/SimpleParameterTablePanel.java b/platform/lang-impl/src/com/intellij/refactoring/util/SimpleParameterTablePanel.java new file mode 100644 index 000000000000..083b3be6d917 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/refactoring/util/SimpleParameterTablePanel.java @@ -0,0 +1,24 @@ +/* + * 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.refactoring.util; + +import java.util.function.Predicate; + +public abstract class SimpleParameterTablePanel extends AbstractParameterTablePanel { + public SimpleParameterTablePanel(Predicate parameterNameValidator) { + super(new PassParameterColumnInfo(), new NameColumnInfo(parameterNameValidator)); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelperBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelperBase.java index f6ca7fb1d0f4..c591b9295522 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelperBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractInfoHelperBase.java @@ -84,7 +84,7 @@ public abstract class ExtractInfoHelperBase implements ExtractInfoHelper { for (ParameterInfo info : infos) { int position = info.getPosition(); assert position < argNames.length; - argNames[position] = info.passAsParameter() ? info.getOldName() : ""; + argNames[position] = info.passAsParameter ? info.getOriginalName() : ""; } return argNames; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractUtil.java index 64bfc1ac3b73..28a1dede6edf 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ExtractUtil.java @@ -420,12 +420,12 @@ public class ExtractUtil { ParameterInfo[] infos = helper.getParameterInfos(); int number = 0; for (ParameterInfo info : infos) { - if (info.passAsParameter()) number++; + if (info.passAsParameter) number++; } ArrayList params = new ArrayList(); for (ParameterInfo info : infos) { - if (info.passAsParameter()) { - PsiType paramType = info.getType(); + if (info.passAsParameter) { + PsiType paramType = info.type; final PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(paramType); if (unboxed != null) paramType = unboxed; @@ -474,7 +474,7 @@ public class ExtractUtil { buffer.append("("); int number = 0; for (ParameterInfo info : helper.getParameterInfos()) { - if (info.passAsParameter()) number++; + if (info.passAsParameter) number++; } int i = 0; String[] argumentNames = helper.getArgumentNames(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/GrParameterTablePanel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/GrParameterTablePanel.java new file mode 100644 index 000000000000..6f6212f2d6eb --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/GrParameterTablePanel.java @@ -0,0 +1,46 @@ +/* + * Copyright 2000-2015 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 org.jetbrains.plugins.groovy.refactoring.extract; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiManager; +import com.intellij.psi.PsiType; +import com.intellij.refactoring.ui.TypeSelector; +import com.intellij.refactoring.util.ParameterTablePanel; +import com.intellij.refactoring.util.VariableData; +import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyNamesUtil; + +/** + * @author ilyas + */ +public abstract class GrParameterTablePanel extends ParameterTablePanel { + + public GrParameterTablePanel() { + super(GroovyNamesUtil::isIdentifier); + } + + public void init(ExtractInfoHelper helper) { + super.init(helper.getParameterInfos(), helper.getProject(), helper.getContext()); + } + + @Override + protected TypeSelector createSelector(Project project, VariableData data, PsiElement[] scopeElements) { + final PsiType type = data.type; + return new TypeSelector(type != null ? type : PsiType.getJavaLangObject(PsiManager.getInstance(project), scopeElements[0].getResolveScope()), project); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ParameterInfo.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ParameterInfo.java index 0b05c58d0168..b335049fb4b6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ParameterInfo.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ParameterInfo.java @@ -17,29 +17,23 @@ package org.jetbrains.plugins.groovy.refactoring.extract; import com.intellij.psi.PsiType; +import com.intellij.refactoring.util.VariableData; import org.jetbrains.annotations.NotNull; /** * @author ilyas */ -public class ParameterInfo { - private final String myOldName; - private String myNewName; +public class ParameterInfo extends VariableData { private int myPosition; - private boolean myPassAsParameter = true; - private PsiType myType; public ParameterInfo(@NotNull String oldName, int position, PsiType psiType){ - myOldName = oldName; - setType(psiType); - myNewName = myOldName; + super(null, psiType); + name = oldName; + passAsParameter = true; + originalName = oldName; myPosition = position; } - public String getOldName() { - return myOldName; - } - public int getPosition() { return myPosition; } @@ -47,28 +41,4 @@ public class ParameterInfo { public void setPosition(int position) { myPosition = position; } - - public String getName() { - return myNewName; - } - - public PsiType getType() { - return myType; - } - - public void setNewName(String newName) { - myNewName = newName; - } - - public boolean passAsParameter() { - return myPassAsParameter; - } - - public void setPassAsParameter(boolean passAsParameter) { - myPassAsParameter = passAsParameter; - } - - public void setType(PsiType type) { - myType = type; - } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ParameterTablePanel.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ParameterTablePanel.java deleted file mode 100644 index 9b9a9ffbd3f5..000000000000 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/ParameterTablePanel.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright 2000-2015 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 org.jetbrains.plugins.groovy.refactoring.extract; - -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiManager; -import com.intellij.psi.PsiPrimitiveType; -import com.intellij.psi.PsiType; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.refactoring.ui.TypeSelector; -import com.intellij.ui.*; -import com.intellij.ui.table.JBTable; -import com.intellij.util.ui.AbstractTableCellEditor; -import com.intellij.util.ui.EditableModel; -import com.intellij.util.ui.JBUI; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyNamesUtil; -import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; - -import javax.swing.*; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.DefaultTableCellRenderer; -import javax.swing.table.TableCellEditor; -import javax.swing.table.TableColumn; -import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.KeyEvent; - -/** - * @author ilyas - */ -public abstract class ParameterTablePanel extends JPanel { - - private ParameterInfo[] myParameterInfos; - private TypeSelector[] myParameterTypeSelectors; - - private JBTable myTable; - private MyTableModel myTableModel; - private JComboBox myTypeRendererCombo; - - public ParameterTablePanel() { - super(new BorderLayout()); - } - - public void init(ExtractInfoHelper helper) { - - setBorder(IdeBorderFactory.createTitledBorder(GroovyRefactoringBundle.message("parameters.border.title"), false)); - - myParameterInfos = helper.getParameterInfos(); - - myTableModel = new MyTableModel(); - myTable = new JBTable(myTableModel); - DefaultCellEditor defaultEditor = (DefaultCellEditor)myTable.getDefaultEditor(Object.class); - defaultEditor.setClickCountToStart(1); - - myTable.setTableHeader(null); - myTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - TableColumn checkBoxColumn = myTable.getColumnModel().getColumn(MyTableModel.CHECKMARK_COLUMN); - TableUtil.setupCheckboxColumn(checkBoxColumn); - checkBoxColumn.setCellRenderer(new CheckBoxTableCellRenderer()); - - myTable.getColumnModel().getColumn(MyTableModel.PARAMETER_NAME_COLUMN).setCellRenderer(new DefaultTableCellRenderer() { - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - ParameterInfo info = myParameterInfos[row]; - setText(info.getName()); - return this; - } - }); - - Project project = helper.getProject(); - PsiManager manager = PsiManager.getInstance(project); - GlobalSearchScope scope = GlobalSearchScope.allScope(project); - myParameterTypeSelectors = new TypeSelector[myParameterInfos.length]; - for (int i = 0; i < myParameterTypeSelectors.length; i++) { -// final GrExpression[] occurrences = ExtractUtil.findVariableOccurrences(helper.getStatements(), myParameterInfos[i].getName()); -// final TypeSelectorManager manager = new TypeSelectorManagerImpl(myProject, myParameterInfos[i].getType(), occurrences, areTypesDirected()); - PsiType type = myParameterInfos[i].getType(); - myParameterTypeSelectors[i] = new TypeSelector(type != null ? type : PsiType.getJavaLangObject(manager, scope), project); -// myParameterInfos[i].setTypeName(myParameterTypeSelectors[i].getSelectedType()); - } - - myTypeRendererCombo = new JComboBox(myParameterInfos); - myTypeRendererCombo.setOpaque(true); - myTypeRendererCombo.setBorder(null); - - myTypeRendererCombo.setRenderer(new ListCellRendererWrapper() { - @Override - public void customize(JList list, ParameterInfo info, int index, boolean selected, boolean hasFocus) { - PsiType type = info.getType(); - PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(type); - type = unboxed != null ? unboxed : type; - setText(type != null ? type.getPresentableText() : ""); - } - }); - - myTable.getColumnModel().getColumn(MyTableModel.PARAMETER_TYPE_COLUMN).setCellEditor(new AbstractTableCellEditor() { - TypeSelector myCurrentSelector; - - @Override - public Object getCellEditorValue() { - return myCurrentSelector.getSelectedType(); - } - - @Override - public Component getTableCellEditorComponent(final JTable table, - final Object value, - final boolean isSelected, - final int row, - final int column) { - myCurrentSelector = myParameterTypeSelectors[row]; - return myCurrentSelector.getComponent(); - } - }); - - myTable.getColumnModel().getColumn(MyTableModel.PARAMETER_TYPE_COLUMN).setCellRenderer(new DefaultTableCellRenderer() { - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - if (myParameterTypeSelectors[row].getComponent() instanceof JComboBox) { - myTypeRendererCombo.setSelectedIndex(row); - return myTypeRendererCombo; - } - - super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - ParameterInfo info = myParameterInfos[row]; - PsiType type = info.getType(); - PsiPrimitiveType unboxed = PsiPrimitiveType.getUnboxedType(type); - type = unboxed != null ? unboxed : type; - setText(type != null ? type.getPresentableText() : ""); - return this; - } - }); - - myTable.setPreferredScrollableViewportSize(JBUI.size(250, myTable.getRowHeight() * 5)); - myTable.setShowGrid(false); - myTable.setIntercellSpacing(JBUI.emptySize()); - @NonNls final InputMap inputMap = myTable.getInputMap(); - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "enable_disable"); - @NonNls final ActionMap actionMap = myTable.getActionMap(); - actionMap.put("enable_disable", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - if (myTable.isEditing()) return; - int[] rows = myTable.getSelectedRows(); - if (rows.length > 0) { - boolean valueToBeSet = false; - for (int row : rows) { - if (!myParameterInfos[row].passAsParameter()) { - valueToBeSet = true; - break; - } - } - for (int row : rows) { - myParameterInfos[row].setPassAsParameter(valueToBeSet); - } - myTableModel.fireTableRowsUpdated(rows[0], rows[rows.length - 1]); - TableUtil.selectRows(myTable, rows); - } - } - }); - // F2 should edit the name - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0), "edit_parameter_name"); - actionMap.put("edit_parameter_name", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - if (!myTable.isEditing()) { - int row = myTable.getSelectedRow(); - if (row >= 0 && row < myTableModel.getRowCount()) { - TableUtil.editCellAt(myTable, row, MyTableModel.PARAMETER_NAME_COLUMN); - } - } - } - }); - - // make ENTER work when the table has focus - inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "invokeImpl"); - actionMap.put("invokeImpl", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - TableCellEditor editor = myTable.getCellEditor(); - if (editor != null) { - editor.stopCellEditing(); - } - else { - doEnterAction(); - } - } - }); - - // make ESCAPE work when the table has focus - actionMap.put("doCancel", new AbstractAction() { - @Override - public void actionPerformed(ActionEvent e) { - TableCellEditor editor = myTable.getCellEditor(); - if (editor != null) { - editor.stopCellEditing(); - } - else { - doCancelAction(); - } - } - }); - - JPanel listPanel = ToolbarDecorator.createDecorator(myTable).disableAddAction().disableRemoveAction().createPanel(); - add(listPanel, BorderLayout.CENTER); - } - - protected abstract void updateSignature(); - - protected abstract void doEnterAction(); - - protected abstract void doCancelAction(); - - private class MyTableModel extends AbstractTableModel implements EditableModel { - public static final int CHECKMARK_COLUMN = 0; - public static final int PARAMETER_TYPE_COLUMN = 1; - public static final int PARAMETER_NAME_COLUMN = 2; - - @Override - public void addRow() { - throw new IllegalAccessError("Not implemented"); - } - - @Override - public void removeRow(int index) { - throw new IllegalAccessError("Not implemented"); - } - - @Override - public void exchangeRows(int oldIndex, int newIndex) { - if (oldIndex < 0 || newIndex < 0) return; - if (oldIndex >= myParameterInfos.length || newIndex >= myParameterInfos.length) return; - - final ParameterInfo old = myParameterInfos[oldIndex]; - myParameterInfos[oldIndex] = myParameterInfos[newIndex]; - myParameterInfos[newIndex] = old; - - myParameterInfos[oldIndex].setPosition(oldIndex); - myParameterInfos[newIndex].setPosition(newIndex); - - fireTableRowsUpdated(Math.min(oldIndex, newIndex), Math.max(oldIndex, newIndex)); - updateSignature(); - } - - @Override - public boolean canExchangeRows(int oldIndex, int newIndex) { - if (oldIndex < 0 || newIndex < 0) return false; - if (oldIndex >= myParameterInfos.length || newIndex >= myParameterInfos.length) return false; - return true; - } - - @Override - public int getRowCount() { - return myParameterInfos.length; - } - - @Override - public int getColumnCount() { - return 3; - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: { - return myParameterInfos[rowIndex].passAsParameter(); - } - case PARAMETER_NAME_COLUMN: { - return myParameterInfos[rowIndex].getName(); - } - case PARAMETER_TYPE_COLUMN: { - PsiType type = myParameterInfos[rowIndex].getType(); - return type != null ? type.getPresentableText() : ""; - } - } - assert false; - return null; - } - - @Override - public void setValueAt(Object aValue, int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: { - myParameterInfos[rowIndex].setPassAsParameter((Boolean)aValue); - fireTableRowsUpdated(rowIndex, rowIndex); - myTable.getSelectionModel().setSelectionInterval(rowIndex, rowIndex); - updateSignature(); - break; - } - case PARAMETER_NAME_COLUMN: { - ParameterInfo info = myParameterInfos[rowIndex]; - String name = (String)aValue; - if (GroovyNamesUtil.isIdentifier(name)) { - info.setNewName(name); - } - updateSignature(); - break; - } - case PARAMETER_TYPE_COLUMN: { - ParameterInfo info = myParameterInfos[rowIndex]; - info.setType((PsiType)aValue); - updateSignature(); - break; - } - } - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - switch (columnIndex) { - case CHECKMARK_COLUMN: - return isEnabled(); - case PARAMETER_NAME_COLUMN: - return isEnabled() && myParameterInfos[rowIndex].passAsParameter(); - case PARAMETER_TYPE_COLUMN: - return isEnabled() && - myParameterInfos[rowIndex].passAsParameter() && - !(myParameterTypeSelectors[rowIndex].getComponent() instanceof JLabel); - default: - return false; - } - } - - @Override - public Class getColumnClass(int columnIndex) { - if (columnIndex == CHECKMARK_COLUMN) { - return Boolean.class; - } - return super.getColumnClass(columnIndex); - } - } - - private class CheckBoxTableCellRenderer extends BooleanTableCellRenderer { - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - Component rendererComponent = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - rendererComponent.setEnabled(ParameterTablePanel.this.isEnabled()); - return rendererComponent; - } - } -} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodDialog.java index 60a41dae6c1c..69fe683fcfde 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodDialog.java @@ -44,8 +44,8 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.utils.DuplicatesUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; import org.jetbrains.plugins.groovy.refactoring.extract.ExtractUtil; +import org.jetbrains.plugins.groovy.refactoring.extract.GrParameterTablePanel; import org.jetbrains.plugins.groovy.refactoring.extract.InitialInfo; -import org.jetbrains.plugins.groovy.refactoring.extract.ParameterTablePanel; import org.jetbrains.plugins.groovy.refactoring.ui.GrMethodSignatureComponent; import org.jetbrains.plugins.groovy.refactoring.ui.GroovyComboboxVisibilityPanel; import org.jetbrains.plugins.groovy.settings.GroovyApplicationSettings; @@ -76,7 +76,7 @@ public class GroovyExtractMethodDialog extends DialogWrapper { private ComboBoxVisibilityPanel myVisibilityPanel; private Splitter mySplitter; private JCheckBox myForceReturnCheckBox; - private ParameterTablePanel myParameterTablePanel; + private GrParameterTablePanel myParameterTablePanel; private final Project myProject; public GroovyExtractMethodDialog(InitialInfo info, PsiClass owner) { @@ -247,7 +247,7 @@ public class GroovyExtractMethodDialog extends DialogWrapper { } }); - myParameterTablePanel = new ParameterTablePanel() { + myParameterTablePanel = new GrParameterTablePanel() { @Override protected void updateSignature(){ GroovyExtractMethodDialog.this.updateSignature(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodHandler.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodHandler.java index d6872c464d56..c44580432699 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodHandler.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/method/GroovyExtractMethodHandler.java @@ -275,7 +275,7 @@ public class GroovyExtractMethodHandler implements RefactoringActionHandler { final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(helper.getProject()); for (ParameterInfo info : helper.getParameterInfos()) { - final String oldName = info.getOldName(); + final String oldName = info.getOriginalName(); final String newName = info.getName(); final ArrayList result = new ArrayList(); if (!oldName.equals(newName)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java index 85d638f1f296..934ec49e0612 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/parameter/GrIntroduceParameterDialog.java @@ -57,8 +57,8 @@ import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.HelpID; import org.jetbrains.plugins.groovy.refactoring.extract.ExtractUtil; +import org.jetbrains.plugins.groovy.refactoring.extract.GrParameterTablePanel; import org.jetbrains.plugins.groovy.refactoring.extract.ParameterInfo; -import org.jetbrains.plugins.groovy.refactoring.extract.ParameterTablePanel; import org.jetbrains.plugins.groovy.refactoring.extract.closure.ExtractClosureFromClosureProcessor; import org.jetbrains.plugins.groovy.refactoring.extract.closure.ExtractClosureFromMethodProcessor; import org.jetbrains.plugins.groovy.refactoring.extract.closure.ExtractClosureHelperImpl; @@ -89,7 +89,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { private final TObjectIntHashMap toRemoveCBs; private GrMethodSignatureComponent mySignature; - private ParameterTablePanel myTable; + private GrParameterTablePanel myTable; private JPanel mySignaturePanel; private JCheckBox myForceReturnCheckBox; private final Project myProject; @@ -139,7 +139,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { final GrParameter param = parameters[index]; final ParameterInfo pinfo = findParamByOldName(param.getName()); if (pinfo != null) { - pinfo.setPassAsParameter(false); + pinfo.passAsParameter = false; } return true; } @@ -207,7 +207,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { private JPanel createSignaturePanel() { mySignature = new GrMethodSignatureComponent("", myProject); - myTable = new ParameterTablePanel() { + myTable = new GrParameterTablePanel() { @Override protected void updateSignature() { GrIntroduceParameterDialog.this.updateSignature(); @@ -406,7 +406,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { final GrParameter param = myInfo.getToReplaceIn().getParameters()[index]; final ParameterInfo pinfo = findParamByOldName(param.getName()); - if (pinfo == null || !pinfo.passAsParameter()) return true; + if (pinfo == null || !pinfo.passAsParameter) return true; final String message = GroovyRefactoringBundle .message("you.cannot.pass.as.parameter.0.because.you.remove.1.from.base.method", pinfo.getName(), param.getName()); @@ -425,7 +425,7 @@ public class GrIntroduceParameterDialog extends DialogWrapper { @Nullable private ParameterInfo findParamByOldName(String name) { for (ParameterInfo info : myInfo.getParameterInfos()) { - if (name.equals(info.getOldName())) return info; + if (name.equals(info.getOriginalName())) return info; } return null; } diff --git a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java index 2898211f315e..a47c87a6c0e4 100644 --- a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java +++ b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java @@ -37,6 +37,7 @@ import com.intellij.refactoring.listeners.RefactoringElementListenerComposite; import com.intellij.refactoring.listeners.RefactoringEventData; import com.intellij.refactoring.listeners.RefactoringEventListener; import com.intellij.refactoring.rename.RenameUtil; +import com.intellij.refactoring.util.AbstractVariableData; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.usageView.UsageInfo; import com.intellij.util.Consumer; @@ -105,7 +106,7 @@ public class PyExtractMethodUtil { final String methodName = data.first; final AbstractVariableData[] variableData = data.second; - final SimpleDuplicatesFinder finder = new SimpleDuplicatesFinder(statement1, statement2, variableData, fragment.getOutputVariables()); + final SimpleDuplicatesFinder finder = new SimpleDuplicatesFinder(statement1, statement2, fragment.getOutputVariables(), variableData); CommandProcessor.getInstance().executeCommand(project, new Runnable() { public void run() { @@ -300,7 +301,7 @@ public class PyExtractMethodUtil { final String methodName = data.first; final AbstractVariableData[] variableData = data.second; - final SimpleDuplicatesFinder finder = new SimpleDuplicatesFinder(expression, expression, variableData, fragment.getOutputVariables()); + final SimpleDuplicatesFinder finder = new SimpleDuplicatesFinder(expression, expression, fragment.getOutputVariables(), variableData); if (fragment.getOutputVariables().isEmpty()) { CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override @@ -625,7 +626,7 @@ public class PyExtractMethodUtil { final boolean isMethod = PyPsiUtils.isMethodContext(element); final ExtractMethodDecorator decorator = new ExtractMethodDecorator() { @NotNull - public String createMethodPreview(final String methodName, @NotNull final AbstractVariableData[] variableDatas) { + public String createMethodSignature(final String methodName, @NotNull final AbstractVariableData[] variableDatas) { final StringBuilder builder = new StringBuilder(); if (isClassMethod) { builder.append("cls"); @@ -663,7 +664,7 @@ public class PyExtractMethodUtil { return Pair.empty(); } - return Pair.create(dialog.getMethodName(), dialog.getVariableData()); + return Pair.create(dialog.getMethodName(), dialog.getAbstractVariableData()); } @NotNull From c1f7cc4c14abadb1b0f84ab0ea6b6e21fe35b183 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Wed, 13 Apr 2016 14:05:30 +0300 Subject: [PATCH 59/64] inspection tool window: extract popup action group to LangActions.xml + extract Exclude/Include actions to reusable ones (review) --- .../ui/InspectionResultsView.java | 28 ++++++----- ...up.java => QuickFixesViewActionGroup.java} | 2 +- .../exclusion/ExcludeTreeNodeAction.java | 27 +++++++++++ .../actions/exclusion/ExclusionHandler.java | 39 +++++++++++++++ .../exclusion/IncludeTreeNodeAction.java | 27 +++++++++++ .../TreeNodeExclusionAction.java | 48 +++++-------------- .../src/idea/LangActions.xml | 6 +-- 7 files changed, 125 insertions(+), 52 deletions(-) rename platform/lang-impl/src/com/intellij/codeInspection/ui/actions/{QuickFixesActionGroup.java => QuickFixesViewActionGroup.java} (96%) create mode 100644 platform/platform-api/src/com/intellij/ide/actions/exclusion/ExcludeTreeNodeAction.java create mode 100644 platform/platform-api/src/com/intellij/ide/actions/exclusion/ExclusionHandler.java create mode 100644 platform/platform-api/src/com/intellij/ide/actions/exclusion/IncludeTreeNodeAction.java rename platform/platform-api/src/com/intellij/ide/actions/{ => exclusion}/TreeNodeExclusionAction.java (67%) diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java index f19cdf153680..4b1e89f86781 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/InspectionResultsView.java @@ -32,7 +32,7 @@ import com.intellij.diff.util.DiffUtil; import com.intellij.icons.AllIcons; import com.intellij.ide.*; import com.intellij.ide.actions.ContextHelpAction; -import com.intellij.ide.actions.TreeNodeExclusionAction; +import com.intellij.ide.actions.exclusion.ExclusionHandler; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; @@ -119,7 +119,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren @NotNull private final InspectionRVContentProvider myProvider; - private final TreeNodeExclusionAction.ExclusionHandler myExclusionHandler; + private final ExclusionHandler myExclusionHandler; private EditorEx myPreviewEditor; private InspectionTreeLoadingProgressAware myLoadingProgressPreview; private final ExcludedInspectionTreeNodesManager myExcludedInspectionTreeNodesManager = new ExcludedInspectionTreeNodesManager(); @@ -150,19 +150,20 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } }); add(mySplitter, BorderLayout.CENTER); - myExclusionHandler = new TreeNodeExclusionAction.ExclusionHandler() { + myExclusionHandler = new ExclusionHandler() { @Override public boolean isNodeExcluded(@NotNull InspectionTreeNode node) { return node.isResolved(myExcludedInspectionTreeNodesManager); } @Override - public void excludeNode(@NotNull InspectionTreeNode node, boolean isExcluded) { - if (isExcluded) { - node.ignoreElement(myExcludedInspectionTreeNodesManager); - } else { - node.amnesty(myExcludedInspectionTreeNodesManager); - } + public void excludeNode(@NotNull InspectionTreeNode node) { + node.ignoreElement(myExcludedInspectionTreeNodesManager); + } + + @Override + public void includeNode(@NotNull InspectionTreeNode node) { + node.amnesty(myExcludedInspectionTreeNodesManager); } @Override @@ -171,7 +172,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } @Override - public void updateUiWhenActionWasPerformed(boolean isExcludeAction) { + public void onDone(boolean isExcludeAction) { if (isExcludeAction && myGlobalInspectionContext.getUIOptions().FILTER_RESOLVED_ITEMS) { update(); } @@ -181,10 +182,11 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren } @Override - public boolean isValid() { - return !isDisposed(); + public void dispose() { + } }; + Disposer.register(this, myExclusionHandler); createActionsToolbar(); } @@ -762,7 +764,7 @@ public class InspectionResultsView extends JPanel implements Disposable, Occuren public Object getData(String dataId) { if (PlatformDataKeys.HELP_ID.is(dataId)) return HELP_ID; if (DATA_KEY.is(dataId)) return this; - if (TreeNodeExclusionAction.EXCLUSION_HANDLER.is(dataId)) return myExclusionHandler; + if (ExclusionHandler.EXCLUSION_HANDLER.is(dataId)) return myExclusionHandler; if (myTree == null) return null; TreePath[] paths = myTree.getSelectionPaths(); diff --git a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesActionGroup.java b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesViewActionGroup.java similarity index 96% rename from platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesActionGroup.java rename to platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesViewActionGroup.java index 1793d20a1346..994df27eef7e 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesActionGroup.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/ui/actions/QuickFixesViewActionGroup.java @@ -29,7 +29,7 @@ import static com.intellij.codeInspection.ui.actions.InspectionViewActionBase.ge /** * @author Dmitry Batkovich */ -public class QuickFixesActionGroup extends ActionGroup { +public class QuickFixesViewActionGroup extends ActionGroup { @NotNull @Override public AnAction[] getChildren(@Nullable AnActionEvent e) { diff --git a/platform/platform-api/src/com/intellij/ide/actions/exclusion/ExcludeTreeNodeAction.java b/platform/platform-api/src/com/intellij/ide/actions/exclusion/ExcludeTreeNodeAction.java new file mode 100644 index 000000000000..119252c24241 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/actions/exclusion/ExcludeTreeNodeAction.java @@ -0,0 +1,27 @@ +/* + * 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.actions.exclusion; + +import javax.swing.tree.MutableTreeNode; + +/** + * @author Dmitry Batkovich + */ +public final class ExcludeTreeNodeAction extends TreeNodeExclusionAction { + public ExcludeTreeNodeAction() { + super(true); + } +} diff --git a/platform/platform-api/src/com/intellij/ide/actions/exclusion/ExclusionHandler.java b/platform/platform-api/src/com/intellij/ide/actions/exclusion/ExclusionHandler.java new file mode 100644 index 000000000000..2c3ea411ed53 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/actions/exclusion/ExclusionHandler.java @@ -0,0 +1,39 @@ +/* + * 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.actions.exclusion; + +import com.intellij.openapi.Disposable; +import com.intellij.openapi.actionSystem.DataKey; +import org.jetbrains.annotations.NotNull; + +import javax.swing.tree.MutableTreeNode; + +/** + * @author Dmitry Batkovich + */ +public interface ExclusionHandler extends Disposable { + DataKey EXCLUSION_HANDLER = DataKey.create("tree.exclusion.handler"); + + boolean isNodeExcluded(@NotNull T node); + + void excludeNode(@NotNull T node); + + void includeNode(@NotNull T node); + + boolean isActionEnabled(boolean isExcludeAction); + + void onDone(boolean isExcludeAction); +} diff --git a/platform/platform-api/src/com/intellij/ide/actions/exclusion/IncludeTreeNodeAction.java b/platform/platform-api/src/com/intellij/ide/actions/exclusion/IncludeTreeNodeAction.java new file mode 100644 index 000000000000..b700840faecf --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/actions/exclusion/IncludeTreeNodeAction.java @@ -0,0 +1,27 @@ +/* + * 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.actions.exclusion; + +import javax.swing.tree.MutableTreeNode; + +/** + * @author Dmitry Batkovich + */ +public final class IncludeTreeNodeAction extends TreeNodeExclusionAction { + public IncludeTreeNodeAction() { + super(false); + } +} diff --git a/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java b/platform/platform-api/src/com/intellij/ide/actions/exclusion/TreeNodeExclusionAction.java similarity index 67% rename from platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java rename to platform/platform-api/src/com/intellij/ide/actions/exclusion/TreeNodeExclusionAction.java index 91480b084920..a60ddfdb9269 100644 --- a/platform/platform-api/src/com/intellij/ide/actions/TreeNodeExclusionAction.java +++ b/platform/platform-api/src/com/intellij/ide/actions/exclusion/TreeNodeExclusionAction.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.ide.actions; +package com.intellij.ide.actions.exclusion; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; -import org.jetbrains.annotations.NotNull; +import com.intellij.openapi.util.Disposer; import javax.swing.*; import javax.swing.tree.MutableTreeNode; @@ -27,46 +27,20 @@ import java.awt.*; /** * @author Dmitry Batkovich. */ -public class TreeNodeExclusionAction extends AnAction { +class TreeNodeExclusionAction extends AnAction { private final static Logger LOG = Logger.getInstance(TreeNodeExclusionAction.class); - public static final DataKey EXCLUSION_HANDLER = DataKey.create("tree.exclusion.handler"); - private final boolean myIsExclude; - public interface ExclusionHandler { - boolean isNodeExcluded(@NotNull T node); - - void excludeNode(@NotNull T node, boolean isExcluded); - - boolean isActionEnabled(boolean isExcludeAction); - - void updateUiWhenActionWasPerformed(boolean isExcludeAction); - - boolean isValid(); - } - - public static class Exclude extends TreeNodeExclusionAction { - public Exclude() { - super(true); - } - } - - public static class Include extends TreeNodeExclusionAction { - public Include() { - super(false); - } - } - - private TreeNodeExclusionAction(boolean isExclude) { + TreeNodeExclusionAction(boolean isExclude) { myIsExclude = isExclude; getTemplatePresentation().setText(getActionText()); } @Override public void update(AnActionEvent e) { - final ExclusionHandler exclusionProcessor = EXCLUSION_HANDLER.getData(e.getDataContext()); - if (exclusionProcessor == null || !exclusionProcessor.isValid()) { + final ExclusionHandler exclusionProcessor = ExclusionHandler.EXCLUSION_HANDLER.getData(e.getDataContext()); + if (exclusionProcessor == null || Disposer.isDisposed(exclusionProcessor)) { e.getPresentation().setEnabledAndVisible(false); return; } @@ -107,15 +81,19 @@ public class TreeNodeExclusionAction extends AnAction LOG.assertTrue(tree != null); final TreePath[] paths = tree.getSelectionPaths(); LOG.assertTrue(paths != null); - final ExclusionHandler exclusionProcessor = EXCLUSION_HANDLER.getData(e.getDataContext()); + final ExclusionHandler exclusionProcessor = ExclusionHandler.EXCLUSION_HANDLER.getData(e.getDataContext()); LOG.assertTrue(exclusionProcessor != null); for (TreePath path : paths) { final T node = (T)path.getLastPathComponent(); if (Boolean.valueOf(myIsExclude) != exclusionProcessor.isNodeExcluded(node)) { - exclusionProcessor.excludeNode(node, myIsExclude); + if (myIsExclude) { + exclusionProcessor.excludeNode(node); + } else { + exclusionProcessor.includeNode(node); + } } } - exclusionProcessor.updateUiWhenActionWasPerformed(myIsExclude); + exclusionProcessor.onDone(myIsExclude); } private String getActionText() { diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index e71eeef5de21..c332d188420b 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -990,8 +990,8 @@ - - + + > @@ -999,7 +999,7 @@ - + From c0f9e8001ae50c53641eff76fd0fdf77e045f93a Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 12 Apr 2016 17:58:11 +0300 Subject: [PATCH 60/64] IDEA-154592 Deadlock in MergingUpdateQueue --- platform/platform-api/src/com/intellij/util/Alarm.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java index 0df57002c02d..a67e23244650 100644 --- a/platform/platform-api/src/com/intellij/util/Alarm.java +++ b/platform/platform-api/src/com/intellij/util/Alarm.java @@ -427,10 +427,11 @@ public class Alarm implements Disposable { @Override public String toString() { + Runnable task; synchronized (LOCK) { - Runnable task = myTask; - return super.toString() + (task != null ? ": "+task : ""); + task = myTask; } + return super.toString() + (task != null ? ": "+task : ""); } } From a314b2e37e77ca3472273f267acc361308377004 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 13 Apr 2016 13:55:48 +0300 Subject: [PATCH 61/64] IDEA-154442 Overriding methods search finds methods twice --- .../src/com/intellij/find/FindUtil.java | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index 9830fd669572..2f7567666a9b 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. @@ -63,7 +63,6 @@ import com.intellij.ui.LightweightHint; import com.intellij.usageView.UsageInfo; import com.intellij.usages.*; import com.intellij.usages.impl.UsageViewImpl; -import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -925,26 +924,22 @@ public class FindUtil { } @Nullable - public static UsageView showInUsageView(PsiElement sourceElement, @NotNull PsiElement[] targets, @NotNull String title, @NotNull final Project project) { + public static UsageView showInUsageView(@Nullable PsiElement sourceElement, + @NotNull PsiElement[] targets, + @NotNull String title, + @NotNull final Project project) { if (targets.length == 0) return null; final UsageViewPresentation presentation = new UsageViewPresentation(); presentation.setCodeUsagesString(title); presentation.setTabName(title); presentation.setTabText(title); - final UsageTarget[] usageTargets = - sourceElement == null ? UsageTarget.EMPTY_ARRAY : new UsageTarget[]{new PsiElement2UsageTargetAdapter(sourceElement)}; + UsageTarget[] usageTargets = sourceElement == null ? UsageTarget.EMPTY_ARRAY : new UsageTarget[]{new PsiElement2UsageTargetAdapter(sourceElement)}; - final PsiElement[] primary = sourceElement == null ? PsiElement.EMPTY_ARRAY : new PsiElement[]{sourceElement}; - final Usage[] usages = {UsageInfoToUsageConverter.convert(primary, new UsageInfo(targets[0]))}; - final UsageView view = - UsageViewManager.getInstance(project).showUsages(usageTargets, usages, presentation); + PsiElement[] primary = sourceElement == null ? PsiElement.EMPTY_ARRAY : new PsiElement[]{sourceElement}; + UsageView view = UsageViewManager.getInstance(project).showUsages(usageTargets, Usage.EMPTY_ARRAY, presentation); - final List pointers = ContainerUtil.map(targets, new Function() { - @Override - public SmartPsiElementPointer fun(PsiElement psiElement) { - return SmartPointerManager.getInstance(project).createSmartPsiElementPointer(psiElement); - } - }); + SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(project); + List pointers = ContainerUtil.map(targets, smartPointerManager::createSmartPsiElementPointer); // usage view will load document/AST so still referencing all these PSI elements might lead to out of memory //noinspection UnusedAssignment @@ -955,13 +950,10 @@ public class FindUtil { public void run(@NotNull ProgressIndicator indicator) { for (final SmartPsiElementPointer pointer : pointers) { if (((UsageViewImpl)view).isDisposed()) break; - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - final PsiElement target = pointer.getElement(); - if (target != null) { - view.appendUsage(UsageInfoToUsageConverter.convert(primary, new UsageInfo(target))); - } + ApplicationManager.getApplication().runReadAction(() -> { + final PsiElement target = pointer.getElement(); + if (target != null) { + view.appendUsage(UsageInfoToUsageConverter.convert(primary, new UsageInfo(target))); } }); } From 659b4edf2acf666f23c3e3e6b0fd623739c62011 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 13 Apr 2016 14:00:05 +0300 Subject: [PATCH 62/64] lambdify --- .../src/com/intellij/find/FindUtil.java | 248 ++++++++---------- 1 file changed, 106 insertions(+), 142 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/find/FindUtil.java b/platform/lang-impl/src/com/intellij/find/FindUtil.java index 2f7567666a9b..489f6936c4c5 100644 --- a/platform/lang-impl/src/com/intellij/find/FindUtil.java +++ b/platform/lang-impl/src/com/intellij/find/FindUtil.java @@ -68,7 +68,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; public class FindUtil { private static final Key KEY = Key.create("FindUtil.KEY"); @@ -77,7 +80,7 @@ public class FindUtil { } @Nullable - static VirtualFile getVirtualFile(@NotNull Editor myEditor) { + private static VirtualFile getVirtualFile(@NotNull Editor myEditor) { Project project = myEditor.getProject(); PsiFile file = project != null ? PsiDocumentManager.getInstance(project).getPsiFile(myEditor.getDocument()) : null; return file != null ? file.getVirtualFile() : null; @@ -134,12 +137,7 @@ public class FindUtil { } } else { - if (firstSearch) { - stringToFind = ""; - } - else { - stringToFind = model.getStringToFind(); - } + stringToFind = firstSearch ? "" : model.getStringToFind(); } model.setReplaceState(replace); model.setStringToFind(stringToFind); @@ -233,48 +231,45 @@ public class FindUtil { model.setReplaceState(false); model.setFindAllEnabled(PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()) != null); - findManager.showFindDialog(model, new Runnable() { - @Override - public void run() { - if (model.isFindAll()) { - findManager.setFindNextModel(model); - findAllAndShow(project, editor, model); + findManager.showFindDialog(model, () -> { + if (model.isFindAll()) { + findManager.setFindNextModel(model); + findAllAndShow(project, editor, model); + return; + } + + if (!model.isGlobal() && editor.getSelectionModel().hasSelection()) { + int offset = model.isForward() + ? editor.getSelectionModel().getSelectionStart() + : editor.getSelectionModel().getSelectionEnd(); + ScrollType scrollType = model.isForward() ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; + moveCaretAndDontChangeSelection(editor, offset, scrollType); + } + + int offset; + if (model.isGlobal()) { + if (model.isFromCursor()) { + offset = editor.getCaretModel().getOffset(); + } + else { + offset = model.isForward() ? 0 : editor.getDocument().getTextLength(); + } + } + else { + // in selection + + if (!editor.getSelectionModel().hasSelection()) { + // TODO[anton] actually, this should never happen - Find dialog should not allow such combination + findManager.setFindNextModel(null); return; } - if (!model.isGlobal() && editor.getSelectionModel().hasSelection()) { - int offset = model.isForward() - ? editor.getSelectionModel().getSelectionStart() - : editor.getSelectionModel().getSelectionEnd(); - ScrollType scrollType = model.isForward() ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; - moveCaretAndDontChangeSelection(editor, offset, scrollType); - } - - int offset; - if (model.isGlobal()) { - if (model.isFromCursor()) { - offset = editor.getCaretModel().getOffset(); - } - else { - offset = model.isForward() ? 0 : editor.getDocument().getTextLength(); - } - } - else { - // in selection - - if (!editor.getSelectionModel().hasSelection()) { - // TODO[anton] actually, this should never happen - Find dialog should not allow such combination - findManager.setFindNextModel(null); - return; - } - - offset = model.isForward() ? editor.getSelectionModel().getSelectionStart() : editor.getSelectionModel().getSelectionEnd(); - } - - findManager.setFindNextModel(null); - findManager.getFindInFileModel().copyFrom(model); - doSearch(project, editor, offset, true, model, true); + offset = model.isForward() ? editor.getSelectionModel().getSelectionStart() : editor.getSelectionModel().getSelectionEnd(); } + + findManager.setFindNextModel(null); + findManager.getFindInFileModel().copyFrom(model); + doSearch(project, editor, offset, true, model, true); }); } @@ -286,7 +281,7 @@ public class FindUtil { CharSequence text = document.getCharsSequence(); int textLength = document.getTextLength(); - final List usages = new ArrayList(); + final List usages = new ArrayList<>(); FindManager findManager = FindManager.getInstance(project); findModel.setForward(true); // when find all there is no diff in direction @@ -368,7 +363,7 @@ public class FindUtil { return searchAgain(project, editor, context); } - public static boolean searchAgain(final Project project, final Editor editor, @Nullable DataContext context) { + private static boolean searchAgain(final Project project, final Editor editor, @Nullable DataContext context) { FindManager findManager = FindManager.getInstance(project); if (!findManager.findWasPerformed() && !findManager.selectNextOccurrenceWasPerformed()) { new IncrementalFindAction().getHandler().execute(editor, context); @@ -433,62 +428,54 @@ public class FindUtil { } model.setReplaceState(true); - findManager.showFindDialog(model, new Runnable() { - @Override - public void run() { - if (!model.isGlobal() && editor.getSelectionModel().hasSelection()) { - int offset = model.isForward() - ? editor.getSelectionModel().getSelectionStart() - : editor.getSelectionModel().getSelectionEnd(); - ScrollType scrollType = model.isForward() ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; - moveCaretAndDontChangeSelection(editor, offset, scrollType); - } - int offset; - if (model.isGlobal()) { - if (model.isFromCursor()) { - offset = editor.getCaretModel().getOffset(); - if (!model.isForward()) { - offset++; - } - } - else { - offset = model.isForward() ? 0 : editor.getDocument().getTextLength(); + findManager.showFindDialog(model, () -> { + if (!model.isGlobal() && editor.getSelectionModel().hasSelection()) { + int offset = model.isForward() + ? editor.getSelectionModel().getSelectionStart() + : editor.getSelectionModel().getSelectionEnd(); + ScrollType scrollType = model.isForward() ? ScrollType.CENTER_DOWN : ScrollType.CENTER_UP; + moveCaretAndDontChangeSelection(editor, offset, scrollType); + } + int offset; + if (model.isGlobal()) { + if (model.isFromCursor()) { + offset = editor.getCaretModel().getOffset(); + if (!model.isForward()) { + offset++; } } else { - // in selection - - if (!editor.getSelectionModel().hasSelection()) { - // TODO[anton] actually, this should never happen - Find dialog should not allow such combination - findManager.setFindNextModel(null); - return; - } - - offset = model.isForward() ? editor.getSelectionModel().getSelectionStart() : editor.getSelectionModel().getSelectionEnd(); + offset = model.isForward() ? 0 : editor.getDocument().getTextLength(); } - - if (s != null && editor.getSelectionModel().hasSelection() && s.equals(model.getStringToFind())) { - if (model.isFromCursor() && model.isForward()) { - offset = Math.min(editor.getSelectionModel().getSelectionStart(), offset); - } - else if (model.isFromCursor() && !model.isForward()) { - offset = Math.max(editor.getSelectionModel().getSelectionEnd(), offset); - } - } - findManager.setFindNextModel(null); - findManager.getFindInFileModel().copyFrom(model); - replace(project, editor, offset, model); } + else { + // in selection + + if (!editor.getSelectionModel().hasSelection()) { + // TODO[anton] actually, this should never happen - Find dialog should not allow such combination + findManager.setFindNextModel(null); + return; + } + + offset = model.isForward() ? editor.getSelectionModel().getSelectionStart() : editor.getSelectionModel().getSelectionEnd(); + } + + if (s != null && editor.getSelectionModel().hasSelection() && s.equals(model.getStringToFind())) { + if (model.isFromCursor() && model.isForward()) { + offset = Math.min(editor.getSelectionModel().getSelectionStart(), offset); + } + else if (model.isFromCursor() && !model.isForward()) { + offset = Math.max(editor.getSelectionModel().getSelectionEnd(), offset); + } + } + findManager.setFindNextModel(null); + findManager.getFindInFileModel().copyFrom(model); + replace(project, editor, offset, model); }); } public static boolean replace(Project project, Editor editor, int offset, FindModel model) { - return replace(project, editor, offset, model, new ReplaceDelegate() { - @Override - public boolean shouldReplace(TextRange range, String replace) { - return true; - } - }); + return replace(project, editor, offset, model, (range, replace) -> true); } public static boolean replace(Project project, Editor editor, int offset, FindModel model, ReplaceDelegate delegate) { @@ -520,7 +507,7 @@ public class FindUtil { final FindModel model = aModel.clone(); int occurrences = 0; - List> rangesToChange = new ArrayList>(); + List> rangesToChange = new ArrayList<>(); boolean replaced = false; boolean reallyReplaced = false; @@ -590,12 +577,7 @@ public class FindUtil { if (!toPrompt) { CharSequence text = document.getCharsSequence(); final StringBuilder newText = new StringBuilder(document.getTextLength()); - Collections.sort(rangesToChange, new Comparator>() { - @Override - public int compare(Pair o1, Pair o2) { - return o1.getFirst().getStartOffset() - o2.getFirst().getStartOffset(); - } - }); + Collections.sort(rangesToChange, (o1, o2) -> o1.getFirst().getStartOffset() - o2.getFirst().getStartOffset()); int offsetBefore = 0; for (Pair pair : rangesToChange) { TextRange range = pair.getFirst(); @@ -617,21 +599,13 @@ public class FindUtil { caretOffset = newText.length(); } final int finalCaretOffset = caretOffset; - CommandProcessor.getInstance().executeCommand(project, new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - document.setText(newText); - editor.getCaretModel().moveToOffset(finalCaretOffset); - if (model.isGlobal()) { - editor.getSelectionModel().removeSelection(); - } - } - }); + CommandProcessor.getInstance().executeCommand(project, () -> ApplicationManager.getApplication().runWriteAction(() -> { + document.setText(newText); + editor.getCaretModel().moveToOffset(finalCaretOffset); + if (model.isGlobal()) { + editor.getSelectionModel().removeSelection(); } - }, null, document); + }), null, document); } else { if (reallyReplaced) { @@ -724,12 +698,9 @@ public class FindUtil { selection.removeSelection(); scrollingModel.scrollToCaret(scrollType); scrollingModel.runActionOnScrollingFinished( - new Runnable() { - @Override - public void run() { - scrollingModel.scrollTo(editor.offsetToLogicalPosition(result.getStartOffset()), scrollType); - scrollingModel.scrollTo(editor.offsetToLogicalPosition(result.getEndOffset()), scrollType); - } + () -> { + scrollingModel.scrollTo(editor.offsetToLogicalPosition(result.getStartOffset()), scrollType); + scrollingModel.scrollTo(editor.offsetToLogicalPosition(result.getEndOffset()), scrollType); } ); } @@ -803,7 +774,7 @@ public class FindUtil { AnAction action = ActionManager.getInstance().getAction( modelForNextSearch.isForward() ? IdeActions.ACTION_FIND_NEXT : IdeActions.ACTION_FIND_PREVIOUS); String shortcutsText = KeymapUtil.getFirstKeyboardShortcutText(action); - if (shortcutsText.length() > 0) { + if (!shortcutsText.isEmpty()) { message = FindBundle.message("find.search.again.from.top.hotkey.message", message, shortcutsText); } else { @@ -815,7 +786,7 @@ public class FindUtil { AnAction action = ActionManager.getInstance().getAction( modelForNextSearch.isForward() ? IdeActions.ACTION_FIND_PREVIOUS : IdeActions.ACTION_FIND_NEXT); String shortcutsText = KeymapUtil.getFirstKeyboardShortcutText(action); - if (shortcutsText.length() > 0) { + if (!shortcutsText.isEmpty()) { message = FindBundle.message("find.search.again.from.bottom.hotkey.message", message, shortcutsText); } else { @@ -892,24 +863,16 @@ public class FindUtil { return new TextRange(start, end); } - public static int doReplace(Project project, - final Document document, - final int startOffset, - final int endOffset, - final String stringToReplace) { + private static int doReplace(Project project, + final Document document, + final int startOffset, + final int endOffset, + final String stringToReplace) { final String converted = StringUtil.convertLineSeparators(stringToReplace); - CommandProcessor.getInstance().executeCommand(project, new Runnable() { - @Override - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - //[ven] I doubt converting is a good solution to SCR 21224 - document.replaceString(startOffset, endOffset, converted); - } - }); - } - }, null, null); + CommandProcessor.getInstance().executeCommand(project, () -> ApplicationManager.getApplication().runWriteAction(() -> { + //[ven] I doubt converting is a good solution to SCR 21224 + document.replaceString(startOffset, endOffset, converted); + }), null, null); return startOffset + converted.length(); } @@ -919,6 +882,7 @@ public class FindUtil { editor.getScrollingModel().scrollToCaret(scrollType); } + @FunctionalInterface public interface ReplaceDelegate { boolean shouldReplace(TextRange range, String replace); } @@ -974,7 +938,7 @@ public class FindUtil { if (!editor.getCaretModel().supportsMultipleCarets()) { return; } - ArrayList caretStates = new ArrayList(); + ArrayList caretStates = new ArrayList<>(); while (resultIterator.hasNext()) { FindResult findResult = resultIterator.next(); int caretOffset = getCaretPosition(findResult, caretShiftFromSelectionStart); From 16feef6bdc52715872d0167220b6ecabb5e56c90 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 13 Apr 2016 14:01:44 +0300 Subject: [PATCH 63/64] notnull --- .../psi/refResolve/RefResolveServiceImpl.java | 6 ++-- .../openapi/application/Application.java | 5 ++- .../application/ApplicationAdapter.java | 10 +++--- .../application/ApplicationListener.java | 10 +++--- .../com/intellij/mock/MockApplication.java | 4 +-- .../psi/impl/DocumentCommitThread.java | 4 +-- .../completion/CompletionPhase.java | 4 +-- .../daemon/impl/DaemonListeners.java | 4 +-- .../impl/ProjectRootManagerComponent.java | 6 ++-- .../source/PostprocessReformattingAspect.java | 6 ++-- .../util/indexing/FileBasedIndexImpl.java | 2 +- .../application/impl/ApplicationImpl.java | 32 +++++++------------ .../progress/util/ProgressIndicatorUtils.java | 6 ++-- .../openapi/project/CacheUpdateRunner.java | 2 +- .../openapi/vfs/newvfs/impl/VfsData.java | 4 +-- .../openapi/vcs/ex/LineStatusTracker.java | 4 +-- 16 files changed, 52 insertions(+), 57 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/refResolve/RefResolveServiceImpl.java b/java/java-impl/src/com/intellij/psi/refResolve/RefResolveServiceImpl.java index c8c9434fe8e6..6a486935ebba 100644 --- a/java/java-impl/src/com/intellij/psi/refResolve/RefResolveServiceImpl.java +++ b/java/java-impl/src/com/intellij/psi/refResolve/RefResolveServiceImpl.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -235,12 +235,12 @@ public class RefResolveServiceImpl extends RefResolveService implements Runnable }); myApplication.addApplicationListener(new ApplicationAdapter() { @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { disable(); } @Override - public void writeActionFinished(Object action) { + public void writeActionFinished(@NotNull Object action) { enable(); } diff --git a/platform/core-api/src/com/intellij/openapi/application/Application.java b/platform/core-api/src/com/intellij/openapi/application/Application.java index d47a915fa93c..7231e3a0d79f 100644 --- a/platform/core-api/src/com/intellij/openapi/application/Application.java +++ b/platform/core-api/src/com/intellij/openapi/application/Application.java @@ -22,7 +22,6 @@ import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.ThrowableComputable; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.concurrent.Callable; @@ -105,7 +104,7 @@ public interface Application extends ComponentManager { * @param actionClass the class of the write action to return. * @return true if the action is running, or false if no action of the specified class is currently executing. */ - boolean hasWriteAction(@Nullable Class actionClass); + boolean hasWriteAction(@NotNull Class actionClass); /** * Asserts whether the read access is allowed. @@ -414,7 +413,7 @@ public interface Application extends ComponentManager { * Returns lock used for write operations, should be closed in finally block */ @NotNull - AccessToken acquireWriteActionLock(/*@NotNull*/ Class marker); + AccessToken acquireWriteActionLock(@NotNull Class marker); boolean isInternal(); diff --git a/platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java b/platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java index 3c3f509ebecb..d3f0abafe44c 100644 --- a/platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java +++ b/platform/core-api/src/com/intellij/openapi/application/ApplicationAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. @@ -15,6 +15,8 @@ */ package com.intellij.openapi.application; +import org.jetbrains.annotations.NotNull; + public abstract class ApplicationAdapter implements ApplicationListener { @Override public boolean canExitApplication() { @@ -26,14 +28,14 @@ public abstract class ApplicationAdapter implements ApplicationListener { } @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { } @Override - public void writeActionStarted(Object action) { + public void writeActionStarted(@NotNull Object action) { } @Override - public void writeActionFinished(Object action) { + public void writeActionFinished(@NotNull Object action) { } } \ No newline at end of file diff --git a/platform/core-api/src/com/intellij/openapi/application/ApplicationListener.java b/platform/core-api/src/com/intellij/openapi/application/ApplicationListener.java index d42737d474f8..f9845687227f 100644 --- a/platform/core-api/src/com/intellij/openapi/application/ApplicationListener.java +++ b/platform/core-api/src/com/intellij/openapi/application/ApplicationListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * 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. @@ -15,6 +15,8 @@ */ package com.intellij.openapi.application; +import org.jetbrains.annotations.NotNull; + import java.util.EventListener; /** @@ -35,15 +37,15 @@ public interface ApplicationListener extends EventListener { /** * Is called before action start. */ - void beforeWriteActionStart(Object action); + void beforeWriteActionStart(@NotNull Object action); /** * Is called on action start. */ - void writeActionStarted(Object action); + void writeActionStarted(@NotNull Object action); /** * Is called on action finish. */ - void writeActionFinished(Object action); + void writeActionFinished(@NotNull Object action); } \ No newline at end of file diff --git a/platform/core-impl/src/com/intellij/mock/MockApplication.java b/platform/core-impl/src/com/intellij/mock/MockApplication.java index a1d9f142bd88..f59a40f57a1d 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-2014 JetBrains s.r.o. + * 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. @@ -162,7 +162,7 @@ public class MockApplication extends MockComponentManager implements Application } @Override - public boolean hasWriteAction(@Nullable Class actionClass) { + public boolean hasWriteAction(@NotNull Class actionClass) { return false; } diff --git a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java index 0dd36a9c90de..bbff39c7d03e 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java +++ b/platform/core-impl/src/com/intellij/psi/impl/DocumentCommitThread.java @@ -105,7 +105,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi assert !application.isWriteAccessAllowed() || application.isUnitTestMode(); // crazy stuff happens in tests, e.g. UIUtil.dispatchInvocationEvents() inside write action application.addApplicationListener(new ApplicationAdapter() { @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { int writeActionsBefore = runningWriteActions++; if (writeActionsBefore == 0) { disable("Write action started: " + action); @@ -113,7 +113,7 @@ public class DocumentCommitThread implements Runnable, Disposable, DocumentCommi } @Override - public void writeActionFinished(Object action) { + public void writeActionFinished(@NotNull Object action) { // crazy things happen when running tests, like starting write action in one thread but firing its end in the other int writeActionsAfter = runningWriteActions = Math.max(0,runningWriteActions-1); if (writeActionsAfter == 0) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java index b997934523f6..bcaeeb0976b2 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionPhase.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. @@ -170,7 +170,7 @@ public abstract class CompletionPhase implements Disposable { super(indicator); ApplicationManager.getApplication().addApplicationListener(new ApplicationAdapter() { @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { if (!indicator.getLookup().isLookupDisposed() && !indicator.isCanceled()) { indicator.scheduleRestart(); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java index 2b1d64b2fcfd..dd17e8ef98dc 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DaemonListeners.java @@ -407,14 +407,14 @@ public class DaemonListeners implements Disposable { private boolean myDaemonWasRunning; @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { myDaemonWasRunning = myDaemonCodeAnalyzer.isRunning(); if (!myDaemonWasRunning) return; // we'll restart in writeActionFinished() stopDaemon(true, "Write action start"); } @Override - public void writeActionFinished(Object action) { + public void writeActionFinished(@NotNull Object action) { stopDaemon(true, "Write action finish"); } } diff --git a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java index 7a37554e950e..5acf72be1258 100644 --- a/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java +++ b/platform/lang-impl/src/com/intellij/openapi/roots/impl/ProjectRootManagerComponent.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -316,12 +316,12 @@ public class ProjectRootManagerComponent extends ProjectRootManagerImpl implemen private class AppListener extends ApplicationAdapter { @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { myInsideRefresh++; } @Override - public void writeActionFinished(Object action) { + public void writeActionFinished(@NotNull Object action) { if (--myInsideRefresh == 0) { if (myPointerChangesDetected) { myPointerChangesDetected = false; diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java index 2b803d02a853..ce8aaacc2965 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/PostprocessReformattingAspect.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -86,7 +86,7 @@ public class PostprocessReformattingAspect implements PomModelAspect { ApplicationListener applicationListener = new ApplicationAdapter() { @Override - public void writeActionStarted(final Object action) { + public void writeActionStarted(@NotNull final Object action) { if (processor != null) { final Project project = processor.getCurrentCommandProject(); if (project == myProject) { @@ -96,7 +96,7 @@ public class PostprocessReformattingAspect implements PomModelAspect { } @Override - public void writeActionFinished(final Object action) { + public void writeActionFinished(@NotNull final Object action) { if (processor != null) { final Project project = processor.getCurrentCommandProject(); if (project == myProject) { diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java index fc5d7f81bc97..321e532de859 100644 --- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java +++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java @@ -261,7 +261,7 @@ public class FileBasedIndexImpl extends FileBasedIndex { ApplicationManager.getApplication().addApplicationListener(new ApplicationAdapter() { @Override - public void writeActionStarted(Object action) { + public void writeActionStarted(@NotNull Object action) { myUpToDateIndicesForUnsavedOrTransactedDocuments.clear(); } }); diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 18c7c8e30a69..71a6370004f0 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -557,7 +557,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App final JComponent parentComponent, final String cancelText) { assertIsDispatchThread(); - boolean writeAccessAllowed = isInsideWriteActionEDTOnly(); + boolean writeAccessAllowed = isWriteAccessAllowed(); if (writeAccessAllowed // Disallow running process in separate thread from under write action. // The thread will deadlock trying to get read action otherwise. || isHeadlessEnvironment() && !isUnitTestMode() @@ -614,7 +614,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App final String cancelText, final JComponent parentComponent, @NotNull final Runnable process) { assertIsDispatchThread(); - boolean writeAccessAllowed = isInsideWriteActionEDTOnly(); + boolean writeAccessAllowed = isWriteAccessAllowed(); if (writeAccessAllowed // Disallow running process in separate thread from under write action. // The thread will deadlock trying to get read action otherwise. ) { @@ -965,12 +965,12 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App } @Override - public boolean hasWriteAction(@Nullable Class actionClass) { + public boolean hasWriteAction(@NotNull Class actionClass) { assertIsDispatchThread(); for (int i = myWriteActionsStack.size() - 1; i >= 0; i--) { Class action = myWriteActionsStack.get(i); - if (actionClass == action || action != null && actionClass != null && ReflectionUtil.isAssignable(actionClass, action)) return true; + if (actionClass == action || ReflectionUtil.isAssignable(actionClass, action)) return true; } return false; } @@ -1102,7 +1102,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App private final boolean gatherWriteActionStatistics; private final PausesStat writePauses; - private void startWrite(/*@NotNull*/ Class clazz) { + private void startWrite(@NotNull Class clazz) { assertIsDispatchThread("Write access is allowed from event dispatch thread only"); HeavyProcessLatch.INSTANCE.stopThreadPrioritizing(); // let non-cancellable read actions complete faster, if present if (!isDisposed() && !isDisposeInProgress() && !((TransactionGuardImpl)TransactionGuard.getInstance()).isWriteActionAllowed()) { @@ -1141,7 +1141,7 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App fireWriteActionStarted(clazz); } - private void endWrite(/*@NotNull*/ Class clazz) { + private void endWrite(@NotNull Class clazz) { try { fireWriteActionFinished(clazz); // fire listeners before popping stack because if somebody starts write action in a listener, @@ -1160,17 +1160,14 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App @NotNull @Override - public AccessToken acquireWriteActionLock(/*@NotNull */Class clazz) { - if (clazz == null) { - LOG.warn("Parameter must be not null", new Throwable()); - } + public AccessToken acquireWriteActionLock(@NotNull Class clazz) { return new WriteAccessToken(clazz); } private class WriteAccessToken extends AccessToken { - private final Class clazz; + @NotNull private final Class clazz; - public WriteAccessToken(/*@NotNull*/ Class clazz) { + public WriteAccessToken(@NotNull Class clazz) { this.clazz = clazz; startWrite(clazz); markThreadNameInStackTrace(); @@ -1253,11 +1250,6 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App return isDispatchThread() && myLock.isWriteLocked(); } - // cheaper version of isWriteAccessAllowed(). must be called from EDT - private boolean isInsideWriteActionEDTOnly() { - return !myWriteActionsStack.isEmpty(); - } - @Override public boolean isWriteActionInProgress() { return myLock.isWriteLocked(); @@ -1291,15 +1283,15 @@ public class ApplicationImpl extends PlatformComponentManagerImpl implements App myDispatcher.getMulticaster().applicationExiting(); } - private void fireBeforeWriteActionStart(Class action) { + private void fireBeforeWriteActionStart(@NotNull Class action) { myDispatcher.getMulticaster().beforeWriteActionStart(action); } - private void fireWriteActionStarted(Class action) { + private void fireWriteActionStarted(@NotNull Class action) { myDispatcher.getMulticaster().writeActionStarted(action); } - private void fireWriteActionFinished(Class action) { + private void fireWriteActionFinished(@NotNull Class action) { myDispatcher.getMulticaster().writeActionFinished(action); } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java index 139de38b1af7..7287555569af 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressIndicatorUtils.java @@ -49,7 +49,7 @@ public class ProgressIndicatorUtils { public static ProgressIndicator forceWriteActionPriority(@NotNull final ProgressIndicator progress, @NotNull final Disposable builder) { ApplicationManager.getApplication().addApplicationListener(new ApplicationAdapter() { @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { if (progress.isRunning()) { progress.cancel(); } @@ -114,7 +114,7 @@ public class ProgressIndicatorUtils { final ApplicationAdapter listener = new ApplicationAdapter() { @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { if (!progressIndicator.isCanceled()) progressIndicator.cancel(); } }; @@ -162,7 +162,7 @@ public class ProgressIndicatorUtils { if (application.isDisposed()) return; final ApplicationAdapter listener = new ApplicationAdapter() { @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { if (!progressIndicator.isCanceled()) { progressIndicator.cancel(); readTask.onCanceled(progressIndicator); diff --git a/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java b/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java index aef3eeb9bc44..9004e5113471 100644 --- a/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java +++ b/platform/platform-impl/src/com/intellij/openapi/project/CacheUpdateRunner.java @@ -105,7 +105,7 @@ public class CacheUpdateRunner { }; final ApplicationAdapter canceller = new ApplicationAdapter() { @Override - public void beforeWriteActionStart(Object action) { + public void beforeWriteActionStart(@NotNull Object action) { innerIndicator.cancel(); } }; diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java index 9d21e6b3e176..e80117e0b1eb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/impl/VfsData.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * 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. @@ -88,7 +88,7 @@ public class VfsData { static { ApplicationManager.getApplication().addApplicationListener(new ApplicationAdapter() { @Override - public void writeActionFinished(Object action) { + public void writeActionFinished(@NotNull Object action) { // after top-level write action is finished, all the deletion listeners should have processed the deleted files // and their data is considered safe to remove. From this point on accessing a removed file will result in an exception. if (!ApplicationManager.getApplication().isWriteAccessAllowed()) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java index 3768338f2648..3724d54db348 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/ex/LineStatusTracker.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. + * 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. @@ -369,7 +369,7 @@ public class LineStatusTracker { private class MyApplicationListener extends ApplicationAdapter { @Override - public void writeActionFinished(Object action) { + public void writeActionFinished(@NotNull Object action) { if (!myInitialized || myReleased || myBulkUpdate || myDuringRollback || myAnathemaThrown) return; if (myDirtyRange != null) { try { From a3caef0360bd1069747c82268dac7d00682625ad Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 13 Apr 2016 14:04:11 +0300 Subject: [PATCH 64/64] cleanup --- .../impl/search/JavaDirectInheritorsSearcher.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java index e9f6b483ad86..ded26be91cc9 100644 --- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java +++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/JavaDirectInheritorsSearcher.java @@ -160,11 +160,11 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor)baseClass::getName); - if (StringUtil.isEmpty(className)) { + final String baseClassName = ApplicationManager.getApplication().runReadAction((Computable)baseClass::getName); + if (StringUtil.isEmpty(baseClassName)) { return Pair.create(Collections.emptyList(), new AtomicIntegerArray(0)); } - Pair, AtomicIntegerArray> pair = calculateDirectSubClasses(project, baseClass, className); + Pair, AtomicIntegerArray> pair = calculateDirectSubClasses(project, baseClass, baseClassName); HighlightingCaches.getInstance(project).DIRECT_SUB_CLASSES.put(baseClass, pair); return pair; } @@ -172,11 +172,10 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor, AtomicIntegerArray> calculateDirectSubClasses(@NotNull Project project, @NotNull PsiClass baseClass, - @NotNull String className) { + @NotNull String baseClassName) { GlobalSearchScope allScope = GlobalSearchScope.allScope(project); Collection candidates = - MethodUsagesSearcher - .resolveInReadAction(project, () -> JavaSuperClassNameOccurenceIndex.getInstance().get(className, project, allScope)); + MethodUsagesSearcher.resolveInReadAction(project, () -> JavaSuperClassNameOccurenceIndex.getInstance().get(baseClassName, project, allScope)); Map> classes = new HashMap<>(); int count = 0; @@ -196,7 +195,7 @@ public class JavaDirectInheritorsSearcher implements QueryExecutor anonymousCandidates = - MethodUsagesSearcher.resolveInReadAction(project, () -> JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(className, project, allScope)); + MethodUsagesSearcher.resolveInReadAction(project, () -> JavaAnonymousClassBaseRefOccurenceIndex.getInstance().get(baseClassName, project, allScope)); List result = new ArrayList<>(count + classes.size() + anonymousCandidates.size() + 1); for (Map.Entry> entry : classes.entrySet()) {