From c977930e50b00f788a3a697ac17b565685ea282e Mon Sep 17 00:00:00 2001 From: "Andrey.Cherkasov" Date: Tue, 31 May 2022 13:16:30 +0300 Subject: [PATCH] [java-highlighting] Stabilize the order of missing branches GitOrigin-RevId: cca86a5d95906306a0a4c68b976e8d6950e3cb72 --- .../SwitchBlockHighlightingModel.java | 12 ++++++---- .../afterAbstractSelectorEmptySwitch.java | 15 ++++++++----- ... afterAbstractSelectorNonEmptySwitch.java} | 2 +- .../afterNonAbstractSelector.java | 18 --------------- .../afterNonAbstractSelectorEmptySwitch.java | 15 ++++++++----- ...fterNonAbstractSelectorNonEmptySwitch.java | 21 ++++++++++++++++++ .../afterPermitsListOrder.java | 22 +++++++++++++++++++ .../beforeAbstractSelectorEmptySwitch.java | 9 +++++--- ...beforeAbstractSelectorNonEmptySwitch.java} | 2 +- .../beforeNonAbstractSelector.java | 12 ---------- .../beforeNonAbstractSelectorEmptySwitch.java | 9 +++++--- ...foreNonAbstractSelectorNonEmptySwitch.java | 17 ++++++++++++++ .../beforePermitsListOrder.java | 14 ++++++++++++ 13 files changed, 116 insertions(+), 52 deletions(-) rename java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/{afterDeepHierarchy.java => afterAbstractSelectorNonEmptySwitch.java} (94%) delete mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelector.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelectorNonEmptySwitch.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterPermitsListOrder.java rename java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/{beforeDeepHierarchy.java => beforeAbstractSelectorNonEmptySwitch.java} (93%) delete mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelector.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelectorNonEmptySwitch.java create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforePermitsListOrder.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SwitchBlockHighlightingModel.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SwitchBlockHighlightingModel.java index c4deb3b54fb5..3adee3e2d5c1 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SwitchBlockHighlightingModel.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/SwitchBlockHighlightingModel.java @@ -317,7 +317,8 @@ public class SwitchBlockHighlightingModel { } void checkEnumCompleteness(@NotNull PsiClass selectorClass, @NotNull List enumElements, @NotNull List results) { - Set missingConstants = StreamEx.of(selectorClass.getFields()).select(PsiEnumConstant.class).map(PsiField::getName).toSet(); + LinkedHashSet missingConstants = + StreamEx.of(selectorClass.getFields()).select(PsiEnumConstant.class).map(PsiField::getName).toCollection(LinkedHashSet::new); if (!enumElements.isEmpty()) { enumElements.forEach(missingConstants::remove); if (missingConstants.isEmpty()) return; @@ -843,7 +844,7 @@ public class SwitchBlockHighlightingModel { } HighlightInfo info = createCompletenessInfoForSwitch(!elements.isEmpty()); List allNames = collectLabelElementNames(elements, missingClasses, patternClasses); - Set missingCases = ContainerUtil.map2Set(missingClasses, PsiClass::getQualifiedName); + Set missingCases = ContainerUtil.map2LinkedSet(missingClasses, PsiClass::getQualifiedName); IntentionAction fix = getFixFactory().createAddMissingSealedClassBranchesFix(myBlock, missingCases, allNames); QuickFixAction.registerQuickFixAction(info, fix); return info; @@ -877,10 +878,13 @@ public class SwitchBlockHighlightingModel { private static Collection getPermittedClasses(@NotNull PsiClass psiClass) { PsiReferenceList permitsList = psiClass.getPermitsList(); if (permitsList == null) { + TreeSet result = new TreeSet<>(Comparator.comparing(aClass -> aClass.getName())); GlobalSearchScope fileScope = GlobalSearchScope.fileScope(psiClass.getContainingFile()); - return new ArrayList<>(DirectClassInheritorsSearch.search(psiClass, fileScope).findAll()); + result.addAll(DirectClassInheritorsSearch.search(psiClass, fileScope).findAll()); + return result; } - return Stream.of(permitsList.getReferencedTypes()).map(type -> type.resolve()).filter(Objects::nonNull).collect(Collectors.toSet()); + return Stream.of(permitsList.getReferencedTypes()).map(type -> type.resolve()).filter(Objects::nonNull) + .collect(Collectors.toCollection(LinkedHashSet::new)); } @Nullable diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterAbstractSelectorEmptySwitch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterAbstractSelectorEmptySwitch.java index fe8701f98dc9..da73ced4e2e1 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterAbstractSelectorEmptySwitch.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterAbstractSelectorEmptySwitch.java @@ -1,14 +1,19 @@ -// "Create missing branches: 'B', and 'C'" "true" +// "Create missing branches: 'AA', 'AB', and 'AC'" "true" abstract sealed class A {} -final class B extends A {} -final class C extends A {} +final class AA extends A {} +sealed class AB extends A {} +non-sealed class AC extends A {} +final class ABA extends AB {} +non-sealed class ABC extends AB {} class Test { void test(A a) { switch (a) { - case B b -> { + case AA aa -> { } - case C c -> { + case AB ab -> { + } + case AC ac -> { } } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterDeepHierarchy.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterAbstractSelectorNonEmptySwitch.java similarity index 94% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterDeepHierarchy.java rename to java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterAbstractSelectorNonEmptySwitch.java index d3e61928d537..3a510d8c80ac 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterDeepHierarchy.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterAbstractSelectorNonEmptySwitch.java @@ -5,7 +5,7 @@ final class Aaa implements Aa {} final class Aab implements Aa {} final class Ab implements A {} -public class Test { +class Test { void test(A a) { switch (a) { case Aaa x -> { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelector.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelector.java deleted file mode 100644 index fa5519da6e64..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelector.java +++ /dev/null @@ -1,18 +0,0 @@ -// "Create missing branches: 'A', 'B', and 'C'" "true" -sealed class A {} -final class B extends A {} -final class C extends A {} - -class Test { - void test(A a) { - switch (a) { - case B b && b.hashCode() > 21 -> {} - case B b -> { - } - case C c -> { - } - case A a1 -> { - } - } - } -} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelectorEmptySwitch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelectorEmptySwitch.java index e47d37791013..cc2cf02a9552 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelectorEmptySwitch.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelectorEmptySwitch.java @@ -1,14 +1,19 @@ -// "Create missing branches: 'A', 'B', and 'C'" "true" +// "Create missing branches: 'AA', 'AB', 'AC', and 'A'" "true" sealed class A {} -final class B extends A {} -final class C extends A {} +final class AA extends A {} +sealed class AB extends A {} +non-sealed class AC extends A {} +final class ABA extends AB {} +non-sealed class ABC extends AB {} class Test { void test(A a) { switch (a) { - case B b -> { + case AA aa -> { } - case C c -> { + case AB ab -> { + } + case AC ac -> { } case A a1 -> { } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelectorNonEmptySwitch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelectorNonEmptySwitch.java new file mode 100644 index 000000000000..ef5471fed3f4 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterNonAbstractSelectorNonEmptySwitch.java @@ -0,0 +1,21 @@ +// "Create missing branches: 'Ab', and 'A'" "true" +sealed class A {} +abstract sealed class Aa extends A {} +final class Aaa extends Aa {} +final class Aab extends Aa {} +final class Ab extends A {} + +class Test { + void test(A a) { + switch (a) { + case Aaa x -> { + } + case Aab x -> { + } + case Ab ab -> { + } + case A a1 -> { + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterPermitsListOrder.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterPermitsListOrder.java new file mode 100644 index 000000000000..10485bb4428a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/afterPermitsListOrder.java @@ -0,0 +1,22 @@ +// "Create missing branches: 'AC', 'AA', 'AB', and 'A'" "true" +sealed class A permits AC, AA, AB {} +final class AA extends A {} +sealed class AB extends A permits ABC, ABA {} +non-sealed class AC extends A {} +final class ABA extends AB {} +non-sealed class ABC extends AB {} + +class Test { + void test(A a) { + switch (a) { + case AC ac -> { + } + case AA aa -> { + } + case AB ab -> { + } + case A a1 -> { + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeAbstractSelectorEmptySwitch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeAbstractSelectorEmptySwitch.java index 0b0cada9916f..653479214dec 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeAbstractSelectorEmptySwitch.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeAbstractSelectorEmptySwitch.java @@ -1,7 +1,10 @@ -// "Create missing branches: 'B', and 'C'" "true" +// "Create missing branches: 'AA', 'AB', and 'AC'" "true" abstract sealed class A {} -final class B extends A {} -final class C extends A {} +final class AA extends A {} +sealed class AB extends A {} +non-sealed class AC extends A {} +final class ABA extends AB {} +non-sealed class ABC extends AB {} class Test { void test(A a) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeDeepHierarchy.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeAbstractSelectorNonEmptySwitch.java similarity index 93% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeDeepHierarchy.java rename to java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeAbstractSelectorNonEmptySwitch.java index 8723ce50b586..6aa28c842e84 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeDeepHierarchy.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeAbstractSelectorNonEmptySwitch.java @@ -5,7 +5,7 @@ final class Aaa implements Aa {} final class Aab implements Aa {} final class Ab implements A {} -public class Test { +class Test { void test(A a) { switch (a) { case Aaa x -> { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelector.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelector.java deleted file mode 100644 index a169fd5c8792..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelector.java +++ /dev/null @@ -1,12 +0,0 @@ -// "Create missing branches: 'A', 'B', and 'C'" "true" -sealed class A {} -final class B extends A {} -final class C extends A {} - -class Test { - void test(A a) { - switch (a) { - case B b && b.hashCode() > 21 -> {} - } - } -} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelectorEmptySwitch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelectorEmptySwitch.java index 4f4cd835ec7c..2301a60cccc2 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelectorEmptySwitch.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelectorEmptySwitch.java @@ -1,7 +1,10 @@ -// "Create missing branches: 'A', 'B', and 'C'" "true" +// "Create missing branches: 'AA', 'AB', 'AC', and 'A'" "true" sealed class A {} -final class B extends A {} -final class C extends A {} +final class AA extends A {} +sealed class AB extends A {} +non-sealed class AC extends A {} +final class ABA extends AB {} +non-sealed class ABC extends AB {} class Test { void test(A a) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelectorNonEmptySwitch.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelectorNonEmptySwitch.java new file mode 100644 index 000000000000..8a51dcf47fc6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforeNonAbstractSelectorNonEmptySwitch.java @@ -0,0 +1,17 @@ +// "Create missing branches: 'Ab', and 'A'" "true" +sealed class A {} +abstract sealed class Aa extends A {} +final class Aaa extends Aa {} +final class Aab extends Aa {} +final class Ab extends A {} + +class Test { + void test(A a) { + switch (a) { + case Aaa x -> { + } + case Aab x -> { + } + } + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforePermitsListOrder.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforePermitsListOrder.java new file mode 100644 index 000000000000..8b561b9d1905 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createMissingSealedClassSwitchBranches/beforePermitsListOrder.java @@ -0,0 +1,14 @@ +// "Create missing branches: 'AC', 'AA', 'AB', and 'A'" "true" +sealed class A permits AC, AA, AB {} +final class AA extends A {} +sealed class AB extends A permits ABC, ABA {} +non-sealed class AC extends A {} +final class ABA extends AB {} +non-sealed class ABC extends AB {} + +class Test { + void test(A a) { + switch (a) { + } + } +} \ No newline at end of file