mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
[java-highlighting] Fix bug about applying "Create missing switch branch" fix produces a red code
(IDEA-278884) GitOrigin-RevId: 690fa0ae782ee065b35e91f6d1e0df846bd9369f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e722456de1
commit
086e760e08
@@ -783,11 +783,12 @@ public class SwitchBlockHighlightingModel {
|
||||
@NotNull List<PsiCaseLabelElement> elements,
|
||||
@NotNull List<HighlightInfo> results) {
|
||||
Set<PsiClass> missingClasses;
|
||||
Map<PsiClass, PsiPattern> patternClasses = null;
|
||||
if (elements.isEmpty()) {
|
||||
missingClasses = Collections.emptySet();
|
||||
}
|
||||
else {
|
||||
Map<PsiClass, PsiPattern> patternClasses = new HashMap<>();
|
||||
patternClasses = new HashMap<>();
|
||||
for (PsiCaseLabelElement element : elements) {
|
||||
PsiPattern patternLabelElement = ObjectUtils.tryCast(element, PsiPattern.class);
|
||||
if (patternLabelElement == null) continue;
|
||||
@@ -821,15 +822,42 @@ public class SwitchBlockHighlightingModel {
|
||||
}
|
||||
HighlightInfo info = createCompletenessInfoForSwitch(!elements.isEmpty());
|
||||
if (!missingClasses.isEmpty()) {
|
||||
List<String> allNames = findAllNames(elements, missingClasses, patternClasses);
|
||||
Set<String> missingCases = new SmartHashSet<>();
|
||||
missingClasses.forEach(aClass -> missingCases.add(aClass.getQualifiedName()));
|
||||
IntentionAction fix =
|
||||
getFixFactory().createAddMissingSealedClassBranchesFix(myBlock, missingCases, StreamEx.of(missingCases).toList());
|
||||
IntentionAction fix = getFixFactory().createAddMissingSealedClassBranchesFix(myBlock, missingCases, allNames);
|
||||
QuickFixAction.registerQuickFixAction(info, fix);
|
||||
}
|
||||
results.add(info);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> findAllNames(@NotNull List<PsiCaseLabelElement> elements,
|
||||
@NotNull Set<PsiClass> missingClasses,
|
||||
@NotNull Map<PsiClass, PsiPattern> patternClasses) {
|
||||
List<String> result = new ArrayList<>();
|
||||
elements.forEach(element -> result.add(element.getText()));
|
||||
for (PsiClass aClass : missingClasses) {
|
||||
String className = aClass.getQualifiedName();
|
||||
PsiPattern pattern = patternClasses.get(aClass);
|
||||
if (pattern != null) {
|
||||
result.add(result.lastIndexOf(pattern.getText()) + 1, className);
|
||||
}
|
||||
else {
|
||||
pattern =
|
||||
StreamEx.of(elements).select(PsiPattern.class).findFirst(who -> JavaPsiPatternUtil.dominates(who, TypeUtils.getType(aClass)))
|
||||
.orElse(null);
|
||||
if (pattern != null) {
|
||||
result.add(result.indexOf(pattern.getText()), aClass.getQualifiedName());
|
||||
}
|
||||
else {
|
||||
result.add(aClass.getQualifiedName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Collection<PsiClass> getPermittedClasses(@NotNull PsiClass psiClass) {
|
||||
PsiReferenceList permitsList = psiClass.getPermitsList();
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// "Create missing switch branch 'Sub2'" "true"
|
||||
sealed abstract class I {
|
||||
}
|
||||
|
||||
final class Sub1 extends I {
|
||||
}
|
||||
|
||||
final class Sub2 extends I {
|
||||
}
|
||||
|
||||
class Test {
|
||||
void testI(I i) {
|
||||
switch (i) {
|
||||
case Sub1 s1:
|
||||
System.out.println("ok");
|
||||
break;
|
||||
case Sub2 sub2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// "Create missing branches: 'Scratch.X', and 'Scratch.Parent.X'" "true"
|
||||
class Scratch {
|
||||
sealed interface Parent {
|
||||
record X() implements Parent {}
|
||||
}
|
||||
record X() implements Parent {}
|
||||
record Y() implements Parent {}
|
||||
|
||||
void test(Parent parent) {
|
||||
switch (parent) {
|
||||
case Y y -> {}
|
||||
case X x -> {
|
||||
}
|
||||
case Parent.X x -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// "Create missing switch branch 'Ab'" "true"
|
||||
sealed interface A {}
|
||||
sealed interface Aa extends A {}
|
||||
final class Aaa implements Aa {}
|
||||
final class Aab implements Aa {}
|
||||
final class Ab implements A {}
|
||||
|
||||
public class Test {
|
||||
void test(A a) {
|
||||
switch (a) {
|
||||
case Aaa x -> {
|
||||
}
|
||||
case Aab x -> {
|
||||
}
|
||||
case Ab ab -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// "Create missing switch branch 'Sub1'" "true"
|
||||
sealed interface I {}
|
||||
sealed interface J extends I {}
|
||||
final class Sub1 implements I, J {}
|
||||
final class Sub2 implements I {}
|
||||
|
||||
class Test {
|
||||
void test(I i) {
|
||||
switch (i) {
|
||||
case Sub2 sub2:
|
||||
break;
|
||||
case Sub1 sub1:
|
||||
break;
|
||||
case J j:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// "Create missing switch branch 'Sub1'" "true"
|
||||
sealed interface I {}
|
||||
sealed interface J extends I {}
|
||||
final class Sub1 implements I, J {}
|
||||
final class Sub2 implements I {}
|
||||
|
||||
class Test {
|
||||
void test(I i) {
|
||||
switch (i) {
|
||||
case Sub1 sub1 && Math.random() > 0.5:
|
||||
break;
|
||||
case Sub1 sub1:
|
||||
break;
|
||||
case Sub2 sub2:
|
||||
break;
|
||||
case J j:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,12 +6,12 @@ final class Sub2 implements I {}
|
||||
class Test {
|
||||
void test(I i) {
|
||||
switch (i) {
|
||||
case Sub1 sub1 && sub1 != null:
|
||||
break;
|
||||
case Sub2 sub2:
|
||||
case Sub1 sub1 && Math.random() > 0.5:
|
||||
break;
|
||||
case Sub1 sub1:
|
||||
break;
|
||||
case Sub2 sub2:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// "Create missing switch branch 'Sub1'" "true"
|
||||
sealed interface I {}
|
||||
final class Sub1 implements I {}
|
||||
final class Sub2 implements I {}
|
||||
|
||||
class Test {
|
||||
void test(I i) {
|
||||
switch (i) {
|
||||
case Sub1 sub1 && Math.random() > 0.5 -> {}
|
||||
case Sub1 sub1 && Math.random() > 0.1 -> {}
|
||||
case Sub1 sub1 && Math.random() > 0.5 -> {}
|
||||
case Sub1 sub1 -> {
|
||||
}
|
||||
case Sub2 sub2 -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// "Create missing switch branch 'Sub2'" "true"
|
||||
sealed abstract class I {
|
||||
}
|
||||
|
||||
final class Sub1 extends I {
|
||||
}
|
||||
|
||||
final class Sub2 extends I {
|
||||
}
|
||||
|
||||
class Test {
|
||||
void testI(I i) {
|
||||
switch (i<caret>) {
|
||||
case Sub1 s1:
|
||||
System.out.println("ok");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
// "Create missing branches: 'Scratch.X', and 'Scratch.Parent.X'" "true"
|
||||
class Scratch {
|
||||
sealed interface Parent {
|
||||
record X() implements Parent {}
|
||||
}
|
||||
record X() implements Parent {}
|
||||
record Y() implements Parent {}
|
||||
|
||||
void test(Parent parent) {
|
||||
switch (parent<caret>) {
|
||||
case Y y -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// "Create missing switch branch 'Ab'" "true"
|
||||
sealed interface A {}
|
||||
sealed interface Aa extends A {}
|
||||
final class Aaa implements Aa {}
|
||||
final class Aab implements Aa {}
|
||||
final class Ab implements A {}
|
||||
|
||||
public class Test {
|
||||
void test(A a) {
|
||||
switch (a<caret>) {
|
||||
case Aaa x -> {
|
||||
}
|
||||
case Aab x -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// "Create missing switch branch 'Sub1'" "true"
|
||||
sealed interface I {}
|
||||
sealed interface J extends I {}
|
||||
final class Sub1 implements I, J {}
|
||||
final class Sub2 implements I {}
|
||||
|
||||
class Test {
|
||||
void test(I i) {
|
||||
switch (i<caret>) {
|
||||
case Sub2 sub2:
|
||||
break;
|
||||
case J j:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// "Create missing switch branch 'Sub1'" "true"
|
||||
sealed interface I {}
|
||||
sealed interface J extends I {}
|
||||
final class Sub1 implements I, J {}
|
||||
final class Sub2 implements I {}
|
||||
|
||||
class Test {
|
||||
void test(I i) {
|
||||
switch (i<caret>) {
|
||||
case Sub1 sub1 && Math.random() > 0.5:
|
||||
break;
|
||||
case Sub2 sub2:
|
||||
break;
|
||||
case J j:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ final class Sub2 implements I {}
|
||||
class Test {
|
||||
void test(I i) {
|
||||
switch (i<caret>) {
|
||||
case Sub1 sub1 && sub1 != null:
|
||||
case Sub1 sub1 && Math.random() > 0.5:
|
||||
break;
|
||||
case Sub2 sub2:
|
||||
break;
|
||||
@@ -0,0 +1,15 @@
|
||||
// "Create missing switch branch 'Sub1'" "true"
|
||||
sealed interface I {}
|
||||
final class Sub1 implements I {}
|
||||
final class Sub2 implements I {}
|
||||
|
||||
class Test {
|
||||
void test(I i) {
|
||||
switch (i<caret>) {
|
||||
case Sub1 sub1 && Math.random() > 0.5 -> {}
|
||||
case Sub1 sub1 && Math.random() > 0.1 -> {}
|
||||
case Sub1 sub1 && Math.random() > 0.5 -> {}
|
||||
case Sub2 sub2 -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,9 @@
|
||||
package com.siyeh.ig.fixes;
|
||||
|
||||
import com.intellij.codeInsight.intention.FileModifier;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiSwitchBlock;
|
||||
import com.intellij.psi.PsiSwitchLabelStatementBase;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -46,6 +44,10 @@ public class CreateSealedClassMissingSwitchBranchesFix extends CreateMissingSwit
|
||||
|
||||
@Override
|
||||
protected @NotNull Function<PsiSwitchLabelStatementBase, List<String>> getCaseExtractor() {
|
||||
return label -> Collections.emptyList();
|
||||
return label -> {
|
||||
PsiCaseLabelElementList list = label.getCaseLabelElementList();
|
||||
if (list == null) return Collections.emptyList();
|
||||
return ContainerUtil.map(list.getElements(), PsiCaseLabelElement::getText);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ public final class CreateSwitchBranchesUtil {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(block.getBody(), PsiSwitchLabelStatementBase.class);
|
||||
}
|
||||
Map<String, String> prevToNext =
|
||||
StreamEx.of(allNames).pairMap(Couple::of).toMap(c -> c.getFirst(), c -> c.getSecond());
|
||||
StreamEx.of(allNames).distinct().pairMap(Couple::of).toMap(c -> c.getFirst(), c -> c.getSecond());
|
||||
List<String> missingLabels = StreamEx.of(allNames).filter(missingNames::contains).toList();
|
||||
String nextLabel = getNextLabel(prevToNext, missingLabels);
|
||||
PsiElement bodyElement = body.getFirstBodyElement();
|
||||
@@ -90,8 +90,8 @@ public final class CreateSwitchBranchesUtil {
|
||||
while (bodyElement != null) {
|
||||
PsiSwitchLabelStatementBase label = ObjectUtils.tryCast(bodyElement, PsiSwitchLabelStatementBase.class);
|
||||
if (label != null) {
|
||||
List<String> constants = caseExtractor.apply(label);
|
||||
while (nextLabel != null && constants.contains(nextLabel)) {
|
||||
List<String> caseLabelNames = caseExtractor.apply(label);
|
||||
while (nextLabel != null && caseLabelNames.contains(nextLabel)) {
|
||||
addedLabels.add(addSwitchLabelStatementBefore(missingLabels.get(0), bodyElement, switchBlock, isRuleBasedFormat, isPatternsGenerated));
|
||||
missingLabels.remove(0);
|
||||
if (missingLabels.isEmpty()) {
|
||||
|
||||
Reference in New Issue
Block a user