mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 21:11:28 +07:00
[java-highlighting] IDEA-357866 Spurious "Different case kinds used in the switch" error on incomplete code
- fixes - not double error messages GitOrigin-RevId: 8f789243ee4e09d3eb8de6a2db7dcbe25ee517db
This commit is contained in:
committed by
intellij-monorepo-bot
parent
cd14483af8
commit
e01d24d5c8
@@ -7,6 +7,7 @@ import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.intention.impl.PriorityIntentionActionWrapper;
|
||||
import com.intellij.core.JavaPsiBundle;
|
||||
import com.intellij.modcommand.ModCommandAction;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
@@ -111,6 +112,13 @@ public class SwitchBlockHighlightingModel {
|
||||
}
|
||||
else if (element instanceof PsiStatement statement) {
|
||||
if (enhancedLabels) {
|
||||
//let's not highlight twice
|
||||
if (statement instanceof PsiSwitchLabelStatement labelStatement &&
|
||||
labelStatement.getChildren().length != 0 &&
|
||||
labelStatement.getChildren()[labelStatement.getChildren().length - 1] instanceof PsiErrorElement errorElement &&
|
||||
errorElement.getErrorDescription().startsWith(JavaPsiBundle.message("expected.colon.or.arrow"))) {
|
||||
break;
|
||||
}
|
||||
alien = statement;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.core.JavaPsiBundle;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -31,6 +32,27 @@ public final class JavaErrorQuickFixProvider implements ErrorQuickFixProvider {
|
||||
registrar.add(new AddExceptionToCatchFix(false).asIntention());
|
||||
registrar.add(new AddFinallyFix((PsiTryStatement)parent).asIntention());
|
||||
}
|
||||
if (parent instanceof PsiSwitchLabelStatementBase && description.equals(JavaPsiBundle.message("expected.colon.or.arrow"))) {
|
||||
PsiSwitchBlock switchBlock = PsiTreeUtil.getParentOfType(parent, PsiSwitchBlock.class);
|
||||
if (switchBlock != null && switchBlock.getBody() != null) {
|
||||
boolean isOld = false;
|
||||
boolean isRule = false;
|
||||
for (@NotNull PsiElement child : switchBlock.getBody().getChildren()) {
|
||||
if (child instanceof PsiSwitchLabeledRuleStatement) {
|
||||
isRule = true;
|
||||
}
|
||||
if (child instanceof PsiSwitchLabelStatement && !PsiTreeUtil.isAncestor(child, parent, false)) {
|
||||
isOld = true;
|
||||
}
|
||||
}
|
||||
if (isOld) {
|
||||
info.registerFix(new InsertMissingTokenFix(":", true), null, null, null, null);
|
||||
}
|
||||
if (isRule) {
|
||||
info.registerFix(new InsertMissingTokenFix(" ->", true), null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent instanceof PsiSwitchLabeledRuleStatement && description.equals(JavaPsiBundle.message("expected.switch.rule"))) {
|
||||
IntentionAction action =
|
||||
QuickFixFactory.getInstance().createWrapSwitchRuleStatementsIntoBlockFix((PsiSwitchLabeledRuleStatement)parent);
|
||||
|
||||
@@ -15,10 +15,17 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class InsertMissingTokenFix implements ModCommandAction {
|
||||
@NotNull
|
||||
private final String myToken;
|
||||
private final boolean myMoveAfter;
|
||||
|
||||
public InsertMissingTokenFix(String token) {
|
||||
public InsertMissingTokenFix(@NotNull String token) {
|
||||
this(token, false);
|
||||
}
|
||||
|
||||
public InsertMissingTokenFix(@NotNull String token, boolean moveAfter) {
|
||||
myToken = token;
|
||||
myMoveAfter = moveAfter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -44,7 +51,11 @@ public class InsertMissingTokenFix implements ModCommandAction {
|
||||
String oldText = document.getText();
|
||||
String newText = oldText.substring(0, offset) + myToken + oldText.substring(offset);
|
||||
VirtualFile file = Objects.requireNonNull(FileDocumentManager.getInstance().getFile(document));
|
||||
return new ModUpdateFileText(file, oldText, newText,
|
||||
List.of(new ModUpdateFileText.Fragment(offset, 0, myToken.length())));
|
||||
ModCommand fix = new ModUpdateFileText(file, oldText, newText,
|
||||
List.of(new ModUpdateFileText.Fragment(offset, 0, myToken.length())));
|
||||
if (myMoveAfter) {
|
||||
fix = fix.andThen(new ModNavigate(file, -1, -1, offset + myToken.length()));
|
||||
}
|
||||
return fix;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
class IncompleteSwitch {
|
||||
|
||||
|
||||
public void testStatement(char o) {
|
||||
switch (o) {
|
||||
case
|
||||
<error descr="':' or '->' expected"><error descr="Expression, pattern, 'default' or 'null' expected">}</error></error>
|
||||
switch (o) {
|
||||
case '1'<EOLError descr="':' or '->' expected"></EOLError>
|
||||
}
|
||||
switch (o) {
|
||||
case '1' when<EOLError descr="Expression expected"></EOLError><EOLError descr="':' or '->' expected"></EOLError>
|
||||
}
|
||||
switch (o) {
|
||||
case <error descr="Primitive types in patterns, instanceof and switch are not supported at language level '21'">char a</error> when a == '1'<EOLError descr="':' or '->' expected"></EOLError>
|
||||
}
|
||||
|
||||
|
||||
switch (o) {
|
||||
case '2' -> System.out.println("1");
|
||||
case
|
||||
<error descr="':' or '->' expected"><error descr="Expression, pattern, 'default' or 'null' expected">}</error></error>
|
||||
switch (o) {
|
||||
case '2' -> System.out.println("1");
|
||||
case '1'<EOLError descr="':' or '->' expected"></EOLError>
|
||||
}
|
||||
switch (o) {
|
||||
case '2' -> System.out.println("1");
|
||||
case '1' when<EOLError descr="Expression expected"></EOLError><EOLError descr="':' or '->' expected"></EOLError>
|
||||
}
|
||||
switch (o) {
|
||||
case '2' -> System.out.println("1");
|
||||
case <error descr="Primitive types in patterns, instanceof and switch are not supported at language level '21'">char a</error> when a == '1'<EOLError descr="':' or '->' expected"></EOLError>
|
||||
}
|
||||
}
|
||||
|
||||
public void testExpression(char o) {
|
||||
|
||||
int i = switch (<error descr="'switch' expression does not cover all possible input values">o</error>) {
|
||||
case '2':
|
||||
yield 1;
|
||||
case
|
||||
<error descr="':' or '->' expected"><error descr="Expression, pattern, 'default' or 'null' expected">}</error></error>;
|
||||
|
||||
i = switch (<error descr="'switch' expression does not cover all possible input values">o</error>) {
|
||||
case '2':
|
||||
yield 2;
|
||||
case '1'<EOLError descr="':' or '->' expected"></EOLError>
|
||||
};
|
||||
i = switch (<error descr="'switch' expression does not cover all possible input values">o</error>) {
|
||||
case '2':
|
||||
yield 2;
|
||||
case '1' when<EOLError descr="Expression expected"></EOLError><EOLError descr="':' or '->' expected"></EOLError>
|
||||
};
|
||||
i = switch (o) {
|
||||
case '2':
|
||||
yield 2;
|
||||
case <error descr="Primitive types in patterns, instanceof and switch are not supported at language level '21'">char a</error> when a == '1'<EOLError descr="':' or '->' expected"></EOLError>
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class IncompleteSwitchFixColon {
|
||||
|
||||
public void testStatement(char o) {
|
||||
|
||||
switch (o) {
|
||||
case '2'-> System.out.println("1");
|
||||
case '1'<caret><EOLError descr="':' or '->' expected"></EOLError>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class IncompleteSwitchFixColon {
|
||||
|
||||
public void testStatement(char o) {
|
||||
|
||||
switch (o) {
|
||||
case '2'-> System.out.println("1");
|
||||
case '1' -><caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class IncompleteSwitchFixColon {
|
||||
|
||||
public void testStatement(char o) {
|
||||
|
||||
switch (o) {
|
||||
case '2':
|
||||
System.out.println("1");
|
||||
break;
|
||||
case '1'<caret><EOLError descr="':' or '->' expected"></EOLError>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class IncompleteSwitchFixColon {
|
||||
|
||||
public void testStatement(char o) {
|
||||
|
||||
switch (o) {
|
||||
case '2':
|
||||
System.out.println("1");
|
||||
break;
|
||||
case '1':<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
// Copyright 2000-2019 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-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeInsight.daemon
|
||||
|
||||
import com.intellij.JavaTestUtil
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.InsertMissingTokenFix
|
||||
import com.intellij.codeInspection.redundantCast.RedundantCastInspection
|
||||
import com.intellij.pom.java.LanguageLevel
|
||||
import com.intellij.testFramework.IdeaTestUtil
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.JAVA_15
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase.assertEquals
|
||||
|
||||
class JavaSwitchExpressionsHighlightingTest : LightJavaCodeInsightFixtureTestCase() {
|
||||
override fun getProjectDescriptor() = JAVA_15
|
||||
@@ -32,6 +35,26 @@ class JavaSwitchExpressionsHighlightingTest : LightJavaCodeInsightFixtureTestCas
|
||||
myFixture.enableInspections(RedundantCastInspection())
|
||||
doTest()
|
||||
}
|
||||
fun testIncompleteSwitch() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21) { doTest() }
|
||||
fun testIncompleteSwitchFixColon() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21) {
|
||||
doTest()
|
||||
val availableIntentions = myFixture.availableIntentions
|
||||
.mapNotNull { it.asModCommandAction() }
|
||||
.filter { it is InsertMissingTokenFix }
|
||||
assertEquals(1, availableIntentions.size)
|
||||
myFixture.launchAction(availableIntentions.first().asIntention())
|
||||
myFixture.checkResultByFile("${getTestName(false)}_after.java")
|
||||
}
|
||||
|
||||
fun testIncompleteSwitchFixArray() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21) {
|
||||
doTest()
|
||||
val availableIntentions = myFixture.availableIntentions
|
||||
.mapNotNull { it.asModCommandAction() }
|
||||
.filter { it is InsertMissingTokenFix }
|
||||
assertEquals(1, availableIntentions.size)
|
||||
myFixture.launchAction(availableIntentions.first().asIntention())
|
||||
myFixture.checkResultByFile("${getTestName(false)}_after.java")
|
||||
}
|
||||
|
||||
private fun doTest() {
|
||||
myFixture.configureByFile("${getTestName(false)}.java")
|
||||
|
||||
Reference in New Issue
Block a user