From d9e6f8d96edaa3eb4615354ff4a4ad8bede7b9bb Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 20 Dec 2017 18:18:28 +0100 Subject: [PATCH 01/58] surround with closeable: don't include unrelated variables (IDEA-159434) --- .../impl/SurroundAutoCloseableAction.java | 5 ++++- .../UnrelatedVariable.java | 14 ++++++++++++++ .../UnrelatedVariable_after.java | 17 +++++++++++++++++ .../SurroundAutoCloseableActionTest.java | 1 + 4 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 java/java-tests/testData/codeInsight/surroundAutoCloseable/UnrelatedVariable.java create mode 100644 java/java-tests/testData/codeInsight/surroundAutoCloseable/UnrelatedVariable_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java index 88a35f376472..5ba141974e61 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SurroundAutoCloseableAction.java @@ -188,13 +188,16 @@ public class SurroundAutoCloseableAction extends PsiElementBaseIntentionAction { i = PsiTreeUtil.skipWhitespacesAndCommentsForward(i); if (!(child instanceof PsiDeclarationStatement)) continue; + int endOffset = last.getTextRange().getEndOffset(); + //declared after last usage + if (child.getTextOffset() > endOffset) break; PsiElement anchor = child; PsiElement[] declaredElements = ((PsiDeclarationStatement)child).getDeclaredElements(); for (PsiElement declared : declaredElements) { if (!(declared instanceof PsiLocalVariable)) continue; - int endOffset = last.getTextRange().getEndOffset(); + boolean contained = ReferencesSearch.search(declared, scope).forEach(ref -> ref.getElement().getTextOffset() <= endOffset); if (!contained) { diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/UnrelatedVariable.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/UnrelatedVariable.java new file mode 100644 index 000000000000..e8a23dcfbc75 --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/UnrelatedVariable.java @@ -0,0 +1,14 @@ +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +class C { + void m(File file) throws IOException { + FileInputStream fileInputStream = new FileInputStream(file); + String s = "initial value";//Non-NLS + s = s + fileInputStream.read(); + s += "end"; + int time = 0; + System.out.println(time); + } +} diff --git a/java/java-tests/testData/codeInsight/surroundAutoCloseable/UnrelatedVariable_after.java b/java/java-tests/testData/codeInsight/surroundAutoCloseable/UnrelatedVariable_after.java new file mode 100644 index 000000000000..56dcf902e31b --- /dev/null +++ b/java/java-tests/testData/codeInsight/surroundAutoCloseable/UnrelatedVariable_after.java @@ -0,0 +1,17 @@ +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +class C { + void m(File file) throws IOException { + String s; + try (FileInputStream fileInputStream = new FileInputStream(file)) { + //Non-NLS + s = "initial value"; + s = s + fileInputStream.read(); + } + s += "end"; + int time = 0; + System.out.println(time); + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/SurroundAutoCloseableActionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/SurroundAutoCloseableActionTest.java index 8f088d62bc3b..7c98141535dd 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/SurroundAutoCloseableActionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/SurroundAutoCloseableActionTest.java @@ -35,6 +35,7 @@ public class SurroundAutoCloseableActionTest extends LightCodeInsightFixtureTest public void testSplitVar() { doTest(); } public void testExpression() { doTest(); } public void testExpressionIncomplete() { doTest(); } + public void testUnrelatedVariable() { doTest(); } public void testCommentsInVarDeclaration() { JavaCodeStyleSettings styleSettings = JavaCodeStyleSettings.getInstance(getProject()); boolean finalLocals = styleSettings.GENERATE_FINAL_LOCALS; From 0fcc5001bbd491f901081144ec630d3f1aed3abb Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 20 Dec 2017 18:51:52 +0100 Subject: [PATCH 02/58] java mad tests: skip an intention --- .../com/intellij/java/propertyBased/JavaIntentionPolicy.java | 1 + 1 file changed, 1 insertion(+) diff --git a/java/java-tests/testSrc/com/intellij/java/propertyBased/JavaIntentionPolicy.java b/java/java-tests/testSrc/com/intellij/java/propertyBased/JavaIntentionPolicy.java index 4fde37e81b44..be16220a76df 100644 --- a/java/java-tests/testSrc/com/intellij/java/propertyBased/JavaIntentionPolicy.java +++ b/java/java-tests/testSrc/com/intellij/java/propertyBased/JavaIntentionPolicy.java @@ -49,6 +49,7 @@ class JavaIntentionPolicy extends IntentionPolicy { protected static boolean mayBreakCompilation(String actionText) { return actionText.startsWith("Flip") || // doesn't care about compilability actionText.startsWith("Convert to string literal") || // can produce uncompilable code by design + actionText.startsWith("Replace string literal with character") || // can produce uncompilable code by design actionText.startsWith("Detail exceptions") || // can produce uncompilable code if 'catch' section contains 'instanceof's actionText.startsWith("Insert call to super method") || // super method can declare checked exceptions, unexpected at this point actionText.startsWith("Cast to ") || // produces uncompilable code by design From efd79f32162128e1888cef4d233ba965750cceae Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 20 Dec 2017 18:53:05 +0100 Subject: [PATCH 03/58] add more meta-data to ConcurrencyUtil.cacheOrGet(AtomicRef) (IDEA-CR-28066) --- platform/util/src/com/intellij/util/ConcurrencyUtil.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/platform/util/src/com/intellij/util/ConcurrencyUtil.java b/platform/util/src/com/intellij/util/ConcurrencyUtil.java index afa62163c846..b9d098cd5a08 100644 --- a/platform/util/src/com/intellij/util/ConcurrencyUtil.java +++ b/platform/util/src/com/intellij/util/ConcurrencyUtil.java @@ -15,6 +15,7 @@ */ package com.intellij.util; +import com.intellij.ReviseWhenPortedToJDK; import com.intellij.diagnostic.ThreadDumper; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -92,6 +93,8 @@ public class ConcurrencyUtil { /** * @return defaultValue if the reference contains null (in that case defaultValue is placed there), or reference value otherwise. */ + @ReviseWhenPortedToJDK("8") // todo "replace with return ref.updateAndGet(prev -> prev == null ? defaultValue : prev)" + @NotNull public static T cacheOrGet(@NotNull AtomicReference ref, @NotNull T defaultValue) { T value = ref.get(); while (value == null) { From 8678782c6569d213e3ab216c78c5e15a2bd3e792 Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Mon, 11 Dec 2017 15:02:32 +0300 Subject: [PATCH 04/58] Ignore `__getitem__` for `Generic` indirect inheritors (PY-27102) --- .../typing/PyTypingInspectionExtension.kt | 2 +- .../typingGenericIndirectInheritorGetItem.py | 19 +++++++++++++++++++ ...Py3UnresolvedReferencesInspectionTest.java | 5 +++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 python/testData/inspections/PyUnresolvedReferencesInspection3K/typingGenericIndirectInheritorGetItem.py diff --git a/python/src/com/jetbrains/python/codeInsight/typing/PyTypingInspectionExtension.kt b/python/src/com/jetbrains/python/codeInsight/typing/PyTypingInspectionExtension.kt index 938498a6edfb..01c4e61997a1 100644 --- a/python/src/com/jetbrains/python/codeInsight/typing/PyTypingInspectionExtension.kt +++ b/python/src/com/jetbrains/python/codeInsight/typing/PyTypingInspectionExtension.kt @@ -36,7 +36,7 @@ class PyTypingInspectionExtension : PyInspectionExtension() { private fun isGenericItselfOrDescendant(type: PyClassLikeType, context: TypeEvalContext): Boolean { return PyTypingTypeProvider.GENERIC_CLASSES.contains(type.classQName) || - type.getSuperClassTypes(context).any { PyTypingTypeProvider.GENERIC_CLASSES.contains(it.classQName) } + type.getAncestorTypes(context).any { PyTypingTypeProvider.GENERIC_CLASSES.contains(it.classQName) } } private fun isBuiltin(type: PyClassLikeType): Boolean { diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection3K/typingGenericIndirectInheritorGetItem.py b/python/testData/inspections/PyUnresolvedReferencesInspection3K/typingGenericIndirectInheritorGetItem.py new file mode 100644 index 000000000000..9ac4f278ea56 --- /dev/null +++ b/python/testData/inspections/PyUnresolvedReferencesInspection3K/typingGenericIndirectInheritorGetItem.py @@ -0,0 +1,19 @@ +import typing + + +T = typing.TypeVar('T') + + +class X(typing.Generic[T]): + pass + + +class Y(X[T]): + pass + + +class Z(Y[T]): + pass + + +Z[int] \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java index a789363f4d20..e3d3a7763ce7 100644 --- a/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java +++ b/python/testSrc/com/jetbrains/python/inspections/Py3UnresolvedReferencesInspectionTest.java @@ -215,6 +215,11 @@ public class Py3UnresolvedReferencesInspectionTest extends PyInspectionTestCase doTest(); } + // PY-27102 + public void testTypingGenericIndirectInheritorGetItem() { + doTest(); + } + // PY-21655 public void testUsageOfFunctionDecoratedWithAsyncioCoroutine() { doMultiFileTest("a.py"); From 5a857ac73315f7d98093eed8d11afc316fc79be7 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 20 Dec 2017 19:31:33 +0100 Subject: [PATCH 05/58] tests: fork by MODULE_WORKING_DIR as well (IDEA-152227) --- .../com/intellij/execution/JavaTestFrameworkRunnableState.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java index 4dda0a5007d3..5f1947f6bc66 100644 --- a/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java +++ b/java/execution/impl/src/com/intellij/execution/JavaTestFrameworkRunnableState.java @@ -38,6 +38,7 @@ import com.intellij.execution.testframework.sm.runner.ui.SMTRunnerConsoleView; import com.intellij.execution.testframework.sm.runner.ui.SMTestRunnerResultsForm; import com.intellij.execution.testframework.ui.BaseTestsOutputConsoleView; import com.intellij.execution.util.JavaParametersUtil; +import com.intellij.execution.util.ProgramParametersConfigurator; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; @@ -398,7 +399,7 @@ public abstract class JavaTestFrameworkRunnableState Date: Wed, 20 Dec 2017 20:12:29 +0100 Subject: [PATCH 06/58] unused import: process full file but imports (IDEA-183760) --- .../unusedImport/ImportsAreUsedVisitor.java | 5 +++++ .../unusedImport/UnusedImportInspection.java | 21 +++++-------------- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedImport/ImportsAreUsedVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedImport/ImportsAreUsedVisitor.java index 182296962b64..2d6e4e3963d8 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedImport/ImportsAreUsedVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedImport/ImportsAreUsedVisitor.java @@ -44,6 +44,11 @@ class ImportsAreUsedVisitor extends JavaRecursiveElementWalkingVisitor { } } + @Override + public void visitImportList(PsiImportList list) { + //ignore imports + } + @Override public void visitElement(PsiElement element) { if (importStatements.isEmpty()) { diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedImport/UnusedImportInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedImport/UnusedImportInspection.java index b9bca62c92b6..a0bfcc033330 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/unusedImport/UnusedImportInspection.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unusedImport/UnusedImportInspection.java @@ -16,7 +16,10 @@ package com.intellij.codeInspection.unusedImport; import com.intellij.codeInspection.*; -import com.intellij.psi.*; +import com.intellij.psi.PsiErrorElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiImportStatementBase; +import com.intellij.psi.PsiJavaFile; import com.intellij.psi.util.FileTypeUtils; import com.intellij.psi.util.PsiTreeUtil; import com.siyeh.InspectionGadgetsBundle; @@ -37,22 +40,8 @@ public class UnusedImportInspection extends GlobalSimpleInspectionTool { @NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) { if (!(file instanceof PsiJavaFile) || FileTypeUtils.isInServerPageFile(file)) return; PsiJavaFile javaFile = (PsiJavaFile)file; - final PsiPackageStatement packageStatement = javaFile.getPackageStatement(); - final PsiModifierList annotationList; - if (packageStatement != null) { - annotationList = packageStatement.getAnnotationList(); - } - else { - annotationList = null; - } - final ImportsAreUsedVisitor visitor = new ImportsAreUsedVisitor(javaFile); - for (PsiClass aClass : javaFile.getClasses()) { - aClass.accept(visitor); - } - if (annotationList != null) { - annotationList.accept(visitor); - } + javaFile.accept(visitor); for (PsiImportStatementBase unusedImportStatement : visitor.getUnusedImportStatements()) { if (unusedImportStatement.getImportReference() != null && !(PsiTreeUtil.skipWhitespacesForward(unusedImportStatement) instanceof PsiErrorElement)) { From c8810774d1115112797bd689871f69ad8fd525d4 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Wed, 20 Dec 2017 20:13:53 +0100 Subject: [PATCH 07/58] don't recognize packages under resource roots (IDEA-184002) --- .../psi/impl/file/JavaDirectoryServiceImpl.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java b/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java index 7bfd3d822380..706ef85881a9 100644 --- a/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/file/JavaDirectoryServiceImpl.java @@ -40,6 +40,7 @@ import com.intellij.psi.impl.JavaPsiImplementationHelper; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import java.util.Collections; import java.util.Map; @@ -50,10 +51,12 @@ public class JavaDirectoryServiceImpl extends CoreJavaDirectoryService { @Override public PsiPackage getPackage(@NotNull PsiDirectory dir) { - ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(dir.getProject()).getFileIndex(); - String packageName = projectFileIndex.getPackageNameByDirectory(dir.getVirtualFile()); - if (packageName == null) return null; - return JavaPsiFacade.getInstance(dir.getProject()).findPackage(packageName); + Project project = dir.getProject(); + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(project).getFileIndex(); + VirtualFile virtualFile = dir.getVirtualFile(); + String packageName = projectFileIndex.getPackageNameByDirectory(virtualFile); + if (packageName == null || projectFileIndex.isUnderSourceRootOfType(virtualFile, JavaModuleSourceRootTypes.RESOURCES)) return null; + return JavaPsiFacade.getInstance(project).findPackage(packageName); } @Override From 1ed6dda7496eae100c35b320f98d235fe3a75fbd Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 20 Dec 2017 22:16:23 +0300 Subject: [PATCH 08/58] support selected icons in our list-based popup menus with new checkmarks --- .../intellij/dvcs/ui/BranchActionGroup.java | 2 +- .../dvcs/ui/BranchActionGroupPopup.java | 7 +- .../openapi/actionSystem/Presentation.java | 1 + .../openapi/ui/popup/ListItemDescriptor.java | 4 + .../openapi/ui/popup/ListPopupStep.java | 4 + .../ide/ui/laf/darcula/DarculaLaf.java | 16 ++ .../actionSystem/impl/ActionMenuItem.java | 22 +-- .../intellij/ui/popup/PopupFactoryImpl.java | 184 ++++-------------- .../popup/list/GroupedItemsListRenderer.java | 2 +- .../popup/list/PopupListElementRenderer.java | 5 + 10 files changed, 78 insertions(+), 169 deletions(-) diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroup.java b/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroup.java index f698143a8f7d..d4732a134145 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroup.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroup.java @@ -43,7 +43,7 @@ public abstract class BranchActionGroup extends ActionGroup implements DumbAware myIcon = new LayeredIcon(favorite, notFavorite); myHoveredIcon = new LayeredIcon(favoriteOnHover, notFavoriteOnHover); getTemplatePresentation().setIcon(myIcon); - getTemplatePresentation().setHoveredIcon(myHoveredIcon); + getTemplatePresentation().setSelectedIcon(myHoveredIcon); updateIcons(); } diff --git a/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java b/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java index a50be08ca200..d663eab99558 100644 --- a/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java +++ b/platform/dvcs-impl/src/com/intellij/dvcs/ui/BranchActionGroupPopup.java @@ -71,7 +71,6 @@ public class BranchActionGroupPopup extends FlatSpeedSearchPopup { preselectActionCondition, true); myProject = project; DataManager.registerDataProvider(getList(), dataId -> POPUP_MODEL.is(dataId) ? getListModel() : null); - installOnHoverIconsSupport(getListElementRenderer()); myKey = dimensionKey; if (myKey != null) { Dimension storedSize = WindowStateService.getInstance(myProject).getSizeFor(myProject, myKey); @@ -126,7 +125,6 @@ public class BranchActionGroupPopup extends FlatSpeedSearchPopup { // don't store children popup userSize; myKey = null; DataManager.registerDataProvider(getList(), dataId -> POPUP_MODEL.is(dataId) ? getListModel() : null); - installOnHoverIconsSupport(getListElementRenderer()); } private void trackDimensions(@Nullable String dimensionKey) { @@ -364,10 +362,7 @@ public class BranchActionGroupPopup extends FlatSpeedSearchPopup { super.customizeComponent(list, value, isSelected); myTextLabel.setIcon(null); myTextLabel.setDisabledIcon(null); - if (value instanceof PopupFactoryImpl.ActionItem) { - ((PopupFactoryImpl.ActionItem)value).setIconHovered(isSelected); - } - myIconLabel.setIcon(myDescriptor.getIconFor(value)); + myIconLabel.setIcon(isSelected ? myDescriptor.getSelectedIconFor(value) : myDescriptor.getIconFor(value)); PopupElementWithAdditionalInfo additionalInfoAction = getSpecificAction(value, PopupElementWithAdditionalInfo.class); updateInfoComponent(myInfoLabel, additionalInfoAction != null ? additionalInfoAction.getInfoText() : null, isSelected); } diff --git a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java index a918161ad8a5..0af4b17f90d1 100644 --- a/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java +++ b/platform/editor-ui-api/src/com/intellij/openapi/actionSystem/Presentation.java @@ -312,6 +312,7 @@ public final class Presentation implements Cloneable { setText(presentation.getTextWithMnemonic(), presentation.myDisplayedMnemonicIndex > -1); setDescription(presentation.getDescription()); setIcon(presentation.getIcon()); + setSelectedIcon(presentation.getSelectedIcon()); setDisabledIcon(presentation.getDisabledIcon()); setHoveredIcon(presentation.getHoveredIcon()); setVisible(presentation.isVisible()); diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/ListItemDescriptor.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/ListItemDescriptor.java index ae9dee1448a5..e84e5ae5c7c3 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/ListItemDescriptor.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/ListItemDescriptor.java @@ -32,6 +32,10 @@ public interface ListItemDescriptor { @Nullable Icon getIconFor(T value); + default Icon getSelectedIconFor(T value) { + return getIconFor(value); + } + boolean hasSeparatorAboveOf(T value); @Nullable diff --git a/platform/platform-api/src/com/intellij/openapi/ui/popup/ListPopupStep.java b/platform/platform-api/src/com/intellij/openapi/ui/popup/ListPopupStep.java index ca5192bea1ed..1871fbff7608 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/popup/ListPopupStep.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/popup/ListPopupStep.java @@ -55,6 +55,10 @@ public interface ListPopupStep extends PopupStep { @Nullable Icon getIconFor(T aValue); + default Icon getSelectedIconFor(T value) { + return getIconFor(value); + } + /** * Returns the text to display for the specified list item. * diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java index bd253e0eb035..f5a3ed701c71 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java @@ -19,6 +19,7 @@ import com.intellij.ide.IdeEventQueue; import com.intellij.ide.ui.laf.DarculaMetalTheme; import com.intellij.ide.ui.laf.IdeaLaf; import com.intellij.ide.ui.laf.LafManagerImpl; +import com.intellij.ide.ui.laf.intellij.MacIntelliJIconCache; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -575,4 +576,19 @@ public class DarculaLaf extends BasicLookAndFeel { public static Icon loadIcon(String iconName) { return IconLoader.findIcon("/com/intellij/ide/ui/laf/darcula/icons/" + iconName, DarculaLaf.class, true); } + + public static Icon getCheckmarkIcon(boolean darcula) { + if (darcula) return loadIcon("checkmark.png"); + return MacIntelliJIconCache.getIcon("checkmark", false, false, true); + } + + public static Icon getCheckmarkSelectedIcon(boolean darcula) { + if (darcula) return loadIcon("checkmarkSelected.png"); + return MacIntelliJIconCache.getIcon("checkmark", true, false, true); + } + + public static Icon getCheckmarkDisabledIcon(boolean darcula) { + if (darcula) return loadIcon("checkmarkDisabled.png"); + return MacIntelliJIconCache.getIcon("checkmark", false, false, false); + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java index 96aaad00585b..eeade5d0e45a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenuItem.java @@ -4,7 +4,6 @@ package com.intellij.openapi.actionSystem.impl; import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.laf.darcula.DarculaLaf; -import com.intellij.ide.ui.laf.intellij.MacIntelliJIconCache; import com.intellij.internal.statistic.customUsageCollectors.actions.MainMenuCollector; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; @@ -221,9 +220,9 @@ public class ActionMenuItem extends JBCheckBoxMenuItem { else if (!(getUI() instanceof GtkMenuItemUI)) { if (myToggled) { boolean darcula = UIUtil.isUnderDarcula(); - setIcon(getIcon(darcula)); - setSelectedIcon(getSelectedIcon(darcula)); - setDisabledIcon(getDisabledIcon(darcula)); + setIcon(DarculaLaf.getCheckmarkIcon(darcula)); + setSelectedIcon(DarculaLaf.getCheckmarkSelectedIcon(darcula)); + setDisabledIcon(DarculaLaf.getCheckmarkDisabledIcon(darcula)); } else { setIcon(EmptyIcon.ICON_16); @@ -247,21 +246,6 @@ public class ActionMenuItem extends JBCheckBoxMenuItem { } } - private static Icon getIcon(boolean darcula) { - if (darcula) return DarculaLaf.loadIcon("checkmark.png"); - return MacIntelliJIconCache.getIcon("checkmark", false, false, true); - } - - private static Icon getSelectedIcon(boolean darcula) { - if (darcula) return DarculaLaf.loadIcon("checkmarkSelected.png"); - return MacIntelliJIconCache.getIcon("checkmark", true, false, true); - } - - private static Icon getDisabledIcon(boolean darcula) { - if (darcula) return DarculaLaf.loadIcon("checkmarkDisabled.png"); - return MacIntelliJIconCache.getIcon("checkmark", false, false, false); - } - @Override public void setIcon(Icon icon) { if (SystemInfo.isMacSystemMenu && ActionPlaces.MAIN_MENU.equals(myPlace)) { diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java index ab55ac2da8c9..a1fcd8b503cb 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupFactoryImpl.java @@ -20,6 +20,7 @@ import com.intellij.icons.AllIcons; import com.intellij.ide.DataManager; import com.intellij.ide.IdeEventQueue; import com.intellij.ide.IdeTooltipManager; +import com.intellij.ide.ui.laf.darcula.DarculaLaf; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ActionUtil; @@ -47,16 +48,16 @@ import com.intellij.openapi.wm.impl.IdeFrameImpl; import com.intellij.ui.ColorUtil; import com.intellij.ui.FocusTrackback; import com.intellij.ui.HintHint; +import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.awt.RelativePoint; import com.intellij.ui.components.panels.NonOpaquePanel; -import com.intellij.ui.popup.list.IconListPopupRenderer; import com.intellij.ui.popup.list.ListPopupImpl; import com.intellij.ui.popup.mock.MockConfirmation; import com.intellij.ui.popup.tree.TreePopupImpl; -import com.intellij.util.IconUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.PlatformIcons; import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.EmptyIcon; import com.intellij.util.ui.StatusText; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; @@ -228,7 +229,6 @@ public class PopupFactoryImpl extends JBPopupFactory { private final Runnable myDisposeCallback; private final Component myComponent; private final String myActionPlace; - private IconHoverListener myIconsHoverListener; public ActionGroupPopup(final String title, @NotNull ActionGroup actionGroup, @@ -334,8 +334,6 @@ public class PopupFactoryImpl extends JBPopupFactory { if (myDisposeCallback != null) { myDisposeCallback.run(); } - getList().removeMouseMotionListener(myIconsHoverListener); - getList().removeListSelectionListener(myIconsHoverListener); ActionMenu.showDescriptionInStatusBar(true, myComponent, null); super.dispose(); } @@ -380,19 +378,6 @@ public class PopupFactoryImpl extends JBPopupFactory { getList().repaint(); } - public void installOnHoverIconsSupport(@NotNull IconListPopupRenderer iconListPopupRenderer) { - //OnHover icons listener should be installed once - assert myIconsHoverListener == null; - myIconsHoverListener = new IconHoverListener(iconListPopupRenderer); - } - - @Override - protected boolean beforeShow() { - getList().addMouseMotionListener(myIconsHoverListener); - getList().addListSelectionListener(myIconsHoverListener); - return super.beforeShow(); - } - @Nullable private static T getActionByClass(@Nullable Object value, @NotNull ActionPopupStep actionPopupStep, @NotNull Class actionClass) { ActionItem item = value instanceof ActionItem ? (ActionItem)value : null; @@ -400,42 +385,6 @@ public class PopupFactoryImpl extends JBPopupFactory { if (!actionPopupStep.isSelectable(item)) return null; return actionClass.isInstance(item.getAction()) ? actionClass.cast(item.getAction()) : null; } - - private class IconHoverListener extends MouseMotionAdapter implements ListSelectionListener { - @NotNull private IconListPopupRenderer myRenderer; - - public IconHoverListener(@NotNull IconListPopupRenderer renderer) { - myRenderer = renderer; - } - - @Override - public void mouseMoved(MouseEvent e) { - Point point = e.getPoint(); - int index = getList().locationToIndex(point); - Rectangle bounds = getList().getCellBounds(index, index); - Object selectedValue = getList().getSelectedValue(); - if (selectedValue instanceof ActionItem) { - ((ActionItem)selectedValue).setIconHovered(myRenderer.isIconAt(point)); - } - if (bounds != null) { - getList().repaint(bounds); - } - } - - @Override - public void valueChanged(ListSelectionEvent e) { - if (!e.getValueIsAdjusting()) { - int selected = getSelectedIndex(); - int unselected = e.getFirstIndex() == selected ? e.getLastIndex() : e.getFirstIndex(); - Object elementAt = getList().getModel().getElementAt(unselected); - if (elementAt instanceof ActionItem) { - ActionItem actionItem = (ActionItem)elementAt; - actionItem.setIconHovered(false); - getList().repaint(); - } - } - } - } } @NotNull @@ -645,8 +594,7 @@ public class PopupFactoryImpl extends JBPopupFactory { int[] selectionRows = tree.getSelectionRows(); if (selectionRows != null) { Arrays.sort(selectionRows); - for (int i = 0; i < selectionRows.length; i++) { - int row = selectionRows[i]; + for (int row : selectionRows) { Rectangle rowBounds = tree.getRowBounds(row); if (visibleRect.contains(rowBounds)) { popupMenuPoint = new Point(rowBounds.x + 2, rowBounds.y + rowBounds.height - 1); @@ -659,8 +607,7 @@ public class PopupFactoryImpl extends JBPopupFactory { int bestRow = -1; Point rowCenter; double distance; - for (int i = 0; i < selectionRows.length; i++) { - int row = selectionRows[i]; + for (int row : selectionRows) { Rectangle rowBounds = tree.getRowBounds(row); rowCenter = new Point(rowBounds.x + rowBounds.width / 2, rowBounds.y + rowBounds.height / 2); distance = visibleCenter.distance(rowCenter); @@ -745,7 +692,8 @@ public class PopupFactoryImpl extends JBPopupFactory { private final AnAction myAction; private String myText; private final boolean myIsEnabled; - @Nullable private ActionStepBuilder.IconWrapper myIcon; + private final Icon myIcon; + private final Icon mySelectedIcon; private final boolean myPrependWithSeparator; private final String mySeparatorText; private final String myDescription; @@ -754,36 +702,28 @@ public class PopupFactoryImpl extends JBPopupFactory { @NotNull String text, @Nullable String description, boolean enabled, - @Nullable ActionStepBuilder.IconWrapper icon, + @Nullable Icon icon, + @Nullable Icon selectedIcon, final boolean prependWithSeparator, String separatorText) { myAction = action; myText = text; myIsEnabled = enabled; myIcon = icon; + mySelectedIcon = selectedIcon; myPrependWithSeparator = prependWithSeparator; mySeparatorText = separatorText; myDescription = description; myAction.getTemplatePresentation().addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { - if (evt.getPropertyName() == PROP_ICON || evt.getPropertyName() == PROP_HOVERED_ICON) { - updateIcons(); - } - else if (evt.getPropertyName() == PROP_TEXT) { + if (evt.getPropertyName() == PROP_TEXT) { myText = myAction.getTemplatePresentation().getText(); } } }); } - private void updateIcons() { - // we can't set icons if it hasn't existed before, because alignment will be destroyed; use IconWrapper with null icon instead of null - if (myIcon == null) return; - Presentation presentation = myAction.getTemplatePresentation(); - myIcon.setIcons(presentation.getIcon(), presentation.getHoveredIcon()); - } - @NotNull public AnAction getAction() { return myAction; @@ -795,8 +735,8 @@ public class PopupFactoryImpl extends JBPopupFactory { } @Nullable - public ActionStepBuilder.IconWrapper getIcon() { - return myIcon; + public Icon getIcon(boolean selected) { + return selected && mySelectedIcon != null ? mySelectedIcon : myIcon; } public boolean isPrependWithSeparator() { @@ -823,12 +763,6 @@ public class PopupFactoryImpl extends JBPopupFactory { public String toString() { return myText; } - - public void setIconHovered(boolean isHovered) { - if (myIcon != null) { - myIcon.setHovered(isHovered); - } - } } private static class ActionPopupStep implements ListPopupStepEx, MnemonicNavigationFilter, SpeedSearchFilter { @@ -895,7 +829,12 @@ public class PopupFactoryImpl extends JBPopupFactory { @Override public Icon getIconFor(final ActionItem aValue) { - return aValue.getIcon(); + return aValue.getIcon(false); + } + + @Override + public Icon getSelectedIconFor(ActionItem value) { + return value.getIcon(true); } @Override @@ -1038,7 +977,7 @@ public class PopupFactoryImpl extends JBPopupFactory { private boolean myPrependWithSeparator; private String mySeparatorText; private final boolean myHonorActionMnemonics; - private IconWrapper myEmptyIcon; + private Icon myEmptyIcon; private int myMaxIconWidth = -1; private int myMaxIconHeight = -1; @NotNull private String myActionPlace; @@ -1069,12 +1008,12 @@ public class PopupFactoryImpl extends JBPopupFactory { public void buildGroup(@NotNull ActionGroup actionGroup) { calcMaxIconSize(actionGroup); - myEmptyIcon = myMaxIconHeight != -1 && myMaxIconWidth != -1 ? createWrapper(null) : null; + myEmptyIcon = myMaxIconHeight != -1 && myMaxIconWidth != -1 ? EmptyIcon.create(myMaxIconWidth, myMaxIconHeight) : null; appendActionsFromGroup(actionGroup); if (myListModel.isEmpty()) { - myListModel.add(new ActionItem(Utils.EMPTY_MENU_FILLER, Utils.NOTHING_HERE, null, false, null, false, null)); + myListModel.add(new ActionItem(Utils.EMPTY_MENU_FILLER, Utils.NOTHING_HERE, null, false, null, null, false, null)); } } @@ -1136,7 +1075,8 @@ public class PopupFactoryImpl extends JBPopupFactory { AnActionEvent event = createActionEvent(action); ActionUtil.performDumbAwareUpdate(LaterInvocator.isInModalContext(), action, event, true); - if ((myShowDisabled || presentation.isEnabled()) && presentation.isVisible()) { + boolean enabled = presentation.isEnabled(); + if ((myShowDisabled || enabled) && presentation.isVisible()) { String text = presentation.getText(); if (myShowNumbers) { if (myCurrentNumber < 9) { @@ -1151,76 +1091,38 @@ public class PopupFactoryImpl extends JBPopupFactory { myCurrentNumber++; } else if (myHonorActionMnemonics) { - text = Presentation.restoreTextWithMnemonic(text, action.getTemplatePresentation().getMnemonic()); + text = restoreTextWithMnemonic(text, action.getTemplatePresentation().getMnemonic()); } - Icon icon = presentation.isEnabled() ? presentation.getIcon() : IconLoader.getDisabledIcon(presentation.getIcon()); - IconWrapper iconWrapper; - if (icon == null && presentation.getHoveredIcon() == null) { + Icon icon = presentation.getIcon(); + Icon selectedIcon = presentation.getSelectedIcon(); + Icon disabledIcon = presentation.getDisabledIcon(); + if (icon == null && selectedIcon == null) { @NonNls final String actionId = ActionManager.getInstance().getId(action); if (actionId != null && actionId.startsWith("QuickList.")) { - iconWrapper = createWrapper(AllIcons.Actions.QuickList); + icon = AllIcons.Actions.QuickList; } - else if (action instanceof Toggleable) { - boolean toggled = Boolean.TRUE.equals(presentation.getClientProperty(Toggleable.SELECTED_PROPERTY)); - iconWrapper = toggled ? createWrapper(PlatformIcons.CHECK_ICON) : myEmptyIcon; - } - else { - iconWrapper = myEmptyIcon; + else if (action instanceof Toggleable && Boolean.TRUE.equals(presentation.getClientProperty(Toggleable.SELECTED_PROPERTY))) { + boolean darcula = UIUtil.isUnderDarcula(); + icon = DarculaLaf.getCheckmarkIcon(darcula); + selectedIcon = DarculaLaf.getCheckmarkSelectedIcon(darcula); + disabledIcon = DarculaLaf.getCheckmarkDisabledIcon(darcula); } } - else { - iconWrapper = new IconWrapper(icon, presentation.getHoveredIcon(), myMaxIconWidth, myMaxIconHeight); + if (!enabled) { + icon = disabledIcon != null ? disabledIcon : IconLoader.getDisabledIcon(icon); + selectedIcon = disabledIcon != null ? disabledIcon : IconLoader.getDisabledIcon(selectedIcon); } + if (icon == null) icon = selectedIcon != null ? selectedIcon : myEmptyIcon; boolean prependSeparator = (!myListModel.isEmpty() || mySeparatorText != null) && myPrependWithSeparator; assert text != null : action + " has no presentation"; myListModel.add( - new ActionItem(action, text, (String)presentation.getClientProperty(JComponent.TOOL_TIP_TEXT_KEY), presentation.isEnabled(), iconWrapper, - prependSeparator, mySeparatorText)); + new ActionItem(action, text, (String)presentation.getClientProperty(JComponent.TOOL_TIP_TEXT_KEY), + enabled, icon, selectedIcon, prependSeparator, mySeparatorText)); myPrependWithSeparator = false; mySeparatorText = null; } } - - /** - * Adjusts icon size to maximum, so that icons with different sizes were aligned correctly. - */ - public static class IconWrapper extends IconUtil.IconSizeWrapper { - - @Nullable private Icon myIcon; - @Nullable private Icon myHoverIcon; - - private boolean isHovered; - - public IconWrapper(@Nullable Icon icon, @Nullable Icon hoverIcon, int width, int height) { - super(null, width, height); - setIcons(icon, hoverIcon); - } - - @Override - public void paintIcon(Component c, Graphics g, int x, int y) { - paintIcon(myHoverIcon != null && isHovered ? myHoverIcon : myIcon, c, g, x, y); - } - - public boolean isHovered() { - return isHovered; - } - - public void setHovered(boolean hovered) { - isHovered = hovered; - } - - public void setIcons(@Nullable Icon icon, @Nullable Icon hoveredIcon) { - myIcon = icon; - myHoverIcon = hoveredIcon; - } - } - - @NotNull - public IconWrapper createWrapper(@Nullable Icon icon) { - return new IconWrapper(icon, null, myMaxIconWidth, myMaxIconHeight); - } - } @NotNull @@ -1267,11 +1169,9 @@ public class PopupFactoryImpl extends JBPopupFactory { final JPanel content = new NonOpaquePanel(new BorderLayout((int)(label.getIconTextGap() * 1.5), (int)(label.getIconTextGap() * 1.5))); final NonOpaquePanel textWrapper = new NonOpaquePanel(new GridBagLayout()); - JScrollPane scrolledText = new JScrollPane(text); + JScrollPane scrolledText = ScrollPaneFactory.createScrollPane(text, true); scrolledText.setBackground(fillColor); scrolledText.getViewport().setBackground(fillColor); - scrolledText.getViewport().setBorder(null); - scrolledText.setBorder(null); textWrapper.add(scrolledText); content.add(textWrapper, BorderLayout.CENTER); diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java b/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java index 045c8a3eca21..3304403d9ce4 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/GroupedItemsListRenderer.java @@ -44,7 +44,7 @@ public class GroupedItemsListRenderer extends GroupedElementsRenderer.List im boolean hasSeparator = myDescriptor.hasSeparatorAboveOf(value); if (index == 0 && StringUtil.isEmptyOrSpaces(caption)) hasSeparator = false; - Icon icon = myDescriptor.getIconFor(value); + Icon icon = isSelected ? myDescriptor.getSelectedIconFor(value) : myDescriptor.getIconFor(value); final JComponent result = configureComponent(myDescriptor.getTextFor(value), myDescriptor.getTooltipFor(value), icon, icon, isSelected, hasSeparator, caption, -1); diff --git a/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java b/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java index 298391b936e1..695d609b4146 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/list/PopupListElementRenderer.java @@ -49,6 +49,11 @@ public class PopupListElementRenderer extends GroupedItemsListRenderer { return aPopup.getListStep().getIconFor(value); } + @Override + public Icon getSelectedIconFor(E value) { + return aPopup.getListStep().getSelectedIconFor(value); + } + @Override public boolean hasSeparatorAboveOf(E value) { return aPopup.getListModel().isSeparatorAboveOf(value); From a9e3839d7ac36080e6af6fb6a5ab8c37689de04e Mon Sep 17 00:00:00 2001 From: Sergey Malenkov Date: Wed, 20 Dec 2017 22:40:04 +0300 Subject: [PATCH 09/58] to test a tree content after selecting or state restoring you must wait until tree is busy --- .../com/intellij/projectView/ProjectViewUpdatingTest.java | 2 ++ .../com/intellij/projectView/StructureViewUpdatingTest.java | 1 + 2 files changed, 3 insertions(+) diff --git a/java/java-tests/testSrc/com/intellij/projectView/ProjectViewUpdatingTest.java b/java/java-tests/testSrc/com/intellij/projectView/ProjectViewUpdatingTest.java index c60f526277a6..f3bcc99f8b8a 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ProjectViewUpdatingTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/ProjectViewUpdatingTest.java @@ -148,6 +148,7 @@ public class ProjectViewUpdatingTest extends BaseProjectViewTestCase { PlatformTestUtil.waitForAlarm(600); final PsiFile containingFile2 = aClass2.getContainingFile(); pane.select(aClass2, containingFile2.getVirtualFile(), true); + PlatformTestUtil.waitUntilBusy(pane.getTree()); PlatformTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + " -PsiDirectory: updateProjectView\n" + " -PsiDirectory: src\n" + @@ -227,6 +228,7 @@ public class ProjectViewUpdatingTest extends BaseProjectViewTestCase { final PsiField lastField = aClass.getFields()[1]; pane.select(lastField, containingFile.getVirtualFile(), true); + PlatformTestUtil.waitUntilBusy(pane.getTree()); PlatformTestUtil.assertTreeEqual(pane.getTree(), "-Project\n" + " -PsiDirectory: showClassMembers\n" + " -PsiDirectory: src\n" + diff --git a/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java b/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java index b4290e02e227..1ce282558ad9 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java +++ b/java/java-tests/testSrc/com/intellij/projectView/StructureViewUpdatingTest.java @@ -137,6 +137,7 @@ public class StructureViewUpdatingTest extends TestSourceBasedTestCase { svc.select(innerClassField, true); + PlatformTestUtil.waitUntilBusy(svc.getTree()); PlatformTestUtil.assertTreeEqual( svc.getTree(), "-Class2.java\n" + From 03319011cbb1baf679dceac60d768e33a642de4f Mon Sep 17 00:00:00 2001 From: "Vassiliy.Kudryashov" Date: Wed, 20 Dec 2017 22:58:43 +0300 Subject: [PATCH 10/58] GDPR support: fix wrong border, show a hint when consents are empty --- .../platform-impl/src/com/intellij/ui/AppUIUtil.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java index b4983a1f165a..c9d827d3c0be 100644 --- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java @@ -374,12 +374,19 @@ public class AppUIUtil { @Nullable @Override protected Border createContentPaneBorder() { - return null; + return new EmptyBorder(0, 0, UIUtil.PANEL_REGULAR_INSETS.bottom, 0); } @Override protected JComponent createCenterPanel() { + if (consents.isEmpty()) { + JLabel label = new JLabel("There are no data-sharing options available", SwingConstants.CENTER); + label.setVerticalAlignment(SwingConstants.CENTER); + label.setOpaque(true); + label.setBackground(JBColor.background()); + return label; + } final JPanel body = new JPanel(new GridBagLayout()); //noinspection UseDPIAwareInsets From 88901fd9fa50add37044e222efe54eee6c3e47f2 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Thu, 21 Dec 2017 01:26:49 +0300 Subject: [PATCH 11/58] PY-26447: Unify UI between all test runners and obey UX guide --- .../python/testing/PyTestSharedForm.form | 23 +++----- .../python/testing/PyTestSharedForm.java | 57 ++++++++++--------- .../PythonDocTestRunConfigurationForm.java | 6 +- 3 files changed, 39 insertions(+), 47 deletions(-) diff --git a/python/src/com/jetbrains/python/testing/PyTestSharedForm.form b/python/src/com/jetbrains/python/testing/PyTestSharedForm.form index 022ca667b564..92bbf9d5898f 100644 --- a/python/src/com/jetbrains/python/testing/PyTestSharedForm.form +++ b/python/src/com/jetbrains/python/testing/PyTestSharedForm.form @@ -8,38 +8,32 @@ - + - + - + - + - + - + - - - - - - @@ -56,10 +50,9 @@ - - + - + diff --git a/python/src/com/jetbrains/python/testing/PyTestSharedForm.java b/python/src/com/jetbrains/python/testing/PyTestSharedForm.java index f00a7bb10d18..b5f0e140dff1 100644 --- a/python/src/com/jetbrains/python/testing/PyTestSharedForm.java +++ b/python/src/com/jetbrains/python/testing/PyTestSharedForm.java @@ -25,13 +25,13 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.psi.PsiDirectory; +import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.TextAccessor; -import com.intellij.ui.components.JBLabel; import com.intellij.ui.components.JBRadioButton; import com.intellij.ui.components.JBTextField; import com.intellij.uiDesigner.core.GridConstraints; -import com.intellij.uiDesigner.core.GridLayoutManager; import com.intellij.util.ThreeState; +import com.intellij.util.ui.JBUI; import com.jetbrains.PySymbolFieldWithBrowseButton; import com.jetbrains.extenstions.ContextAnchor; import com.jetbrains.extenstions.ModuleBasedContextAnchor; @@ -78,10 +78,6 @@ public final class PyTestSharedForm implements SimplePropertiesProvider { * Panel for environment options */ private JPanel myOptionsPanel; - /** - * Test label - */ - private JBLabel myLabel; /** * Panel for custom options, specific for runner and for "Additional Arguments"al;sop */ @@ -143,6 +139,13 @@ public final class PyTestSharedForm implements SimplePropertiesProvider { }); } + /** + * Titles border used among test run configurations + */ + public static void setBorderToPanel(@NotNull final JPanel panel, @NotNull final String title) { + panel.setBorder(IdeBorderFactory.createTitledBorder(title, false)); + } + /** * @param configuration configuration to configure form on creation * @param customOptions additional option names this form shall support. Make sure your configuration has appropriate properties. @@ -153,7 +156,8 @@ public final class PyTestSharedForm implements SimplePropertiesProvider { final PyTestSharedForm form = new PyTestSharedForm(configuration.getModule(), configuration); for (final TestTargetType testTargetType : TestTargetType.values()) { - final JBRadioButton button = new JBRadioButton(StringUtil.capitalize(testTargetType.getCustomName().toLowerCase(Locale.getDefault()))); + final JBRadioButton button = + new JBRadioButton(StringUtil.capitalize(testTargetType.getCustomName().toLowerCase(Locale.getDefault()))); button.setActionCommand(testTargetType.name()); button.addActionListener(o -> form.onTargetTypeChanged()); form.myButtonGroup.add(button); @@ -166,9 +170,7 @@ public final class PyTestSharedForm implements SimplePropertiesProvider { constraints.setFill(GridConstraints.FILL_BOTH); form.myOptionsPanel.add(form.myOptionsForm.getMainPanel(), constraints); - - form.myLabel.setText(configuration.getTestFrameworkName()); - + setBorderToPanel(form.myPanel, configuration.getTestFrameworkName()); form.addCustomOptions( ObjectArrays.concat(customOptions, new CustomOption(PyTestsSharedKt.getAdditionalArgumentsPropertyName(), TestTargetType.values())) @@ -186,29 +188,28 @@ public final class PyTestSharedForm implements SimplePropertiesProvider { final JBTextField textField = new JBTextField(); optionValueFields.put(option.myName, textField); } - myCustomOptionsPanel.setLayout(new GridLayoutManager(customOptions.length, 2)); - for (int i = 0; i < customOptions.length; i++) { - final CustomOption option = customOptions[i]; + final GridBagConstraints constraints = new GridBagConstraints(); + constraints.insets = JBUI.insets(3); + constraints.gridy = 0; + constraints.anchor = GridBagConstraints.LINE_START; + + for (final CustomOption option : customOptions) { final JBTextField textField = optionValueFields.get(option.myName); - - final GridConstraints labelConstraints = new GridConstraints(); - labelConstraints.setFill(GridConstraints.FILL_VERTICAL); - labelConstraints.setRow(i); - labelConstraints.setColumn(0); - labelConstraints.setHSizePolicy(GridConstraints.SIZEPOLICY_CAN_SHRINK); - - final JLabel label = new JLabel(StringUtil.capitalize(CAPITAL_LETTER.matcher(option.myName).replaceAll(" "))); + final JLabel label = new JLabel(StringUtil.capitalize(CAPITAL_LETTER.matcher(option.myName).replaceAll(" ") + ':')); label.setHorizontalAlignment(SwingConstants.LEFT); - myCustomOptionsPanel.add(label, labelConstraints); + constraints.fill = GridBagConstraints.NONE; + constraints.gridx = 0; + constraints.weightx = 0; + myCustomOptionsPanel.add(label, constraints); - final GridConstraints textConstraints = new GridConstraints(); - textConstraints.setFill(GridConstraints.FILL_BOTH); - textConstraints.setRow(i); - textConstraints.setColumn(1); - textConstraints.setHSizePolicy(GridConstraints.SIZEPOLICY_CAN_GROW); - myCustomOptionsPanel.add(textField, textConstraints); + constraints.gridx = 1; + constraints.weightx = 1.0; + constraints.fill = GridBagConstraints.HORIZONTAL; + myCustomOptionsPanel.add(textField, constraints); + + constraints.gridy++; myCustomOptions.put(option.myName, new OptionHolder(option, label, textField)); } diff --git a/python/src/com/jetbrains/python/testing/doctest/PythonDocTestRunConfigurationForm.java b/python/src/com/jetbrains/python/testing/doctest/PythonDocTestRunConfigurationForm.java index aab24dfcf210..e277624b0d03 100644 --- a/python/src/com/jetbrains/python/testing/doctest/PythonDocTestRunConfigurationForm.java +++ b/python/src/com/jetbrains/python/testing/doctest/PythonDocTestRunConfigurationForm.java @@ -18,10 +18,10 @@ package com.jetbrains.python.testing.doctest; import com.intellij.openapi.project.Project; import com.jetbrains.python.PyBundle; import com.jetbrains.python.testing.AbstractPythonTestRunConfigurationParams; +import com.jetbrains.python.testing.PyTestSharedForm; import com.jetbrains.python.testing.PythonTestLegacyRunConfigurationForm; import javax.swing.*; -import javax.swing.border.TitledBorder; import java.awt.*; public class PythonDocTestRunConfigurationForm implements PythonDocTestRunConfigurationParams { @@ -33,9 +33,7 @@ public class PythonDocTestRunConfigurationForm implements PythonDocTestRunConfig public PythonDocTestRunConfigurationForm(final Project project, final PythonDocTestRunConfiguration configuration) { myRootPanel = new JPanel(new BorderLayout()); myTestRunConfigurationForm = new PythonTestLegacyRunConfigurationForm(project, configuration); - TitledBorder border = (TitledBorder)myTestRunConfigurationForm.getTestsPanel().getBorder(); - border.setTitle(PyBundle.message("runcfg.doctest.display_name")); - + PyTestSharedForm.setBorderToPanel(myTestRunConfigurationForm.getTestsPanel(), PyBundle.message("runcfg.doctest.display_name")); myRootPanel.add(myTestRunConfigurationForm.getPanel(), BorderLayout.CENTER); } From a2ebc63fbf9c66b28ae12a6beb000a180715ad29 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 21 Dec 2017 01:54:34 +0100 Subject: [PATCH 12/58] remove help button from toolbars --- .../ui/PanelWithActionsAndCloseButton.java | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/platform/platform-api/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java b/platform/platform-api/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java index 167a6dd85b98..cbf56cf25d47 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/PanelWithActionsAndCloseButton.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.openapi.ui; @@ -69,8 +57,6 @@ public abstract class PanelWithActionsAndCloseButton extends JPanel implements D protected void init(){ addActionsTo(myToolbarGroup); myToolbarGroup.add(new MyCloseAction()); - myToolbarGroup.add(ActionManager.getInstance().getAction(IdeActions.ACTION_CONTEXT_HELP)); - ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.FILEHISTORY_VIEW_TOOLBAR, myToolbarGroup, ! myVerticalToolbar); JComponent centerPanel = createCenterPanel(); From e5f85dddfdcb006d18a553caa85754b5db985dad Mon Sep 17 00:00:00 2001 From: Egor Ushakov Date: Thu, 21 Dec 2017 10:51:59 +0300 Subject: [PATCH 13/58] use constants instead of magic numbers --- .../debugger/engine/JavaStackFrame.java | 13 ++-- .../debugger/engine/SuspendManagerImpl.java | 20 ++---- .../engine/requests/RequestManagerImpl.java | 12 ++-- .../com/intellij/debugger/jdi/JvmtiError.java | 63 +++++++++++++++++++ .../debugger/jdi/StackFrameProxyImpl.java | 24 ++----- .../jdi/ThreadReferenceProxyImpl.java | 2 +- .../debugger/ui/impl/watch/DebuggerTree.java | 7 +-- .../ui/impl/watch/NodeManagerImpl.java | 17 +---- 8 files changed, 92 insertions(+), 66 deletions(-) create mode 100644 java/debugger/impl/src/com/intellij/debugger/jdi/JvmtiError.java diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java index 6debbdffbb4c..bf3fea02edd8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java @@ -1,6 +1,6 @@ -// Copyright 2000-2017 JetBrains s.r.o. -// Use of this source code is governed by the Apache 2.0 license that can be -// found in the LICENSE file. +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ package com.intellij.debugger.engine; import com.intellij.debugger.DebuggerBundle; @@ -13,10 +13,7 @@ import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.impl.DebuggerUtilsEx; -import com.intellij.debugger.jdi.DecompiledLocalVariable; -import com.intellij.debugger.jdi.LocalVariableProxyImpl; -import com.intellij.debugger.jdi.LocalVariablesUtil; -import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.*; import com.intellij.debugger.memory.utils.StackFrameItem; import com.intellij.debugger.settings.CapturePoint; import com.intellij.debugger.settings.DebuggerSettings; @@ -238,7 +235,7 @@ public class JavaStackFrame extends XStackFrame implements JVMStackFrameInfoProv //notifyCancelled(); } catch (InternalException e) { - if (e.errorCode() == 35) { + if (e.errorCode() == JvmtiError.INVALID_SLOT) { node.setErrorMessage(DebuggerBundle.message("error.corrupt.debug.info", e.getMessage())); //myChildren.add( // myNodeManager.createMessageNode(new MessageDescriptor(DebuggerBundle.message("error.corrupt.debug.info", e.getMessage())))); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java index d6670be3547d..f49efa8531b0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendManagerImpl.java @@ -1,21 +1,10 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.engine; import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.jdi.JvmtiError; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.registry.Registry; @@ -77,7 +66,7 @@ public class SuspendManagerImpl implements SuspendManager { //InternalException 13 means that there are running threads that we are trying to resume //On MacOS it happened that native thread didn't stop while some java thread reached breakpoint //noinspection StatementWithEmptyBody - if (/*Patches.MAC_RESUME_VM_HACK && */e.errorCode() == 13) { + if (/*Patches.MAC_RESUME_VM_HACK && */e.errorCode() == JvmtiError.THREAD_NOT_SUSPENDED) { //Its funny, but second resume solves the problem } else { @@ -147,7 +136,8 @@ public class SuspendManagerImpl implements SuspendManager { //InternalException 13 means that there are running threads that we are trying to resume //On MacOS it happened that native thread didn't stop while some java thread reached breakpoint //noinspection StatementWithEmptyBody - if (/*Patches.MAC_RESUME_VM_HACK && */e.errorCode() == 13 && set.suspendPolicy() == EventRequest.SUSPEND_ALL) { + if (/*Patches.MAC_RESUME_VM_HACK && */e.errorCode() == JvmtiError.THREAD_NOT_SUSPENDED && + set.suspendPolicy() == EventRequest.SUSPEND_ALL) { //Its funny, but second resume solves the problem } else { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java index f3f2fb5011a5..1dfa3e083fb6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java @@ -1,4 +1,6 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ package com.intellij.debugger.engine.requests; import com.intellij.debugger.DebuggerBundle; @@ -6,6 +8,7 @@ import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.JvmtiError; import com.intellij.debugger.requests.ClassPrepareRequestor; import com.intellij.debugger.requests.RequestManager; import com.intellij.debugger.requests.Requestor; @@ -15,7 +18,6 @@ import com.intellij.diagnostic.ThreadDumper; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiClass; import com.intellij.ui.classFilter.ClassFilter; @@ -277,7 +279,7 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque } catch (InternalException e) { //noinspection StatementWithEmptyBody - if (e.errorCode() == 41) { + if (e.errorCode() == JvmtiError.NOT_FOUND) { //event request not found //there could be no requests after hotswap } @@ -337,9 +339,9 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque request.enable(); } catch (InternalException e) { switch (e.errorCode()) { - case 40 /* DUPLICATE */ : LOG.info(e); break; + case JvmtiError.DUPLICATE : LOG.info(e); break; - case 41 /* NOT_FOUND */ : break; + case JvmtiError.NOT_FOUND : break; //event request not found //there could be no requests after hotswap diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/JvmtiError.java b/java/debugger/impl/src/com/intellij/debugger/jdi/JvmtiError.java new file mode 100644 index 000000000000..ed84b7228767 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/JvmtiError.java @@ -0,0 +1,63 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ +package com.intellij.debugger.jdi; + +/** + * Copied from jvmti.h + * @author egor + */ +public class JvmtiError { + private JvmtiError() { + } + + public static final int NONE = 0; + public static final int INVALID_THREAD = 10; + public static final int INVALID_THREAD_GROUP = 11; + public static final int INVALID_PRIORITY = 12; + public static final int THREAD_NOT_SUSPENDED = 13; + public static final int THREAD_SUSPENDED = 14; + public static final int THREAD_NOT_ALIVE = 15; + public static final int INVALID_OBJECT = 20; + public static final int INVALID_CLASS = 21; + public static final int CLASS_NOT_PREPARED = 22; + public static final int INVALID_METHODID = 23; + public static final int INVALID_LOCATION = 24; + public static final int INVALID_FIELDID = 25; + public static final int NO_MORE_FRAMES = 31; + public static final int OPAQUE_FRAME = 32; + public static final int TYPE_MISMATCH = 34; + public static final int INVALID_SLOT = 35; + public static final int DUPLICATE = 40; + public static final int NOT_FOUND = 41; + public static final int INVALID_MONITOR = 50; + public static final int NOT_MONITOR_OWNER = 51; + public static final int INTERRUPT = 52; + public static final int INVALID_CLASS_FORMAT = 60; + public static final int CIRCULAR_CLASS_DEFINITION = 61; + public static final int FAILS_VERIFICATION = 62; + public static final int UNSUPPORTED_REDEFINITION_METHOD_ADDED = 63; + public static final int UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED = 64; + public static final int INVALID_TYPESTATE = 65; + public static final int UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED = 66; + public static final int UNSUPPORTED_REDEFINITION_METHOD_DELETED = 67; + public static final int UNSUPPORTED_VERSION = 68; + public static final int NAMES_DONT_MATCH = 69; + public static final int UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED = 70; + public static final int UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED = 71; + public static final int UNMODIFIABLE_CLASS = 79; + public static final int NOT_AVAILABLE = 98; + public static final int MUST_POSSESS_CAPABILITY = 99; + public static final int NULL_POINTER = 100; + public static final int ABSENT_INFORMATION = 101; + public static final int INVALID_EVENT_TYPE = 102; + public static final int ILLEGAL_ARGUMENT = 103; + public static final int NATIVE_METHOD = 104; + public static final int CLASS_LOADER_UNSUPPORTED = 106; + public static final int OUT_OF_MEMORY = 110; + public static final int ACCESS_DENIED = 111; + public static final int WRONG_PHASE = 112; + public static final int INTERNAL = 113; + public static final int UNATTACHED_THREAD = 115; + public static final int INVALID_ENVIRONMENT = 116; +} diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java index 41fe1f01b97c..1ed0ec8628f4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/StackFrameProxyImpl.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ /* @@ -77,7 +65,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { clearCaches(); } catch (InternalException e) { - if (e.errorCode() == 23 /*INVALID_METHODID according to JDI sources*/) { + if (e.errorCode() == JvmtiError.INVALID_METHODID) { myIsObsolete = ThreeState.YES; return true; } @@ -229,7 +217,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { } catch (InternalException e) { // suppress some internal errors caused by bugs in specific JDI implementations - if (e.errorCode() != 23 && e.errorCode() != 35) { + if (e.errorCode() != JvmtiError.INVALID_METHODID && e.errorCode() != JvmtiError.INVALID_SLOT) { throw EvaluateExceptionUtil.createEvaluateException(e); } else { @@ -319,7 +307,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { clearCaches(); } catch (InternalException e) { - if (e.errorCode() == 35 || e.errorCode() == 101) { + if (e.errorCode() == JvmtiError.INVALID_SLOT || e.errorCode() == JvmtiError.ABSENT_INFORMATION) { throw new EvaluateException(DebuggerBundle.message("error.corrupt.debug.info", e.getMessage()), e); } else throw e; @@ -341,7 +329,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { // From Oracle's forums: // This could be a JPDA bug. Unexpected JDWP Error: 32 means that an 'opaque' frame was detected at the lower JPDA levels, // typically a native frame. - if (e.errorCode() == 32 /*opaque frame JDI bug*/ ) { + if (e.errorCode() == JvmtiError.OPAQUE_FRAME /*opaque frame JDI bug*/ ) { return Collections.emptyList(); } else { @@ -373,7 +361,7 @@ public class StackFrameProxyImpl extends JdiProxy implements StackFrameProxy { } catch (InternalException e) { // extra logging for IDEA-141270 - if (e.errorCode() == 35 || e.errorCode() == 101) { + if (e.errorCode() == JvmtiError.INVALID_SLOT || e.errorCode() == JvmtiError.ABSENT_INFORMATION) { LOG.info(e); myAllValues = Collections.emptyMap(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java index 47369b304354..82584eee1425 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadReferenceProxyImpl.java @@ -305,7 +305,7 @@ public final class ThreadReferenceProxyImpl extends ObjectReferenceProxyImpl imp catch (InvalidStackFrameException | ObjectCollectedException ignored) { } catch (InternalException e) { - if (e.errorCode() == 32) { + if (e.errorCode() == JvmtiError.OPAQUE_FRAME) { throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("drop.frame.error.no.information")); } else throw EvaluateExceptionUtil.createEvaluateException(e); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java index 74611a824609..3e4ea26a31b7 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java @@ -20,10 +20,7 @@ import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; -import com.intellij.debugger.jdi.LocalVariableProxyImpl; -import com.intellij.debugger.jdi.StackFrameProxyImpl; -import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; -import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.jdi.*; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.settings.ThreadsViewSettings; import com.intellij.debugger.ui.breakpoints.Breakpoint; @@ -505,7 +502,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi notifyCancelled(); } catch (InternalException e) { - if (e.errorCode() == 35) { + if (e.errorCode() == JvmtiError.INVALID_SLOT) { myChildren.add( myNodeManager.createMessageNode(new MessageDescriptor(DebuggerBundle.message("error.corrupt.debug.info", e.getMessage())))); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java index 44350497219e..71ea9f4c444a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.ui.impl.watch; @@ -20,6 +8,7 @@ import com.intellij.debugger.engine.evaluation.EvaluationContext; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.JvmtiError; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.ui.impl.nodes.NodeComparator; import com.intellij.debugger.ui.tree.DebuggerTreeNode; @@ -131,7 +120,7 @@ public class NodeManagerImpl extends NodeDescriptorFactoryImpl implements NodeMa catch (EvaluateException ignored) { } catch (InternalException ie) { - if (ie.errorCode() != 23) { // INVALID_METHODID + if (ie.errorCode() != JvmtiError.INVALID_METHODID) { throw ie; } } From 81ded84970d4694bae56bfaa838e1a5bab77931b Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 21 Dec 2017 09:10:01 +0100 Subject: [PATCH 14/58] deliver consistent PSI events when replacing a child after changing its subtree --- .../tree/events/impl/TreeChangeEventImpl.java | 17 ++++++++-------- .../psi/impl/PsiEventConsistencyTest.kt | 20 ++++++++++++++++++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/platform/core-impl/src/com/intellij/pom/tree/events/impl/TreeChangeEventImpl.java b/platform/core-impl/src/com/intellij/pom/tree/events/impl/TreeChangeEventImpl.java index a8f6faf8d074..d11bda895421 100644 --- a/platform/core-impl/src/com/intellij/pom/tree/events/impl/TreeChangeEventImpl.java +++ b/platform/core-impl/src/com/intellij/pom/tree/events/impl/TreeChangeEventImpl.java @@ -90,7 +90,7 @@ public class TreeChangeEventImpl implements TreeChangeEvent{ CompositeElement newParent = nextChange.getChangedParent(); for (TreeChangeImpl descendant : new ArrayList<>(myChangesByAllParents.get(newParent))) { - TreeElement ancestorChild = findAncestorChild(newParent, descendant.getChangedParent()); + TreeElement ancestorChild = findAncestorChild(newParent, descendant); if (ancestorChild != null) { nextChange.markChildChanged(ancestorChild, descendant.getLengthDelta()); } @@ -115,15 +115,14 @@ public class TreeChangeEventImpl implements TreeChangeEvent{ } } + /** @return a direct child of {@code ancestor} which contains {@code change} */ @Nullable - private static TreeElement findAncestorChild(@NotNull TreeElement ancestor, @NotNull TreeElement candidate) { - TreeElement element = candidate.getTreeParent(); - while (element != null) { - if (element == ancestor) return candidate; - candidate = element; - element = element.getTreeParent(); - } - return null; + private static TreeElement findAncestorChild(@NotNull CompositeElement ancestor, @NotNull TreeChangeImpl change) { + List superParents = change.getSuperParents(); + int index = superParents.indexOf(ancestor); + return index < 0 ? null : + index == 0 ? change.getChangedParent() : + superParents.get(index - 1); } @Override diff --git a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiEventConsistencyTest.kt b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiEventConsistencyTest.kt index 5e6e5b3e1ed7..e057ba0fab2a 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiEventConsistencyTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/psi/impl/PsiEventConsistencyTest.kt @@ -22,6 +22,21 @@ import one.util.streamex.IntStreamEx */ class PsiEventConsistencyTest : LightPlatformCodeInsightFixtureTestCase() { + fun `test replacing child after changing its subtree`() { + WriteCommandAction.runWriteCommandAction(project) { + // prepare + val root = createEmptyFile().node + root.replaceChild(root.firstChildNode, createComposite(compositeTypes[0], listOf(createLeaf(leafTypes[0], "d")))) + + // actual composite change + ChangeUtil.prepareAndRunChangeAction(ChangeUtil.ChangeAction { + root.firstChildNode.removeChild(root.firstChildNode.firstChildNode) // remove "d" leaf + root.replaceChild(root.firstChildNode, createComposite(compositeTypes[0], listOf())) // replace now empty composite with another one + }, root as FileElement) + assertEquals("", root.text) + } + } + fun testPsiDocSynchronization() { PropertyChecker.forAll(commands).shouldHold { cmd -> runCommand(cmd) @@ -30,7 +45,7 @@ class PsiEventConsistencyTest : LightPlatformCodeInsightFixtureTestCase() { } private fun runCommand(cmd: AstCommand) { - val file = PsiFileFactory.getInstance(project).createFileFromText("a.txt", PlainTextLanguage.INSTANCE, "", true, false) + val file = createEmptyFile() val document = file.viewProvider.document!! WriteCommandAction.runWriteCommandAction(project) { cmd.performChange(file) @@ -39,6 +54,9 @@ class PsiEventConsistencyTest : LightPlatformCodeInsightFixtureTestCase() { } } + private fun createEmptyFile() : PsiFile = + PsiFileFactory.getInstance(project).createFileFromText("a.txt", PlainTextLanguage.INSTANCE, "", true, false) + private interface AstCommand { fun performChange(file: PsiFile) } From 41f2d5fe241c15630dafbf2b6fbc69fdc164470d Mon Sep 17 00:00:00 2001 From: nik Date: Wed, 20 Dec 2017 17:02:14 +0300 Subject: [PATCH 15/58] project configuration: save project after converting module groups This will also help Git to detect that *.iml files are actually renamed. --- .../ide/actions/project/convertModuleGroupsToQualifiedNames.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/platform-impl/src/com/intellij/ide/actions/project/convertModuleGroupsToQualifiedNames.kt b/platform/platform-impl/src/com/intellij/ide/actions/project/convertModuleGroupsToQualifiedNames.kt index 334f06314e3c..d788b8867d63 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/project/convertModuleGroupsToQualifiedNames.kt +++ b/platform/platform-impl/src/com/intellij/ide/actions/project/convertModuleGroupsToQualifiedNames.kt @@ -162,6 +162,7 @@ class ConvertModuleGroupsToQualifiedNamesDialog(val project: Project) : DialogWr if (rememberOldNamesCheckBox.isSelected) { (ModulePointerManager.getInstance(project) as ModulePointerManagerImpl).setRenamingScheme(renamingScheme) } + project.save() } super.doOKAction() From a8a3d240bca77aeaf3e45708f241d61464921a2e Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Dec 2017 11:47:05 +0300 Subject: [PATCH 16/58] build scripts: clean up update.sh Remove reference to non-existing jar. --- build/update.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build/update.sh b/build/update.sh index 0cdc4959029c..92c7133f8e1a 100755 --- a/build/update.sh +++ b/build/update.sh @@ -34,9 +34,8 @@ fi echo "Updating $WORK_IDEA_HOME from compiled classes in $DEV_IDEA_HOME" ANT_HOME="$DEV_IDEA_HOME/lib/ant" -ANT_CLASSPATH="$DEV_IDEA_HOME/build/lib/gant/lib/jps.jar" "$JAVA_BIN" -Xms64m -Xmx512m -Dant.home="$ANT_HOME" -classpath "$ANT_HOME/lib/ant-launcher.jar" org.apache.tools.ant.launch.Launcher \ - -lib "$ANT_CLASSPATH" -f "$DEV_IDEA_HOME/build/update.xml" -Dwork.idea.home="$WORK_IDEA_HOME" ${TARGET} + -f "$DEV_IDEA_HOME/build/update.xml" -Dwork.idea.home="$WORK_IDEA_HOME" ${TARGET} if [ "$?" != "0" ]; then echo "Update failed; work IDEA build not modified." From e8c93ab81cac057dfa2803cfceb4fce0019f61a3 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 19 Dec 2017 12:28:05 +0100 Subject: [PATCH 17/58] IG: add quick fixes and handle abstract classes better in "Comparable implemented but 'equals()' not overridden" inspection --- ...entedButEqualsNotOverriddenInspection.java | 186 ++++++++++++++---- .../AbstractClass1.java | 8 + .../AbstractClass2.java | 4 + .../AbstractClass3.java | 10 + .../Note.java | 11 ++ ...dButEqualsNotOverriddenInspectionTest.java | 4 + 6 files changed, 185 insertions(+), 38 deletions(-) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass1.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass2.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass3.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/Note.java diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ComparableImplementedButEqualsNotOverriddenInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ComparableImplementedButEqualsNotOverriddenInspection.java index 1686f5b5bb6a..863ce5652cac 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ComparableImplementedButEqualsNotOverriddenInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/bugs/ComparableImplementedButEqualsNotOverriddenInspection.java @@ -15,34 +15,119 @@ */ package com.siyeh.ig.bugs; +import com.intellij.codeInspection.ProblemDescriptor; import com.intellij.openapi.project.Project; -import com.intellij.psi.CommonClassNames; -import com.intellij.psi.JavaPsiFacade; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMethod; -import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.codeStyle.CodeStyleManager; +import com.intellij.psi.javadoc.PsiDocComment; +import com.intellij.psi.javadoc.PsiDocToken; import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.psi.util.PsiUtil; import com.siyeh.HardcodedMethodConstants; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.psiutils.MethodUtils; +import com.siyeh.ig.InspectionGadgetsFix; +import com.siyeh.ig.psiutils.ClassUtils; +import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + public class ComparableImplementedButEqualsNotOverriddenInspection extends BaseInspection { @Override @NotNull public String getDisplayName() { - return InspectionGadgetsBundle.message( - "comparable.implemented.but.equals.not.overridden.display.name"); + return InspectionGadgetsBundle.message("comparable.implemented.but.equals.not.overridden.display.name"); } @Override @NotNull protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "comparable.implemented.but.equals.not.overridden.problem.descriptor"); + return InspectionGadgetsBundle.message("comparable.implemented.but.equals.not.overridden.problem.descriptor"); + } + + @NotNull + @Override + protected InspectionGadgetsFix[] buildFixes(Object... infos) { + return new InspectionGadgetsFix[] { + new GenerateEqualsMethodFix(), + new AddNoteFix() + }; + } + + private static class GenerateEqualsMethodFix extends InspectionGadgetsFix { + @Nls + @NotNull + @Override + public String getFamilyName() { + return "Generate 'equals()' method"; + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) { + final PsiClass aClass = (PsiClass)descriptor.getPsiElement().getParent(); + final StringBuilder methodText = new StringBuilder(); + if (PsiUtil.isLanguageLevel5OrHigher(aClass)) { + methodText.append("@java.lang.Override "); + } + methodText.append("public "); + methodText.append("boolean equals(Object o) {\n"); + methodText.append("if (!(o instanceof ").append(aClass.getName()).append("))").append("return false;"); + methodText.append("return compareTo((").append(aClass.getName()).append(")o)==0;\n"); + methodText.append("}"); + final PsiMethod method = + JavaPsiFacade.getElementFactory(project).createMethodFromText(methodText.toString(), aClass, PsiUtil.getLanguageLevel(aClass)); + final PsiElement newMethod = aClass.add(method); + CodeStyleManager.getInstance(project).reformat(newMethod); + } + } + + private static class AddNoteFix extends InspectionGadgetsFix { + + private static final Pattern PARAM_PATTERN = Pattern.compile("\\*[ \t]+@"); + + @Nls + @NotNull + @Override + public String getFamilyName() { + return "Add 'ordering inconsistent with equals' JavaDoc note"; + } + + @Override + protected void doFix(Project project, ProblemDescriptor descriptor) { + final PsiClass aClass = (PsiClass)descriptor.getPsiElement().getParent(); + final PsiDocComment comment = aClass.getDocComment(); + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project); + if (comment == null) { + final PsiDocComment newComment = factory.createDocCommentFromText( + "/**\n" + + "* Note: this class has a natural ordering that is inconsistent with equals.\n" + + "*/", aClass); + aClass.addBefore(newComment, aClass.getFirstChild()); + } + else { + final String text = comment.getText(); + final Matcher matcher = PARAM_PATTERN.matcher(text); + String newCommentText; + if (matcher.find()) { + newCommentText = text.substring(0, matcher.start()) + + " * Note: this class has a natural ordering that is inconsistent with equals.\n" + + text.substring(matcher.start()); + } + else { + newCommentText = text.substring(0, text.length() - 2) + + " * Note: this class has a natural ordering that is inconsistent with equals.\n*/"; + } + final PsiDocComment newComment = factory.createDocCommentFromText(newCommentText); + comment.replace(newComment); + } + } } @Override @@ -56,43 +141,68 @@ public class ComparableImplementedButEqualsNotOverriddenInspection extends BaseI public void visitClass(PsiClass aClass) { super.visitClass(aClass); if (aClass.isInterface()) { + // the problem can't be fixed for an interface, so let's not report it return; } - final PsiMethod[] methods = aClass.findMethodsByName(HardcodedMethodConstants.COMPARE_TO, false); - if (methods.length == 0) { - return; - } - final Project project = aClass.getProject(); - final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); - final GlobalSearchScope scope = aClass.getResolveScope(); final PsiClass comparableClass = - psiFacade.findClass(CommonClassNames.JAVA_LANG_COMPARABLE, - scope); - if (comparableClass == null) { + JavaPsiFacade.getInstance(aClass.getProject()).findClass(CommonClassNames.JAVA_LANG_COMPARABLE, aClass.getResolveScope()); + if (comparableClass == null || !aClass.isInheritor(comparableClass, true)) { return; } - if (!aClass.isInheritor(comparableClass, true)) { + final PsiMethod[] comparableMethods = comparableClass.getMethods(); + if (comparableMethods.length != 1) { // incorrect/broken jdk return; } - final PsiMethod compareToMethod = comparableClass.getMethods()[0]; - boolean foundCompareTo = false; - for (PsiMethod method : methods) { - if (MethodSignatureUtil.isSuperMethod(compareToMethod, method)) { - foundCompareTo = true; - break; + final PsiMethod comparableMethod = MethodSignatureUtil.findMethodBySuperMethod(aClass, comparableMethods[0], false); + if (comparableMethod == null || comparableMethod.hasModifierProperty(PsiModifier.ABSTRACT) || + comparableMethod.getBody() == null) { + return; + } + final PsiClass objectClass = ClassUtils.findObjectClass(aClass); + if (objectClass == null) { + return; + } + final PsiMethod[] equalsMethods = objectClass.findMethodsByName(HardcodedMethodConstants.EQUALS, false); + if (equalsMethods.length != 1) { // incorrect/broken jdk + return; + } + final PsiMethod equalsMethod = MethodSignatureUtil.findMethodBySuperMethod(aClass, equalsMethods[0], false); + if (equalsMethod != null && !equalsMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { + return; + } + final String docCommentText = collapseWhitespace(getActualCommentText(aClass.getDocComment())); + if (StringUtil.containsIgnoreCase(docCommentText, "this class has a natural ordering that is inconsistent with equals")) { + // see Comparable.compareTo() javadoc + return; + } + registerClassError(aClass, aClass); + } + + private static String getActualCommentText(PsiDocComment comment) { + if (comment == null) return ""; + return Arrays.stream(comment.getChildren()) + .filter(e -> (e instanceof PsiDocToken) && ((PsiDocToken)e).getTokenType() == JavaDocTokenType.DOC_COMMENT_DATA) + .map(PsiElement::getText) + .collect(Collectors.joining()); + } + + private static String collapseWhitespace(String s) { + final StringBuilder result = new StringBuilder(); + boolean space = false; + for (int i = 0, length = s.length(); i < length; i++) { + char ch = s.charAt(i); + if (StringUtil.isWhiteSpace(ch)) { + if (!space) { + result.append(' '); + space = true; + } + } + else { + result.append(ch); + space = false; } } - if (!foundCompareTo) { - return; - } - final PsiMethod[] equalsMethods = aClass.findMethodsByName( - HardcodedMethodConstants.EQUALS, false); - for (PsiMethod equalsMethod : equalsMethods) { - if (MethodUtils.isEquals(equalsMethod)) { - return; - } - } - registerClassError(aClass); + return result.toString(); } } } diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass1.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass1.java new file mode 100644 index 000000000000..95bdc82ff4c6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass1.java @@ -0,0 +1,8 @@ +abstract class AbstractClass1 implements Comparable { + + int field = 1; + + public int compareTo(AbstractClass1 other) { + return field > other.field ? 1 : (field == other.field ? 0 : -1); + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass2.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass2.java new file mode 100644 index 000000000000..7b99a07e178c --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass2.java @@ -0,0 +1,4 @@ +abstract class AbstractClass2 implements Comparable { + + public abstract int compareTo(AbstractClass2 other); +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass3.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass3.java new file mode 100644 index 000000000000..9c9f5f9bfe83 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/AbstractClass3.java @@ -0,0 +1,10 @@ +abstract class AbstractClass3 implements Comparable { + + int field; + + public int compareTo(AbstractClass3 other) { + return field > other.field ? 1 : (field == other.field ? 0 : -1); + } + + public abstract boolean equals(Object other); +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/Note.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/Note.java new file mode 100644 index 000000000000..ea8235218929 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/comparable_implemented_but_equals_not_overridden/Note.java @@ -0,0 +1,11 @@ +/** + * Note: This class has a natural + * ordering that is INCONSISTENT with equals. + */ +class Note implements Comparable { + + @Override + public int compareTo(Note other) { + return 0; + } +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ComparableImplementedButEqualsNotOverriddenInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ComparableImplementedButEqualsNotOverriddenInspectionTest.java index 11f392fbfd32..c1ab7d827162 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ComparableImplementedButEqualsNotOverriddenInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/bugs/ComparableImplementedButEqualsNotOverriddenInspectionTest.java @@ -26,6 +26,10 @@ public class ComparableImplementedButEqualsNotOverriddenInspectionTest extends L public void testInterfaceImplementingComparable() { doTest(); } public void testSimple() { doTest(); } + public void testAbstractClass1() { doTest(); } + public void testAbstractClass2() { doTest(); } + public void testAbstractClass3() { doTest(); } + public void testNote() { doTest(); } @Nullable @Override From 3e37b4f6a4bff1180dc3f682a033bc75e4e1b7fe Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Wed, 20 Dec 2017 13:32:48 +0100 Subject: [PATCH 18/58] IG: make field final --- .../com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java index d1544ee92858..33b8e44f1eda 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/abstraction/TypeMayBeWeakenedInspection.java @@ -76,7 +76,7 @@ public class TypeMayBeWeakenedInspection extends AbstractBaseJavaLocalInspection public OrderedSet myStopClassSet = new OrderedSet<>(); - private ListWrappingTableModel myStopClassesModel = new ListWrappingTableModel(myStopClassSet, InspectionGadgetsBundle + private final ListWrappingTableModel myStopClassesModel = new ListWrappingTableModel(myStopClassSet, InspectionGadgetsBundle .message("inspection.type.may.be.weakened.add.stop.class.selection.table")); class AddStopWordQuickfix implements LowPriorityAction, LocalQuickFix { From 50ce4ec7a68c95fe6a631bbd57831c8f3f32f601 Mon Sep 17 00:00:00 2001 From: Egor Ushakov Date: Thu, 21 Dec 2017 12:17:36 +0300 Subject: [PATCH 19/58] disable any editor mouse drag processing with right mouse button disabled by default for now, selection appeared with two buttons (left+right) pressed, which is bad for powermouse plugin users for example --- .../src/com/intellij/openapi/editor/impl/EditorImpl.java | 3 ++- platform/util/resources/misc/registry.properties | 3 +++ 2 files changed, 5 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 2a31069dacca..c63b84387e7a 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 @@ -2274,7 +2274,8 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi } private void processMouseDragged(@NotNull MouseEvent e) { - if (!JBSwingUtilities.isLeftMouseButton(e) && !JBSwingUtilities.isMiddleMouseButton(e)) { + if (!JBSwingUtilities.isLeftMouseButton(e) && !JBSwingUtilities.isMiddleMouseButton(e) + || (Registry.is("editor.disable.drag.with.right.button") && JBSwingUtilities.isRightMouseButton(e))) { return; } diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index 9577d9aba3c3..505e4895fa45 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -1401,5 +1401,8 @@ editor.show.right.margin.in.read.only.files.description=Show right margin for re editor.text.fractional.metrics=false editor.text.fractional.metrics.description=Do not round glyph advances to integer values +editor.disable.drag.with.right.button=false +editor.disable.drag.with.right.button.description=Disable any mouse drag processing in editor with right mouse button pressed + idea.invalidate.caches.invalidates.vfs=false idea.invalidate.caches.invalidates.vfs.description=Invalidate caches tries to invalidate everything, including Local History \ No newline at end of file From f5b9eaffb9a025abb03b7554ebf2a9cdab587516 Mon Sep 17 00:00:00 2001 From: Egor Ushakov Date: Thu, 21 Dec 2017 12:17:49 +0300 Subject: [PATCH 20/58] cleanup: use streams --- .../engine/requests/RequestManagerImpl.java | 9 ++--- .../jdi/ObjectReferenceProxyImpl.java | 27 +++------------ .../jdi/ThreadGroupReferenceProxyImpl.java | 33 +++---------------- .../debugger/jdi/VirtualMachineProxyImpl.java | 15 +++------ .../settings/CompositeDataBinding.java | 29 +++------------- .../intellij/debugger/ui/HotSwapUIImpl.java | 29 ++-------------- .../debugger/ui/RunHotswapDialog.java | 22 ++----------- .../EditInstanceFiltersDialog.java | 22 ++----------- .../ui/impl/watch/CompilingEvaluatorImpl.java | 15 ++------- .../ui/impl/watch/StaticDescriptorImpl.java | 26 ++------------- .../ui/tree/render/BatchEvaluator.java | 21 ++---------- .../JavaBreakpointFiltersPanel.java | 8 +---- .../debugger/engine/JSR45PositionManager.java | 23 +++---------- .../engine/SourcePositionHighlighter.java | 16 ++------- .../ui/tree/NodeDescriptorNameAdjuster.java | 21 +++--------- .../BreakpointsFavoriteListProvider.java | 22 ++----------- 16 files changed, 50 insertions(+), 288 deletions(-) diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java index 1dfa3e083fb6..91cee0dfa291 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java @@ -366,13 +366,8 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque public boolean isVerified(Requestor requestor) { DebuggerManagerThreadImpl.assertIsManagerThread(); - for (EventRequest request : findRequests(requestor)) { - /*ClassPrepareRequest is added in any case, so do not count it*/ - if (!(request instanceof ClassPrepareRequest)) { - return true; - } - } - return false; + //ClassPrepareRequest is added in any case, so do not count it + return findRequests(requestor).stream().anyMatch(r -> !(r instanceof ClassPrepareRequest)); } public void processDetached(DebugProcessImpl process, boolean closedByUser) { diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java index d4365472d9d2..7c799dc79890 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/ObjectReferenceProxyImpl.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ /* @@ -21,10 +9,10 @@ package com.intellij.debugger.jdi; import com.intellij.util.ThreeState; import com.sun.jdi.*; +import one.util.streamex.StreamEx; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -104,18 +92,11 @@ public class ObjectReferenceProxyImpl extends JdiProxy { * @throws IncompatibleThreadStateException */ public List waitingThreads() throws IncompatibleThreadStateException { - List list = getObjectReference().waitingThreads(); - List proxiesList = new ArrayList<>(list.size()); - - for (ThreadReference threadReference : list) { - proxiesList.add(getVirtualMachineProxy().getThreadReferenceProxy(threadReference)); - } - return proxiesList; + return StreamEx.of(getObjectReference().waitingThreads()).map(getVirtualMachineProxy()::getThreadReferenceProxy).toList(); } public ThreadReferenceProxyImpl owningThread() throws IncompatibleThreadStateException { - ThreadReference threadReference = getObjectReference().owningThread(); - return getVirtualMachineProxy().getThreadReferenceProxy(threadReference); + return getVirtualMachineProxy().getThreadReferenceProxy(getObjectReference().owningThread()); } public int entryCount() throws IncompatibleThreadStateException { diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java index 9b2cc6c77bc5..5ec174f59d7c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/ThreadGroupReferenceProxyImpl.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ /* @@ -22,10 +10,9 @@ package com.intellij.debugger.jdi; import com.intellij.debugger.engine.jdi.ThreadGroupReferenceProxy; import com.intellij.openapi.diagnostic.Logger; import com.sun.jdi.ThreadGroupReference; -import com.sun.jdi.ThreadReference; +import one.util.streamex.StreamEx; import org.jetbrains.annotations.NonNls; -import java.util.ArrayList; import java.util.List; public class ThreadGroupReferenceProxyImpl extends ObjectReferenceProxyImpl implements ThreadGroupReferenceProxy{ @@ -73,23 +60,11 @@ public class ThreadGroupReferenceProxyImpl extends ObjectReferenceProxyImpl impl } public List threads() { - List list = getThreadGroupReference().threads(); - List proxies = new ArrayList<>(list.size()); - - for (ThreadReference threadReference : list) { - proxies.add(getVirtualMachineProxy().getThreadReferenceProxy(threadReference)); - } - return proxies; + return StreamEx.of(getThreadGroupReference().threads()).map(getVirtualMachineProxy()::getThreadReferenceProxy).toList(); } public List threadGroups() { - List list = getThreadGroupReference().threadGroups(); - List proxies = new ArrayList<>(list.size()); - - for (ThreadGroupReference threadGroupReference : list) { - proxies.add(getVirtualMachineProxy().getThreadGroupReferenceProxy(threadGroupReference)); - } - return proxies; + return StreamEx.of(getThreadGroupReference().threadGroups()).map(getVirtualMachineProxy()::getThreadGroupReferenceProxy).toList(); } public void clearCaches() { diff --git a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java index 34f0643d6286..548354764af6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/jdi/VirtualMachineProxyImpl.java @@ -1,4 +1,6 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ /* * @author Eugene Zhuravlev @@ -22,6 +24,7 @@ import com.sun.jdi.event.EventQueue; import com.sun.jdi.request.EventRequestManager; import com.sun.tools.jdi.JNITypeParser; import com.sun.tools.jdi.TargetVM; +import one.util.streamex.StreamEx; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -247,15 +250,7 @@ public class VirtualMachineProxyImpl implements JdiTimer, VirtualMachineProxy { * @return a list of threadGroupProxies */ public List topLevelThreadGroups() { - List list = getVirtualMachine().topLevelThreadGroups(); - - List result = new ArrayList<>(list.size()); - - for (ThreadGroupReference threadGroup : list) { - result.add(getThreadGroupReferenceProxy(threadGroup)); - } - - return result; + return StreamEx.of(getVirtualMachine().topLevelThreadGroups()).map(this::getThreadGroupReferenceProxy).toList(); } public void threadGroupCreated(ThreadGroupReference threadGroupReference){ diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompositeDataBinding.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompositeDataBinding.java index 492f8ca74a0d..1537743628bd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/CompositeDataBinding.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompositeDataBinding.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.settings; @@ -29,23 +17,14 @@ public class CompositeDataBinding implements DataBinding{ } public void loadData(Object from) { - for (DataBinding myBinding : myBindings) { - myBinding.loadData(from); - } + myBindings.forEach(binding -> binding.loadData(from)); } public void saveData(Object to) { - for (DataBinding myBinding : myBindings) { - myBinding.saveData(to); - } + myBindings.forEach(binding -> binding.saveData(to)); } public boolean isModified(Object obj) { - for (DataBinding myBinding : myBindings) { - if (myBinding.isModified(obj)) { - return true; - } - } - return false; + return myBindings.stream().anyMatch(binding -> binding.isModified(obj)); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java index 85cdbc5d3e59..c8bd9bceec6b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/HotSwapUIImpl.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.ui; @@ -105,12 +93,7 @@ public class HotSwapUIImpl extends HotSwapUI { return false; } // todo: return false if yourkit agent is inactive - for (DebuggerSession session : sessions) { - if (session.isPaused()) { - return true; - } - } - return false; + return sessions.stream().anyMatch(DebuggerSession::isPaused); } private void hotSwapSessions(final List sessions, @Nullable final Map> generatedPaths) { @@ -132,13 +115,7 @@ public class HotSwapUIImpl extends HotSwapUI { findClassesProgress = new HotSwapProgressImpl(myProject); } else { - boolean createProgress = false; - for (DebuggerSession session : sessions) { - if (session.isModifiedClassesScanRequired()) { - createProgress = true; - break; - } - } + boolean createProgress = sessions.stream().anyMatch(DebuggerSession::isModifiedClassesScanRequired); findClassesProgress = createProgress ? new HotSwapProgressImpl(myProject) : null; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/RunHotswapDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/RunHotswapDialog.java index 6d8f655707c0..6b46fcdb3a21 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/RunHotswapDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/RunHotswapDialog.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.ui; @@ -25,6 +13,7 @@ import com.intellij.openapi.ui.MultiLineLabelUI; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.OptionsDialog; import com.intellij.util.ui.UIUtil; +import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -116,12 +105,7 @@ public class RunHotswapDialog extends OptionsDialog { } public Collection getSessionsToReload() { - final List markedElements = myElementsChooser.getMarkedElements(); - final List sessions = new ArrayList<>(markedElements.size()); - for (SessionItem item : markedElements) { - sessions.add(item.getSession()); - } - return sessions; + return StreamEx.of(myElementsChooser.getMarkedElements()).map(SessionItem::getSession).toList(); } private static class SessionItem { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java index d4b873811fbf..c160222275da 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/EditInstanceFiltersDialog.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.ui.breakpoints; @@ -26,6 +14,7 @@ import com.intellij.util.ui.JBUI; import javax.swing.*; import java.awt.*; +import java.util.Arrays; public class EditInstanceFiltersDialog extends DialogWrapper{ private InstanceFilterEditor myInstanceFilterEditor; @@ -69,11 +58,6 @@ public class EditInstanceFiltersDialog extends DialogWrapper{ } public InstanceFilter[] getFilters() { - ClassFilter [] cFilters = myInstanceFilterEditor.getFilters(); - InstanceFilter [] ifilters = new InstanceFilter[cFilters.length]; - for (int i = 0; i < ifilters.length; i++) { - ifilters[i] = InstanceFilter.create(cFilters[i]); - } - return ifilters; + return Arrays.stream(myInstanceFilterEditor.getFilters()).map(InstanceFilter::create).toArray(InstanceFilter[]::new); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java index aef4cd5150dc..6548478c66ab 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.ui.impl.watch; @@ -41,6 +29,7 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.refactoring.extractMethod.PrepareFailedException; import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler; +import one.util.streamex.StreamEx; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.incremental.java.JavaBuilder; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java index 6284de46b724..de1aca671572 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StaticDescriptorImpl.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2009 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ /* @@ -27,8 +15,8 @@ import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.tree.StaticDescriptor; import com.intellij.debugger.ui.tree.render.ClassRenderer; import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; -import com.sun.jdi.Field; import com.sun.jdi.ReferenceType; +import com.sun.jdi.TypeComponent; public class StaticDescriptorImpl extends NodeDescriptorImpl implements StaticDescriptor{ @@ -37,15 +25,7 @@ public class StaticDescriptorImpl extends NodeDescriptorImpl implements StaticDe public StaticDescriptorImpl(ReferenceType refType) { myType = refType; - - boolean hasStaticFields = false; - for (Field field : myType.allFields()) { - if (field.isStatic()) { - hasStaticFields = true; - break; - } - } - myHasStaticFields = hasStaticFields; + myHasStaticFields = myType.allFields().stream().anyMatch(TypeComponent::isStatic); } public ReferenceType getType() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/BatchEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/BatchEvaluator.java index c119ab54e701..52db0f5fd63d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/BatchEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/BatchEvaluator.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.ui.tree.render; @@ -29,6 +17,7 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.rt.debugger.BatchEvaluatorServer; import com.intellij.util.containers.HashMap; import com.sun.jdi.*; +import one.util.streamex.StreamEx; import java.util.ArrayList; import java.util.Collections; @@ -160,11 +149,7 @@ public class BatchEvaluator { private boolean doEvaluateBatch(List requests, EvaluationContext evaluationContext) { try { DebugProcess debugProcess = evaluationContext.getDebugProcess(); - List values = new ArrayList<>(); - for (ToStringCommand toStringCommand : requests) { - Value value = toStringCommand.getValue(); - values.add(value instanceof ObjectReference ? ((ObjectReference)value) : value); - } + List values = StreamEx.of(requests).map(ToStringCommand::getValue).toList(); ArrayType objectArrayClass = (ArrayType)debugProcess.findClass( evaluationContext, diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java index 031ab5828ae7..ef1a86a335b1 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java @@ -14,7 +14,6 @@ import com.intellij.psi.PsiClass; import com.intellij.ui.FieldPanel; import com.intellij.ui.MultiLineTooltipUI; import com.intellij.util.ui.JBUI; -import com.intellij.util.ui.UIUtil; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; @@ -204,12 +203,7 @@ public class JavaBreakpointFiltersPanel filters = new ArrayList<>(); - for (InstanceFilter instanceFilter : myInstanceFilters) { - if (instanceFilter.isEnabled()) { - filters.add(Long.toString(instanceFilter.getId())); - } - } + List filters = StreamEx.of(myInstanceFilters).filter(InstanceFilter::isEnabled).map(f -> Long.toString(f.getId())).toList(); if (updateText) { myInstanceFiltersField.setText(StringUtil.join(filters, " ")); } diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java index 69ed26c20f0a..ecc646dfc380 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/JSR45PositionManager.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.engine; @@ -180,12 +168,9 @@ public abstract class JSR45PositionManager implements PositionManager { // Finds exact server file name (from available in type) // This is needed because some servers (e.g. WebSphere) put not exact file name such as 'A.jsp ' private String getSourceName(final String name, final ReferenceType type) throws AbsentInformationException { - for(String sourceNameFromType: type.sourceNames(myStratumId)) { - if (sourceNameFromType.contains(name)) { - return sourceNameFromType; - } - } - return name; + return type.sourceNames(myStratumId).stream() + .filter(sourceNameFromType -> sourceNameFromType.contains(name)) + .findFirst().orElse(name); } }); } diff --git a/java/debugger/openapi/src/com/intellij/debugger/engine/SourcePositionHighlighter.java b/java/debugger/openapi/src/com/intellij/debugger/engine/SourcePositionHighlighter.java index e95decf6e8ff..246041879d8b 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/engine/SourcePositionHighlighter.java +++ b/java/debugger/openapi/src/com/intellij/debugger/engine/SourcePositionHighlighter.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.engine; @@ -21,6 +9,8 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.TextRange; import org.jetbrains.annotations.Nullable; +import java.util.Objects; + /** * During indexing, only extensions that implement {@link com.intellij.openapi.project.DumbAware} are called. * See also {@link DumbService}. diff --git a/java/debugger/openapi/src/com/intellij/debugger/ui/tree/NodeDescriptorNameAdjuster.java b/java/debugger/openapi/src/com/intellij/debugger/ui/tree/NodeDescriptorNameAdjuster.java index 5fa255b10957..fa5793b532c4 100644 --- a/java/debugger/openapi/src/com/intellij/debugger/ui/tree/NodeDescriptorNameAdjuster.java +++ b/java/debugger/openapi/src/com/intellij/debugger/ui/tree/NodeDescriptorNameAdjuster.java @@ -1,23 +1,13 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.debugger.ui.tree; import com.intellij.openapi.extensions.ExtensionPointName; import org.jetbrains.annotations.NotNull; +import java.util.Arrays; + /** * @author Nikolay.Tropin */ @@ -29,9 +19,6 @@ public abstract class NodeDescriptorNameAdjuster { public abstract String fixName(String name, @NotNull NodeDescriptor descriptor); public static NodeDescriptorNameAdjuster findFor(@NotNull NodeDescriptor descriptor) { - for (NodeDescriptorNameAdjuster adjuster:EP_NAME.getExtensions()) { - if (adjuster.isApplicable(descriptor)) return adjuster; - } - return null; + return Arrays.stream(EP_NAME.getExtensions()).filter(adjuster -> adjuster.isApplicable(descriptor)).findFirst().orElse(null); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java index a1f199423bbc..2c7e7e66cdf6 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointsFavoriteListProvider.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.xdebugger.impl.breakpoints; @@ -138,13 +126,7 @@ public class BreakpointsFavoriteListProvider extends AbstractFavoritesListProvid if (node.getValue() instanceof Navigatable && ((Navigatable)node.getValue()).canNavigate()) { return true; } - Collection children = node.getChildren(); - for (AbstractTreeNode child : children) { - if (checkNavigatable(child)) { - return true; - } - } - return false; + return node.getChildren().stream().anyMatch(BreakpointsFavoriteListProvider::checkNavigatable); } @Nullable From b5e2cd8ccbc23bf084cd9400d851d36c7d9cdd8d Mon Sep 17 00:00:00 2001 From: Nicolay Mitropolsky Date: Wed, 20 Dec 2017 21:10:33 +0300 Subject: [PATCH 21/58] Removing deprecated `ImplementedAtRuntimeCondition` --- .../src/META-INF/JavaAnalysisPlugin.xml | 2 -- .../ImplementedAtRuntimeCondition.java | 32 ------------------ .../ImplementedAtRuntimeConditionImpl.java | 33 ------------------- resources/src/META-INF/IdeaPlugin.xml | 2 -- 4 files changed, 69 deletions(-) delete mode 100644 java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeCondition.java delete mode 100644 java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeConditionImpl.java diff --git a/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml b/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml index e175e2c69192..a1c0333612a2 100644 --- a/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml +++ b/java/java-analysis-impl/src/META-INF/JavaAnalysisPlugin.xml @@ -42,8 +42,6 @@ - EP_NAME = ExtensionPointName.create("com.intellij.codeInsight.implementedAtRuntime"); - - public abstract boolean isImplementedAtRuntime(@NotNull PsiClass psiClass); -} diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeConditionImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeConditionImpl.java deleted file mode 100644 index 7fe21ad1ea12..000000000000 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ImplementedAtRuntimeConditionImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2000-2017 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.inheritance; - -import com.intellij.psi.PsiClass; -import org.jetbrains.annotations.NotNull; - -@Deprecated -public class ImplementedAtRuntimeConditionImpl extends ImplementedAtRuntimeCondition { - @Override - public boolean isImplementedAtRuntime(@NotNull PsiClass psiClass) { - for (ImplicitSubclassProvider provider : ImplicitSubclassProvider.EP_NAME.getExtensions()) { - ImplicitSubclassProvider.SubclassingInfo info = provider.getSubclassingInfo(psiClass); - if (info != null && !info.isAbstract()) { - return true; - } - } - return false; - } -} diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index fdbe334a18b2..bea9a9aada67 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -148,8 +148,6 @@ - - From 8f4431b91b5b0471c96dd9524acf25ff4d56607c Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Thu, 21 Dec 2017 12:48:29 +0300 Subject: [PATCH 22/58] improve message for diagnostic --- .../ex/GlobalInspectionToolWrapper.java | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionToolWrapper.java b/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionToolWrapper.java index ff19150c288c..eadd46e7b604 100644 --- a/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionToolWrapper.java +++ b/platform/analysis-impl/src/com/intellij/codeInspection/ex/GlobalInspectionToolWrapper.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.codeInspection.ex; @@ -87,7 +75,7 @@ public class GlobalInspectionToolWrapper extends InspectionToolWrapper Date: Tue, 19 Dec 2017 17:46:51 +0300 Subject: [PATCH 23/58] assertion for avoiding creation of Single/MultipleRootFileProvider for injected contents, where InjectedFileViewProvider should have been used instead. --- .../psi/AbstractFileViewProvider.java | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/platform/core-impl/src/com/intellij/psi/AbstractFileViewProvider.java b/platform/core-impl/src/com/intellij/psi/AbstractFileViewProvider.java index 46a13dcb54c5..842be5ec7b15 100644 --- a/platform/core-impl/src/com/intellij/psi/AbstractFileViewProvider.java +++ b/platform/core-impl/src/com/intellij/psi/AbstractFileViewProvider.java @@ -16,6 +16,7 @@ package com.intellij.psi; import com.intellij.injected.editor.DocumentWindow; +import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.ASTNode; import com.intellij.lang.Language; import com.intellij.lang.LanguageParserDefinitions; @@ -65,14 +66,17 @@ public abstract class AbstractFileViewProvider extends UserDataHolderBase implem private static final Logger LOG = Logger.getInstance("#com.intellij.psi.AbstractFileViewProvider"); public static final Key FREE_THREADED = Key.create("FREE_THREADED"); private static final Key> KNOWN_COPIES = Key.create("KNOWN_COPIES"); - @NotNull private final PsiManagerEx myManager; - @NotNull private final VirtualFile myVirtualFile; + @NotNull + private final PsiManagerEx myManager; + @NotNull + private final VirtualFile myVirtualFile; private final boolean myEventSystemEnabled; private final boolean myPhysical; private boolean myInvalidated; private volatile Content myContent; private volatile Reference myDocument; - @NotNull private final FileType myFileType; + @NotNull + private final FileType myFileType; private final PsiLock myPsiLock = new PsiLock(); protected AbstractFileViewProvider(@NotNull PsiManager manager, @@ -88,6 +92,9 @@ public abstract class AbstractFileViewProvider extends UserDataHolderBase implem !(virtualFile.getFileSystem() instanceof NonPhysicalFileSystem); virtualFile.putUserData(FREE_THREADED, isFreeThreaded(this)); myFileType = type; + if (virtualFile instanceof VirtualFileWindow && !(this instanceof FreeThreadedFileViewProvider)) { + throw new IllegalArgumentException("Must not create "+getClass()+" for injected file "+virtualFile+"; InjectedFileViewProvider must be used instead"); + } } public static boolean isFreeThreaded(@NotNull FileViewProvider provider) { @@ -383,6 +390,7 @@ public abstract class AbstractFileViewProvider extends UserDataHolderBase implem public abstract PsiFile getCachedPsi(@NotNull Language target); + @NotNull public abstract List getCachedPsiFiles(); @NotNull @@ -415,6 +423,7 @@ public abstract class AbstractFileViewProvider extends UserDataHolderBase implem } private interface Content { + @NotNull CharSequence getText(); int getTextLength(); @@ -422,6 +431,7 @@ public abstract class AbstractFileViewProvider extends UserDataHolderBase implem } private class VirtualFileContent implements Content { + @NotNull @Override public CharSequence getText() { final VirtualFile virtualFile = getVirtualFile(); @@ -459,10 +469,11 @@ public abstract class AbstractFileViewProvider extends UserDataHolderBase implem } } - private CharSequence getLastCommittedText(Document document) { + @NotNull + private CharSequence getLastCommittedText(@NotNull Document document) { return PsiDocumentManager.getInstance(myManager.getProject()).getLastCommittedText(document); } - private long getLastCommittedStamp(Document document) { + private long getLastCommittedStamp(@NotNull Document document) { return PsiDocumentManager.getInstance(myManager.getProject()).getLastCommittedStamp(document); } @@ -474,7 +485,7 @@ public abstract class AbstractFileViewProvider extends UserDataHolderBase implem @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private final List myFileElementHardRefs = new SmartList<>(); - private PsiFileContent(final PsiFileImpl file, final long modificationStamp) { + private PsiFileContent(@NotNull PsiFileImpl file, final long modificationStamp) { myFile = file; myModificationStamp = modificationStamp; for (PsiFile aFile : getAllFiles()) { @@ -484,6 +495,7 @@ public abstract class AbstractFileViewProvider extends UserDataHolderBase implem } } + @NotNull @Override public CharSequence getText() { String content = myContent; From 4ae89192356783531adb64896eba28c7f539c1b0 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 19 Dec 2017 17:57:04 +0300 Subject: [PATCH 24/58] Too many cooks spoil the broth; also made simple TestCase to start faster --- .../psi/util/NameUtilMatchingTest.java | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.java b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.java index 5b0517bfe523..ce90d3e7c031 100644 --- a/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.java +++ b/platform/platform-tests/testSrc/com/intellij/psi/util/NameUtilMatchingTest.java @@ -27,19 +27,14 @@ import com.intellij.testFramework.UsefulTestCase; import com.intellij.ui.SpeedSearchComparator; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.Matcher; +import junit.framework.TestCase; import org.jetbrains.annotations.NonNls; import org.junit.Assert; import java.util.ArrayList; import java.util.List; -/** - * @author max - * @author peter - * @author Konstantin Bulenkov - */ -public class NameUtilMatchingTest extends UsefulTestCase { - +public class NameUtilMatchingTest extends TestCase { public void testSimpleCases() { assertMatches("N", "NameUtilTest"); assertMatches("NU", "NameUtilTest"); @@ -473,34 +468,34 @@ public class NameUtilMatchingTest extends UsefulTestCase { public void testMatchingFragments() { @NonNls String sample = "NoClassDefFoundException"; // 0 2 7 10 15 21 - assertOrderedEquals(NameUtil.buildMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), - TextRange.from(0, 1), TextRange.from(2, 2), TextRange.from(7, 1), TextRange.from(10, 3), TextRange.from(21, 3)); + UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("ncldfou*ion", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + TextRange.from(0, 1), TextRange.from(2, 2), TextRange.from(7, 1), TextRange.from(10, 3), TextRange.from(21, 3)); sample = "doGet(HttpServletRequest, HttpServletResponse):void"; // 0 22 - assertOrderedEquals(NameUtil.buildMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("d*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 1), TextRange.from(22, 2)); - assertOrderedEquals(NameUtil.buildMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("doge*st", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 4), TextRange.from(22, 2)); sample = "_test"; - assertOrderedEquals(NameUtil.buildMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("_", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 1)); - assertOrderedEquals(NameUtil.buildMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("_t", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 2)); } public void testMatchingFragmentsSorted() { @NonNls String sample = "SWUPGRADEHDLRFSPR7TEST"; // 0 9 12 - assertOrderedEquals(NameUtil.buildMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("SWU*H*R", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 3), TextRange.from(9, 1), TextRange.from(12, 1)); } public void testPreferCapsMatching() { String sample = "getCurrentUser"; // 0 4 10 - assertOrderedEquals(NameUtil.buildMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), + UsefulTestCase.assertOrderedEquals(NameUtil.buildMatcher("getCU", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments(sample), TextRange.from(0, 4), TextRange.from(10, 1)); } @@ -685,7 +680,7 @@ public class NameUtilMatchingTest extends UsefulTestCase { } public void testOnlyUnderscoresPerformance() { - PlatformTestUtil.startPerformanceTest(getTestName(false), 120, () -> { + PlatformTestUtil.startPerformanceTest(getName(), 120, () -> { String small = StringUtil.repeat("_", 50000); String big = StringUtil.repeat("_", small.length() + 1); assertMatches("*" + small, big); @@ -694,7 +689,7 @@ public class NameUtilMatchingTest extends UsefulTestCase { } public void testRepeatedLetterPerformance() { - PlatformTestUtil.startPerformanceTest(getTestName(false), 30, () -> { + PlatformTestUtil.startPerformanceTest(getName(), 30, () -> { String big = StringUtil.repeat("Aaaaaa", 50000); assertMatches("aaaaaaaaaaaaaaaaaaaaaaaa", big); assertDoesntMatch("aaaaaaaaaaaaaaaaaaaaaaaab", big); @@ -704,12 +699,12 @@ public class NameUtilMatchingTest extends UsefulTestCase { public void testMatchingAllOccurrences() { String text = "some text"; MinusculeMatcher matcher = new AllOccurrencesMatcher("*e", NameUtil.MatchingCaseSensitivity.NONE, ""); - assertOrderedEquals(matcher.matchingFragments(text), + UsefulTestCase.assertOrderedEquals(matcher.matchingFragments(text), new TextRange(3, 4), new TextRange(6, 7)); } public void testCamelHumpWinsOverConsecutiveCaseMismatch() { - assertSize(3, NameUtil.buildMatcher("GEN", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments("GetExtendedName")); + UsefulTestCase.assertSize(3, NameUtil.buildMatcher("GEN", NameUtil.MatchingCaseSensitivity.NONE).matchingFragments("GetExtendedName")); assertPreference("GEN", "GetName", "GetExtendedName"); assertPreference("*GEN", "GetName", "GetExtendedName"); @@ -720,5 +715,4 @@ public class NameUtilMatchingTest extends UsefulTestCase { assertMatches("pl", "printlnFoo"); assertDoesntMatch("pl", "printlnx"); } - } From 53986857b2e03afca8342033808c193d83eca97a Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Tue, 19 Dec 2017 18:43:06 +0300 Subject: [PATCH 25/58] increase ridiculously small number of iterations for more stable measurements --- .../com/intellij/openapi/fileTypes/impl/FileTypesTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java index c97a341efe92..83cd1ffe9799 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/fileTypes/impl/FileTypesTest.java @@ -109,8 +109,8 @@ public class FileTypesTest extends PlatformTestCase { String name = String.valueOf(i % 10 * 10 + i * 100 + i + 1); names[i] = name + name + name + name; } - PlatformTestUtil.startPerformanceTest("isFileIgnored", 150, () -> { - for (int i=0;i<1000;i++) { + PlatformTestUtil.startPerformanceTest("isFileIgnored", 15_000, () -> { + for (int i = 0; i < 100_000; i++) { for (String name : names) { myFileTypeManager.isFileIgnored(name); } @@ -262,9 +262,9 @@ public class FileTypesTest extends PlatformTestCase { public void test7BitIsText() throws IOException { File d = createTempDirectory(); - File f = new File(d, "xx.asfdasdfas"); byte[] bytes = {9, 10, 13, 'x', 'a', 'b'}; assertEquals(CharsetToolkit.GuessedEncoding.SEVEN_BIT, new CharsetToolkit(bytes).guessFromContent(bytes.length)); + File f = new File(d, "xx.asfdasdfas"); FileUtil.writeToFile(f, bytes); VirtualFile vFile = getVirtualFile(f); From cd68feda0f65dfcf37d0d1aff6bea9c33edb9ba4 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Dec 2017 19:14:37 +0300 Subject: [PATCH 26/58] cleanup --- .../psi/PsiLanguageInjectionHost.java | 3 ++ .../template/LiveTemplateBuilder.java | 30 +++++++------------ .../com/intellij/openapi/util/TextRange.java | 2 +- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/platform/core-api/src/com/intellij/psi/PsiLanguageInjectionHost.java b/platform/core-api/src/com/intellij/psi/PsiLanguageInjectionHost.java index 5c71e83a63d3..4f72f22a2a70 100644 --- a/platform/core-api/src/com/intellij/psi/PsiLanguageInjectionHost.java +++ b/platform/core-api/src/com/intellij/psi/PsiLanguageInjectionHost.java @@ -78,6 +78,9 @@ public interface PsiLanguageInjectionHost extends PsiElement { @Nullable PsiLanguageInjectionHost getHost(); + /** + * @return range in decoded PSI + */ @NotNull TextRange getRange(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java b/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java index 5f28811983ca..9bdea5902942 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/LiveTemplateBuilder.java @@ -42,7 +42,7 @@ public class LiveTemplateBuilder { private final int mySegmentLimit; private final boolean myAddEndVariableAtTheEndOfTemplate; private String myLastEndVarName; - private boolean myIsToReformat = false; + private boolean myIsToReformat; @SuppressWarnings("UnusedDeclaration") @@ -133,15 +133,7 @@ public class LiveTemplateBuilder { } List variableOccurrences = getListWithLimit(myVariableOccurrences); - Collections.sort(variableOccurrences, (o1, o2) -> { - if (o1.myOffset < o2.myOffset) { - return -1; - } - if (o1.myOffset > o2.myOffset) { - return 1; - } - return 0; - }); + Collections.sort(variableOccurrences, Comparator.comparingInt(o -> o.myOffset)); int last = 0; for (VarOccurence occurence : variableOccurrences) { template.addTextSegment(myText.substring(last, occurence.myOffset)); @@ -161,7 +153,7 @@ public class LiveTemplateBuilder { return Collections.emptyList(); } if (mySegmentLimit > 0 && list.size() > mySegmentLimit) { - LOGGER.warn("Template with more than " + mySegmentLimit + " segments had been build (" + list.size() + "). Text: " + myText); + warnTooManySegments(list.size()); return list.subList(0, Math.min(list.size(), mySegmentLimit)); } return list; @@ -229,12 +221,12 @@ public class LiveTemplateBuilder { String text = template.getTemplateText(); insertText(offset, text, false); - Map newVarNames = new HashMap<>(); Set oldVarNames = new HashSet<>(); for (int i = 0; i < template.getVariableCount(); i++) { String varName = template.getVariableNameAt(i); oldVarNames.add(varName); } + Map newVarNames = new HashMap<>(); for (int i = 0; i < template.getVariableCount(); i++) { String varName = template.getVariableNameAt(i); if (!TemplateImpl.INTERNAL_VARS_SET.contains(varName)) { @@ -256,7 +248,7 @@ public class LiveTemplateBuilder { Variable var = new Variable(newVarName, template.getExpressionStringAt(i), template.getDefaultValueStringAt(i), template.isAlwaysStopAt(i)); if (mySegmentLimit >= 0 && myVariables.size() >= mySegmentLimit) { if (mySegmentLimit > 0) { - LOGGER.warn("Template with more than " + mySegmentLimit + " segments had been build. Text: " + myText); + warnTooManySegments(myVariables.size()); } break; } @@ -298,6 +290,11 @@ public class LiveTemplateBuilder { return endOffset; } + private void warnTooManySegments(int size) { + LOGGER.warn("Too many (" + size + " with the limit of " + mySegmentLimit + ") segments were requested" + + " for the template with the text: " + myText); + } + private void removeEndVarAtOffset(int offset) { for (Iterator it = myVariableOccurrences.iterator(); it.hasNext();) { VarOccurence occurence = it.next(); @@ -306,12 +303,7 @@ public class LiveTemplateBuilder { } if (occurence.myOffset == offset) { it.remove(); - for (Iterator it1 = myVariables.iterator(); it1.hasNext();) { - Variable variable = it1.next(); - if (occurence.myName.equals(variable.getName())) { - it1.remove(); - } - } + myVariables.removeIf(variable -> occurence.myName.equals(variable.getName())); } } } diff --git a/platform/util/src/com/intellij/openapi/util/TextRange.java b/platform/util/src/com/intellij/openapi/util/TextRange.java index 83934550169c..c530101db6ff 100644 --- a/platform/util/src/com/intellij/openapi/util/TextRange.java +++ b/platform/util/src/com/intellij/openapi/util/TextRange.java @@ -226,7 +226,7 @@ public class TextRange implements Segment, Serializable { public static void assertProperRange(int startOffset, int endOffset, @NotNull Object message) { if (!isProperRange(startOffset, endOffset)) { - LOG.error("Invalid range specified: (" + startOffset + "," + endOffset + "); " + message); + LOG.error("Invalid range specified: (" + startOffset + ", " + endOffset + "); " + message); } } From 6f301c984dac695f056cddfb7a39a01000d9a7ad Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Dec 2017 19:17:29 +0300 Subject: [PATCH 27/58] view provider for injected file must be always cached --- .../src/com/intellij/psi/impl/file/impl/FileManagerImpl.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java index 35f32547fab0..14e9a81bee4d 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/impl/FileManagerImpl.java @@ -167,7 +167,9 @@ public class FileManagerImpl implements FileManager { assert !file.isDirectory(); FileViewProvider viewProvider = findCachedViewProvider(file); if (viewProvider != null) return viewProvider; - + if (file instanceof VirtualFileWindow) { + throw new IllegalStateException("File " + file + " is invalid"); + } viewProvider = createFileViewProvider(file, true); if (file instanceof LightVirtualFile) { return file.putUserDataIfAbsent(myPsiHardRefKey, viewProvider); From 8cac4aeeb00b4790adbc5edc02dcc292a20fc10d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Dec 2017 19:18:29 +0300 Subject: [PATCH 28/58] make work better in case of invalid injected file --- .../fixtures/impl/CodeInsightTestFixtureImpl.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index 4c103be48295..37252291a552 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -54,6 +54,7 @@ import com.intellij.ide.util.gotoByName.ChooseByNamePopup; import com.intellij.ide.util.gotoByName.GotoClassModel2; import com.intellij.injected.editor.DocumentWindow; import com.intellij.injected.editor.EditorWindow; +import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.internal.DumpLookupElementWeights; import com.intellij.lang.Language; import com.intellij.lang.LanguageStructureViewBuilder; @@ -1139,7 +1140,7 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig @Override protected void run(@NotNull Result result) { PsiDocumentManager.getInstance(getProject()).commitAllDocuments(); - EditorUtil.fillVirtualSpaceUntilCaret(myEditor); + EditorUtil.fillVirtualSpaceUntilCaret(getHostEditor()); checkResult("TEXT", stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromText(text), getHostFile().getText()); } }.execute(); @@ -1462,8 +1463,8 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig } private PsiFile getHostFile() { - PsiElement element = getFile(); - return InjectedLanguageManager.getInstance(element.getProject()).getTopLevelFile(element); + VirtualFile hostVFile = myFile instanceof VirtualFileWindow ? ((VirtualFileWindow)myFile).getDelegate() : myFile; + return ReadAction.compute(() -> PsiManager.getInstance(getProject()).findFile(hostVFile)); } private long collectAndCheckHighlighting(@NotNull ExpectedHighlightingData data) { From 789e1d1f6e64b3e64dd7ec0c11d2a883a0e9f8c0 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 20 Dec 2017 19:50:53 +0300 Subject: [PATCH 29/58] show more diagnostics for failing tests --- .../testSrc/com/intellij/util/AlarmTest.java | 46 ++++++++++--------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/platform/platform-tests/testSrc/com/intellij/util/AlarmTest.java b/platform/platform-tests/testSrc/com/intellij/util/AlarmTest.java index bde2e349210f..f53953413f7b 100644 --- a/platform/platform-tests/testSrc/com/intellij/util/AlarmTest.java +++ b/platform/platform-tests/testSrc/com/intellij/util/AlarmTest.java @@ -34,7 +34,7 @@ package com.intellij.util; import java.util.stream.Collectors; import java.util.stream.Stream; -public class AlarmTest extends PlatformTestCase { + public class AlarmTest extends PlatformTestCase { public void testTwoAddsWithZeroDelayMustExecuteSequentially() throws Exception { Alarm alarm = new Alarm(getTestRootDisposable()); assertRequestsExecuteSequentially(alarm); @@ -85,37 +85,41 @@ public class AlarmTest extends PlatformTestCase { public void testOneAlarmDoesNotStartTooManyThreads() { Alarm alarm = new Alarm(getTestRootDisposable()); - Map before = Thread.getAllStackTraces(); AtomicInteger executed = new AtomicInteger(); int N = 100000; - for (int i = 0; i < N; i++) { - alarm.addRequest(executed::incrementAndGet, 10); - } - while (executed.get() != N) { - UIUtil.dispatchAllInvocationEvents(); - } + checkNotTooManyThreadsCreatedIn(()->{ + for (int i = 0; i < N; i++) { + alarm.addRequest(executed::incrementAndGet, 10); + } + while (executed.get() != N) { + UIUtil.dispatchAllInvocationEvents(); + } + }); + } + + private static void checkNotTooManyThreadsCreatedIn(Runnable runnable) { + Map before = Thread.getAllStackTraces(); + runnable.run(); Map after = Thread.getAllStackTraces(); Map> diff = new HashMap<>(); after.forEach((key, value) -> diff.put(key, Arrays.asList(value))); - before.keySet().forEach(diff::remove); + diff.keySet().removeAll(before.keySet()); if (!(after.size() - before.size() < 10)) { - fail("before: "+before.size()+"; after: "+after.size()+"Diff:\n"+diff); + fail("before: "+before.size()+"; after: "+after.size()+"; Diff:\n"+diff); } } public void testManyAlarmsDoNotStartTooManyThreads() { - Map before = Thread.getAllStackTraces(); - AtomicInteger executed = new AtomicInteger(); - int N = 100000; - List alarms = Stream.generate(() -> new Alarm(getTestRootDisposable())).limit(N).collect(Collectors.toList()); - alarms.forEach(alarm -> alarm.addRequest(executed::incrementAndGet, 10)); + checkNotTooManyThreadsCreatedIn(()->{ + AtomicInteger executed = new AtomicInteger(); + int N = 100000; + List alarms = Stream.generate(() -> new Alarm(getTestRootDisposable())).limit(N).collect(Collectors.toList()); + alarms.forEach(alarm -> alarm.addRequest(executed::incrementAndGet, 10)); - while (executed.get() != N) { - UIUtil.dispatchAllInvocationEvents(); - } - Map after = Thread.getAllStackTraces(); - LOG.debug("before: "+before.size()+"; after: "+after.size()); - assertTrue(after.size() - before.size() < 10); + while (executed.get() != N) { + UIUtil.dispatchAllInvocationEvents(); + } + }); } public void testOrderIsPreservedAfterModalitySwitching() { From 4eaebc052203890a8453622aa3d47d8088898dbb Mon Sep 17 00:00:00 2001 From: Anton Tarasov Date: Thu, 21 Dec 2017 12:45:08 +0300 Subject: [PATCH 30/58] IDEA-183253 [fps] expandable tree item is shifted --- .../ui/AbstractExpandableItemsHandler.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java index 0a8df4bc90cc..75c0b5e870af 100644 --- a/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java +++ b/platform/platform-impl/src/com/intellij/ui/AbstractExpandableItemsHandler.java @@ -25,10 +25,7 @@ import com.intellij.ui.popup.AbstractPopup; import com.intellij.ui.popup.MovablePopup; import com.intellij.util.Alarm; import com.intellij.util.ObjectUtils; -import com.intellij.util.ui.JBInsets; -import com.intellij.util.ui.MouseEventAdapter; -import com.intellij.util.ui.MouseEventHandler; -import com.intellij.util.ui.UIUtil; +import com.intellij.util.ui.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -48,7 +45,20 @@ public abstract class AbstractExpandableItemsHandler Date: Thu, 21 Dec 2017 12:11:44 +0300 Subject: [PATCH 31/58] IDEA-183876 Parameter hint popup looks strange in some cases --- .../codeInsight/hint/ParameterInfoComponent.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java index 266577a4d04e..e585664696c1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ParameterInfoComponent.java @@ -1,6 +1,6 @@ -// Copyright 2000-2017 JetBrains s.r.o. -// Use of this source code is governed by the Apache 2.0 license that can be -// found in the LICENSE file. +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ package com.intellij.codeInsight.hint; @@ -140,9 +140,9 @@ public class ParameterInfoComponent extends JPanel { @Override public Dimension getPreferredSize() { - int size = myPanels.length; + long visibleRows = Stream.of(myPanels).filter(Component::isVisible).count(); final Dimension preferredSize = super.getPreferredSize(); - if (size >= 0 && size <= 20) { + if (visibleRows <= 20) { return preferredSize; } else { From 9f89cdac84794191b227b8462c1ff5a6c8f5bc90 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Dec 2017 13:40:34 +0300 Subject: [PATCH 32/58] IDEA project configuration: convert gant-groovy to repository library --- .idea/libraries/gant_groovy.xml | 12 + .../dependencies/setupBuildScriptsDeps.gradle | 1 + build/gant.xml | 4 - build/lib/gant/README_Install.txt | 110 -------- build/lib/gant/bin/gant | 119 -------- build/lib/gant/bin/gant.bat | 71 ----- build/lib/gant/bin/startGroovy.bat | 258 ------------------ build/lib/gant/conf/gant-starter.conf | 44 --- .../lib/gant/lib/gant-1.9.11_groovy-2.3.0.jar | Bin 302632 -> 0 bytes .../jps-standalone-builder.iml | 10 +- .../build/CommunityLibraryLicenses.groovy | 2 +- .../build-scripts/platform-build-scripts.iml | 10 +- 12 files changed, 16 insertions(+), 625 deletions(-) create mode 100644 .idea/libraries/gant_groovy.xml delete mode 100644 build/lib/gant/README_Install.txt delete mode 100755 build/lib/gant/bin/gant delete mode 100755 build/lib/gant/bin/gant.bat delete mode 100755 build/lib/gant/bin/startGroovy.bat delete mode 100644 build/lib/gant/conf/gant-starter.conf delete mode 100644 build/lib/gant/lib/gant-1.9.11_groovy-2.3.0.jar diff --git a/.idea/libraries/gant_groovy.xml b/.idea/libraries/gant_groovy.xml new file mode 100644 index 000000000000..6bbdba4df2dd --- /dev/null +++ b/.idea/libraries/gant_groovy.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/build/dependencies/setupBuildScriptsDeps.gradle b/build/dependencies/setupBuildScriptsDeps.gradle index b688134b689f..6c6cbee60e09 100644 --- a/build/dependencies/setupBuildScriptsDeps.gradle +++ b/build/dependencies/setupBuildScriptsDeps.gradle @@ -35,6 +35,7 @@ dependencies { buildScriptsDeps loadLibraryMavenId("Trove4j") buildScriptsDeps loadLibraryMavenId("NanoXML") buildScriptsDeps loadLibraryMavenId("Guava") + buildScriptsDeps(loadLibraryMavenId("gant-groovy"), { transitive = false }) } /** diff --git a/build/gant.xml b/build/gant.xml index c7a81b2ce857..93955df3f5ec 100644 --- a/build/gant.xml +++ b/build/gant.xml @@ -1,7 +1,6 @@ - @@ -24,9 +23,6 @@ - - - diff --git a/build/lib/gant/README_Install.txt b/build/lib/gant/README_Install.txt deleted file mode 100644 index 5f6cc4ae2aa6..000000000000 --- a/build/lib/gant/README_Install.txt +++ /dev/null @@ -1,110 +0,0 @@ -Gant -- A Groovy way of scripting Ant tasks. - - -This is Gant, a Groovy way of working with Ant tasks -- no more XML :-) - -The method of installation depends on whether you have downloaded a tarball or -zipfile distribution, or you have a Git clone -- or even a Bazaar branch -- of -the source. - - -Distribution ------------- - -The Gant distributions contain a ready-made install directory hierarchy. -Untar the tarball or unzip the zipfile to the location where you want the Gant -installation to reside. A directory with the name structured -gant- will be created in the location specified for the -untar or unzip. - -There are a number of distinct distributions: - - 1. Requires a separate Groovy installation. There are builds: - a. compiled against Groovy 1.7.10; and - b. compiled against Groovy 1.8.6; and - c. compiled against Groovy 2.0.0-beta-2 - - 2. Self-contained, includes all dependent jars. - -You might like to set up an environment variable GANT_HOME set to the -directory created by the untar or unzip, though this is not essential, it is -just an efficiency. - -The script $GANT_HOME/bin/gant for systems with a Posix shell, or -$GANT_HOME/bin/gant.bat on Windows is the mechanism for launching a Gant run. - -Distributions 1a, 1b and 1c only include the direct Gant materials. The Maven -target set depends on use of the Maven Ant tasks, and the Ivy tool depends on -the Ivy jar, these will have to be downloaded and installed into -$GANT_HOME/lib unless they are already available on on your CLASSPATH. - - -Using a Git Clone ------------------ - -Gant's mainline is a Git repository on GitHub, see - - https://github.com/Gant/Gant - -you should fork this on GitHub and then clone to give you a local repository. - -The repository on Codehaus at: - - git://git.codehaus.org/gant.git - -is an administrative clone of the GitHub mainline and should not be used in -normal circumstances. - -Gradle is used as the build system for Gant, so you will need to set the -gant_installPath property in ~/.gradle/gradle.properties so you can install -Gant. So for example: - - gant_installPath = ${System.properties.'user.home'}/lib/JavaPackages/gant-trunk - -Then you type: - - ./gradlew :gant:install - -and all the necessary magic happens. The first time you use the Gradle -Wrapper, it will connect to the Internet to download the various jars that -comprise Gradle. This takes a while. However this is only needed the first -time, thereafter it uses the version you downloaded. - -You probably want to set the GROOVY_HOME environment variable to point at the -Groovy installation that the Gant installation is to work with. - - -Using a Bazaar Branch ---------------------- - -For anyone prefering to use Bazaar rather than Git, there is an automated -bridge of the master branch of the Git clone on Launchpad. - -To get a branch: - - bzr branch lp:gant Gant - -or if you want to use bzr-git directly: - - bzr branch git://github.com/Gant/Gant.git Gant - -(If you are going to actively develop Gant, you almost certainly want to have -a shared repository in which this mirror branch is kept so that you can then -make feature branches from it.) - -All the information in the previous section about Gradle and building Gant -apply when using Bazaar. - - -Contact -------- - -If you have any problems using Gant, or have any ideas for improvements, -please make use of the Gant users mailing list: user@gant.codehaus.org - -Russel Winder - - -;;; Local Variables: *** -;;; fill-column: 78 *** -;;; End: *** diff --git a/build/lib/gant/bin/gant b/build/lib/gant/bin/gant deleted file mode 100755 index 327e4542ac51..000000000000 --- a/build/lib/gant/bin/gant +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/sh - -# Gant -- A Groovy way of scripting Ant tasks. -# -# Copyright © 2006–2010, 2013 Russel Winder -# -# 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. -# -# Author : Russel Winder - -# Gant initiation script for Linux and UNIX -- requires Groovy version. - -# Solaris 10 does not have readlink as standard -- though some people will have the version from -# Sunfreeware which is the same as the version on Ubuntu, Cygwin, MSYS, etc. Mac OS X has a version of -# readlink that is very different to that on Ubuntu, Solaris/Sunfreeware, Cygwin, MSYS, etc. -# -# This function attempts to just do the right thing. - -doReadLink() { - case `uname` in - Darwin) - gantLocation=`dirname $1` - gantPath=`readlink "$1"` - if [ "$gantPath" = "" ] - then - readlinkValue="$1" - else - linkDir=`dirname $gantPath` - currentDirectory=`pwd` - cd $gantLocation - cd $linkDir - gantLocation=`pwd` - gantPath=`basename $gantPath` - readlinkValue="$gantLocation/$gantPath" - cd $currentDirectory - fi - ;; - SunOS) - readlinkPath=`which readlink` - if [ `expr "$readlinkPath" : '\([^ ]*\)'` = "no" ] - then - echo "No readlink command available, please set $2." - exit 1 - else - readlinkValue=`readlink -f $1` - fi - ;; - *) - readlinkValue=`readlink -f $1` - ;; - esac -} - -# If GANT_HOME is not set, deduce a path. Assume the executable is in $GANT_HOME/bin. - -if [ -z "$GANT_HOME" ] -then - if [ -h $0 ] - then - doReadLink $0 GANT_HOME - GANT_HOME=$readlinkValue - GANT_HOME=`dirname $GANT_HOME` - else - GANT_HOME=`dirname $0` - fi - GANT_HOME=`dirname $GANT_HOME` -fi - -# If GROOVY_HOME is not set, deduce a path -- this is needed in order to discover the location of the -# startGroovy script. Assume the executable is in $GROOVY_HOME/bin. - -if [ -z "$GROOVY_HOME" ] -then - GROOVY_HOME=`which groovy` - if [ -h $GROOVY_HOME ] - then - doReadLink $GROOVY_HOME GROOVY_HOME - GROOVY_HOME=$readlinkValue - fi - GROOVY_HOME=`dirname "$GROOVY_HOME"` - GROOVY_HOME=`dirname "$GROOVY_HOME"` -fi - -# If ANT_HOME is not set, deduce a path -- this is needed in order to discover the location of the jars -# associated with the Ant installation. Assume the executable is in $ANT_HOME/bin. - -if [ -z "$ANT_HOME" ] -then - ANT_HOME=`which ant` - if [ -h $ANT_HOME ] - then - doReadLink $ANT_HOME ANT_HOME - ANT_HOME=$readlinkValue - fi - ANT_HOME=`dirname "$ANT_HOME"` - ANT_HOME=`dirname "$ANT_HOME"` -fi - -GROOVY_APP_NAME=Gant -GROOVY_CONF="$GANT_HOME/conf/gant-starter.conf" - -. "$GROOVY_HOME/bin/startGroovy" - -if $cygwin -then - GANT_HOME=`cygpath --mixed "$GANT_HOME"` - ANT_HOME=`cygpath --mixed "$ANT_HOME"` -fi -JAVA_OPTS="$JAVA_OPTS -Dgant.home=$GANT_HOME -Dant.home=$ANT_HOME" - -startGroovy gant.Gant "$@" diff --git a/build/lib/gant/bin/gant.bat b/build/lib/gant/bin/gant.bat deleted file mode 100755 index ccd28602158e..000000000000 --- a/build/lib/gant/bin/gant.bat +++ /dev/null @@ -1,71 +0,0 @@ -@if "%DEBUG%" == "" @echo off - -@rem Gant -- A Groovy way of scripting Ant tasks. -@rem -@rem Copyright © 2008,2010 Russel Winder -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in -@rem compliance with the License. You may obtain a copy of the License at -@rem -@rem http://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software distributed under the License is -@rem distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -@rem implied. See the License for the specific language governing permissions and limitations under the -@rem License. -@rem -@rem Author : Russel Winder - -@rem Gant initiation script for Windows. - -@rem Set local scope for the variables with windows NT shell -if "%OS%" == "Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=.\ - -@rem If GANT_HOME is not set, deduce a path. - -if not "%GANT_HOME%" == "" goto endSetGantHome - set GANT_HOME="%DIRNAME%.." -:endSetGantHome - -@rem If GROOVY_HOME is not set, deduce a path -- this is needed in order to discover the location of the -@rem startGroovy script. - -if not "%GROOVY_HOME%" == "" goto endSetGroovyHome - for %%P in ( %PATH% ) do if exist %%P\groovy.exe set GROOVY_HOME=%%P\.. - if not "%GROOVY_HOME%" == "" goto endSetGroovyHome - for %%P in ( %PATH% ) do if exist %%P\groovy.bat set GROOVY_HOME=%%P\.. - if not "%GROOVY_HOME%" == "" goto endSetGroovyHome - call :environmentVariableError GROOVY_HOME - goto :EOF -:endSetGroovyHome - -@rem If ANT_HOME is not set, deduce a path -- this is needed in order to discover the location of the jars -@rem asscoiated with the Ant installation. - -if not "%ANT_HOME%" == "" goto endSetAntHome - for %%P in ( %PATH% ) do if exist %%P\ant.bat set ANT_HOME=%%P\.. - if not "%ANT_HOME%" == "" goto endSetAntHome - call :environmentVariableError ANT_HOME - goto :EOF -:endSetAntHome - -set PROGNAME=gant.bat -set GROOVY_SCRIPT_NAME=gant.bat -set STARTER_CONF="%GANT_HOME%\conf\gant-starter.conf" -set JAVA_OPTS=%JAVA_OPTS% -Dgant.home="%GANT_HOME%" -Dant.home="%ANT_HOME%" - -"%GANT_HOME%\bin\startGroovy.bat" "%DIRNAME%" gant.Gant %* - -@rem End local scope for the variables with windows NT shell -if "%OS%" == "Windows_NT" endlocal - -%COMSPEC% /C exit /B %ERRORLEVEL% - -:environmentVariableError - echo. - echo ERROR: Environment variable %1 has not been set. - echo Attempting to find %1 from PATH also failed. - goto :EOF diff --git a/build/lib/gant/bin/startGroovy.bat b/build/lib/gant/bin/startGroovy.bat deleted file mode 100755 index 5f4540b22c7e..000000000000 --- a/build/lib/gant/bin/startGroovy.bat +++ /dev/null @@ -1,258 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem ## -@rem Groovy JVM Bootstrap for Windowz ## -@rem ## -@rem ########################################################################## - -@rem -@rem $Revision$ $Date$ -@rem - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal enabledelayedexpansion - -set DIRNAME=%~1 -shift - -set CLASS=%~1 -shift - -if exist "%USERPROFILE%/.groovy/preinit.bat" call "%USERPROFILE%/.groovy/preinit.bat" - -@rem Determine the command interpreter to execute the "CD" later -set COMMAND_COM="cmd.exe" -if exist "%SystemRoot%\system32\cmd.exe" set COMMAND_COM="%SystemRoot%\system32\cmd.exe" -if exist "%SystemRoot%\command.com" set COMMAND_COM="%SystemRoot%\command.com" - -@rem Use explicit find.exe to prevent cygwin and others find.exe from being used -set FIND_EXE="find.exe" -if exist "%SystemRoot%\system32\find.exe" set FIND_EXE="%SystemRoot%\system32\find.exe" -if exist "%SystemRoot%\command\find.exe" set FIND_EXE="%SystemRoot%\command\find.exe" - -:check_JAVA_HOME -@rem Make sure we have a valid JAVA_HOME -if not "%JAVA_HOME%" == "" goto have_JAVA_HOME -set PATHTMP=%PATH% -:loop -for /f "delims=; tokens=1*" %%i in ("!PATHTMP!") do ( - if exist "%%i\..\bin\java.exe" ( - set "JAVA_HOME=%%i\.." - goto found_JAVA_HOME - ) - set PATHTMP=%%j - goto loop -) -goto check_default_JAVA_EXE - -:found_JAVA_HOME -@rem Remove trailing \bin\.. from JAVA_HOME -if "%JAVA_HOME:~-7%"=="\bin\.." SET "JAVA_HOME=%JAVA_HOME:~0,-7%" -set JAVA_EXE=%JAVA_HOME%\bin\java.exe - -:check_default_JAVA_EXE -if not "%JAVA_HOME%" == "" goto valid_JAVA_HOME -java -version 2>NUL -if not ERRORLEVEL 1 goto default_JAVA_EXE - -echo. -echo ERROR: Environment variable JAVA_HOME has not been set. -echo Attempting to find JAVA_HOME from PATH also failed. -goto common_error - -:have_JAVA_HOME -@rem Remove trailing slash from JAVA_HOME if found -if "%JAVA_HOME:~-1%"=="\" SET JAVA_HOME=%JAVA_HOME:~0,-1% - -@rem Validate JAVA_HOME -%COMMAND_COM% /C DIR "%JAVA_HOME%" 2>&1 | %FIND_EXE% /I /C "%JAVA_HOME%" >nul -if not errorlevel 1 goto valid_JAVA_HOME_DIR - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% - -:common_error -echo Please set the JAVA_HOME variable in your environment -echo to match the location of your Java installation. -goto end - -:default_JAVA_EXE -set JAVA_EXE=java.exe -goto check_GROOVY_HOME - -:valid_JAVA_HOME_DIR -set JAVA_EXE=%JAVA_HOME%\bin\java.exe -if exist "%JAVA_EXE%" goto valid_JAVA_HOME - -echo. -echo ERROR: No java.exe found at: %JAVA_EXE% -goto common_error - -:valid_JAVA_HOME -if exist "%JAVA_HOME%\lib\tools.jar" set TOOLS_JAR=%JAVA_HOME%\lib\tools.jar - -:check_GROOVY_HOME -@rem Define GROOVY_HOME if not set -if "%GROOVY_HOME%" == "" set GROOVY_HOME=%DIRNAME%.. - -@rem Remove trailing slash from GROOVY_HOME if found -if "%GROOVY_HOME:~-1%"=="\" SET GROOVY_HOME=%GROOVY_HOME:~0,-1% - -@rem classpath handling -set _SKIP=2 -set CP= -if "x%~1" == "x-cp" set CP=%~2 -if "x%~1" == "x-classpath" set CP=%~2 -if "x%~1" == "x--classpath" set CP=%~2 -if "x" == "x%CP%" goto init -set _SKIP=4 -shift -shift - -:init -@rem get name of script to launch with full path -set GROOVY_SCRIPT_NAME=%~f1 -@rem Get command-line arguments, handling Windowz variants -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -rem horrible roll your own arg processing inspired by jruby equivalent - -rem escape minus (-d), quotes (-q), star (-s). -set _ARGS=%* -if not defined _ARGS goto execute -set _ARGS=%_ARGS:-=-d% -set _ARGS=%_ARGS:"=-q% -rem Windowz will try to match * with files so we escape it here -rem but it is also a meta char for env var string substitution -rem so it can't be first char here, hack just for common cases. -rem If in doubt use a space or bracket before * if using -e. -set _ARGS=%_ARGS: *= -s% -set _ARGS=%_ARGS:)*=)-s% -set _ARGS=%_ARGS:0*=0-s% -set _ARGS=%_ARGS:1*=1-s% -set _ARGS=%_ARGS:2*=2-s% -set _ARGS=%_ARGS:3*=3-s% -set _ARGS=%_ARGS:4*=4-s% -set _ARGS=%_ARGS:5*=5-s% -set _ARGS=%_ARGS:6*=6-s% -set _ARGS=%_ARGS:7*=7-s% -set _ARGS=%_ARGS:8*=8-s% -set _ARGS=%_ARGS:9*=9-s% - -rem prequote all args for 'for' statement -set _ARGS="%_ARGS%" - -set _ARG= -:win9xME_args_loop -rem split args by spaces into first and rest -for /f "tokens=1,*" %%i in (%_ARGS%) do call :get_arg "%%i" "%%j" -goto process_arg - -:get_arg -rem remove quotes around first arg -for %%i in (%1) do set _ARG=%_ARG% %%~i -rem set the remaining args -set _ARGS=%2 -rem remove the leading space we'll add the first time -if "x%_ARG:~0,1%" == "x " set _ARG=%_ARG:~1% -rem return -goto :EOF - -:process_arg -if "%_ARG%" == "" goto execute - -rem collect all parts of a quoted argument containing spaces -if not "%_ARG:~0,2%" == "-q" goto :argIsComplete -if "%_ARG:~-2%" == "-q" goto :argIsComplete -rem _ARG starts with a quote but does not end with one: -rem add the next part to _ARG until the matching quote is found -goto :win9xME_args_loop - -:argIsComplete -if "x4" == "x%_SKIP%" goto skip_4 -if "x3" == "x%_SKIP%" goto skip_3 -if "x2" == "x%_SKIP%" goto skip_2 -if "x1" == "x%_SKIP%" goto skip_1 - -rem now unescape -q, -s, -d -set _ARG=%_ARG:-s=*% -set _ARG=%_ARG:-q="% -set _ARG=%_ARG:-d=-% - -set CMD_LINE_ARGS=%CMD_LINE_ARGS% %_ARG% -set _ARG= -goto win9xME_args_loop - -:skip_4 -set _ARG= -set _SKIP=3 -goto win9xME_args_loop - -:skip_3 -set _ARG= -set _SKIP=2 -goto win9xME_args_loop - -:skip_2 -set _ARG= -set _SKIP=1 -goto win9xME_args_loop - -:skip_1 -set _ARG= -set _SKIP=0 -goto win9xME_args_loop - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line -set STARTER_CLASSPATH=%GROOVY_HOME%\lib\groovy-all-2.3.0.jar - -if exist "%USERPROFILE%/.groovy/init.bat" call "%USERPROFILE%/.groovy/init.bat" - -@rem Setting a classpath using the -cp or -classpath option means not to use -@rem the global classpath. Groovy behaves then the same as the java -@rem interpreter -if "x" == "x%CP%" goto empty_cp -:non_empty_cp -set CP=%CP%;. -goto after_cp -:empty_cp -set CP=. -if "x" == "x%CLASSPATH%" goto after_cp -set CP=%CLASSPATH%;%CP% -:after_cp - -set STARTER_MAIN_CLASS=org.codehaus.groovy.tools.GroovyStarter -set STARTER_CONF=%GROOVY_HOME%\conf\groovy-starter.conf - -set GROOVY_OPTS="-Xmx128m" -set GROOVY_OPTS=%GROOVY_OPTS% -Dprogram.name="%PROGNAME%" -set GROOVY_OPTS=%GROOVY_OPTS% -Dgroovy.home="%GROOVY_HOME%" -if not "%TOOLS_JAR%" == "" set GROOVY_OPTS=%GROOVY_OPTS% -Dtools.jar="%TOOLS_JAR%" -set GROOVY_OPTS=%GROOVY_OPTS% -Dgroovy.starter.conf="%STARTER_CONF%" -set GROOVY_OPTS=%GROOVY_OPTS% -Dscript.name="%GROOVY_SCRIPT_NAME%" - -if exist "%USERPROFILE%/.groovy/postinit.bat" call "%USERPROFILE%/.groovy/postinit.bat" - -@rem Execute Groovy -"%JAVA_EXE%" %GROOVY_OPTS% %JAVA_OPTS% -classpath "%STARTER_CLASSPATH%" %STARTER_MAIN_CLASS% --main %CLASS% --conf "%STARTER_CONF%" --classpath "%CP%" %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" endlocal - -@rem Optional pause the batch file -if "%GROOVY_BATCH_PAUSE%" == "on" pause -%COMSPEC% /C exit /B %ERRORLEVEL% diff --git a/build/lib/gant/conf/gant-starter.conf b/build/lib/gant/conf/gant-starter.conf deleted file mode 100644 index 75aef0043c9a..000000000000 --- a/build/lib/gant/conf/gant-starter.conf +++ /dev/null @@ -1,44 +0,0 @@ -# Gant -- A Groovy way of scripting Ant tasks. -# -# Copyright © 2008, 2010, 2013 Russel Winder -# -# 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. -# -# Author : Russel Winder - -# Load user specific libraries that are Gant specific. -load !{user.home}/.gant/lib/*.jar - -# Load user specific libraries that are Ant specific. -load !{user.home}/.ant/lib/*.jar - -# Load user specific libraries that are for Groovy. -load !{user.home}/.groovy/lib/*.jar - -# Load required libraries -load !{gant.home}/lib/*.jar - -# Load Ant libraries. If xml-apis.jar and xercesImpl.jar are in this directory then it leads to a: -# -# Caught: java.lang.LinkageError: loader constraint violation: loader (instance of ) previously initiated loading for a different type with name "org/w3c/dom/NodeList" -# -# whenever an XML processing program that (possibly indirectly) uses a DOM is executed. Get round this by -# selecting jars, basically all the known Ant jars, and ignoring everything else. -# -# The directory might contain ant.jar but it would be bad to include this since Groovy is distributed -# with a version of Ant and that should be used. See next rule. -load !{ant.home}/lib/ant-*.jar - -# load required libraries -load !{groovy.home}/lib/*.jar - -# tools.jar for ant tasks -load ${tools.jar} diff --git a/build/lib/gant/lib/gant-1.9.11_groovy-2.3.0.jar b/build/lib/gant/lib/gant-1.9.11_groovy-2.3.0.jar deleted file mode 100644 index f3d98426914a8e0987b6e5e964de2b0acd799d15..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 302632 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 dNgs;~>y#L1y?^W4b^3LiA?Dnw)V61AJ$ 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 Nfo - - - - - - - - - + \ No newline at end of file diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy index 77ac994157a6..6245f14785a8 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy @@ -117,7 +117,7 @@ class CommunityLibraryLicenses { url: "http://freemarker.sourceforge.net/"), new LibraryLicense(name: "fxg-utils", libraryName: "fxg-utils", version: "4.9.1", license: "Apache 2.0", url: "http://flex.apache.org", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0"), - new LibraryLicense(name: "Gant", version: "1.9.8", libraryName: "gant-1.9.11_groovy-2.3.0.jar", license: "Apache 2.0", + new LibraryLicense(name: "Gant", version: "1.9.8", libraryName: "gant-groovy", license: "Apache 2.0", url: "https://github.com/codehaus/gant", licenseUrl: "https://github.com/codehaus/gant/blob/master/LICENCE.txt"), new LibraryLicense(name: "Gherkin", libraryName: "Gherkin", version: "2.12.2", license: "MIT", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "https://github.com/cucumber/gherkin"), diff --git a/platform/build-scripts/platform-build-scripts.iml b/platform/build-scripts/platform-build-scripts.iml index 27b570b7b563..1606b1ca0e12 100644 --- a/platform/build-scripts/platform-build-scripts.iml +++ b/platform/build-scripts/platform-build-scripts.iml @@ -25,15 +25,7 @@ - - - - - - - - - + \ No newline at end of file From e886b18bdf5962f94663e2fdb7875ba681fee3f3 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Dec 2017 13:42:59 +0300 Subject: [PATCH 33/58] IDEA project configuration: convert jgoodies-common to repository library And updated from 1.2.1 to 1.4.0. --- .idea/libraries/jgoodies_common.xml | 9 ++++++--- lib/jgoodies-common-1.2.1.jar | Bin 27788 -> 0 bytes .../build/CommunityLibraryLicenses.groovy | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) delete mode 100644 lib/jgoodies-common-1.2.1.jar diff --git a/.idea/libraries/jgoodies_common.xml b/.idea/libraries/jgoodies_common.xml index b28cc7072292..9f61581b7d53 100644 --- a/.idea/libraries/jgoodies_common.xml +++ b/.idea/libraries/jgoodies_common.xml @@ -1,9 +1,12 @@ - + + - + - + + + \ No newline at end of file diff --git a/lib/jgoodies-common-1.2.1.jar b/lib/jgoodies-common-1.2.1.jar deleted file mode 100644 index 5088a1fd84cf20c64f9f6a5c5b140ea2cceaee1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27788 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 diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy index 6245f14785a8..8126fe4185ba 100644 --- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy +++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy @@ -179,7 +179,7 @@ class CommunityLibraryLicenses { licenseUrl: "http://www.eclipse.org/org/documents/edl-v10.php", url: "https://github.com/FasterXML/jackson"), new LibraryLicense(name: "JGit", libraryName: "jgit", version: "4.0", license: "Eclipse Distribution License 1.0", licenseUrl: "http://www.eclipse.org/org/documents/edl-v10.php", url: "https://eclipse.org/jgit/"), - new LibraryLicense(name: "JGoodies Common", libraryName: "jgoodies-common", version: "1.2.1", license: "BSD", + new LibraryLicense(name: "JGoodies Common", libraryName: "jgoodies-common", version: "1.4.0", license: "BSD", url: "http://www.jgoodies.com/freeware/libraries/looks/", licenseUrl: "https://opensource.org/licenses/bsd-license.html"), new LibraryLicense(name: "JGoodies Forms", libraryName: "jgoodies-forms", version: "1.1-preview 2006-05-04 11:55:37", license: "BSD", url: "http://www.jgoodies.com/freeware/libraries/forms/", licenseUrl: "https://opensource.org/licenses/bsd-license.html"), From 426f1ea6ed6f6c5fc5d4f5a274901407fbfd83b9 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 14 Dec 2017 19:34:35 +0100 Subject: [PATCH 34/58] platform: remove unused class --- .../ide/mavenService/DownloadResult.java | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 platform/platform-api/src/com/intellij/ide/mavenService/DownloadResult.java diff --git a/platform/platform-api/src/com/intellij/ide/mavenService/DownloadResult.java b/platform/platform-api/src/com/intellij/ide/mavenService/DownloadResult.java deleted file mode 100644 index 63645e685dc7..000000000000 --- a/platform/platform-api/src/com/intellij/ide/mavenService/DownloadResult.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2000-2010 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.mavenService; - -import java.io.File; - -/** - * @author Dmitry Avdeev - */ -public interface DownloadResult { - - int BINARY = 0x01; - int SOURCE = 0x02; - int JAVADOCS = 0x04; - - File[] getFile(int option); -} From 6b5c6b78a0c72b1f82f9298def7bec527167645f Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 14 Dec 2017 20:57:51 +0100 Subject: [PATCH 35/58] platform: add UTM parameters to download URLs from About popup Introduce IdeUrlTrackingParametersProvider service which is overriden in products to append necessary parameters, remove 'fromIDE' parameter from *ApplicationInfo.xml files. (IDEA-CR-27675, IDEA-183268) --- .../src/idea/IdeaApplicationInfo.xml | 2 +- .../IdeUrlTrackingParametersProvider.java | 27 ++++++++++++++ .../application/impl/ApplicationInfoImpl.java | 4 +- .../UtmIdeUrlTrackingParametersProvider.java | 37 +++++++++++++++++++ .../intellij/help/impl/HelpManagerImpl.java | 11 +----- .../updateSettings/impl/UpdateInfoDialog.java | 21 +---------- .../src/META-INF/PlatformExtensions.xml | 2 + .../idea/PlatformLangXmlApplicationInfo.xml | 2 +- .../idea/PyCharmEduApplicationInfo.xml | 2 +- .../src/META-INF/PyCharmEduPlugin.xml | 3 ++ python/ide/src/META-INF/PyCharmCorePlugin.xml | 6 +++ .../idea/PyCharmCoreApplicationInfo.xml | 2 +- resources/src/META-INF/IdeaPlugin.xml | 3 ++ 13 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 platform/core-api/src/com/intellij/openapi/application/IdeUrlTrackingParametersProvider.java create mode 100644 platform/platform-api/src/com/intellij/ide/customization/UtmIdeUrlTrackingParametersProvider.java diff --git a/community-resources/src/idea/IdeaApplicationInfo.xml b/community-resources/src/idea/IdeaApplicationInfo.xml index 762ac1d64d37..9356fe90f2f9 100644 --- a/community-resources/src/idea/IdeaApplicationInfo.xml +++ b/community-resources/src/idea/IdeaApplicationInfo.xml @@ -2,7 +2,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jetbrains.org/intellij/schema/application-info http://jetbrains.org/intellij/schema/ApplicationInfo.xsd"> - + diff --git a/platform/core-api/src/com/intellij/openapi/application/IdeUrlTrackingParametersProvider.java b/platform/core-api/src/com/intellij/openapi/application/IdeUrlTrackingParametersProvider.java new file mode 100644 index 000000000000..05a02ed6fe43 --- /dev/null +++ b/platform/core-api/src/com/intellij/openapi/application/IdeUrlTrackingParametersProvider.java @@ -0,0 +1,27 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ +package com.intellij.openapi.application; + +import com.intellij.openapi.components.ServiceManager; +import org.jetbrains.annotations.NotNull; + +/** + * Allows IDEs to add tracking parameters to URLs which are opened from IDE and lead to company sites (e.g. download/update links, product documentation). + * Override this service in your IDE to append tracking parameters to these URLs if you need to collect statistics on your site. + *
+ * This service isn't supposed to be overridden in regular plugins. + */ +public class IdeUrlTrackingParametersProvider { + public static IdeUrlTrackingParametersProvider getInstance() { + return ServiceManager.getService(IdeUrlTrackingParametersProvider.class); + } + + /** + * @return {@code originalUrl} with appended parameters + */ + @NotNull + public String augmentUrl(@NotNull String originalUrl) { + return originalUrl; + } +} diff --git a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java index d1d5dcfbd0ad..a744d0fafbb8 100644 --- a/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/application/impl/ApplicationInfoImpl.java @@ -18,6 +18,7 @@ package com.intellij.openapi.application.impl; import com.google.common.annotations.VisibleForTesting; import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.openapi.application.ApplicationNamesInfo; +import com.intellij.openapi.application.IdeUrlTrackingParametersProvider; import com.intellij.openapi.application.PathManager; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.util.BuildNumber; @@ -28,7 +29,6 @@ import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.JBColor; import com.intellij.util.ArrayUtil; -import com.intellij.util.ObjectUtils; import com.intellij.util.PlatformUtils; import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; @@ -331,7 +331,7 @@ public class ApplicationInfoImpl extends ApplicationInfoEx { @Override public String getCompanyURL() { - return myCompanyUrl; + return IdeUrlTrackingParametersProvider.getInstance().augmentUrl(myCompanyUrl); } @Nullable diff --git a/platform/platform-api/src/com/intellij/ide/customization/UtmIdeUrlTrackingParametersProvider.java b/platform/platform-api/src/com/intellij/ide/customization/UtmIdeUrlTrackingParametersProvider.java new file mode 100644 index 000000000000..96d34e5746c4 --- /dev/null +++ b/platform/platform-api/src/com/intellij/ide/customization/UtmIdeUrlTrackingParametersProvider.java @@ -0,0 +1,37 @@ +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ +package com.intellij.ide.customization; + +import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.IdeUrlTrackingParametersProvider; +import com.intellij.openapi.diagnostic.Logger; +import org.apache.http.client.utils.URIBuilder; +import org.jetbrains.annotations.NotNull; + +import java.net.URISyntaxException; + +/** + * @author nik + */ +public class UtmIdeUrlTrackingParametersProvider extends IdeUrlTrackingParametersProvider { + private static final Logger LOG = Logger.getInstance(UtmIdeUrlTrackingParametersProvider.class); + + @NotNull + @Override + public String augmentUrl(@NotNull String originalUrl) { + try { + ApplicationInfo info = ApplicationInfo.getInstance(); + String productVersion = info.getMajorVersion() + "." + info.getMinorVersionMainPart(); + return new URIBuilder(originalUrl).addParameter("utm_source", "product") + .addParameter("utm_medium", "link") + .addParameter("utm_campaign", info.getBuild().getProductCode()) + .addParameter("utm_content", productVersion) + .build().toString(); + } + catch (URISyntaxException e) { + LOG.warn(originalUrl, e); + return originalUrl; + } + } +} diff --git a/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java b/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java index be72ac021384..7a68ec1304b1 100644 --- a/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/help/impl/HelpManagerImpl.java @@ -23,6 +23,7 @@ import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.ide.plugins.PluginManagerCore; import com.intellij.internal.statistic.UsageTrigger; import com.intellij.openapi.application.ApplicationInfo; +import com.intellij.openapi.application.IdeUrlTrackingParametersProvider; import com.intellij.openapi.application.ex.ApplicationInfoEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.extensions.ExtensionPointName; @@ -31,7 +32,6 @@ import com.intellij.openapi.help.WebHelpProvider; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.text.StringUtil; import com.intellij.reference.SoftReference; -import com.intellij.util.PlatformUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -86,14 +86,7 @@ public class HelpManagerImpl extends HelpManager { if (!url.endsWith("/")) url += "/"; url += productVersion + "/?" + id; - if (PlatformUtils.isJetBrainsProduct()) { - String productCode = info.getBuild().getProductCode(); - if(!StringUtil.isEmpty(productCode)) { - url += "&utm_source=from_product&utm_medium=help_link&utm_campaign=" + productCode + "&utm_content=" + productVersion; - } - } - - BrowserUtil.browse(url); + BrowserUtil.browse(IdeUrlTrackingParametersProvider.getInstance().augmentUrl(url)); return; } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java index 5bf61c31fa2f..1ad463dfb18c 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java @@ -8,10 +8,7 @@ import com.intellij.ide.plugins.IdeaPluginDescriptor; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.NotificationType; -import com.intellij.openapi.application.ApplicationInfo; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.openapi.application.PathManager; +import com.intellij.openapi.application.*; import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.openapi.application.impl.ApplicationImpl; @@ -33,7 +30,6 @@ import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.text.DateFormatUtil; import com.intellij.util.ui.JBUI; -import org.apache.http.client.utils.URIBuilder; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,7 +39,6 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.io.File; import java.io.IOException; -import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; @@ -338,18 +333,6 @@ class UpdateInfoDialog extends AbstractUpdateDialog { } private static String augmentUrl(String url) { - try { - ApplicationInfo info = ApplicationInfo.getInstance(); - String productVersion = info.getMajorVersion() + "." + info.getMinorVersionMainPart(); - return new URIBuilder(url).addParameter("utm_source", "product") - .addParameter("utm_medium", "link") - .addParameter("utm_campaign", info.getBuild().getProductCode()) - .addParameter("utm_content", productVersion) - .build().toString(); - } - catch (URISyntaxException e) { - Logger.getInstance(UpdateInfoDialog.class).warn(url, e); - return url; - } + return IdeUrlTrackingParametersProvider.getInstance().augmentUrl(url); } } \ No newline at end of file diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 499cd99cd8ea..64f5bdbaed2b 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -152,6 +152,8 @@ + + - + diff --git a/python/educational-python/resources/idea/PyCharmEduApplicationInfo.xml b/python/educational-python/resources/idea/PyCharmEduApplicationInfo.xml index bb5b1da9297d..57146632e3cc 100644 --- a/python/educational-python/resources/idea/PyCharmEduApplicationInfo.xml +++ b/python/educational-python/resources/idea/PyCharmEduApplicationInfo.xml @@ -2,7 +2,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jetbrains.org/intellij/schema/application-info http://jetbrains.org/intellij/schema/ApplicationInfo.xsd"> - + + diff --git a/python/ide/src/META-INF/PyCharmCorePlugin.xml b/python/ide/src/META-INF/PyCharmCorePlugin.xml index 3e1f95d0b15b..c60c1bcb06df 100644 --- a/python/ide/src/META-INF/PyCharmCorePlugin.xml +++ b/python/ide/src/META-INF/PyCharmCorePlugin.xml @@ -13,4 +13,10 @@ + + + + diff --git a/python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml b/python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml index edcfd1d9c8c7..c6350af0bd84 100644 --- a/python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml +++ b/python/python-community-ide-resources/resources/idea/PyCharmCoreApplicationInfo.xml @@ -2,7 +2,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jetbrains.org/intellij/schema/application-info http://jetbrains.org/intellij/schema/ApplicationInfo.xsd"> - + + From e6d2f60d6780949e44393fd525da8df3293ab385 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 20 Dec 2017 15:07:12 +0100 Subject: [PATCH 36/58] convert UsageViewSettings to kotlin --- .../intellij/usages/UsageViewSettings.java | 146 ++++++------------ 1 file changed, 49 insertions(+), 97 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/UsageViewSettings.java b/platform/usageView/src/com/intellij/usages/UsageViewSettings.java index 86485f594240..b0687c992e6a 100644 --- a/platform/usageView/src/com/intellij/usages/UsageViewSettings.java +++ b/platform/usageView/src/com/intellij/usages/UsageViewSettings.java @@ -1,119 +1,71 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ -package com.intellij.usages; +package com.intellij.usages -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import com.intellij.util.xmlb.annotations.Transient; -import org.jetbrains.annotations.NonNls; +import com.intellij.openapi.components.* +import com.intellij.util.PathUtil +import com.intellij.util.xmlb.XmlSerializerUtil +import com.intellij.util.xmlb.annotations.OptionTag +import com.intellij.util.xmlb.annotations.Transient -import java.io.File; - -@State( - name = "UsageViewSettings", - storages = { - @Storage("usageView.xml"), - @Storage(value = "other.xml", deprecated = true) - } -) -public class UsageViewSettings implements PersistentStateComponent { - @NonNls public String EXPORT_FILE_NAME = "report.txt"; - public boolean IS_EXPANDED; - public boolean IS_SHOW_PACKAGES = true; - public boolean IS_SHOW_METHODS; - public boolean IS_AUTOSCROLL_TO_SOURCE; - public boolean IS_FILTER_DUPLICATED_LINE = true; - public boolean IS_SHOW_MODULES; - public boolean IS_PREVIEW_USAGES; - public boolean IS_SORT_MEMBERS_ALPHABETICALLY = true; - public float PREVIEW_USAGES_SPLITTER_PROPORTIONS = 0.5f; - - public boolean GROUP_BY_USAGE_TYPE = true; - public boolean GROUP_BY_MODULE = true; - public boolean FLATTEN_MODULES = true; - public boolean GROUP_BY_PACKAGE = true; - public boolean GROUP_BY_FILE_STRUCTURE = true; - public boolean GROUP_BY_SCOPE; - - public static UsageViewSettings getInstance() { - return ServiceManager.getService(UsageViewSettings.class); +@State(name = "UsageViewSettings", storages = arrayOf(Storage("usageView.xml"), Storage(value = "other.xml", deprecated = true))) +class UsageViewSettings : BaseState(), PersistentStateComponent { + companion object { + @JvmStatic + val instance: UsageViewSettings + get() = ServiceManager.getService(UsageViewSettings::class.java) } - public boolean isExpanded() { - return IS_EXPANDED; - } + var EXPORT_FILE_NAME by string("report.txt") - public void setExpanded(boolean val) { - IS_EXPANDED = val; - } + var isExpanded by property(false) + var isShowPackages by property(true) + var isShowMethods by property(false) - public boolean isShowPackages() { - return IS_SHOW_PACKAGES; - } + @get:OptionTag("IS_AUTOSCROLL_TO_SOURCE") + var isAutoScrollToSource by property(false) - public void setShowPackages(boolean val) { - IS_SHOW_PACKAGES = val; - } + var isFilterDuplicatedLine by property(true) + var isShowModules by property(false) - public boolean isShowMethods() { - return IS_SHOW_METHODS; - } + @get:OptionTag("IS_PREVIEW_USAGES") + var isPreviewUsages by property(false) - public boolean isShowModules() { - return IS_SHOW_MODULES; - } + @get:OptionTag("IS_SORT_MEMBERS_ALPHABETICALLY") + var isSortAlphabetically by property(false) - public void setShowMethods(boolean val) { - IS_SHOW_METHODS = val; - } + @get:OptionTag("PREVIEW_USAGES_SPLITTER_PROPORTIONS") + var previewUsagesSplitterProportion by property(0.5f) - public void setShowModules(boolean val) { - IS_SHOW_MODULES = val; - } + @get:OptionTag("GROUP_BY_USAGE_TYPE") + var isGroupByUsageType by property(true) - public boolean isFilterDuplicatedLine() { - return IS_FILTER_DUPLICATED_LINE; - } + @get:OptionTag("GROUP_BY_MODULE") + var isGroupByModule by property(true) - public void setFilterDuplicatedLine(boolean val) { - IS_FILTER_DUPLICATED_LINE = val; - } + @get:OptionTag("FLATTEN_MODULES") + var isFlattenModules by property(true) - @Transient - public String getExportFileName() { - return EXPORT_FILE_NAME != null ? EXPORT_FILE_NAME.replace('/', File.separatorChar) : null; - } + @get:OptionTag("GROUP_BY_PACKAGE") + var isGroupByPackage by property(true) - public void setExportFileName(String s) { - if (s != null){ - s = s.replace(File.separatorChar, '/'); + @get:OptionTag("GROUP_BY_FILE_STRUCTURE") + var isGroupByFileStructure by property(true) + + @get:OptionTag("GROUP_BY_SCOPE") + var isGroupByScope: Boolean by property(false) + + var exportFileName: String? + @Transient + get() = PathUtil.toSystemDependentName(EXPORT_FILE_NAME) + set(value) { + EXPORT_FILE_NAME = PathUtil.toSystemIndependentName(value) } - EXPORT_FILE_NAME = s; - } - @Override - public UsageViewSettings getState() { - return this; - } + override fun getState() = this - @Override - public void loadState(final UsageViewSettings object) { - XmlSerializerUtil.copyBean(object, this); + override fun loadState(`object`: UsageViewSettings) { + XmlSerializerUtil.copyBean(`object`, this) } } From c7185f48fab80a23fe7fe26452efd193b0bed968 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 20 Dec 2017 15:07:18 +0100 Subject: [PATCH 37/58] convert UsageViewSettings to kotlin --- .../usages/{UsageViewSettings.java => UsageViewSettings.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename platform/usageView/src/com/intellij/usages/{UsageViewSettings.java => UsageViewSettings.kt} (100%) diff --git a/platform/usageView/src/com/intellij/usages/UsageViewSettings.java b/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt similarity index 100% rename from platform/usageView/src/com/intellij/usages/UsageViewSettings.java rename to platform/usageView/src/com/intellij/usages/UsageViewSettings.kt From 405223081db9da23ec24dfd3584bd40c77cf6a81 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 20 Dec 2017 15:13:12 +0100 Subject: [PATCH 38/58] =?UTF-8?q?UsageViewSettings=20=E2=80=94=20use=20Bas?= =?UTF-8?q?eState?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intellij/unscramble/ThreadDumpPanel.java | 30 ++--------- .../usages/impl/rules/MethodGroupingRule.java | 16 +----- .../psi/usages/JavaUsageViewTreeTest.java | 12 +++-- .../FavoritesTreeViewPanel.java | 28 +--------- .../ExporterToTextFileHierarchy.java | 30 +---------- .../ui/DependenciesPanel.java | 16 ------ .../src/com/intellij/slicer/SlicePanel.java | 20 ++----- .../slicer/SliceToTextFileExporter.java | 34 ++---------- .../com/intellij/ide/ExporterToTextFile.java | 38 +++++++------- .../usages/impl/UsageViewTreeTest.java | 22 ++------ .../intellij/usages/ShowUsagesSettings.java | 24 ++++----- .../com/intellij/usages/UsageViewSettings.kt | 10 ++-- .../usages/impl/ExporterToTextFile.java | 34 ++---------- .../usages/impl/PreviewUsageAction.java | 18 ++----- .../impl/SortMembersAlphabeticallyAction.java | 19 ++----- .../impl/UsageGroupingRuleProviderImpl.java | 52 +++++++------------ .../intellij/usages/impl/UsageViewImpl.java | 10 ++-- 17 files changed, 99 insertions(+), 314 deletions(-) diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java index 5705fd5edd35..788e63162302 100644 --- a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java +++ b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.unscramble; @@ -47,14 +35,15 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.datatransfer.StringSelection; import java.io.File; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import static com.intellij.icons.AllIcons.Debugger.ThreadStates.*; @@ -413,17 +402,6 @@ public class ThreadDumpPanel extends JPanel implements DataProvider { myThreadStates = threadStates; } - @Override - public JComponent getSettingsEditor() { - return null; - } - - @Override - public void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException {} - - @Override - public void removeSettingsChangedListener(ChangeListener listener) {} - @NotNull @Override public String getReportText() { diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java index 910dc6a36063..ac2533582b1f 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.impl.rules; @@ -169,7 +157,7 @@ public class MethodGroupingRule extends SingleParentUsageGroupingRule { if (SmartPointerManager.getInstance(myProject).pointToTheSameElement(myMethodPointer, other.myMethodPointer)) { return 0; } - if (!UsageViewSettings.getInstance().IS_SORT_MEMBERS_ALPHABETICALLY) { + if (!UsageViewSettings.getInstance().isSortAlphabetically()) { Segment segment1 = myMethodPointer.getRange(); Segment segment2 = other.myMethodPointer.getRange(); if (segment1 != null && segment2 != null) { diff --git a/java/java-tests/testSrc/com/intellij/java/psi/usages/JavaUsageViewTreeTest.java b/java/java-tests/testSrc/com/intellij/java/psi/usages/JavaUsageViewTreeTest.java index a5fe6d68bcc6..af5f8317edf7 100644 --- a/java/java-tests/testSrc/com/intellij/java/psi/usages/JavaUsageViewTreeTest.java +++ b/java/java-tests/testSrc/com/intellij/java/psi/usages/JavaUsageViewTreeTest.java @@ -1,4 +1,6 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ package com.intellij.java.psi.usages; import com.intellij.openapi.util.Disposer; @@ -23,10 +25,10 @@ public class JavaUsageViewTreeTest extends LightCodeInsightFixtureTestCase { XmlSerializerUtil.copyBean(settings.getState(), oldSettingsState); disposeOnTearDown(() -> settings.loadState(oldSettingsState)); - settings.GROUP_BY_MODULE = false; - settings.GROUP_BY_FILE_STRUCTURE = true; - settings.GROUP_BY_USAGE_TYPE = false; - settings.GROUP_BY_PACKAGE = false; + settings.setGroupByModule(false); + settings.setGroupByFileStructure(true); + settings.setGroupByUsageType(false); + settings.setGroupByPackage(false); } public void testSimpleModule() { diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java index 5cf59c0ed235..8da40f904d3d 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.ide.favoritesTreeView; @@ -68,7 +56,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.ChangeListener; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; @@ -258,19 +245,6 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider, Dock private ExporterToTextFile createTextExporter() { return new ExporterToTextFile() { - @Override - public JComponent getSettingsEditor() { - return null; - } - - @Override - public void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException { - } - - @Override - public void removeSettingsChangedListener(ChangeListener listener) { - } - @NotNull @Override public String getReportText() { diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/ExporterToTextFileHierarchy.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/ExporterToTextFileHierarchy.java index 5095aa645704..1b4414bf9318 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/ExporterToTextFileHierarchy.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/ExporterToTextFileHierarchy.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.ide.hierarchy; @@ -20,11 +8,8 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.SystemProperties; import org.jetbrains.annotations.NotNull; -import javax.swing.*; -import javax.swing.event.ChangeListener; import javax.swing.tree.DefaultMutableTreeNode; import java.util.Enumeration; -import java.util.TooManyListenersException; class ExporterToTextFileHierarchy implements ExporterToTextFile { private static final Logger LOG = Logger.getInstance(ExporterToTextFileHierarchy.class); @@ -34,19 +19,6 @@ class ExporterToTextFileHierarchy implements ExporterToTextFile { myHierarchyBrowserBase = hierarchyBrowserBase; } - @Override - public JComponent getSettingsEditor() { - return null; - } - - @Override - public void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException { - } - - @Override - public void removeSettingsChangedListener(ChangeListener listener) { - } - @NotNull @Override public String getReportText() { diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java index 07e9ea32616b..2f40c8ebe8c3 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java @@ -60,7 +60,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import javax.swing.event.ChangeListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeModel; @@ -673,22 +672,7 @@ public class DependenciesPanel extends JPanel implements Disposable, DataProvide } } - private class DependenciesExporterToTextFile implements ExporterToTextFile { - - @Override - public JComponent getSettingsEditor() { - return null; - } - - @Override - public void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException { - } - - @Override - public void removeSettingsChangedListener(ChangeListener listener) { - } - @NotNull @Override public String getReportText() { diff --git a/platform/lang-impl/src/com/intellij/slicer/SlicePanel.java b/platform/lang-impl/src/com/intellij/slicer/SlicePanel.java index 981e6170e451..708463faa7c5 100644 --- a/platform/lang-impl/src/com/intellij/slicer/SlicePanel.java +++ b/platform/lang-impl/src/com/intellij/slicer/SlicePanel.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.slicer; @@ -143,7 +131,7 @@ public abstract class SlicePanel extends JPanel implements TypeSafeDataProvider, pane.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT | SideBorder.RIGHT)); boolean vertical = myToolWindow.getAnchor() == ToolWindowAnchor.LEFT || myToolWindow.getAnchor() == ToolWindowAnchor.RIGHT; - Splitter splitter = new Splitter(vertical, UsageViewSettings.getInstance().PREVIEW_USAGES_SPLITTER_PROPORTIONS); + Splitter splitter = new Splitter(vertical, UsageViewSettings.getInstance().getPreviewUsagesSplitterProportion()); splitter.setFirstComponent(pane); myUsagePreviewPanel = new UsagePreviewPanel(myProject, new UsageViewPresentation()); myUsagePreviewPanel.setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT)); @@ -167,7 +155,7 @@ public abstract class SlicePanel extends JPanel implements TypeSafeDataProvider, @Override public void dispose() { if (myUsagePreviewPanel != null) { - UsageViewSettings.getInstance().PREVIEW_USAGES_SPLITTER_PROPORTIONS = ((Splitter)myUsagePreviewPanel.getParent()).getProportion(); + UsageViewSettings.getInstance().setPreviewUsagesSplitterProportion(((Splitter)myUsagePreviewPanel.getParent()).getProportion()); myUsagePreviewPanel = null; } @@ -175,7 +163,7 @@ public abstract class SlicePanel extends JPanel implements TypeSafeDataProvider, ToolTipManager.sharedInstance().unregisterComponent(myTree); } - class MultiLanguageTreeCellRenderer implements TreeCellRenderer { + static class MultiLanguageTreeCellRenderer implements TreeCellRenderer { @NotNull private final SliceUsageCellRendererBase rootRenderer; diff --git a/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java b/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java index 106a544196a4..b08c55ca4a65 100644 --- a/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java +++ b/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.slicer; @@ -20,10 +8,7 @@ import com.intellij.usages.UsageViewSettings; import com.intellij.util.SystemProperties; import org.jetbrains.annotations.NotNull; -import javax.swing.*; -import javax.swing.event.ChangeListener; import java.util.List; -import java.util.TooManyListenersException; /** * @author nik @@ -36,19 +21,6 @@ public class SliceToTextFileExporter implements ExporterToTextFile { myBuilder = builder; } - @Override - public JComponent getSettingsEditor() { - return null; - } - - @Override - public void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException { - } - - @Override - public void removeSettingsChangedListener(ChangeListener listener) { - } - @NotNull @Override public String getReportText() { @@ -78,12 +50,12 @@ public class SliceToTextFileExporter implements ExporterToTextFile { @NotNull @Override public String getDefaultFilePath() { - return UsageViewSettings.getInstance().EXPORT_FILE_NAME; + return UsageViewSettings.getInstance().getExportFileName(); } @Override public void exportedTo(String filePath) { - UsageViewSettings.getInstance().EXPORT_FILE_NAME = filePath; + UsageViewSettings.getInstance().setExportFileName(filePath); } @Override diff --git a/platform/platform-api/src/com/intellij/ide/ExporterToTextFile.java b/platform/platform-api/src/com/intellij/ide/ExporterToTextFile.java index 4fdf61f1b2ba..90dc48cff6a1 100644 --- a/platform/platform-api/src/com/intellij/ide/ExporterToTextFile.java +++ b/platform/platform-api/src/com/intellij/ide/ExporterToTextFile.java @@ -1,32 +1,34 @@ /* - * Copyright 2000-2009 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.ide; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import javax.swing.event.ChangeListener; import java.util.TooManyListenersException; public interface ExporterToTextFile { - JComponent getSettingsEditor(); - void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException; - void removeSettingsChangedListener(ChangeListener listener); - @NotNull String getReportText(); - @NotNull String getDefaultFilePath(); + @Nullable + default JComponent getSettingsEditor() { + return null; + } + + default void addSettingsChangedListener(ChangeListener listener) throws TooManyListenersException { + } + + default void removeSettingsChangedListener(ChangeListener listener) { + } + + @NotNull + String getReportText(); + + @NotNull + String getDefaultFilePath(); + void exportedTo(String filePath); + boolean canExport(); } diff --git a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTreeTest.java b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTreeTest.java index 2416f18b16e1..9d1927aaa7fd 100644 --- a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTreeTest.java +++ b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTreeTest.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.impl; @@ -61,9 +49,9 @@ public class UsageViewTreeTest extends UsefulTestCase { XmlSerializerUtil.copyBean(settings.getState(), oldSettingsState); disposeOnTearDown(() -> settings.loadState(oldSettingsState)); - settings.GROUP_BY_FILE_STRUCTURE = false; - settings.GROUP_BY_USAGE_TYPE = false; - settings.GROUP_BY_PACKAGE = false; + settings.setGroupByFileStructure(false); + settings.setGroupByUsageType(false); + settings.setGroupByPackage(false); } public void testSimpleModule() throws Exception { @@ -81,7 +69,7 @@ public class UsageViewTreeTest extends UsefulTestCase { addModule("xxx.main"); PsiFile file = myFixture.addFileToProject("xxx.main/A.txt", "hello"); Usage[] usages = {new UsageInfo2UsageAdapter(new UsageInfo(file))}; - UsageViewSettings.getInstance().FLATTEN_MODULES = false; + UsageViewSettings.getInstance().setFlattenModules(false); ModuleGroupTestsKt.runWithQualifiedModuleNamesEnabled(() -> { assertUsageViewStructureEquals(usages, "Usage (1 usage)\n" + " Non-code usages (1 usage)\n" + diff --git a/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java b/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java index d3e2ecbc4d3b..d3c633dd6682 100644 --- a/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java +++ b/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java @@ -1,4 +1,6 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ package com.intellij.usages; import com.intellij.openapi.components.PersistentStateComponent; @@ -6,14 +8,10 @@ import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.util.xmlb.XmlSerializerUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -@State( - name = "ShowUsagesSettings", - storages = { - @Storage("usageView.xml") - } -) +@State(name = "ShowUsagesSettings", storages = @Storage("usageView.xml")) public class ShowUsagesSettings implements PersistentStateComponent { private final UsageViewSettings myState = new UsageViewSettings(); @@ -24,7 +22,7 @@ public class ShowUsagesSettings implements PersistentStateComponent Date: Wed, 20 Dec 2017 16:01:16 +0100 Subject: [PATCH 39/58] convert ShowUsagesSettings to kotlin --- .../intellij/usages/ShowUsagesSettings.java | 45 +++++++------------ 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java b/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java index d3c633dd6682..b415eedef1cb 100644 --- a/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java +++ b/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java @@ -1,40 +1,29 @@ /* * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ -package com.intellij.usages; +package com.intellij.usages -import com.intellij.openapi.components.PersistentStateComponent; -import com.intellij.openapi.components.ServiceManager; -import com.intellij.openapi.components.State; -import com.intellij.openapi.components.Storage; -import com.intellij.util.xmlb.XmlSerializerUtil; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import com.intellij.openapi.components.PersistentStateComponent +import com.intellij.openapi.components.ServiceManager +import com.intellij.openapi.components.State +import com.intellij.openapi.components.Storage +import com.intellij.util.xmlb.XmlSerializerUtil -@State(name = "ShowUsagesSettings", storages = @Storage("usageView.xml")) -public class ShowUsagesSettings implements PersistentStateComponent { - private final UsageViewSettings myState = new UsageViewSettings(); - - @Nullable - @Override - public UsageViewSettings getState() { - return myState; +@State(name = "ShowUsagesSettings", storages = arrayOf(Storage("usageView.xml"))) +class ShowUsagesSettings : PersistentStateComponent { + private val myState = UsageViewSettings(false, false, false, false, false) + + override fun getState(): UsageViewSettings? { + return myState } - @Override - public void loadState(@NotNull UsageViewSettings state) { - XmlSerializerUtil.copyBean(state, myState); + override fun loadState(state: UsageViewSettings) { + XmlSerializerUtil.copyBean(state, myState) } - public static ShowUsagesSettings getInstance() { - return ServiceManager.getService(ShowUsagesSettings.class); - } + companion object { - public ShowUsagesSettings() { - myState.setGroupByFileStructure(false); - myState.setGroupByModule(false); - myState.setGroupByPackage(false); - myState.setGroupByUsageType(false); - myState.setGroupByScope(false); + val instance: ShowUsagesSettings + get() = ServiceManager.getService(ShowUsagesSettings::class.java) } } From 1a6fc4bc6402dfb8a65f60fa65310a7f654854ef Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 20 Dec 2017 16:01:22 +0100 Subject: [PATCH 40/58] convert ShowUsagesSettings to kotlin --- .../usages/{ShowUsagesSettings.java => ShowUsagesSettings.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename platform/usageView/src/com/intellij/usages/{ShowUsagesSettings.java => ShowUsagesSettings.kt} (100%) diff --git a/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java b/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.kt similarity index 100% rename from platform/usageView/src/com/intellij/usages/ShowUsagesSettings.java rename to platform/usageView/src/com/intellij/usages/ShowUsagesSettings.kt From 9f98e652bc8bcb65c4157fb23879bea4175de92f Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 20 Dec 2017 16:41:33 +0100 Subject: [PATCH 41/58] =?UTF-8?q?ShowUsagesSettings=20=E2=80=94=20do=20not?= =?UTF-8?q?=20write=20defaults?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../intellij/unscramble/ThreadDumpPanel.java | 5 ---- .../find/actions/ShowUsagesAction.java | 6 ++-- .../FavoritesTreeViewPanel.java | 4 --- .../ExporterToTextFileHierarchy.java | 2 +- .../ui/DependenciesPanel.java | 4 --- .../slicer/SliceToTextFileExporter.java | 2 +- .../intellij/ide/CommonActionsManager.java | 27 +++++++---------- .../com/intellij/ide/ExporterToTextFile.java | 3 +- .../impl/ErrorViewTextExporter.java | 17 +---------- .../ide/impl/CommonActionsManagerImpl.java | 17 ++--------- .../intellij/usages/impl/UsageViewTest.java | 16 ++-------- .../com/intellij/usages/ShowUsagesSettings.kt | 29 ++++++++++--------- .../com/intellij/usages/UsageViewSettings.kt | 26 +++++++++++------ .../usages/impl/ExporterToTextFile.java | 11 ++++--- .../intellij/usages/impl/UsageViewImpl.java | 2 +- 15 files changed, 66 insertions(+), 105 deletions(-) diff --git a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java index 788e63162302..dfc315d97499 100644 --- a/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java +++ b/java/java-impl/src/com/intellij/unscramble/ThreadDumpPanel.java @@ -425,11 +425,6 @@ public class ThreadDumpPanel extends JPanel implements DataProvider { return ""; } - @Override - public void exportedTo(String filePath) { - - } - @Override public boolean canExport() { return !myThreadStates.isEmpty(); diff --git a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java index 29d6428d4405..c654cac6a303 100644 --- a/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java +++ b/platform/lang-impl/src/com/intellij/find/actions/ShowUsagesAction.java @@ -1,4 +1,6 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +/* + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + */ package com.intellij.find.actions; import com.intellij.codeInsight.TargetElementUtil; @@ -240,7 +242,7 @@ public class ShowUsagesAction extends AnAction implements PopupAction { } Disposer.register(usageView, () -> { - showUsagesSettings.loadState(usageViewSettings); + showUsagesSettings.applyUsageViewSettings(usageViewSettings); usageViewSettings.loadState(savedGlobalSettings); }); diff --git a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java index 8da40f904d3d..b514c164168a 100644 --- a/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/favoritesTreeView/FavoritesTreeViewPanel.java @@ -299,10 +299,6 @@ public class FavoritesTreeViewPanel extends JPanel implements DataProvider, Dock return myProject.getBasePath() + File.separator + "Favorites.txt"; } - @Override - public void exportedTo(String filePath) { - } - @Override public boolean canExport() { return true; diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/ExporterToTextFileHierarchy.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/ExporterToTextFileHierarchy.java index 1b4414bf9318..fe89256bc2f2 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/ExporterToTextFileHierarchy.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/ExporterToTextFileHierarchy.java @@ -57,7 +57,7 @@ class ExporterToTextFileHierarchy implements ExporterToTextFile { } @Override - public void exportedTo(String filePath) { + public void exportedTo(@NotNull String filePath) { final HierarchyBrowserManager.State state = HierarchyBrowserManager.getInstance(myHierarchyBrowserBase.myProject).getState(); if (state != null) { state.EXPORT_FILE_PATH = filePath; diff --git a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java index 2f40c8ebe8c3..655acd3e4767 100644 --- a/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java +++ b/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java @@ -707,10 +707,6 @@ public class DependenciesPanel extends JPanel implements Disposable, DataProvide return ""; } - @Override - public void exportedTo(String filePath) { - } - @Override public boolean canExport() { return true; diff --git a/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java b/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java index b08c55ca4a65..7c08bf71fe26 100644 --- a/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java +++ b/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java @@ -54,7 +54,7 @@ public class SliceToTextFileExporter implements ExporterToTextFile { } @Override - public void exportedTo(String filePath) { + public void exportedTo(@NotNull String filePath) { UsageViewSettings.getInstance().setExportFileName(filePath); } diff --git a/platform/platform-api/src/com/intellij/ide/CommonActionsManager.java b/platform/platform-api/src/com/intellij/ide/CommonActionsManager.java index 852764a65a26..a7dafcac3b2e 100644 --- a/platform/platform-api/src/com/intellij/ide/CommonActionsManager.java +++ b/platform/platform-api/src/com/intellij/ide/CommonActionsManager.java @@ -1,23 +1,12 @@ /* - * Copyright 2000-2009 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.ide; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -30,28 +19,34 @@ public abstract class CommonActionsManager { } public abstract AnAction createPrevOccurenceAction(OccurenceNavigator navigator); + public abstract AnAction createNextOccurenceAction(OccurenceNavigator navigator); @Deprecated public abstract AnAction createExpandAllAction(TreeExpander expander); + public abstract AnAction createExpandAllAction(TreeExpander expander, JComponent component); + public abstract AnAction createExpandAllHeaderAction(JTree tree); @Deprecated public abstract AnAction createCollapseAllAction(TreeExpander expander); + public abstract AnAction createCollapseAllAction(TreeExpander expander, JComponent component); + public abstract AnAction createCollapseAllHeaderAction(JTree tree); public abstract AnAction createHelpAction(String helpId); /** * Installs autoscroll capability support to JTree passed. Toggle action returned. + * * @param project - * @return toggle action to be inserted to appropriate toolbar - * @param tree should provide DataConstants.NAVIGATABLE for handler to work on + * @param tree should provide DataConstants.NAVIGATABLE for handler to work on * @param optionProvider get/set API to externalizable property. + * @return toggle action to be inserted to appropriate toolbar */ public abstract AnAction installAutoscrollToSourceHandler(Project project, JTree tree, AutoScrollToSourceOptionProvider optionProvider); - public abstract AnAction createExportToTextFileAction(ExporterToTextFile exporter); + public abstract AnAction createExportToTextFileAction(@NotNull ExporterToTextFile exporter); } diff --git a/platform/platform-api/src/com/intellij/ide/ExporterToTextFile.java b/platform/platform-api/src/com/intellij/ide/ExporterToTextFile.java index 90dc48cff6a1..c8db680fbf4e 100644 --- a/platform/platform-api/src/com/intellij/ide/ExporterToTextFile.java +++ b/platform/platform-api/src/com/intellij/ide/ExporterToTextFile.java @@ -28,7 +28,8 @@ public interface ExporterToTextFile { @NotNull String getDefaultFilePath(); - void exportedTo(String filePath); + default void exportedTo(@NotNull String filePath) { + } boolean canExport(); } diff --git a/platform/platform-impl/src/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java b/platform/platform-impl/src/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java index e2d6e31151a1..0963518e3e5c 100644 --- a/platform/platform-impl/src/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java +++ b/platform/platform-impl/src/com/intellij/ide/errorTreeView/impl/ErrorViewTextExporter.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2011 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.ide.errorTreeView.impl; @@ -70,9 +58,6 @@ public class ErrorViewTextExporter implements ExporterToTextFile { return ""; } - public void exportedTo(String filePath) { - } - public boolean canExport() { return true; } diff --git a/platform/platform-impl/src/com/intellij/ide/impl/CommonActionsManagerImpl.java b/platform/platform-impl/src/com/intellij/ide/impl/CommonActionsManagerImpl.java index a48aa7a49421..9aadad239b37 100644 --- a/platform/platform-impl/src/com/intellij/ide/impl/CommonActionsManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/ide/impl/CommonActionsManagerImpl.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2009 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.ide.impl; @@ -21,6 +9,7 @@ import com.intellij.ide.actions.*; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.project.Project; import com.intellij.ui.AutoScrollToSourceHandler; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -90,7 +79,7 @@ public class CommonActionsManagerImpl extends CommonActionsManager { return handler.createToggleAction(); } - public AnAction createExportToTextFileAction(ExporterToTextFile exporter) { + public AnAction createExportToTextFileAction(@NotNull ExporterToTextFile exporter) { return new ExportToTextFileToolbarAction(exporter); } } diff --git a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTest.java b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTest.java index 14cb9f85209e..5f10b4de9fbb 100644 --- a/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTest.java +++ b/platform/platform-tests/testSrc/com/intellij/usages/impl/UsageViewTest.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.impl; @@ -207,7 +195,7 @@ public class UsageViewTest extends LightPlatformCodeInsightFixtureTestCase { assertEmpty(excluded); - String text = new ExporterToTextFile(usageView).getReportText(); + String text = new ExporterToTextFile(usageView, UsageViewSettings.getInstance()).getReportText(); assertEquals("Found usages (1 usage found)\n" + " Unclassified usage (1 usage found)\n" + " light_idea_test_case (1 usage found)\n" + diff --git a/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.kt b/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.kt index b415eedef1cb..7f6996f33383 100644 --- a/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.kt +++ b/platform/usageView/src/com/intellij/usages/ShowUsagesSettings.kt @@ -7,23 +7,26 @@ import com.intellij.openapi.components.PersistentStateComponent import com.intellij.openapi.components.ServiceManager import com.intellij.openapi.components.State import com.intellij.openapi.components.Storage -import com.intellij.util.xmlb.XmlSerializerUtil @State(name = "ShowUsagesSettings", storages = arrayOf(Storage("usageView.xml"))) -class ShowUsagesSettings : PersistentStateComponent { - private val myState = UsageViewSettings(false, false, false, false, false) - - override fun getState(): UsageViewSettings? { - return myState - } - - override fun loadState(state: UsageViewSettings) { - XmlSerializerUtil.copyBean(state, myState) - } - +class ShowUsagesSettings : PersistentStateComponent { companion object { - + @JvmStatic val instance: ShowUsagesSettings get() = ServiceManager.getService(ShowUsagesSettings::class.java) } + + private var state = ShowUsageViewSettings() + + override fun getState() = state + + override fun loadState(state: ShowUsageViewSettings) { + this.state = state + } + + fun applyUsageViewSettings(otherState: UsageViewSettings) { + state.copyFrom(otherState) + } } + +class ShowUsageViewSettings : UsageViewSettings(false, false, false, false, false) diff --git a/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt b/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt index 3101faba29a5..bb79bc4d9e72 100644 --- a/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt +++ b/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt @@ -5,12 +5,20 @@ package com.intellij.usages import com.intellij.openapi.components.* import com.intellij.util.PathUtil -import com.intellij.util.xmlb.XmlSerializerUtil import com.intellij.util.xmlb.annotations.OptionTag import com.intellij.util.xmlb.annotations.Transient +/** + * Passed params will be used as default values, so, do not use constructor if instance will be used as a state (unless you want to change defaults) + */ @State(name = "UsageViewSettings", storages = arrayOf(Storage("usageView.xml"), Storage(value = "other.xml", deprecated = true))) -class UsageViewSettings : BaseState(), PersistentStateComponent { +open class UsageViewSettings( + isGroupByFileStructure: Boolean = true, + isGroupByModule: Boolean = true, + isGroupByPackage: Boolean = true, + isGroupByUsageType: Boolean = true, + isGroupByScope: Boolean = false +) : BaseState(), PersistentStateComponent { companion object { @JvmStatic val instance: UsageViewSettings @@ -43,22 +51,22 @@ class UsageViewSettings : BaseState(), PersistentStateComponent myExclusionHandler; From 19e2763f9a1b4fe0e2c53584a87ab57f635e545e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Wed, 20 Dec 2017 17:09:16 +0100 Subject: [PATCH 42/58] reduce usage of UsageViewSettings.getInstance() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Current implementation of show usages action is not good — it is bad to call loadState/getState. We should get rid of global usage view settings and use only provided one. --- .../rules/JavaClassGroupRuleProvider.java | 19 ++----- .../rules/JavaMethodGroupRuleProvider.java | 27 +++++----- .../usages/impl/rules/MethodGroupingRule.java | 19 +++++-- .../rules/NonJavaFileGroupRuleProvider.java | 19 ++----- .../src/com/intellij/slicer/SlicePanel.java | 2 +- .../slicer/SliceToTextFileExporter.java | 8 +-- .../src/com/intellij/usages/UsageView.java | 16 +----- .../impl/FileStructureGroupRuleProvider.java | 23 +++------ .../usages/impl/PreviewUsageAction.java | 5 +- .../com/intellij/usages/impl/RuleAction.java | 16 +----- .../impl/SortMembersAlphabeticallyAction.java | 8 +-- .../impl/UsageGroupingRuleProviderImpl.java | 49 ++++++++++--------- .../intellij/usages/impl/UsageViewImpl.java | 44 ++++++++++------- .../impl/rules/FileGroupingRuleProvider.java | 17 ++----- .../rules/UsageGroupingRuleProvider.java | 21 +++----- .../PyClassGroupingRuleProvider.java | 16 +----- .../PyFunctionGroupingRuleProvider.java | 16 +----- 17 files changed, 126 insertions(+), 199 deletions(-) diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/JavaClassGroupRuleProvider.java b/java/java-impl/src/com/intellij/usages/impl/rules/JavaClassGroupRuleProvider.java index 82b156c59385..7de349d0f808 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/JavaClassGroupRuleProvider.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/JavaClassGroupRuleProvider.java @@ -1,30 +1,19 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.impl.rules; +import com.intellij.openapi.project.Project; import com.intellij.usages.impl.FileStructureGroupRuleProvider; import com.intellij.usages.rules.UsageGroupingRule; -import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; /** * @author yole */ public class JavaClassGroupRuleProvider implements FileStructureGroupRuleProvider { @Override - public UsageGroupingRule getUsageGroupingRule(final Project project) { + public UsageGroupingRule getUsageGroupingRule(@NotNull final Project project) { return new ClassGroupingRule(); } } diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/JavaMethodGroupRuleProvider.java b/java/java-impl/src/com/intellij/usages/impl/rules/JavaMethodGroupRuleProvider.java index 6ab324fcaa9c..545eeedcfc10 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/JavaMethodGroupRuleProvider.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/JavaMethodGroupRuleProvider.java @@ -1,30 +1,25 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.impl.rules; +import com.intellij.openapi.project.Project; +import com.intellij.usages.UsageViewSettings; import com.intellij.usages.impl.FileStructureGroupRuleProvider; import com.intellij.usages.rules.UsageGroupingRule; -import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; /** * @author yole */ public class JavaMethodGroupRuleProvider implements FileStructureGroupRuleProvider { @Override - public UsageGroupingRule getUsageGroupingRule(final Project project) { - return new MethodGroupingRule(); + public UsageGroupingRule getUsageGroupingRule(@NotNull Project project) { + return getUsageGroupingRule(project, UsageViewSettings.getInstance()); + } + + @Override + public UsageGroupingRule getUsageGroupingRule(@NotNull Project project, @NotNull UsageViewSettings usageViewSettings) { + return new MethodGroupingRule(usageViewSettings); } } diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java index ac2533582b1f..57124edda828 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/MethodGroupingRule.java @@ -32,7 +32,13 @@ import javax.swing.*; * @author max */ public class MethodGroupingRule extends SingleParentUsageGroupingRule { - private static final Logger LOG = Logger.getInstance("#com.intellij.usages.impl.rules.MethodGroupingRule"); + private static final Logger LOG = Logger.getInstance(MethodGroupingRule.class); + @NotNull + private final UsageViewSettings myUsageViewSettings; + + public MethodGroupingRule(@NotNull UsageViewSettings usageViewSettings) { + myUsageViewSettings = usageViewSettings; + } @Nullable @Override @@ -58,7 +64,7 @@ public class MethodGroupingRule extends SingleParentUsageGroupingRule { while (true); if (containingMethod != null) { - return new MethodUsageGroup((PsiMethod)containingMethod); + return new MethodUsageGroup((PsiMethod)containingMethod, myUsageViewSettings); } } return null; @@ -70,7 +76,10 @@ public class MethodGroupingRule extends SingleParentUsageGroupingRule { private final Icon myIcon; private final Project myProject; - public MethodUsageGroup(PsiMethod psiMethod) { + @NotNull + private final UsageViewSettings myUsageViewSettings; + + public MethodUsageGroup(PsiMethod psiMethod, @NotNull UsageViewSettings usageViewSettings) { myName = PsiFormatUtil.formatMethod( psiMethod, PsiSubstitutor.EMPTY, @@ -81,6 +90,8 @@ public class MethodGroupingRule extends SingleParentUsageGroupingRule { myMethodPointer = SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(psiMethod); myIcon = getIconImpl(psiMethod); + + myUsageViewSettings = usageViewSettings; } @Override @@ -157,7 +168,7 @@ public class MethodGroupingRule extends SingleParentUsageGroupingRule { if (SmartPointerManager.getInstance(myProject).pointToTheSameElement(myMethodPointer, other.myMethodPointer)) { return 0; } - if (!UsageViewSettings.getInstance().isSortAlphabetically()) { + if (!myUsageViewSettings.isSortAlphabetically()) { Segment segment1 = myMethodPointer.getRange(); Segment segment2 = other.myMethodPointer.getRange(); if (segment1 != null && segment2 != null) { diff --git a/java/java-impl/src/com/intellij/usages/impl/rules/NonJavaFileGroupRuleProvider.java b/java/java-impl/src/com/intellij/usages/impl/rules/NonJavaFileGroupRuleProvider.java index 41ccee880de4..d2086e777577 100644 --- a/java/java-impl/src/com/intellij/usages/impl/rules/NonJavaFileGroupRuleProvider.java +++ b/java/java-impl/src/com/intellij/usages/impl/rules/NonJavaFileGroupRuleProvider.java @@ -1,30 +1,19 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.impl.rules; +import com.intellij.openapi.project.Project; import com.intellij.usages.impl.FileStructureGroupRuleProvider; import com.intellij.usages.rules.UsageGroupingRule; -import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; /** * @author yole */ public class NonJavaFileGroupRuleProvider implements FileStructureGroupRuleProvider { @Override - public UsageGroupingRule getUsageGroupingRule(final Project project) { + public UsageGroupingRule getUsageGroupingRule(@NotNull final Project project) { return new NonJavaFileGroupingRule(project); } } diff --git a/platform/lang-impl/src/com/intellij/slicer/SlicePanel.java b/platform/lang-impl/src/com/intellij/slicer/SlicePanel.java index 708463faa7c5..e045b575826e 100644 --- a/platform/lang-impl/src/com/intellij/slicer/SlicePanel.java +++ b/platform/lang-impl/src/com/intellij/slicer/SlicePanel.java @@ -370,7 +370,7 @@ public abstract class SlicePanel extends JPanel implements TypeSafeDataProvider, } myProvider.registerExtraPanelActions(actionGroup, myBuilder); - actionGroup.add(CommonActionsManager.getInstance().createExportToTextFileAction(new SliceToTextFileExporter(myBuilder))); + actionGroup.add(CommonActionsManager.getInstance().createExportToTextFileAction(new SliceToTextFileExporter(myBuilder, UsageViewSettings.getInstance()))); //actionGroup.add(new ContextHelpAction(HELP_ID)); diff --git a/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java b/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java index 7c08bf71fe26..901b1470cd13 100644 --- a/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java +++ b/platform/lang-impl/src/com/intellij/slicer/SliceToTextFileExporter.java @@ -15,10 +15,12 @@ import java.util.List; */ public class SliceToTextFileExporter implements ExporterToTextFile { private final SliceTreeBuilder myBuilder; + @NotNull private final UsageViewSettings myUsageViewSettings; private String myLineSeparator = SystemProperties.getLineSeparator(); - public SliceToTextFileExporter(SliceTreeBuilder builder) { + public SliceToTextFileExporter(@NotNull SliceTreeBuilder builder, @NotNull UsageViewSettings usageViewSettings) { myBuilder = builder; + myUsageViewSettings = usageViewSettings; } @NotNull @@ -50,12 +52,12 @@ public class SliceToTextFileExporter implements ExporterToTextFile { @NotNull @Override public String getDefaultFilePath() { - return UsageViewSettings.getInstance().getExportFileName(); + return myUsageViewSettings.getExportFileName(); } @Override public void exportedTo(@NotNull String filePath) { - UsageViewSettings.getInstance().setExportFileName(filePath); + myUsageViewSettings.setExportFileName(filePath); } @Override diff --git a/platform/usageView/src/com/intellij/usages/UsageView.java b/platform/usageView/src/com/intellij/usages/UsageView.java index b34a397609d5..0a1fefe24afb 100644 --- a/platform/usageView/src/com/intellij/usages/UsageView.java +++ b/platform/usageView/src/com/intellij/usages/UsageView.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2017 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages; @@ -61,7 +49,7 @@ public interface UsageView extends Disposable { boolean isSearchInProgress(); /** - * @deprecated please specify mnemonic by prefixing the mnenonic character with an ampersand (&& for Mac-specific ampersands) + * @deprecated please specify mnemonic by prefixing the mnemonic character with an ampersand (&& for Mac-specific ampersands) */ void addButtonToLowerPane(@NotNull Runnable runnable, @NotNull String text, char mnemonic); void addButtonToLowerPane(@NotNull Runnable runnable, @NotNull String text); diff --git a/platform/usageView/src/com/intellij/usages/impl/FileStructureGroupRuleProvider.java b/platform/usageView/src/com/intellij/usages/impl/FileStructureGroupRuleProvider.java index a39705c69320..fb52130e3f41 100644 --- a/platform/usageView/src/com/intellij/usages/impl/FileStructureGroupRuleProvider.java +++ b/platform/usageView/src/com/intellij/usages/impl/FileStructureGroupRuleProvider.java @@ -1,29 +1,22 @@ /* - * Copyright 2000-2009 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ - package com.intellij.usages.impl; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; +import com.intellij.usages.UsageViewSettings; import com.intellij.usages.rules.UsageGroupingRule; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public interface FileStructureGroupRuleProvider { ExtensionPointName EP_NAME = new ExtensionPointName<>("com.intellij.fileStructureGroupRuleProvider"); @Nullable - UsageGroupingRule getUsageGroupingRule(final Project project); + UsageGroupingRule getUsageGroupingRule(@NotNull Project project); + + default UsageGroupingRule getUsageGroupingRule(@NotNull Project project, @NotNull UsageViewSettings usageViewSettings) { + return getUsageGroupingRule(project); + } } diff --git a/platform/usageView/src/com/intellij/usages/impl/PreviewUsageAction.java b/platform/usageView/src/com/intellij/usages/impl/PreviewUsageAction.java index 69240ca59c79..55a9681ed305 100644 --- a/platform/usageView/src/com/intellij/usages/impl/PreviewUsageAction.java +++ b/platform/usageView/src/com/intellij/usages/impl/PreviewUsageAction.java @@ -7,7 +7,6 @@ import com.intellij.icons.AllIcons; import com.intellij.openapi.util.text.StringUtil; import com.intellij.usageView.UsageViewBundle; import com.intellij.usages.UsageView; -import com.intellij.usages.UsageViewSettings; import org.jetbrains.annotations.NotNull; /** @@ -20,11 +19,11 @@ class PreviewUsageAction extends RuleAction { @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isPreviewUsages(); + return myView.getUsageViewSettings().isPreviewUsages(); } @Override protected void setOptionValue(final boolean value) { - UsageViewSettings.getInstance().setPreviewUsages(value); + myView.getUsageViewSettings().setPreviewUsages(value); } } diff --git a/platform/usageView/src/com/intellij/usages/impl/RuleAction.java b/platform/usageView/src/com/intellij/usages/impl/RuleAction.java index ce7ef7f933a7..fff032a7cd4c 100644 --- a/platform/usageView/src/com/intellij/usages/impl/RuleAction.java +++ b/platform/usageView/src/com/intellij/usages/impl/RuleAction.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.impl; @@ -29,7 +17,7 @@ import javax.swing.*; * @author Eugene Zhuravlev */ abstract class RuleAction extends ToggleAction implements DumbAware { - private final UsageViewImpl myView; + protected final UsageViewImpl myView; private boolean myState; RuleAction(@NotNull UsageView view, @NotNull String text, @NotNull Icon icon) { diff --git a/platform/usageView/src/com/intellij/usages/impl/SortMembersAlphabeticallyAction.java b/platform/usageView/src/com/intellij/usages/impl/SortMembersAlphabeticallyAction.java index 829f108ac2ec..9cb8854e9c00 100644 --- a/platform/usageView/src/com/intellij/usages/impl/SortMembersAlphabeticallyAction.java +++ b/platform/usageView/src/com/intellij/usages/impl/SortMembersAlphabeticallyAction.java @@ -5,23 +5,23 @@ package com.intellij.usages.impl; import com.intellij.icons.AllIcons; import com.intellij.usageView.UsageViewBundle; -import com.intellij.usages.UsageViewSettings; +import org.jetbrains.annotations.NotNull; /** * @author cdr */ class SortMembersAlphabeticallyAction extends RuleAction { - SortMembersAlphabeticallyAction(UsageViewImpl usageView) { + SortMembersAlphabeticallyAction(@NotNull UsageViewImpl usageView) { super(usageView, UsageViewBundle.message("sort.alphabetically.action.text"), AllIcons.ObjectBrowser.Sorted); } @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isSortAlphabetically(); + return myView.getUsageViewSettings().isSortAlphabetically(); } @Override protected void setOptionValue(final boolean value) { - UsageViewSettings.getInstance().setSortAlphabetically(value); + myView.getUsageViewSettings().setSortAlphabetically(value); } } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java index 48353b080566..d3e6bc3beca3 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageGroupingRuleProviderImpl.java @@ -28,7 +28,6 @@ import java.util.List; * @author max */ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider { - protected boolean supportsNonCodeRule() { return true; } @@ -41,29 +40,35 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider return true; } + @NotNull + @Override + public UsageGroupingRule[] getActiveRules(@NotNull Project project) { + return getActiveRules(project, UsageViewSettings.getInstance()); + } + @Override @NotNull - public UsageGroupingRule[] getActiveRules(Project project) { + public UsageGroupingRule[] getActiveRules(@NotNull Project project, @NotNull UsageViewSettings usageViewSettings) { List rules = new ArrayList<>(); if (supportsNonCodeRule()) { rules.add(new NonCodeUsageGroupingRule(project)); } - if (supportsScopesRule() && UsageViewSettings.getInstance().isGroupByScope()) { + if (supportsScopesRule() && usageViewSettings.isGroupByScope()) { rules.add(new UsageScopeGroupingRule()); } - if (UsageViewSettings.getInstance().isGroupByUsageType()) { + if (usageViewSettings.isGroupByUsageType()) { rules.add(new UsageTypeGroupingRule()); } - if (supportsModuleRule() && UsageViewSettings.getInstance().isGroupByModule()) { - rules.add(new ModuleGroupingRule(project, UsageViewSettings.getInstance().isFlattenModules())); + if (supportsModuleRule() && usageViewSettings.isGroupByModule()) { + rules.add(new ModuleGroupingRule(project, usageViewSettings.isFlattenModules())); } - if (UsageViewSettings.getInstance().isGroupByPackage()) { + if (usageViewSettings.isGroupByPackage()) { rules.add(DirectoryGroupingRule.getInstance(project)); } - if (UsageViewSettings.getInstance().isGroupByFileStructure()) { + if (usageViewSettings.isGroupByFileStructure()) { FileStructureGroupRuleProvider[] providers = Extensions.getExtensions(FileStructureGroupRuleProvider.EP_NAME); for (FileStructureGroupRuleProvider ruleProvider : providers) { - ContainerUtil.addIfNotNull(rules, ruleProvider.getUsageGroupingRule(project)); + ContainerUtil.addIfNotNull(rules, ruleProvider.getUsageGroupingRule(project, usageViewSettings)); } } else { @@ -131,11 +136,11 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider } @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isGroupByUsageType(); + return myView.getUsageViewSettings().isGroupByUsageType(); } @Override protected void setOptionValue(boolean value) { - UsageViewSettings.getInstance().setGroupByUsageType(value); + myView.getUsageViewSettings().setGroupByUsageType(value); } } @@ -145,11 +150,11 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider } @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isGroupByScope(); + return myView.getUsageViewSettings().isGroupByScope(); } @Override protected void setOptionValue(boolean value) { - UsageViewSettings.getInstance().setGroupByScope(value); + myView.getUsageViewSettings().setGroupByScope(value); } } @@ -160,12 +165,12 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isGroupByModule(); + return myView.getUsageViewSettings().isGroupByModule(); } @Override protected void setOptionValue(boolean value) { - UsageViewSettings.getInstance().setGroupByModule(value); + myView.getUsageViewSettings().setGroupByModule(value); } } @@ -176,18 +181,18 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isFlattenModules(); + return myView.getUsageViewSettings().isFlattenModules(); } @Override protected void setOptionValue(boolean value) { - UsageViewSettings.getInstance().setFlattenModules(value); + myView.getUsageViewSettings().setFlattenModules(value); } @Override public void update(@NotNull AnActionEvent e) { super.update(e); - e.getPresentation().setEnabled(UsageViewSettings.getInstance().isGroupByModule()); + e.getPresentation().setEnabled(myView.getUsageViewSettings().isGroupByModule()); } } @@ -197,11 +202,11 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider } @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isGroupByPackage(); + return myView.getUsageViewSettings().isGroupByPackage(); } @Override protected void setOptionValue(boolean value) { - UsageViewSettings.getInstance().setGroupByPackage(value); + myView.getUsageViewSettings().setGroupByPackage(value); } } @@ -211,11 +216,11 @@ public class UsageGroupingRuleProviderImpl implements UsageGroupingRuleProvider } @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isGroupByFileStructure(); + return myView.getUsageViewSettings().isGroupByFileStructure(); } @Override protected void setOptionValue(boolean value) { - UsageViewSettings.getInstance().setGroupByFileStructure(value); + myView.getUsageViewSettings().setGroupByFileStructure(value); } } } diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java index 3ca6cc935990..52aa1eeda481 100644 --- a/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java +++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewImpl.java @@ -103,7 +103,7 @@ public class UsageViewImpl implements UsageView { private final Project myProject; private volatile boolean mySearchInProgress = true; - private final ExporterToTextFile myTextFileExporter = new ExporterToTextFile(this, UsageViewSettings.getInstance()); + private final ExporterToTextFile myTextFileExporter = new ExporterToTextFile(this, getUsageViewSettings()); private final Alarm myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); private final ExclusionHandler myExclusionHandler; @@ -181,7 +181,7 @@ public class UsageViewImpl implements UsageView { UsageModelTracker myModelTracker = new UsageModelTracker(project); Disposer.register(this, myModelTracker); - myBuilder = new UsageNodeTreeBuilder(myTargets, getActiveGroupingRules(project), getActiveFilteringRules(project), myRoot, myProject); + myBuilder = new UsageNodeTreeBuilder(myTargets, getActiveGroupingRules(project, getUsageViewSettings()), getActiveFilteringRules(project), myRoot, myProject); final MessageBusConnection messageBusConnection = myProject.getMessageBus().connect(this); messageBusConnection.subscribe(UsageFilteringRuleProvider.RULES_CHANGED, this::rulesChanged); @@ -347,6 +347,10 @@ public class UsageViewImpl implements UsageView { }; } + public UsageViewSettings getUsageViewSettings() { + return UsageViewSettings.getInstance(); + } + // nodes just changed: parent node -> changed child // this collection is needed for firing javax.swing.tree.DefaultTreeModel.nodesChanged() events in batch // has to be linked because events for child nodes should be fired after events for parent nodes @@ -504,8 +508,8 @@ public class UsageViewImpl implements UsageView { myCentralPanel.add(myPreviewSplitter, BorderLayout.CENTER); - if (UsageViewSettings.getInstance().isPreviewUsages()) { - myPreviewSplitter.setProportion(UsageViewSettings.getInstance().getPreviewUsagesSplitterProportion()); + if (getUsageViewSettings().isPreviewUsages()) { + myPreviewSplitter.setProportion(getUsageViewSettings().getPreviewUsagesSplitterProportion()); treePane.putClientProperty(UIUtil.KEEP_BORDER_SIDES, SideBorder.RIGHT); final JBTabbedPane tabbedPane = new JBTabbedPane(SwingConstants.BOTTOM){ @NotNull @@ -580,11 +584,11 @@ public class UsageViewImpl implements UsageView { } @NotNull - private static UsageGroupingRule[] getActiveGroupingRules(@NotNull final Project project) { + private static UsageGroupingRule[] getActiveGroupingRules(@NotNull final Project project, @NotNull UsageViewSettings usageViewSettings) { final UsageGroupingRuleProvider[] providers = Extensions.getExtensions(UsageGroupingRuleProvider.EP_NAME); List list = new ArrayList<>(providers.length); for (UsageGroupingRuleProvider provider : providers) { - ContainerUtil.addAll(list, provider.getActiveRules(project)); + ContainerUtil.addAll(list, provider.getActiveRules(project, usageViewSettings)); } Collections.sort(list, Comparator.comparingInt(UsageGroupingRule::getRank)); @@ -740,7 +744,7 @@ public class UsageViewImpl implements UsageView { @Override public void expandAll() { UsageViewImpl.this.expandAll(); - UsageViewSettings.getInstance().setExpanded(true); + getUsageViewSettings().setExpanded(true); } @Override @@ -751,7 +755,7 @@ public class UsageViewImpl implements UsageView { @Override public void collapseAll() { UsageViewImpl.this.collapseAll(); - UsageViewSettings.getInstance().setExpanded(false); + getUsageViewSettings().setExpanded(false); } @Override @@ -783,7 +787,7 @@ public class UsageViewImpl implements UsageView { collapseAllAction, actionsManager.createPrevOccurenceAction(myRootPanel), actionsManager.createNextOccurenceAction(myRootPanel), - actionsManager.installAutoscrollToSourceHandler(myProject, myTree, new MyAutoScrollToSourceOptionProvider()), + actionsManager.installAutoscrollToSourceHandler(myProject, myTree, new MyAutoScrollToSourceOptionProvider(getUsageViewSettings())), actionsManager.createExportToTextFileAction(myTextFileExporter) }; } @@ -892,7 +896,7 @@ public class UsageViewImpl implements UsageView { Collections.sort(allUsages, USAGE_COMPARATOR); final Set excludedUsages = getExcludedUsages(); reset(); - myBuilder.setGroupingRules(getActiveGroupingRules(myProject)); + myBuilder.setGroupingRules(getActiveGroupingRules(myProject, getUsageViewSettings())); myBuilder.setFilteringRules(getActiveFilteringRules(myProject)); ApplicationManager.getApplication().runReadAction(() -> { for (Usage usage : allUsages) { @@ -1038,12 +1042,12 @@ public class UsageViewImpl implements UsageView { @Override protected boolean getOptionValue() { - return UsageViewSettings.getInstance().isFilterDuplicatedLine(); + return getUsageViewSettings().isFilterDuplicatedLine(); } @Override protected void setOptionValue(boolean value) { - UsageViewSettings.getInstance().setFilterDuplicatedLine(value); + getUsageViewSettings().setFilterDuplicatedLine(value); } } @@ -1268,7 +1272,7 @@ public class UsageViewImpl implements UsageView { } private void saveSplitterProportions() { - UsageViewSettings.getInstance().setPreviewUsagesSplitterProportion(myPreviewSplitter.getProportion()); + getUsageViewSettings().setPreviewUsagesSplitterProportion(myPreviewSplitter.getProportion()); } @Override @@ -1314,7 +1318,7 @@ public class UsageViewImpl implements UsageView { return; } showNode(firstUsageNode); - if (UsageViewSettings.getInstance().isExpanded() && myUsageNodes.size() < 10000) { + if (getUsageViewSettings().isExpanded() && myUsageNodes.size() < 10000) { expandAll(); } }); @@ -1765,14 +1769,20 @@ public class UsageViewImpl implements UsageView { } private static class MyAutoScrollToSourceOptionProvider implements AutoScrollToSourceOptionProvider { + @NotNull private final UsageViewSettings myUsageViewSettings; + + public MyAutoScrollToSourceOptionProvider(@NotNull UsageViewSettings usageViewSettings) { + myUsageViewSettings = usageViewSettings; + } + @Override public boolean isAutoScrollMode() { - return UsageViewSettings.getInstance().isAutoScrollToSource(); + return myUsageViewSettings.isAutoScrollToSource(); } @Override public void setAutoScrollMode(boolean state) { - UsageViewSettings.getInstance().setAutoScrollToSource(state); + myUsageViewSettings.setAutoScrollToSource(state); } } @@ -1940,7 +1950,7 @@ public class UsageViewImpl implements UsageView { } private boolean isFilterDuplicateLines() { - return myPresentation.isMergeDupLinesAvailable() && UsageViewSettings.getInstance().isFilterDuplicatedLine(); + return myPresentation.isMergeDupLinesAvailable() && getUsageViewSettings().isFilterDuplicatedLine(); } public Usage getNextToSelect(@NotNull Usage toDelete) { diff --git a/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRuleProvider.java b/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRuleProvider.java index 0c8e53fff250..d9c779a19d43 100644 --- a/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRuleProvider.java +++ b/platform/usageView/src/com/intellij/usages/impl/rules/FileGroupingRuleProvider.java @@ -1,30 +1,19 @@ /* - * Copyright 2000-2011 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.impl.rules; import com.intellij.openapi.project.Project; import com.intellij.usages.impl.FileStructureGroupRuleProvider; import com.intellij.usages.rules.UsageGroupingRule; +import org.jetbrains.annotations.NotNull; /** * @author yole */ public class FileGroupingRuleProvider implements FileStructureGroupRuleProvider { @Override - public UsageGroupingRule getUsageGroupingRule(Project project) { + public UsageGroupingRule getUsageGroupingRule(@NotNull Project project) { return new FileGroupingRule(project); } } diff --git a/platform/usageView/src/com/intellij/usages/rules/UsageGroupingRuleProvider.java b/platform/usageView/src/com/intellij/usages/rules/UsageGroupingRuleProvider.java index 5ae0b562d012..90c58992210b 100644 --- a/platform/usageView/src/com/intellij/usages/rules/UsageGroupingRuleProvider.java +++ b/platform/usageView/src/com/intellij/usages/rules/UsageGroupingRuleProvider.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2009 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.usages.rules; @@ -19,6 +7,7 @@ import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.project.Project; import com.intellij.usages.UsageView; +import com.intellij.usages.UsageViewSettings; import org.jetbrains.annotations.NotNull; /** @@ -27,7 +16,11 @@ import org.jetbrains.annotations.NotNull; public interface UsageGroupingRuleProvider { ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.usageGroupingRuleProvider"); - @NotNull UsageGroupingRule[] getActiveRules(Project project); + @NotNull UsageGroupingRule[] getActiveRules(@NotNull Project project); + + default @NotNull UsageGroupingRule[] getActiveRules(@NotNull Project project, @NotNull UsageViewSettings usageViewSettings) { + return getActiveRules(project); + } @NotNull AnAction[] createGroupingActions(UsageView view); diff --git a/python/src/com/jetbrains/python/findUsages/PyClassGroupingRuleProvider.java b/python/src/com/jetbrains/python/findUsages/PyClassGroupingRuleProvider.java index dfd8a78659cb..64550fa1c8a7 100644 --- a/python/src/com/jetbrains/python/findUsages/PyClassGroupingRuleProvider.java +++ b/python/src/com/jetbrains/python/findUsages/PyClassGroupingRuleProvider.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.jetbrains.python.findUsages; @@ -34,7 +22,7 @@ import org.jetbrains.annotations.Nullable; * @author yole */ public class PyClassGroupingRuleProvider implements FileStructureGroupRuleProvider { - public UsageGroupingRule getUsageGroupingRule(Project project) { + public UsageGroupingRule getUsageGroupingRule(@NotNull Project project) { return new PyClassGroupingRule(); } diff --git a/python/src/com/jetbrains/python/findUsages/PyFunctionGroupingRuleProvider.java b/python/src/com/jetbrains/python/findUsages/PyFunctionGroupingRuleProvider.java index bb8c560f0749..2454d12f541c 100644 --- a/python/src/com/jetbrains/python/findUsages/PyFunctionGroupingRuleProvider.java +++ b/python/src/com/jetbrains/python/findUsages/PyFunctionGroupingRuleProvider.java @@ -1,17 +1,5 @@ /* - * Copyright 2000-2014 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.jetbrains.python.findUsages; @@ -35,7 +23,7 @@ import org.jetbrains.annotations.Nullable; * @author yole */ public class PyFunctionGroupingRuleProvider implements FileStructureGroupRuleProvider { - public UsageGroupingRule getUsageGroupingRule(Project project) { + public UsageGroupingRule getUsageGroupingRule(@NotNull Project project) { return new PyFunctionGroupingRule(); } From 419afe39171df4f5c601e7f0309930a749ab0cf0 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 21 Dec 2017 12:19:58 +0100 Subject: [PATCH 43/58] =?UTF-8?q?UsageViewSettings=20=E2=80=94=20restore?= =?UTF-8?q?=20compatibility?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/intellij/usages/UsageViewSettings.kt | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt b/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt index bb79bc4d9e72..db5e6f5a7c7a 100644 --- a/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt +++ b/platform/usageView/src/com/intellij/usages/UsageViewSettings.kt @@ -25,6 +25,36 @@ open class UsageViewSettings( get() = ServiceManager.getService(UsageViewSettings::class.java) } + @Suppress("unused") + @JvmField + @Transient + @Deprecated(message = "Use isGroupByModule") + var GROUP_BY_MODULE = isGroupByModule + + @Suppress("unused") + @JvmField + @Transient + @Deprecated(message = "Use isGroupByUsageType") + var GROUP_BY_USAGE_TYPE = isGroupByUsageType + + @Suppress("unused") + @JvmField + @Transient + @Deprecated(message = "Use isGroupByFileStructure") + var GROUP_BY_FILE_STRUCTURE = isGroupByFileStructure + + @Suppress("unused") + @JvmField + @Transient + @Deprecated(message = "Use isGroupByScope") + var GROUP_BY_SCOPE = isGroupByScope + + @Suppress("unused") + @JvmField + @Transient + @Deprecated(message = "Use isGroupByPackage") + var GROUP_BY_PACKAGE = isGroupByPackage + @Suppress("MemberVisibilityCanPrivate") @get:OptionTag("EXPORT_FILE_NAME") internal var EXPORT_FILE_NAME by property("report.txt") @@ -77,7 +107,13 @@ open class UsageViewSettings( override fun getState() = this + @Suppress("DEPRECATION") override fun loadState(state: UsageViewSettings) { copyFrom(state) + GROUP_BY_MODULE = isGroupByModule + GROUP_BY_USAGE_TYPE = isGroupByUsageType + GROUP_BY_FILE_STRUCTURE = isGroupByFileStructure + GROUP_BY_SCOPE = isGroupByScope + GROUP_BY_PACKAGE = isGroupByPackage } } From b36cbf150726373ae352f5d502b0b7b0d6f739c4 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 20 Dec 2017 18:41:26 +0300 Subject: [PATCH 44/58] setFraction makes sense only for determinate progress indicator --- .../com/jetbrains/python/console/PydevConsoleCommunication.java | 1 + 1 file changed, 1 insertion(+) diff --git a/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java b/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java index 7d6d0295dabc..ce636e5447a8 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java +++ b/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java @@ -480,6 +480,7 @@ public class PydevConsoleCommunication extends AbstractConsoleCommunication impl ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> { final ProgressIndicator progressIndicator = ProgressManager.getInstance().getProgressIndicator(); progressIndicator.setText("Waiting for REPL response with " + (int)(TIMEOUT / 10e8) + "s timeout"); + progressIndicator.setIndeterminate(false); final long startTime = System.nanoTime(); while (nextResponse == null) { if (progressIndicator.isCanceled()) { From 05b0c625cfdb10439eaad7e63c66e61e6c8e7806 Mon Sep 17 00:00:00 2001 From: Ekaterina Tuzova Date: Wed, 20 Dec 2017 18:42:02 +0300 Subject: [PATCH 45/58] ConnectionRefusedError is not available in python2 --- python/helpers/pycharm_matplotlib_backend/backend_interagg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/helpers/pycharm_matplotlib_backend/backend_interagg.py b/python/helpers/pycharm_matplotlib_backend/backend_interagg.py index 317d9b86d622..1c70df0ab5ad 100644 --- a/python/helpers/pycharm_matplotlib_backend/backend_interagg.py +++ b/python/helpers/pycharm_matplotlib_backend/backend_interagg.py @@ -86,7 +86,7 @@ class FigureCanvasInterAgg(FigureCanvasAgg): sock.send(struct.pack('>i', plot_index)) sock.send(struct.pack('>i', len(buffer))) sock.send(buffer) - except ConnectionRefusedError as _: + except OSError as _: # nothing bad. It just means, that our tool window doesn't run yet pass From a69ef6b1de3ed33df76002e86a7086a142dd43ca Mon Sep 17 00:00:00 2001 From: Semyon Kolton Date: Thu, 21 Dec 2017 12:06:03 +0300 Subject: [PATCH 46/58] Fix EnvironmentUtil.inlineParentOccurrences() for Windows (ignore case) --- .../com/intellij/util/EnvironmentUtil.java | 31 +++++++++--- .../intellij/util/EnvironmentUtilTest.java | 50 +++++++++++++++++++ 2 files changed, 73 insertions(+), 8 deletions(-) diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java index 55e9a9bd2977..6b7a47bf5a95 100644 --- a/platform/util/src/com/intellij/util/EnvironmentUtil.java +++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java @@ -54,6 +54,13 @@ public class EnvironmentUtil { private static final Future> ourEnvGetter; + /** + * String that is used as a delimiter for referencing parent environment variable. + * "%" on Microsoft Windows; + * "$" on Unix systems + */ + public static final String PARENT_ENV_KEY_DELIMITER = SystemInfo.isWindows ? "%" : "$"; + static { if (SystemInfo.isMac && "unlocked".equals(System.getProperty("__idea.mac.env.lock")) && @@ -374,7 +381,7 @@ public class EnvironmentUtil { } public static void inlineParentOccurrences(@NotNull Map envs) { - inlineParentOccurrences(envs, new HashMap(System.getenv())); + inlineParentOccurrences(envs, getEnvironmentMap()); } public static void inlineParentOccurrences(@NotNull Map envs, @NotNull Map parentEnv) { @@ -382,18 +389,26 @@ public class EnvironmentUtil { String key = entry.getKey(); String value = entry.getValue(); if (value != null) { - String parentVal = parentEnv.get(key); - if (parentVal != null && containsEnvKeySubstitution(key, value)) { - envs.put(key, value.replace("$" + key + "$", parentVal)); + final String parentVal = parentEnv.get(key); + if (parentVal != null) { + StringBuilder newValue = new StringBuilder(); + final String keySubstitution = PARENT_ENV_KEY_DELIMITER + key + PARENT_ENV_KEY_DELIMITER; + for (String part : StringUtil.split(value, File.pathSeparator)) { + if (SystemInfo.isWindows) { + newValue.append(part.equalsIgnoreCase(keySubstitution) ? parentVal : part); + } + else { + newValue.append(part.equals(keySubstitution) ? parentVal : part); + } + newValue.append(File.pathSeparator); + } + newValue.trimToSize(); + envs.put(key, newValue.substring(0, newValue.length() - File.pathSeparator.length())); } } } } - private static boolean containsEnvKeySubstitution(final String envKey, final String val) { - return ArrayUtil.find(val.split(File.pathSeparator), "$" + envKey + "$") != -1; - } - @TestOnly static Map testLoader() { try { diff --git a/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java b/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java index 17afc9565792..b2aa057c93b1 100644 --- a/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java @@ -3,6 +3,9 @@ package com.intellij.util; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.text.CaseInsensitiveStringHashingStrategy; +import org.jetbrains.annotations.NotNull; import org.junit.Test; import java.io.File; @@ -46,6 +49,53 @@ public class EnvironmentUtilTest { } } + @Test + public void inlineParentOccurrences() { + Map parentEnv = SystemInfo.isWindows ? + ContainerUtil.newTroveMap(CaseInsensitiveStringHashingStrategy.INSTANCE) : + ContainerUtil.newHashMap(); + parentEnv.put("Foo", "foo/bar"); + parentEnv.put("smth", "another()thing"); + parentEnv.put("tmp", "tempo#rary"); + parentEnv.put("123", "50m37h1ng"); + + Map childEnv = ContainerUtil.newHashMap(); + childEnv.put("no parent", "no parent indeed"); + childEnv.put("Foo", "have parent but no parent reference"); + childEnv.put("smth", "have parent and reference" + File.pathSeparator + + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "smth" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + + File.pathSeparator + "flavor text"); + childEnv.put("TMP", "case sensitive" + + File.pathSeparator + + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "Tmp" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER); + + EnvironmentUtil.inlineParentOccurrences(childEnv, parentEnv); + + assertEnvVariable(childEnv, "no parent", "no parent indeed"); + assertEnvVariable(childEnv, "Foo", "have parent but no parent reference"); + assertEnvVariable(childEnv, "smth", "have parent and reference" + File.pathSeparator + + "another()thing" + + File.pathSeparator + "flavor text"); + if (SystemInfo.isWindows) { + assertEnvVariable(childEnv, "TMP", "case sensitive" + + File.pathSeparator + "tempo#rary"); + } + else { + assertEnvVariable(childEnv, "TMP", "case sensitive" + + File.pathSeparator + + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "Tmp" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER); + } + assertNull(childEnv.get("123")); + } + + private static void assertEnvVariable(@NotNull Map env, + @NotNull String expectedKey, + @NotNull String expectedValue) { + String actualValue = env.get(expectedKey); + assertNotNull(actualValue); + assertEquals(expectedValue, actualValue); + } + @Test(timeout = 30000) public void load() { assumeTrue(SystemInfo.isUnix); From 55a6a48d94be298b21da8f35cc521a89d6f87011 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 21 Dec 2017 12:55:28 +0100 Subject: [PATCH 47/58] cleanup --- .../ide/projectView/impl/ProjectViewImpl.java | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index b64b03afbab7..9db35eddc8f4 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -129,7 +129,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo private final Map myAutoscrollToSource = new THashMap<>(); private final Map myAutoscrollFromSource = new THashMap<>(); private static final boolean ourAutoscrollFromSourceDefaults = false; - + private boolean myFoldersAlwaysOnTop = true; private String myCurrentViewId; @@ -171,7 +171,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo private static final String ATTRIBUTE_ID = "id"; private JPanel myViewContentPanel; - private static final Comparator PANE_WEIGHT_COMPARATOR = (o1, o2) -> o1.getWeight() - o2.getWeight(); + private static final Comparator PANE_WEIGHT_COMPARATOR = Comparator.comparingInt(AbstractProjectViewPane::getWeight); private final FileEditorManager myFileEditorManager; private final MyPanel myDataProvider; private final SplitterProportionsData splitterProportions = new SplitterProportionsDataImpl(); @@ -611,10 +611,10 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo } @Override - public void update(AnActionEvent e) { + public void update(@NotNull AnActionEvent e) { super.update(e); - final Presentation presentation = e.getPresentation(); - presentation.setVisible(isFlattenPackages(myCurrentViewId)); + + e.getPresentation().setVisible(isFlattenPackages(myCurrentViewId)); } } if (ProjectViewDirectoryHelper.getInstance(myProject).supportsHideEmptyMiddlePackages()) { @@ -1117,7 +1117,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo if (PlatformDataKeys.HELP_ID.is(dataId)) { return HelpID.PROJECT_VIEWS; } - if (ProjectViewImpl.DATA_KEY.is(dataId)) { + if (DATA_KEY.is(dataId)) { return ProjectViewImpl.this; } if (PlatformDataKeys.PROJECT_CONTEXT.is(dataId)) { @@ -1276,7 +1276,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo } } - /** Project view has the same node for module and its single content root + /** Project view has the same node for module and its single content root * => MODULE_CONTEXT data key should return the module when its content root is selected * When there are multiple content roots, they have different nodes under the module node * => MODULE_CONTEXT should be only available for the module node @@ -1413,12 +1413,11 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo Element foldersElement = navigatorElement.getChild(ELEMENT_FOLDERS_ALWAYS_ON_TOP); if (foldersElement != null) myFoldersAlwaysOnTop = Boolean.valueOf(foldersElement.getAttributeValue("value")); - + try { splitterProportions.readExternal(navigatorElement); } - catch (InvalidDataException e) { - // ignore + catch (InvalidDataException ignored) { } } Element panesElement = parentNode.getChild(ELEMENT_PANES); @@ -1470,7 +1469,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo writeOption(navigatorElement, myAutoscrollFromSource, ELEMENT_AUTOSCROLL_FROM_SOURCE); writeOption(navigatorElement, mySortByType, ELEMENT_SORT_BY_TYPE); writeOption(navigatorElement, myManualOrder, ELEMENT_MANUAL_ORDER); - + Element foldersElement = new Element(ELEMENT_FOLDERS_ALWAYS_ON_TOP); foldersElement.setAttribute("value", Boolean.toString(myFoldersAlwaysOnTop)); navigatorElement.addContent(foldersElement); @@ -2002,7 +2001,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo } } } - + private class SortByTypeAction extends ToggleAction implements DumbAware { private SortByTypeAction() { super(IdeBundle.message("action.sort.by.type"), IdeBundle.message("action.sort.by.type"), AllIcons.ObjectBrowser.SortByType); From 4a7992ae84eecff5c1e409517fd7fc4553507a39 Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 21 Dec 2017 13:00:06 +0100 Subject: [PATCH 48/58] default impl of expandAll --- .../ide/projectView/impl/ProjectViewImpl.java | 5 ----- .../src/com/intellij/ide/TreeExpander.java | 20 ++++++------------- .../svn/dialogs/RepositoryBrowserDialog.java | 17 +--------------- 3 files changed, 7 insertions(+), 35 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index 9db35eddc8f4..c26ddfbee979 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -679,11 +679,6 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo titleActions.add(new ScrollFromSourceAction()); } AnAction collapseAllAction = CommonActionsManager.getInstance().createCollapseAllAction(new TreeExpander() { - @Override - public void expandAll() { - - } - @Override public boolean canExpand() { return false; diff --git a/platform/platform-api/src/com/intellij/ide/TreeExpander.java b/platform/platform-api/src/com/intellij/ide/TreeExpander.java index a1dc8a01f310..1b3b4f089075 100644 --- a/platform/platform-api/src/com/intellij/ide/TreeExpander.java +++ b/platform/platform-api/src/com/intellij/ide/TreeExpander.java @@ -1,23 +1,15 @@ /* - * Copyright 2000-2009 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package com.intellij.ide; public interface TreeExpander { - void expandAll(); + default void expandAll() { + } + boolean canExpand(); + void collapseAll(); + boolean canCollapse(); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java index 715987c2d30a..427550bdf22e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/dialogs/RepositoryBrowserDialog.java @@ -1,17 +1,5 @@ /* - * 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. + * Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. */ package org.jetbrains.idea.svn.dialogs; @@ -154,9 +142,6 @@ public class RepositoryBrowserDialog extends DialogWrapper { InputEvent.ALT_MASK | InputEvent.ALT_DOWN_MASK)), browser); AnAction action = CommonActionsManager.getInstance().createCollapseAllAction(new TreeExpander() { - public void expandAll() { - } - public boolean canExpand() { return false; } From 3c0fdc4e89433456fb8d0491f76a458d2f59e48b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Thu, 21 Dec 2017 13:02:23 +0100 Subject: [PATCH 49/58] =?UTF-8?q?quick=20fix=20of=20NPE=20=E2=80=94=20not-?= =?UTF-8?q?null=20panel=20expected,=20so,=20we=20should=20not=20use=20poss?= =?UTF-8?q?ible=20nullable=20field=20without=20fallback?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/com/intellij/ide/projectView/impl/ProjectViewImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java index c26ddfbee979..d48f60d29129 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ProjectViewImpl.java @@ -701,7 +701,7 @@ public class ProjectViewImpl extends ProjectView implements PersistentStateCompo collapseAllAction.getTemplatePresentation().setIcon(AllIcons.General.CollapseAll); collapseAllAction.getTemplatePresentation().setHoveredIcon(AllIcons.General.CollapseAllHover); titleActions.add(collapseAllAction); - getCurrentProjectViewPane().addToolbarActions(myActionGroup); + getProjectViewPaneById(myCurrentViewId == null ? ProjectViewPane.ID : myCurrentViewId).addToolbarActions(myActionGroup); ToolWindowEx window = (ToolWindowEx)ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.PROJECT_VIEW); if (window != null) { From 5806663661dc115c83ba13e157fbd4b87ea0ce3a Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 21 Dec 2017 13:14:44 +0100 Subject: [PATCH 50/58] java completion: put type above signature containing that type (IDEA-181329) --- .../codeInsight/completion/JavaCompletionSorting.java | 6 +++++- .../completion/JavaGenerateMemberCompletionContributor.java | 4 +++- .../normalSorting/PreferTypeToGeneratedMethod.java | 4 ++++ .../completion/NormalCompletionOrderingTest.groovy | 4 ++++ .../java/codeInsight/completion/NormalCompletionTest.groovy | 4 ++-- 5 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normalSorting/PreferTypeToGeneratedMethod.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java index aeb5cd20cd2e..725dd9685a49 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionSorting.java @@ -621,7 +621,11 @@ public class JavaCompletionSorting { @Override public boolean shouldLift(LookupElement shorterElement, LookupElement longerElement) { Object object = shorterElement.getObject(); - if (object instanceof PsiClass && longerElement.getObject() instanceof PsiClass) { + if (!(object instanceof PsiClass)) return false; + + if (longerElement.getUserData(JavaGenerateMemberCompletionContributor.GENERATE_ELEMENT) != null) return true; + + if (longerElement.getObject() instanceof PsiClass) { PsiClass psiClass = (PsiClass)object; PsiFile file = psiClass.getContainingFile(); if (file != null) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java index 60f6f68c70f5..d200b280161b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGenerateMemberCompletionContributor.java @@ -201,7 +201,8 @@ public class JavaGenerateMemberCompletionContributor { } PsiType type = substitutor.substitute(prototype.getReturnType()); - String signature = modifiers + (type == null ? "" : type.getPresentableText() + " ") + methodName; + String typeAndName = (type == null ? "" : type.getPresentableText() + " ") + methodName; + String signature = modifiers + typeAndName; String parameters = "(" + StringUtil.join(prototype.getParameterList().getParameters(), p -> getShortParameterName(substitutor, p) + " " + p.getName(), @@ -209,6 +210,7 @@ public class JavaGenerateMemberCompletionContributor { String overrideSignature = " @Override " + signature; // leading space to make it a middle match, under all annotation suggestions LookupElementBuilder element = LookupElementBuilder.create(prototype, signature).withLookupString(methodName). + withLookupString(typeAndName). withLookupString(signature).withLookupString(overrideSignature).withInsertHandler(insertHandler). appendTailText(parameters, false).appendTailText(" {...}", true).withTypeText(typeText).withIcon(icon); if (prototype.isDeprecated()) { diff --git a/java/java-tests/testData/codeInsight/completion/normalSorting/PreferTypeToGeneratedMethod.java b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferTypeToGeneratedMethod.java new file mode 100644 index 000000000000..dd88fb8b78f1 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normalSorting/PreferTypeToGeneratedMethod.java @@ -0,0 +1,4 @@ +class Foo { + private String zoo; + public Stri +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionOrderingTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionOrderingTest.groovy index 9ae118a03b6a..af9e031817e7 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionOrderingTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionOrderingTest.groovy @@ -824,4 +824,8 @@ class Foo { myFixture.assertPreferredCompletionItems 0, 'out', 'exit' } + void testPreferTypeToGeneratedMethod() { + checkPreferredItems 0, 'String', 'public String getZoo', 'public String toString' + } + } diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy index a462856892d4..f6f05ab6117a 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy @@ -1662,14 +1662,14 @@ class Bar { myFixture.configureByText('a.java', 'class Fooxxxxxxxxxx { Fooxxxxxa f;\n' + 'public void foo() {}\n' * 10000 + '}') def items = myFixture.completeBasic() - PsiClass c1 = items[0].object + PsiClass c1 = items[1].object assert !c1.physical assert CompletionUtil.getOriginalElement(c1) getLookup().hide() myFixture.type('x') items = myFixture.completeBasic() - PsiClass c2 = items[0].object + PsiClass c2 = items[1].object assert !c2.physical assert CompletionUtil.getOriginalElement(c2) From 3dbeaae3f700daa9b2781fecc5bae6f2d6f7b878 Mon Sep 17 00:00:00 2001 From: "Vladislav.Soroka" Date: Thu, 21 Dec 2017 15:36:12 +0300 Subject: [PATCH 51/58] Gradle: obsolete notice updated --- plugins/gradle/resources/i18n/GradleBundle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/gradle/resources/i18n/GradleBundle.properties b/plugins/gradle/resources/i18n/GradleBundle.properties index 5a409331efe9..4854aa1f017e 100644 --- a/plugins/gradle/resources/i18n/GradleBundle.properties +++ b/plugins/gradle/resources/i18n/GradleBundle.properties @@ -2,8 +2,8 @@ gradle.name=Gradle gradle.settings.text.use.default_wrapper.configured=Use default gradle wrapper (recommended) gradle.settings.text.use.default_wrapper.not_configured=Use default gradle wrapper (not configured for the current project) -gradle.settings.text.use.customizable_wrapper=Use gradle wrapper task configuration -gradle.settings.text.wrapper.customization.compatibility=Gradle wrapper customization in script, works with Gradle 1.7 or later +gradle.settings.text.use.customizable_wrapper=Use gradle 'wrapper' task configuration +gradle.settings.text.wrapper.customization.compatibility=Gradle wrapper customization in build script gradle.settings.text.use.local.distribution=Use local gradle distribution gradle.settings.text.use.bundled.distribution=Use bundled gradle distribution: ({0}) gradle.settings.text.create.module.per.sourceset=Create separate module per source set From 8e6aaba2c36af4993bf3845d2a7e31c9f6376f7b Mon Sep 17 00:00:00 2001 From: Artem Gainanov Date: Thu, 21 Dec 2017 20:01:56 +0700 Subject: [PATCH 52/58] [gui-test] tests for plugins. add regexp for path --- .../testGuiFramework/impl/GuiTestCase.kt | 3 ++- .../testCases/PluginTestCase.kt | 27 +++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt index 5677d2724d24..2c7f77a9da9b 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/impl/GuiTestCase.kt @@ -149,7 +149,7 @@ open class GuiTestCase { */ fun chooseFileInFileChooser(path: String, timeout: Long = defaultTimeout) { val macNativeFileChooser = SystemInfo.isMac() && (System.getProperty("ide.mac.file.chooser.native", "true").toLowerCase() == "true") - if (macNativeFileChooser) { + if (!macNativeFileChooser) { MacFileChooserDialogFixture(robot()).selectByPath(path) } else { @@ -170,6 +170,7 @@ open class GuiTestCase { } val dialogFixture = JDialogFixture(robot(), fileChooserDialog) with(dialogFixture) { + asyncProcessIcon().waitUntilStop(20) textfield("") invokeAction("\$SelectAll") typeText(path) diff --git a/platform/testGuiFramework/src/com/intellij/testGuiFramework/testCases/PluginTestCase.kt b/platform/testGuiFramework/src/com/intellij/testGuiFramework/testCases/PluginTestCase.kt index 107f17ee59c9..5354b530b5f5 100644 --- a/platform/testGuiFramework/src/com/intellij/testGuiFramework/testCases/PluginTestCase.kt +++ b/platform/testGuiFramework/src/com/intellij/testGuiFramework/testCases/PluginTestCase.kt @@ -25,6 +25,7 @@ import com.intellij.testGuiFramework.launcher.system.SystemInfo import com.intellij.testGuiFramework.remote.transport.MessageType import com.intellij.testGuiFramework.remote.transport.TransportMessage import org.fest.swing.exception.WaitTimedOutError +import java.io.File import javax.swing.JDialog open class PluginTestCase : GuiTestCase() { @@ -34,6 +35,23 @@ open class PluginTestCase : GuiTestCase() { private val WIN_PLUGIN_HOME = "/Users/jetbrains/Documents/plugins/" private val LINUX_PLUGIN_HOME = "/Users/jetbrains/Documents/plugins/" + private fun getPluginHomePath(): String { + return when { + SystemInfo.isMac() -> MAC_PLUGIN_HOME + SystemInfo.isWin() -> WIN_PLUGIN_HOME + else -> { + LINUX_PLUGIN_HOME + } + } + } + + fun findPlugin(pluginName: String): String { + val f = File(getPluginHomePath()) + return f.listFiles { _, name -> + name.startsWith(pluginName) + }[0].toString() + } + fun installPluginAndRestart(installPluginsFunction: () -> Unit) { val PLUGINS_INSTALLED = "PLUGINS_INSTALLED" if (guiTestRule.getTestName() == GuiTestOptions.getResumeTestName() && @@ -69,14 +87,7 @@ open class PluginTestCase : GuiTestCase() { } } - fun installPluginFromDisk(pluginDir: String, pluginName: String) { - var pluginPath: String = when { - SystemInfo.isMac() -> MAC_PLUGIN_HOME - SystemInfo.isWin() -> WIN_PLUGIN_HOME - else -> { - LINUX_PLUGIN_HOME - } - } + pluginDir + fun installPluginFromDisk(pluginPath: String, pluginName: String) { welcomeFrame { actionLink("Configure").click() popupClick("Plugins") From 687b0877334062dc8518a2772e43e539b02f98cf Mon Sep 17 00:00:00 2001 From: Semyon Kolton Date: Thu, 21 Dec 2017 16:29:46 +0300 Subject: [PATCH 53/58] Revert "Fix EnvironmentUtil.inlineParentOccurrences() for Windows (ignore case)" as it breaks clients This reverts commit a69ef6b --- .../com/intellij/util/EnvironmentUtil.java | 31 +++--------- .../intellij/util/EnvironmentUtilTest.java | 50 ------------------- 2 files changed, 8 insertions(+), 73 deletions(-) diff --git a/platform/util/src/com/intellij/util/EnvironmentUtil.java b/platform/util/src/com/intellij/util/EnvironmentUtil.java index 6b7a47bf5a95..55e9a9bd2977 100644 --- a/platform/util/src/com/intellij/util/EnvironmentUtil.java +++ b/platform/util/src/com/intellij/util/EnvironmentUtil.java @@ -54,13 +54,6 @@ public class EnvironmentUtil { private static final Future> ourEnvGetter; - /** - * String that is used as a delimiter for referencing parent environment variable. - * "%" on Microsoft Windows; - * "$" on Unix systems - */ - public static final String PARENT_ENV_KEY_DELIMITER = SystemInfo.isWindows ? "%" : "$"; - static { if (SystemInfo.isMac && "unlocked".equals(System.getProperty("__idea.mac.env.lock")) && @@ -381,7 +374,7 @@ public class EnvironmentUtil { } public static void inlineParentOccurrences(@NotNull Map envs) { - inlineParentOccurrences(envs, getEnvironmentMap()); + inlineParentOccurrences(envs, new HashMap(System.getenv())); } public static void inlineParentOccurrences(@NotNull Map envs, @NotNull Map parentEnv) { @@ -389,26 +382,18 @@ public class EnvironmentUtil { String key = entry.getKey(); String value = entry.getValue(); if (value != null) { - final String parentVal = parentEnv.get(key); - if (parentVal != null) { - StringBuilder newValue = new StringBuilder(); - final String keySubstitution = PARENT_ENV_KEY_DELIMITER + key + PARENT_ENV_KEY_DELIMITER; - for (String part : StringUtil.split(value, File.pathSeparator)) { - if (SystemInfo.isWindows) { - newValue.append(part.equalsIgnoreCase(keySubstitution) ? parentVal : part); - } - else { - newValue.append(part.equals(keySubstitution) ? parentVal : part); - } - newValue.append(File.pathSeparator); - } - newValue.trimToSize(); - envs.put(key, newValue.substring(0, newValue.length() - File.pathSeparator.length())); + String parentVal = parentEnv.get(key); + if (parentVal != null && containsEnvKeySubstitution(key, value)) { + envs.put(key, value.replace("$" + key + "$", parentVal)); } } } } + private static boolean containsEnvKeySubstitution(final String envKey, final String val) { + return ArrayUtil.find(val.split(File.pathSeparator), "$" + envKey + "$") != -1; + } + @TestOnly static Map testLoader() { try { diff --git a/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java b/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java index b2aa057c93b1..17afc9565792 100644 --- a/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java +++ b/platform/util/testSrc/com/intellij/util/EnvironmentUtilTest.java @@ -3,9 +3,6 @@ package com.intellij.util; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.io.FileUtil; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.text.CaseInsensitiveStringHashingStrategy; -import org.jetbrains.annotations.NotNull; import org.junit.Test; import java.io.File; @@ -49,53 +46,6 @@ public class EnvironmentUtilTest { } } - @Test - public void inlineParentOccurrences() { - Map parentEnv = SystemInfo.isWindows ? - ContainerUtil.newTroveMap(CaseInsensitiveStringHashingStrategy.INSTANCE) : - ContainerUtil.newHashMap(); - parentEnv.put("Foo", "foo/bar"); - parentEnv.put("smth", "another()thing"); - parentEnv.put("tmp", "tempo#rary"); - parentEnv.put("123", "50m37h1ng"); - - Map childEnv = ContainerUtil.newHashMap(); - childEnv.put("no parent", "no parent indeed"); - childEnv.put("Foo", "have parent but no parent reference"); - childEnv.put("smth", "have parent and reference" + File.pathSeparator + - EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "smth" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + - File.pathSeparator + "flavor text"); - childEnv.put("TMP", "case sensitive" + - File.pathSeparator + - EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "Tmp" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER); - - EnvironmentUtil.inlineParentOccurrences(childEnv, parentEnv); - - assertEnvVariable(childEnv, "no parent", "no parent indeed"); - assertEnvVariable(childEnv, "Foo", "have parent but no parent reference"); - assertEnvVariable(childEnv, "smth", "have parent and reference" + File.pathSeparator + - "another()thing" + - File.pathSeparator + "flavor text"); - if (SystemInfo.isWindows) { - assertEnvVariable(childEnv, "TMP", "case sensitive" + - File.pathSeparator + "tempo#rary"); - } - else { - assertEnvVariable(childEnv, "TMP", "case sensitive" + - File.pathSeparator + - EnvironmentUtil.PARENT_ENV_KEY_DELIMITER + "Tmp" + EnvironmentUtil.PARENT_ENV_KEY_DELIMITER); - } - assertNull(childEnv.get("123")); - } - - private static void assertEnvVariable(@NotNull Map env, - @NotNull String expectedKey, - @NotNull String expectedValue) { - String actualValue = env.get(expectedKey); - assertNotNull(actualValue); - assertEquals(expectedValue, actualValue); - } - @Test(timeout = 30000) public void load() { assumeTrue(SystemInfo.isUnix); From bc917088bfb0fdc18e8c606a224e099bfaace5c2 Mon Sep 17 00:00:00 2001 From: Dmitry Batkovich Date: Thu, 21 Dec 2017 12:48:29 +0300 Subject: [PATCH 54/58] properties: do not add redundant "_" to suffix --- .../com/intellij/lang/properties/PropertiesUtil.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java index 2f90e88e033d..a910caaf60b9 100644 --- a/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java +++ b/plugins/properties/properties-psi-api/src/com/intellij/lang/properties/PropertiesUtil.java @@ -152,7 +152,16 @@ public class PropertiesUtil { final String language = splitRawLocale[1]; final String country = splitRawLocale.length > 2 ? splitRawLocale[2] : ""; final String variant = splitRawLocale.length > 3 ? splitRawLocale[3] : ""; - return Pair.create(new Locale(language, country, variant), language + "_" + country + "_" + variant); + + StringBuilder trimmedSuffix = new StringBuilder(language); + if (!country.isEmpty()) { + trimmedSuffix.append("_").append(country); + } + if (!variant.isEmpty()) { + trimmedSuffix.append("_").append(variant); + } + + return Pair.create(new Locale(language, country, variant), trimmedSuffix.toString()); } } return Pair.create(DEFAULT_LOCALE, ""); From e678db4ef294d85c8dcf387680529482eecc8263 Mon Sep 17 00:00:00 2001 From: Rustam Vishnyakov Date: Thu, 21 Dec 2017 16:51:13 +0300 Subject: [PATCH 55/58] Increase max allowed continuation indent size (see IDEA-183665) --- .../src/com/intellij/psi/codeStyle/CodeStyleConstraints.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleConstraints.java b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleConstraints.java index a4a4fbd67cba..ede0c2f9c9ec 100644 --- a/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleConstraints.java +++ b/platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleConstraints.java @@ -18,7 +18,7 @@ package com.intellij.psi.codeStyle; public interface CodeStyleConstraints { int MAX_RIGHT_MARGIN = 1000; int MIN_INDENT_SIZE = 0; - int MAX_INDENT_SIZE = 16; + int MAX_INDENT_SIZE = 32; int MIN_TAB_SIZE = 1; int MAX_TAB_SIZE = 16; } From 04c357661b81eccec8b24087cf6b31b4669efdb7 Mon Sep 17 00:00:00 2001 From: Konstantin Bulenkov Date: Thu, 21 Dec 2017 15:01:53 +0100 Subject: [PATCH 56/58] use fallback font for Splash screen --- .../src/com/intellij/ui/Splash.java | 31 ++----------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/Splash.java b/platform/platform-impl/src/com/intellij/ui/Splash.java index d516d967a305..195c732a6e9c 100644 --- a/platform/platform-impl/src/com/intellij/ui/Splash.java +++ b/platform/platform-impl/src/com/intellij/ui/Splash.java @@ -19,9 +19,6 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.awt.font.TextAttribute; -import java.text.AttributedCharacterIterator; -import java.text.AttributedString; import java.util.List; @@ -176,6 +173,7 @@ public class Splash extends JDialog implements StartupProgress { font = createFont(UIUtil.ARIAL_FONT_NAME); } + g.setFont(UIUtil.getFontWithFallback(font)); g.setColor(textColor); int offsetX = uiScale(15); int offsetY = 30; @@ -188,9 +186,9 @@ public class Splash extends JDialog implements StartupProgress { } } - g.drawString(wrapText(licensedToMessage, font), x + offsetX, y + height - uiScale(offsetY)); + g.drawString(licensedToMessage, x + offsetX, y + height - uiScale(offsetY)); if (licenseRestrictionsMessages.size() > 0) { - g.drawString(wrapText(licenseRestrictionsMessages.get(0), font), x + offsetX, y + height - uiScale(offsetY - 16)); + g.drawString(licenseRestrictionsMessages.get(0), x + offsetX, y + height - uiScale(offsetY - 16)); } } return true; @@ -198,29 +196,6 @@ public class Splash extends JDialog implements StartupProgress { return false; } - private static AttributedCharacterIterator wrapText(String text, Font font) { - Font fallbackFont = createFont("Serif"); - AttributedString result = new AttributedString(text); - if (text.isEmpty()) return result.getIterator(); - - Font curFont = font.canDisplay(text.charAt(0)) ? font : fallbackFont; - int start = 0, end = 0; - - for (int i = 1; i < text.length(); i++) { - Font f = font.canDisplay(text.charAt(i)) ? font : fallbackFont; - if (f != curFont) { - result.addAttribute(TextAttribute.FONT, curFont, start, end); - start = i; - end = start; - curFont = f; - } else { - end++; - } - } - result.addAttribute(TextAttribute.FONT, curFont, start, end); - return result.getIterator(); - } - @NotNull protected static Font createFont(String name) { return new Font(name, Font.PLAIN, uiScale(Registry.is("ide.new.about") ? 12 : SystemInfo.isUnix ? 10 : 11)); From fe947fc0a59d1afe78aa534dd5a360eb89d395c1 Mon Sep 17 00:00:00 2001 From: nik Date: Thu, 21 Dec 2017 17:07:47 +0300 Subject: [PATCH 57/58] project view: do not create implicit module group nodes if they names duplicate module names Previously if there are modules 'foo' and 'foo.bar' in the project we will show two 'foo' nodes in 'Project View', one for 'foo' module and another as an implicit module group for 'foo.bar' module (IDEA-183205). --- .../projectView/ModulesInProjectViewTest.kt | 19 +++++++++++++++++++ .../ide/projectView/impl/ModuleGroup.java | 15 +++++++++++++-- .../GroupModulesByQualifiedNamesTest.kt | 14 ++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/projectView/ModulesInProjectViewTest.kt b/java/java-tests/testSrc/com/intellij/projectView/ModulesInProjectViewTest.kt index 21e5edb58147..e2fb0755cbbf 100644 --- a/java/java-tests/testSrc/com/intellij/projectView/ModulesInProjectViewTest.kt +++ b/java/java-tests/testSrc/com/intellij/projectView/ModulesInProjectViewTest.kt @@ -111,6 +111,25 @@ class ModulesInProjectViewTest : BaseProjectViewTestCase() { """.trimMargin()) } + fun `test do not show groups duplicating module names`() { + val root = directoryContent { + dir("foo") {} + dir("foo.bar") {} + }.generateInVirtualTempDir() + PsiTestUtil.addContentRoot(createModule("xxx.foo"), root.findChild("foo")) + PsiTestUtil.addContentRoot(createModule("xxx.foo.bar"), root.findChild("foo.bar")) + assertStructureEqual(""" + |Project + | Group: xxx + | foo + | foo.bar + | test do not show groups duplicating module names.iml + | xxx.foo.bar.iml + | xxx.foo.iml + | + """.trimMargin()) + } + fun `test modules with common parent group`() { val root = directoryContent { dir("module1") { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java index e5c99c5ca463..6867611e86bf 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/impl/ModuleGroup.java @@ -65,21 +65,32 @@ public class ModuleGroup { @NotNull public Collection modulesInGroup(ModuleGrouper grouper, boolean recursively) { List result = new ArrayList<>(); + Set> moduleAsGroupsPaths = ContainerUtil.map2Set(grouper.getAllModules(), module -> grouper.getModuleAsGroupPath(module)); for (final Module module : grouper.getAllModules()) { List group = grouper.getGroupPath(module); - if (myGroupPath.equals(group) || (recursively && isChild(myGroupPath, group))) { + if (myGroupPath.equals(group) || isChild(myGroupPath, group) && (recursively || allIntermediatePathsAreFromSet(myGroupPath, group, moduleAsGroupsPaths))) { result.add(module); } } return result; } + private static boolean allIntermediatePathsAreFromSet(List parent, List descendant, Set> set) { + for (int i = parent.size() + 1; i < descendant.size() - 1; i++) { + if (!set.contains(descendant.subList(0, i))) { + return false; + } + } + return true; + } + @NotNull public Collection childGroups(ModuleGrouper grouper) { Set result = new THashSet<>(); + Set> moduleAsGroupsPaths = ContainerUtil.map2Set(grouper.getAllModules(), module -> grouper.getModuleAsGroupPath(module)); for (Module module : grouper.getAllModules()) { List group = grouper.getGroupPath(module); - if (isChild(myGroupPath, group)) { + if (!moduleAsGroupsPaths.contains(group) && isChild(myGroupPath, group)) { final List directChild = ContainerUtil.append(myGroupPath, group.get(myGroupPath.size())); result.add(new ModuleGroup(directChild)); } diff --git a/platform/platform-tests/testSrc/com/intellij/module/GroupModulesByQualifiedNamesTest.kt b/platform/platform-tests/testSrc/com/intellij/module/GroupModulesByQualifiedNamesTest.kt index 127d1bbc8231..6b4ed28aed56 100644 --- a/platform/platform-tests/testSrc/com/intellij/module/GroupModulesByQualifiedNamesTest.kt +++ b/platform/platform-tests/testSrc/com/intellij/module/GroupModulesByQualifiedNamesTest.kt @@ -57,6 +57,20 @@ class GroupModulesByQualifiedNamesTest : PlatformTestCase() { assertEmpty(group.childGroups(grouper)) } + fun `test module as a group`() { + val module1 = createModule("a.foo") + val module2 = createModule("a.foo.bar") + + assertEquals("foo", grouper.getShortenedName(module1)) + assertEquals("bar", grouper.getShortenedName(module2)) + + val parentGroup = ModuleGroup(listOf("a")) + assertSameElements(parentGroup.modulesInGroup(grouper, false), module1, module2) + assertSameElements(parentGroup.modulesInGroup(grouper, true), module1, module2) + + assertEmpty(parentGroup.childGroups(grouper)) + } + private val grouper: ModuleGrouper get() = getQualifiedNameModuleGrouper(myProject) } From 7dbff7345412b8be19dbabb0bd9279541c2788ec Mon Sep 17 00:00:00 2001 From: Eugene Zhuravlev Date: Thu, 21 Dec 2017 15:48:52 +0100 Subject: [PATCH 58/58] GDPR support: SentUsageStatistics.isAllowed flag is now part of ConsentOptions; bundled default consents.json --- .../com/intellij/ide/gdpr/ConsentOptions.java | 9 +++ .../src/com/intellij/idea/StartupUtil.java | 2 +- .../actions/SendStatisticsAction.java | 16 ++-- .../configurable/StatisticsConfigurable.java | 76 ------------------- .../StatisticsConfigurationComponent.form | 74 ------------------ .../StatisticsConfigurationComponent.java | 71 ----------------- .../UsageStatisticsPersistenceComponent.java | 17 +++-- .../StatisticsNotificationManager.java | 16 ++-- .../src/com/intellij/ui/AppUIUtil.java | 2 +- .../src/META-INF/PlatformExtensions.xml | 3 - .../platform-resources/src/PrivacyPolicy.html | 7 +- platform/platform-resources/src/consents.json | 9 +++ 12 files changed, 50 insertions(+), 252 deletions(-) delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form delete mode 100644 platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java create mode 100644 platform/platform-resources/src/consents.json diff --git a/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java b/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java index f9a2e498a4c7..0f3636ac7d37 100644 --- a/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java +++ b/platform/platform-impl/src/com/intellij/ide/gdpr/ConsentOptions.java @@ -98,6 +98,15 @@ public final class ConsentOptions { return confirmedConsent == null? Permission.UNDEFINED : confirmedConsent.isAccepted()? Permission.YES : Permission.NO; } + public boolean setSendingUsageStatsAllowed(boolean allowed) { + final Consent defConsent = loadDefaultConsents().get(STATISTICS_OPTION_ID); + if (defConsent != null && !defConsent.isDeleted()) { + saveConfirmedConsents(Collections.singleton(new ConfirmedConsent(defConsent.getId(), defConsent.getVersion(), allowed, 0L))); + return true; + } + return false; + } + @Nullable public String getConfirmedConsentsString() { final Map defaults = loadDefaultConsents(); diff --git a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java index 51ee6a849f8f..91e55a82e0bf 100644 --- a/platform/platform-impl/src/com/intellij/idea/StartupUtil.java +++ b/platform/platform-impl/src/com/intellij/idea/StartupUtil.java @@ -130,7 +130,7 @@ public class StartupUtil { if (!Main.isHeadless()) { AppUIUtil.updateWindowIcon(JOptionPane.getRootFrame()); AppUIUtil.registerBundledFonts(); - AppUIUtil.showEndUserAgreement(); + AppUIUtil.showUserAgreementAndConsentsIfNeeded(); } appStarter.start(newConfigFolder); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java b/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java index 3e49fe81134d..05a4ddf2ae85 100755 --- a/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/actions/SendStatisticsAction.java @@ -15,11 +15,11 @@ */ package com.intellij.internal.statistic.actions; -import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; +import com.intellij.internal.statistic.ApplicationStatisticsPersistenceComponent; import com.intellij.internal.statistic.connect.StatisticsResult; import com.intellij.internal.statistic.connect.StatisticsService; -import com.intellij.internal.statistic.ApplicationStatisticsPersistenceComponent; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; +import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.application.ApplicationManager; @@ -45,10 +45,14 @@ public class SendStatisticsAction extends AnAction { @Override public void run(@NotNull ProgressIndicator indicator) { UsageStatisticsPersistenceComponent statisticsPersistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - boolean sendAllowed = statisticsPersistenceComponent.isAllowed(); - statisticsPersistenceComponent.setAllowed(true); - ApplicationStatisticsPersistenceComponent.persistOpenedProjects(); - statisticsPersistenceComponent.setAllowed(sendAllowed); + final boolean sendAllowed = statisticsPersistenceComponent.isAllowed(); + try { + statisticsPersistenceComponent.setAllowed(true); + ApplicationStatisticsPersistenceComponent.persistOpenedProjects(); + } + finally { + statisticsPersistenceComponent.setAllowed(sendAllowed); + } StatisticsService service = StatisticsUploadAssistant.getStatisticsService(); final StatisticsResult result = service.send(); diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java deleted file mode 100644 index 3ec9f7cf6d97..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurable.java +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.internal.statistic.configurable; - -import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; -import com.intellij.openapi.options.Configurable; -import com.intellij.openapi.options.ConfigurationException; -import com.intellij.openapi.options.SearchableConfigurable; -import org.jetbrains.annotations.Nls; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import javax.swing.*; - -public class StatisticsConfigurable implements SearchableConfigurable, Configurable.NoScroll { - - private boolean modifiedByDefault; - - public StatisticsConfigurable() { - this(false); - } - - public StatisticsConfigurable(boolean isModifiedByDefault) { - modifiedByDefault = isModifiedByDefault; - } - - - private StatisticsConfigurationComponent myConfig; - - @Nls - public String getDisplayName() { - return "Usage Statistics"; - } - - @Override - @Nullable - @NonNls - public String getHelpTopic() { - return "preferences.usage.statictics"; - } - - public JComponent createComponent() { - myConfig = new StatisticsConfigurationComponent(); - return myConfig.getJComponent(); - } - - public boolean isModified() { - final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - return myConfig.isAllowed() != persistenceComponent.isAllowed() || - myConfig.getPeriod() != persistenceComponent.getPeriod() || - modifiedByDefault; - } - - public void apply() throws ConfigurationException { - final UsageStatisticsPersistenceComponent persistenceComponent = UsageStatisticsPersistenceComponent.getInstance(); - - //persistenceComponent.setPeriod(myConfig.getPeriod()); - persistenceComponent.setAllowed(myConfig.isAllowed()); - persistenceComponent.setShowNotification(false); - modifiedByDefault = false; - } - - public void reset() { - myConfig.reset(); - } - - public void disposeUIResources() { - myConfig = null; - } - - @NotNull - @Override - public String getId() { - return "usage.statistics"; - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form deleted file mode 100644 index fc64eadf51ec..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.form +++ /dev/null @@ -1,74 +0,0 @@ - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java deleted file mode 100644 index 3c87c7215cf6..000000000000 --- a/platform/platform-impl/src/com/intellij/internal/statistic/configurable/StatisticsConfigurationComponent.java +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -package com.intellij.internal.statistic.configurable; - -import com.intellij.internal.statistic.StatisticsBundle; -import com.intellij.internal.statistic.connect.StatisticsService; -import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; -import com.intellij.internal.statistic.utils.StatisticsUploadAssistant; -import com.intellij.openapi.application.ApplicationInfo; -import com.intellij.openapi.application.ApplicationNamesInfo; -import com.intellij.ui.RelativeFont; - -import javax.swing.*; -import java.util.Map; - -public class StatisticsConfigurationComponent { - - private JPanel myMainPanel; - private JLabel myTitle; - private JCheckBox myAllowToSendUsagesCheckBox; - private JLabel myLabel; - - public StatisticsConfigurationComponent() { - String product = ApplicationNamesInfo.getInstance().getFullProductName(); - String company = ApplicationInfo.getInstance().getCompanyName(); - myTitle.setText(StatisticsBundle.message("stats.title", product, company)); - myLabel.setText(StatisticsBundle.message("stats.config.details", company)); - RelativeFont.SMALL.install(myLabel); - - myAllowToSendUsagesCheckBox.setText(StatisticsBundle.message("stats.config.allow.send.stats.text", company)); - - // Let current statistics service override labels - StatisticsService service = StatisticsUploadAssistant.getStatisticsService(); - if (service != null) { - Map overrides = service.getStatisticsConfigurationLabels(); - if (overrides != null) { - String s = overrides.get(StatisticsService.TITLE); - if (s != null) { - myTitle.setText(s); - } - s = overrides.get(StatisticsService.DETAILS); - if (s != null) { - myLabel.setText(s); - } - s = overrides.get(StatisticsService.ALLOW_CHECKBOX); - if (s != null) { - myAllowToSendUsagesCheckBox.setText(s); - } - } - } - - myTitle.setText(myTitle.getText().replace("%company%", company)); - myLabel.setText(myLabel.getText().replace("%company%", company)); - myAllowToSendUsagesCheckBox.setText(myAllowToSendUsagesCheckBox.getText().replace("%company%", company)); - } - - public JPanel getJComponent() { - return myMainPanel; - } - - public boolean isAllowed() { - return myAllowToSendUsagesCheckBox.isSelected(); - } - - public void reset() { - myAllowToSendUsagesCheckBox.setSelected(UsageStatisticsPersistenceComponent.getInstance().isAllowed()); - } - - public SendPeriod getPeriod() { - return SendPeriod.DAILY; - } -} diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java index 113a24249b0a..451ab4946533 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/persistence/UsageStatisticsPersistenceComponent.java @@ -2,6 +2,7 @@ package com.intellij.internal.statistic.persistence; +import com.intellij.ide.gdpr.ConsentOptions; import com.intellij.internal.statistic.beans.ConvertUsagesUtil; import com.intellij.internal.statistic.beans.GroupDescriptor; import com.intellij.internal.statistic.beans.UsageDescriptor; @@ -25,7 +26,6 @@ import java.util.Set; public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersistenceComponent implements NamedComponent, PersistentStateComponent { - @NonNls private boolean isAllowed = false; @NonNls private boolean isShowNotification = true; @NotNull private SendPeriod myPeriod = SendPeriod.DAILY; @@ -73,8 +73,11 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste setSentTime(0); } + // compatibility: if was previously allowed, transfer the setting to the new place final String isAllowedValue = element.getAttributeValue(IS_ALLOWED_ATTR); - setAllowed(!StringUtil.isEmptyOrSpaces(isAllowedValue) && Boolean.parseBoolean(isAllowedValue)); + if (!StringUtil.isEmptyOrSpaces(isAllowedValue) && Boolean.parseBoolean(isAllowedValue)) { + setAllowed(true); + } final String isShowNotificationValue = element.getAttributeValue(SHOW_NOTIFICATION_ATTR); setShowNotification(StringUtil.isEmptyOrSpaces(isShowNotificationValue) || Boolean.parseBoolean(isShowNotificationValue)); @@ -100,9 +103,9 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste element.setAttribute(LAST_TIME_ATTR, String.valueOf(lastTimeSent)); } - if (isAllowed()) { - element.setAttribute(IS_ALLOWED_ATTR, "true"); - } + //if (isAllowed()) { + // element.setAttribute(IS_ALLOWED_ATTR, "true"); + //} if (!isShowNotification()) { element.setAttribute(SHOW_NOTIFICATION_ATTR, "false"); } @@ -131,12 +134,12 @@ public class UsageStatisticsPersistenceComponent extends BasicSentUsagesPersiste } public void setAllowed(boolean allowed) { - isAllowed = allowed; + ConsentOptions.getInstance().setSendingUsageStatsAllowed(allowed); } @Override public boolean isAllowed() { - return isAllowed; + return ConsentOptions.getInstance().isSendingUsageStatsAllowed() == ConsentOptions.Permission.YES; } public void setShowNotification(boolean showNotification) { diff --git a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java index 327cbc773727..4293d84393c8 100644 --- a/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java +++ b/platform/platform-impl/src/com/intellij/internal/statistic/updater/StatisticsNotificationManager.java @@ -1,19 +1,18 @@ package com.intellij.internal.statistic.updater; -import com.intellij.internal.statistic.configurable.StatisticsConfigurable; +import com.intellij.ide.gdpr.Consent; +import com.intellij.ide.gdpr.ConsentOptions; import com.intellij.internal.statistic.connect.StatisticsService; import com.intellij.internal.statistic.persistence.UsageStatisticsPersistenceComponent; import com.intellij.notification.Notification; import com.intellij.notification.NotificationListener; import com.intellij.notification.Notifications; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.options.ShowSettingsUtil; -import com.intellij.openapi.wm.IdeFrame; -import com.intellij.openapi.wm.ex.WindowManagerEx; +import com.intellij.ui.AppUIUtil; import org.jetbrains.annotations.NotNull; -import javax.swing.*; import javax.swing.event.HyperlinkEvent; +import java.util.Collection; public class StatisticsNotificationManager { @@ -56,9 +55,10 @@ public class StatisticsNotificationManager { notification.expire(); } else if ("settings".equals(description)) { - final ShowSettingsUtil util = ShowSettingsUtil.getInstance(); - IdeFrame ideFrame = WindowManagerEx.getInstanceEx().findFrameFor(null); - util.editConfigurable((JFrame)ideFrame, new StatisticsConfigurable(true)); + final Collection result = AppUIUtil.confirmConsentOptions(ConsentOptions.getInstance().getConsents().first); + if (result != null) { + ConsentOptions.getInstance().setConsents(result); + } notification.expire(); } } diff --git a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java index c9d827d3c0be..0893de4ea8b1 100644 --- a/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java +++ b/platform/platform-impl/src/com/intellij/ui/AppUIUtil.java @@ -253,7 +253,7 @@ public class AppUIUtil { return iconPath; } - public static void showEndUserAgreement() { + public static void showUserAgreementAndConsentsIfNeeded() { if (ApplicationInfoImpl.getShadowInstance().isVendorJetBrains()) { EndUserAgreement.Document agreement = EndUserAgreement.getLatestDocument(); if (!agreement.isAccepted()) { diff --git a/platform/platform-resources/src/META-INF/PlatformExtensions.xml b/platform/platform-resources/src/META-INF/PlatformExtensions.xml index 64f5bdbaed2b..ae273649247b 100644 --- a/platform/platform-resources/src/META-INF/PlatformExtensions.xml +++ b/platform/platform-resources/src/META-INF/PlatformExtensions.xml @@ -415,9 +415,6 @@ - - diff --git a/platform/platform-resources/src/PrivacyPolicy.html b/platform/platform-resources/src/PrivacyPolicy.html index c3fc6051e6fc..f89b18f35323 100644 --- a/platform/platform-resources/src/PrivacyPolicy.html +++ b/platform/platform-resources/src/PrivacyPolicy.html @@ -1,4 +1,4 @@ - + @@ -12,7 +12,7 @@

This Policy may be amended from time to time. The respective latest version of the policy at the point of time of the purchase/registration of a JetBrains Software Product (whichever occurs later) shall apply. The data controller is JetBrains s.r.o., Praha 4, Na hřebenech - II 1718/10, PSČ 147 00, Česká republika + II 1718/10, PSČ 140 00, Česká republika

In this Privacy Policy, we describe the type of data, including personal data (collectively, “data”), @@ -297,9 +297,6 @@ Website works

  • For security purposes
  • -
  • Make sure you connect to the right service on our Website when we make any changes to the way the - Website works -
  • Accepting these cookies is a condition of using the Website, so if you prevent these cookies we can't diff --git a/platform/platform-resources/src/consents.json b/platform/platform-resources/src/consents.json new file mode 100644 index 000000000000..a44ef27787b9 --- /dev/null +++ b/platform/platform-resources/src/consents.json @@ -0,0 +1,9 @@ +[ + { + "consentId": "rsch.send.usage.stat", + "version": "1.0", + "text": "I consent to submit anonymous usage statistics to help JetBrains improve their products. I agree that the following information will be sent to JetBrains and processed in accordance with JetBrains Privacy Policy https://www.jetbrains.com/company/privacy.html\n * Information about which product features are used\n * General statistics (number of files, file types) of the solutions I am working on\n * General information about my hardware configuration (for example, amount of RAM, CPU speed and number of cores)\n * General information about my software configuration (for example, OS version)\nI can revoke my consent at any time in this Data Sharing Options dialog available at Help | Data Sharing Options", + "printableName": "Send anonymous usage statistics to JetBrains", + "accepted": "false" + } +] \ No newline at end of file