mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
[java-highlighting] Record Patterns (Second Preview) in Java: fix false negative of the error Pattern is not exhaustive
IDEA-312087 GitOrigin-RevId: 8d7a892726aa233a97a16721a6cea1755465f7c4
This commit is contained in:
committed by
intellij-monorepo-bot
parent
629db5f111
commit
d7ddd45967
@@ -50,6 +50,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static com.intellij.psi.PsiModifier.SEALED;
|
||||
import static com.intellij.util.ObjectUtils.tryCast;
|
||||
|
||||
// java highlighting: problems in java code like unresolved/incompatible symbols/methods etc.
|
||||
@@ -2018,14 +2019,26 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (itemType == null) return;
|
||||
checkForEachPatternApplicable(deconstructionPattern, patternType, itemType);
|
||||
if (myHolder.hasErrorResults()) return;
|
||||
if (!PatternsInSwitchBlockHighlightingModel.checkRecordExhaustiveness(Collections.singletonList(deconstructionPattern))) {
|
||||
String description = JavaErrorBundle.message("pattern.is.not.exhaustive", JavaHighlightUtil.formatType(patternType),
|
||||
JavaHighlightUtil.formatType(itemType));
|
||||
add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(deconstructionPattern).descriptionAndTooltip(description));
|
||||
PsiClass selectorClass = PsiUtil.resolveClassInClassTypeOnly(TypeConversionUtil.erasure(itemType));
|
||||
if (selectorClass != null && (selectorClass.hasModifierProperty(SEALED) || selectorClass.isRecord())) {
|
||||
if (!PatternsInSwitchBlockHighlightingModel.checkRecordExhaustiveness(Collections.singletonList(deconstructionPattern))) {
|
||||
add(createPatternIsNotExhaustiveError(deconstructionPattern, patternType, itemType));
|
||||
}
|
||||
}
|
||||
else {
|
||||
add(createPatternIsNotExhaustiveError(deconstructionPattern, patternType, itemType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static HighlightInfo.Builder createPatternIsNotExhaustiveError(@NotNull PsiDeconstructionPattern pattern,
|
||||
@NotNull PsiType patternType,
|
||||
@NotNull PsiType itemType) {
|
||||
String description = JavaErrorBundle.message("pattern.is.not.exhaustive", JavaHighlightUtil.formatType(patternType),
|
||||
JavaHighlightUtil.formatType(itemType));
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(pattern).descriptionAndTooltip(description);
|
||||
}
|
||||
|
||||
private void checkForEachPatternApplicable(@NotNull PsiDeconstructionPattern pattern,
|
||||
@NotNull PsiType patternType,
|
||||
@NotNull PsiType itemType) {
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import java.util.List;
|
||||
|
||||
class Main {
|
||||
|
||||
void genericTest(RecordWithGeneric<InnerRecord> record) {
|
||||
for (RecordWithGeneric(InnerRecord t ) : List.of(record)) {
|
||||
System.out.println(t);
|
||||
}
|
||||
|
||||
List<RecordWithGeneric<InnerRecord>> lists = List.of(record);
|
||||
for (RecordWithGeneric(InnerRecord t) : lists) {
|
||||
System.out.println(t);
|
||||
}
|
||||
}
|
||||
|
||||
record RecordWithGeneric<T>(T t) {}
|
||||
record InnerRecord(int x) {}
|
||||
|
||||
void test1(List<Upper> list) {
|
||||
for (<error descr="Pattern 'Main.Record' is not exhaustive on 'Main.Upper'">Record(var x)</error> : list) {}
|
||||
}
|
||||
|
||||
void test2(List<UpperWithPermit> list) {
|
||||
for (PermittedRecord(var x) : list) {}
|
||||
}
|
||||
|
||||
void test3(List<? extends PermittedRecord> list) {
|
||||
for (PermittedRecord(var x) : list ) {}
|
||||
}
|
||||
|
||||
void test4(List<? extends UpperWithPermit> list) {
|
||||
for (PermittedRecord(var x) : list ) {}
|
||||
}
|
||||
|
||||
<T extends UpperWithPermit> void test5(List<T> list) {
|
||||
for (PermittedRecord(var x) : list ) {}
|
||||
T t = list.get(0);
|
||||
PermittedRecord r = (PermittedRecord) t;
|
||||
}
|
||||
|
||||
void test6(List<? super UpperWithPermit> list) {
|
||||
for (<error descr="Pattern 'Main.PermittedRecord' is not exhaustive on 'capture<? super Main.UpperWithPermit>'">PermittedRecord(var x)</error> : list) {}
|
||||
}
|
||||
|
||||
void test7(List<PermittedRecord> list) {
|
||||
for (PermittedRecord(var x) : list) {}
|
||||
}
|
||||
|
||||
void test8(List<? super PermittedRecord> list) {
|
||||
for (<error descr="Pattern 'Main.PermittedRecord' is not exhaustive on 'capture<? super Main.PermittedRecord>'">PermittedRecord(var x)</error> : list) {}
|
||||
}
|
||||
|
||||
void test9(List list) {
|
||||
for (<error descr="Pattern 'Main.PermittedRecord' is not exhaustive on 'java.lang.Object'">PermittedRecord(var x)</error> : list) {}
|
||||
}
|
||||
|
||||
void test10(List<?> list) {
|
||||
for (<error descr="Pattern 'Main.PermittedRecord' is not exhaustive on 'capture<?>'">PermittedRecord(var x)</error> : list) {}
|
||||
}
|
||||
|
||||
void test11(List<Record> list) {
|
||||
for (Record(var x) : list) {}
|
||||
}
|
||||
|
||||
sealed interface UpperWithPermit permits PermittedRecord {}
|
||||
record PermittedRecord(int x) implements UpperWithPermit {}
|
||||
interface Upper {}
|
||||
record Record(List<String> x) implements Upper {}
|
||||
}
|
||||
@@ -81,6 +81,11 @@ public class LightPatternsHighlightingTest extends LightJavaCodeInsightFixtureTe
|
||||
public void testDeconstructionInstanceOf20() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
}
|
||||
|
||||
public void testForEachPatternExhaustiveness() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
myFixture.checkHighlighting();
|
||||
|
||||
Reference in New Issue
Block a user