mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-06 06:21:16 +07:00
[java-highlighting] SwitchChecker.checkDuplicates migrated
Part of IDEA-365344 Create a new Java error highlighter with minimal dependencies (PSI only) GitOrigin-RevId: 009041ed8f87c4b2af89849393f00388e912d95a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b9999a124d
commit
9c4282bb5f
@@ -324,6 +324,9 @@ switch.label.constant.expected=Constant expression required
|
||||
switch.label.pattern.expected=Pattern expected for switch selector type ''{0}''
|
||||
switch.label.unexpected=Constant expression, pattern or null is required
|
||||
switch.default.label.contains.case=The label for the default case must only use the 'default' keyword, without 'case'
|
||||
switch.label.duplicate.unconditional.pattern=Duplicate unconditional pattern
|
||||
switch.label.duplicate.default=Duplicate default label
|
||||
switch.label.duplicate=Duplicate label ''{0}''
|
||||
|
||||
guard.misplaced=Guard is allowed after patterns only
|
||||
guard.evaluated.to.false=Case label has a guard that is a constant expression with value 'false'
|
||||
|
||||
+1
@@ -642,6 +642,7 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
if (!hasErrorResults()) mySwitchChecker.checkSwitchBlockStatements(block);
|
||||
if (!hasErrorResults()) mySwitchChecker.checkSwitchSelectorType(block);
|
||||
if (!hasErrorResults()) mySwitchChecker.checkLabelSelectorCompatibility(block);
|
||||
if (!hasErrorResults()) mySwitchChecker.checkDuplicates(block);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+13
@@ -15,6 +15,9 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
final class SwitchChecker {
|
||||
private final @NotNull JavaErrorVisitor myVisitor;
|
||||
|
||||
@@ -436,4 +439,14 @@ final class SwitchChecker {
|
||||
}
|
||||
myVisitor.report(JavaErrorKinds.SWITCH_LABEL_UNEXPECTED.create(label));
|
||||
}
|
||||
|
||||
void checkDuplicates(@NotNull PsiSwitchBlock block) {
|
||||
for (Map.Entry<Object, Collection<PsiElement>> entry : JavaPsiSwitchUtil.getValuesAndLabels(block).entrySet()) {
|
||||
if (entry.getValue().size() <= 1) continue;
|
||||
Object duplicateKey = entry.getKey();
|
||||
for (PsiElement duplicateElement : entry.getValue()) {
|
||||
myVisitor.report(JavaErrorKinds.SWITCH_LABEL_DUPLICATE.create(duplicateElement, duplicateKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+20
@@ -955,6 +955,26 @@ public final class JavaErrorKinds {
|
||||
public static final Parameterized<PsiExpression, PsiType> SWITCH_LABEL_PATTERN_EXPECTED =
|
||||
parameterized(PsiExpression.class, PsiType.class, "switch.label.pattern.expected")
|
||||
.withRawDescription((expr, type) -> message("switch.label.pattern.expected", formatType(type)));
|
||||
public static final Parameterized<PsiElement, Object> SWITCH_LABEL_DUPLICATE =
|
||||
parameterized(PsiElement.class, Object.class, "switch.label.duplicate")
|
||||
.withRawDescription((label, value) -> {
|
||||
if (value instanceof JavaPsiSwitchUtil.SwitchSpecialValue specialValue) {
|
||||
return switch (specialValue) {
|
||||
case UNCONDITIONAL_PATTERN -> message("switch.label.duplicate.unconditional.pattern");
|
||||
case DEFAULT_VALUE -> message("switch.label.duplicate.default");
|
||||
case NULL_VALUE -> message("switch.label.duplicate", PsiKeyword.NULL);
|
||||
};
|
||||
}
|
||||
else if (value instanceof PsiEnumConstant constant) {
|
||||
return message("switch.label.duplicate", constant.getName());
|
||||
}
|
||||
else if (label instanceof PsiLiteralExpression literalExpression) {
|
||||
return message("switch.label.duplicate", literalExpression.getValue());
|
||||
}
|
||||
else {
|
||||
return message("switch.label.duplicate", value);
|
||||
}
|
||||
});
|
||||
|
||||
public static final Simple<PsiReferenceExpression> EXPRESSION_EXPECTED = error("expression.expected");
|
||||
public static final Parameterized<PsiReferenceExpression, PsiSuperExpression> EXPRESSION_SUPER_UNQUALIFIED_DEFAULT_METHOD =
|
||||
|
||||
+9
@@ -235,6 +235,15 @@ final class JavaErrorFixProvider {
|
||||
HighlightFixUtil.getIncreaseLanguageLevelFixes(error.psi(), feature).forEach(sink);
|
||||
}
|
||||
});
|
||||
fix(SWITCH_LABEL_DUPLICATE, error -> {
|
||||
if (error.psi() instanceof PsiCaseLabelElement caseLabel) {
|
||||
return myFactory.createDeleteSwitchLabelFix(caseLabel);
|
||||
}
|
||||
else if (error.context() == JavaPsiSwitchUtil.SwitchSpecialValue.DEFAULT_VALUE) {
|
||||
return myFactory.createDeleteDefaultFix(null, error.psi());
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void createMethodFixes() {
|
||||
|
||||
-6
@@ -57,12 +57,6 @@ public class PatternsInSwitchBlockHighlightingModel extends SwitchBlockHighlight
|
||||
PsiCodeBlock body = myBlock.getBody();
|
||||
if (body == null) return;
|
||||
|
||||
MultiMap<Object, PsiElement> elementsToCheckDuplicates = JavaPsiSwitchUtil.getValuesAndLabels(myBlock);
|
||||
|
||||
if (checkDuplicates(elementsToCheckDuplicates, errorSink)) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<List<PsiSwitchLabelStatementBase>> elementsToCheckFallThroughLegality = new SmartList<>();
|
||||
List<PsiElement> elementsToCheckDominance = new ArrayList<>();
|
||||
List<PsiCaseLabelElement> elementsToCheckCompleteness = new ArrayList<>();
|
||||
|
||||
-55
@@ -21,7 +21,6 @@ import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.siyeh.ig.psiutils.SwitchUtils;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.PropertyKey;
|
||||
@@ -86,12 +85,6 @@ public class SwitchBlockHighlightingModel {
|
||||
PsiCodeBlock body = myBlock.getBody();
|
||||
if (body == null) return;
|
||||
|
||||
MultiMap<Object, PsiElement> elementsToCheckDuplicates = JavaPsiSwitchUtil.getValuesAndLabels(myBlock);
|
||||
|
||||
if (checkDuplicates(elementsToCheckDuplicates, errorSink)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// todo replace with needToCheckCompleteness
|
||||
if (myBlock instanceof PsiSwitchExpression && !hasDefaultCase(body)) {
|
||||
PsiClass selectorClass = PsiUtil.resolveClassInClassTypeOnly(mySelectorType);
|
||||
@@ -131,35 +124,6 @@ public class SwitchBlockHighlightingModel {
|
||||
return JavaPsiFacade.getInstance(constant.getProject()).getConstantEvaluationHelper().computeConstantExpression(constant, false);
|
||||
}
|
||||
|
||||
static boolean checkDuplicates(@NotNull MultiMap<Object, PsiElement> values, Consumer<? super HighlightInfo.Builder> errorSink) {
|
||||
boolean reported = false;
|
||||
for (Map.Entry<Object, Collection<PsiElement>> entry : values.entrySet()) {
|
||||
if (entry.getValue().size() <= 1) continue;
|
||||
Object duplicateKey = entry.getKey();
|
||||
for (PsiElement duplicateElement : entry.getValue()) {
|
||||
HighlightInfo.Builder info = createDuplicateInfo(duplicateKey, duplicateElement);
|
||||
errorSink.accept(info);
|
||||
reported = true;
|
||||
}
|
||||
}
|
||||
return reported;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static HighlightInfo.Builder createDuplicateInfo(@Nullable Object duplicateKey, @NotNull PsiElement duplicateElement) {
|
||||
String description = createDuplicateDescription(duplicateKey, duplicateElement);
|
||||
HighlightInfo.Builder info = createError(duplicateElement, description);
|
||||
if (duplicateElement instanceof PsiCaseLabelElement caseLabel) {
|
||||
IntentionAction action = getFixFactory().createDeleteSwitchLabelFix(caseLabel);
|
||||
info.registerFix(action, null, null, null, null);
|
||||
}
|
||||
else if (duplicateKey == JavaPsiSwitchUtil.SwitchSpecialValue.DEFAULT_VALUE) {
|
||||
IntentionAction action = getFixFactory().createDeleteDefaultFix(null, duplicateElement);
|
||||
info.registerFix(action, null, null, null, null);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
boolean needToCheckCompleteness(@NotNull List<? extends PsiCaseLabelElement> elements) {
|
||||
return myBlock instanceof PsiSwitchExpression || myBlock instanceof PsiSwitchStatement && isEnhancedSwitch(elements);
|
||||
}
|
||||
@@ -259,23 +223,4 @@ public class SwitchBlockHighlightingModel {
|
||||
return StreamEx.ofKeys(patternInSwitchModel.findDominatedLabels(dominanceCheckingCandidates), value -> value instanceof PsiPattern)
|
||||
.into(result);
|
||||
}
|
||||
|
||||
private static @NotNull @Nls String createDuplicateDescription(@Nullable Object duplicateKey, @NotNull PsiElement duplicateElement) {
|
||||
if (duplicateKey instanceof JavaPsiSwitchUtil.SwitchSpecialValue specialValue) {
|
||||
return switch (specialValue) {
|
||||
case UNCONDITIONAL_PATTERN -> JavaErrorBundle.message("duplicate.unconditional.pattern.label");
|
||||
case DEFAULT_VALUE -> JavaErrorBundle.message("duplicate.default.switch.label");
|
||||
case NULL_VALUE -> JavaErrorBundle.message("duplicate.switch.label", PsiKeyword.NULL);
|
||||
};
|
||||
}
|
||||
else if (duplicateKey instanceof PsiEnumConstant constant) {
|
||||
return JavaErrorBundle.message("duplicate.switch.label", constant.getName());
|
||||
}
|
||||
else if (duplicateElement instanceof PsiLiteralExpression literalExpression) {
|
||||
return JavaErrorBundle.message("duplicate.switch.label", literalExpression.getValue());
|
||||
}
|
||||
else {
|
||||
return JavaErrorBundle.message("duplicate.switch.label", duplicateKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user