mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 05:51:25 +07:00
[java] IDEA-345498 Remove explicit Java 20-preview support and parenthesized patterns
GitOrigin-RevId: 8d646035979e3ec0a7de3c6f58a4e6ec9967bdbd
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c56dbec5f8
commit
d0cf7b359a
@@ -787,9 +787,7 @@ public final class HighlightControlFlowUtil {
|
||||
LanguageLevel level = PsiUtil.getLanguageLevel(refLabel);
|
||||
//this assignment is covered by com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil.checkOutsideDeclaredCantBeAssignmentInGuard
|
||||
boolean isAssignment = context instanceof PsiReferenceExpression psiExpression && PsiUtil.isAccessedForWriting(psiExpression);
|
||||
if (((level == LanguageLevel.JDK_20_PREVIEW && refLabel != PsiTreeUtil.getParentOfType(variable, PsiSwitchLabelStatementBase.class)) ||
|
||||
(level != LanguageLevel.JDK_20_PREVIEW && !isAssignment &&
|
||||
!PsiTreeUtil.isAncestor(guardExpression, variable, false))) &&
|
||||
if (!isAssignment && !PsiTreeUtil.isAncestor(guardExpression, variable, false) &&
|
||||
!isEffectivelyFinal(variable, refLabel, context)) {
|
||||
String message = JavaErrorBundle.message("guarded.pattern.variable.must.be.final");
|
||||
HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(context).descriptionAndTooltip(message);
|
||||
|
||||
@@ -358,9 +358,6 @@ public final class HighlightUtil {
|
||||
if (expressionVariable == null) {
|
||||
return null;
|
||||
}
|
||||
if (PsiUtil.getLanguageLevel(expressionVariable) == LanguageLevel.JDK_20_PREVIEW) {
|
||||
return null;
|
||||
}
|
||||
if (!PsiUtil.isAccessedForWriting(expressionVariable)) {
|
||||
return null;
|
||||
}
|
||||
@@ -3842,6 +3839,7 @@ public final class HighlightUtil {
|
||||
if (PsiUtil.isAvailable(feature, element)) return;
|
||||
if (feature.isLimited()) return; //no reason for applying it because it can be outdated
|
||||
LanguageLevel applicableLevel = getApplicableLevel(element.getContainingFile(), feature);
|
||||
if (applicableLevel == LanguageLevel.JDK_X) return; // do not suggest to use experimental level
|
||||
registrar.add(getFixFactory().createIncreaseLanguageLevelFix(applicableLevel));
|
||||
registrar.add(getFixFactory().createUpgradeSdkFor(applicableLevel));
|
||||
registrar.add(getFixFactory().createShowModulePropertiesFix(element));
|
||||
|
||||
@@ -878,9 +878,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!hasErrorResults()) HighlightUtil.checkInstanceOfApplicable(expression, myErrorSink);
|
||||
if (!hasErrorResults()) add(GenericsHighlightUtil.checkInstanceOfGenericType(myLanguageLevel, expression));
|
||||
if (!hasErrorResults() &&
|
||||
myLanguageLevel.isAtLeast(LanguageLevel.JDK_16) &&
|
||||
JavaFeature.PATTERNS.isSufficient(myLanguageLevel) &&
|
||||
// 5.20.2 Removed restriction on pattern instanceof for unconditional patterns (JEP 432, 440)
|
||||
(myLanguageLevel.isLessThan(LanguageLevel.JDK_21) && myLanguageLevel != LanguageLevel.JDK_20_PREVIEW)) {
|
||||
!JavaFeature.PATTERN_GUARDS_AND_RECORD_PATTERNS.isSufficient(myLanguageLevel)) {
|
||||
add(HighlightUtil.checkInstanceOfPatternSupertype(expression));
|
||||
}
|
||||
}
|
||||
@@ -2003,16 +2003,10 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
// suggest increasing the language level.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParenthesizedPattern(@NotNull PsiParenthesizedPattern pattern) {
|
||||
super.visitParenthesizedPattern(pattern);
|
||||
add(checkFeature(pattern, JavaFeature.PARENTHESIZED_PATTERNS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPatternVariable(@NotNull PsiPatternVariable variable) {
|
||||
super.visitPatternVariable(variable);
|
||||
if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_20_PREVIEW) && variable.getPattern() instanceof PsiDeconstructionPattern) {
|
||||
if (variable.getPattern() instanceof PsiDeconstructionPattern) {
|
||||
String message = JavaErrorBundle.message("identifier.is.not.allowed.here");
|
||||
add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(variable).descriptionAndTooltip(message));
|
||||
}
|
||||
|
||||
@@ -44,7 +44,6 @@ public enum HighlightingFeature {
|
||||
LOCAL_INTERFACES(JavaFeature.LOCAL_INTERFACES),
|
||||
LOCAL_ENUMS(JavaFeature.LOCAL_ENUMS),
|
||||
INNER_STATICS(JavaFeature.INNER_STATICS),
|
||||
PARENTHESIZED_PATTERNS(JavaFeature.PARENTHESIZED_PATTERNS),
|
||||
PATTERNS_IN_SWITCH(JavaFeature.PATTERNS_IN_SWITCH),
|
||||
PATTERN_GUARDS_AND_RECORD_PATTERNS(JavaFeature.PATTERN_GUARDS_AND_RECORD_PATTERNS),
|
||||
RECORD_PATTERNS_IN_FOR_EACH(JavaFeature.RECORD_PATTERNS_IN_FOR_EACH),
|
||||
|
||||
@@ -12,7 +12,6 @@ import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.modcommand.ModCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.PsiClassType.ClassResolveResult;
|
||||
import com.intellij.psi.util.*;
|
||||
@@ -57,14 +56,6 @@ final class PatternHighlightingModel {
|
||||
errorSink.accept(info);
|
||||
return true;
|
||||
}
|
||||
PsiJavaCodeReferenceElement ref = typeElement.getInnermostComponentReferenceElement();
|
||||
if (recordClass.hasTypeParameters() && ref != null && ref.getTypeParameterCount() == 0 &&
|
||||
PsiUtil.getLanguageLevel(deconstructionPattern).isLessThan(LanguageLevel.JDK_20_PREVIEW)) {
|
||||
String message = JavaErrorBundle.message("error.raw.deconstruction", typeElement.getText());
|
||||
HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(message);
|
||||
errorSink.accept(info);
|
||||
return true;
|
||||
}
|
||||
PsiSubstitutor substitutor = resolveResult.getSubstitutor();
|
||||
PsiRecordComponent[] recordComponents = recordClass.getRecordComponents();
|
||||
PsiPattern[] deconstructionComponents = deconstructionPattern.getDeconstructionList().getDeconstructionComponents();
|
||||
@@ -220,9 +211,6 @@ final class PatternHighlightingModel {
|
||||
static RecordExhaustivenessResult checkRecordExhaustiveness(@NotNull List<? extends PsiCaseLabelElement> elements,
|
||||
@NotNull PsiType selectorType,
|
||||
@NotNull PsiElement context) {
|
||||
if (PsiUtil.getLanguageLevel(context) == LanguageLevel.JDK_20_PREVIEW) {
|
||||
return PatternHighlightingModelJava20Preview.checkRecordExhaustiveness(elements);
|
||||
}
|
||||
return checkRecordPatternExhaustivenessForDescription(preparePatternDescription(elements), selectorType, context);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,310 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.PsiClassType.ClassResolveResult;
|
||||
import com.intellij.psi.util.JavaPsiPatternUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import com.intellij.util.containers.SmartHashSet;
|
||||
import com.siyeh.ig.psiutils.TypeUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.intellij.codeInsight.daemon.impl.analysis.PatternHighlightingModel.RecordExhaustivenessResult;
|
||||
import static com.intellij.psi.PsiModifier.ABSTRACT;
|
||||
import static com.intellij.psi.PsiModifier.SEALED;
|
||||
|
||||
final class PatternHighlightingModelJava20Preview {
|
||||
|
||||
/**
|
||||
* Old implementation for Java 20 PREVIEW
|
||||
*/
|
||||
@NotNull
|
||||
static RecordExhaustivenessResult checkRecordExhaustiveness(@NotNull List<? extends PsiCaseLabelElement> caseElements) {
|
||||
List<PsiPrimaryPattern> unconditionalPatterns =
|
||||
ContainerUtil.mapNotNull(caseElements, element -> JavaPsiPatternUtil.findUnconditionalPattern(element));
|
||||
List<PsiDeconstructionPattern> unconditionalDeconstructions =
|
||||
ContainerUtil.filterIsInstance(unconditionalPatterns, PsiDeconstructionPattern.class);
|
||||
if (unconditionalDeconstructions.isEmpty()) {
|
||||
return RecordExhaustivenessResult.createExhaustiveResult(); //no deconstruction
|
||||
}
|
||||
|
||||
PsiDeconstructionPattern scope = unconditionalDeconstructions.get(0);
|
||||
|
||||
MultiMap<PsiType, PsiDeconstructionPattern> deconstructionGroups =
|
||||
ContainerUtil.groupBy(unconditionalDeconstructions, deconstruction -> JavaPsiPatternUtil.getPatternType(deconstruction));
|
||||
|
||||
MultiMap<PsiType, PsiTypeTestPattern> typeTestPatterns =
|
||||
ContainerUtil.groupBy(
|
||||
ContainerUtil.filterIsInstance(unconditionalPatterns, PsiTypeTestPattern.class),
|
||||
pattern -> JavaPsiPatternUtil.getPatternType(pattern));
|
||||
|
||||
RecordExhaustivenessResult result = RecordExhaustivenessResult.createExhaustiveResult();
|
||||
for (Map.Entry<PsiType, Collection<PsiDeconstructionPattern>> entry : deconstructionGroups.entrySet()) {
|
||||
PsiType type = entry.getKey();
|
||||
if (type == null) continue;
|
||||
Collection<PsiTypeTestPattern> patterns = typeTestPatterns.get(type);
|
||||
if (!patterns.isEmpty()) {
|
||||
for (PsiPrimaryPattern pattern : patterns) {
|
||||
//check, there is a non-deconstruction pattern, which cover it
|
||||
if (JavaPsiPatternUtil.isUnconditionalForType(pattern, type)) {
|
||||
return RecordExhaustivenessResult.createExhaustiveResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
ClassResolveResult resolve = PsiUtil.resolveGenericsClassInType(PsiUtil.captureToplevelWildcards(type, scope));
|
||||
PsiClass selectorClass = resolve.getElement();
|
||||
PsiSubstitutor substitutor = resolve.getSubstitutor();
|
||||
if (selectorClass == null) continue;
|
||||
List<PsiType> recordTypes =
|
||||
ContainerUtil.map(selectorClass.getRecordComponents(), component -> substitutor.substitute(component.getType()));
|
||||
|
||||
List<List<PsiPattern>> deconstructionComponentsGroup = ContainerUtil.map(entry.getValue(), deconstruction -> Arrays.asList(
|
||||
deconstruction.getDeconstructionList().getDeconstructionComponents()));
|
||||
if (ContainerUtil.exists(deconstructionComponentsGroup, group -> group.size() != recordTypes.size())) {
|
||||
return RecordExhaustivenessResult.createExhaustiveResult(); //it checked before, don't repeat error
|
||||
}
|
||||
RecordExhaustivenessResult currentResult = findExhaustiveInGroup(type, recordTypes, deconstructionComponentsGroup);
|
||||
result.merge(currentResult);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Old implementation for Java 20 PREVIEW
|
||||
*/
|
||||
@NotNull
|
||||
private static RecordExhaustivenessResult findExhaustiveInGroup(@NotNull PsiType currentRecordType,
|
||||
@NotNull List<? extends PsiType> leftRecordTypes,
|
||||
@NotNull List<? extends List<PsiPattern>> deconstructions) {
|
||||
if (leftRecordTypes.isEmpty() || ContainerUtil.exists(deconstructions, t -> t.size() == 0)) {
|
||||
//there is no deconstruction, a case with an empty set of labels is considered before, don't repeat errors
|
||||
return RecordExhaustivenessResult.createExhaustiveResult();
|
||||
}
|
||||
PsiType typeToCheck = leftRecordTypes.get(0);
|
||||
//A case with unresolved type checks before, don't repeat errors
|
||||
if (typeToCheck == null) return RecordExhaustivenessResult.createExhaustiveResult();
|
||||
MultiMap<PsiType, List<PsiPattern>> groupedByType = ContainerUtil.groupBy(deconstructions,
|
||||
deconstructionComponents -> JavaPsiPatternUtil.getPatternType(
|
||||
deconstructionComponents.get(0)));
|
||||
List<GroupExhaustiveness> groupsExhaustiveness = getGroupsExhaustiveness(currentRecordType, leftRecordTypes, groupedByType);
|
||||
if (groupsExhaustiveness.isEmpty()) return RecordExhaustivenessResult.createNotBeAdded();
|
||||
List<PsiPattern> checkedExhaustivePatterns = new ArrayList<>();
|
||||
Map<PsiType, BranchesExhaustiveness> notExhaustive = new LinkedHashMap<>();
|
||||
for (GroupExhaustiveness group : groupsExhaustiveness) {
|
||||
if (!group.branchesExhaustiveness().result().isExhaustive()) {
|
||||
PsiType notExhaustiveType = group.psiType();
|
||||
notExhaustive.put(notExhaustiveType, group.branchesExhaustiveness());
|
||||
continue;
|
||||
}
|
||||
Collection<List<PsiPattern>> lists = groupedByType.get(group.psiType());
|
||||
if (lists.isEmpty()) continue;
|
||||
List<PsiPattern> next = lists.iterator().next();
|
||||
if (next == null || next.isEmpty()) continue;
|
||||
checkedExhaustivePatterns.add(next.get(0));
|
||||
}
|
||||
if (ContainerUtil.exists(checkedExhaustivePatterns, pattern -> JavaPsiPatternUtil.isUnconditionalForType(pattern, typeToCheck, true))) {
|
||||
return RecordExhaustivenessResult.createExhaustiveResult(); // exhaustive even without not-exhaustive-subgroup
|
||||
}
|
||||
Set<PsiClass> missedClasses = findMissedClassesForSealed(typeToCheck, checkedExhaustivePatterns);
|
||||
if (missedClasses.isEmpty() && !checkedExhaustivePatterns.isEmpty()) {
|
||||
return RecordExhaustivenessResult.createExhaustiveResult(); //exhaustive even without not-exhaustive-subgroup
|
||||
}
|
||||
//if one of them is unconditional, return any of them
|
||||
List<BranchesExhaustiveness> coveredPatterns =
|
||||
ContainerUtil.filter(notExhaustive.values(), group ->
|
||||
group.branches().stream()
|
||||
.filter(t -> !t.isEmpty())
|
||||
.map(patterns -> patterns.get(0))
|
||||
.anyMatch(pattern -> JavaPsiPatternUtil.isUnconditionalForType(pattern, typeToCheck, true)));
|
||||
if (!coveredPatterns.isEmpty()) {
|
||||
RecordExhaustivenessResult nextResult = coveredPatterns.get(0).result();
|
||||
nextResult.addNextType(currentRecordType, typeToCheck);
|
||||
return nextResult;
|
||||
}
|
||||
return mergeMissedClasses(currentRecordType, leftRecordTypes, notExhaustive, missedClasses);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Old implementation for Java 20 PREVIEW
|
||||
*/
|
||||
@NotNull
|
||||
private static RecordExhaustivenessResult mergeMissedClasses(@NotNull PsiType recordType,
|
||||
@NotNull List<? extends PsiType> recordTypes,
|
||||
@NotNull Map<PsiType, BranchesExhaustiveness> notExhaustiveBranches,
|
||||
@NotNull Set<PsiClass> missedClasses) {
|
||||
RecordExhaustivenessResult result = RecordExhaustivenessResult.createNotExhaustiveResult();
|
||||
for (PsiClass missedClass : missedClasses) {
|
||||
PsiClassType missedType = PsiTypesUtil.getClassType(missedClass);
|
||||
BranchesExhaustiveness branchesExhaustiveness = notExhaustiveBranches.get(missedType);
|
||||
if (branchesExhaustiveness == null) {
|
||||
//There is a chance that branchExhaustiveness cover partially this new branch,
|
||||
//but let's not recalculate and make it simple and fast.
|
||||
//Otherwise, we have to process all classes in a permit list every time
|
||||
result.addNewBranch(recordType, missedType, recordTypes);
|
||||
}
|
||||
else {
|
||||
RecordExhaustivenessResult recordExhaustivenessResult = branchesExhaustiveness.result();
|
||||
recordExhaustivenessResult.addNextType(recordType, missedType);
|
||||
result.merge(recordExhaustivenessResult);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Old implementation for Java 20 PREVIEW
|
||||
*/
|
||||
private record GroupExhaustiveness(@NotNull PsiType psiType,
|
||||
@NotNull PatternHighlightingModelJava20Preview.BranchesExhaustiveness branchesExhaustiveness) {
|
||||
GroupExhaustiveness(@NotNull PsiType psiType, @NotNull RecordExhaustivenessResult result,
|
||||
@NotNull Collection<List<PsiPattern>> branches) {
|
||||
this(psiType, new BranchesExhaustiveness(result, branches));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Old implementation for Java 20 PREVIEW
|
||||
*/
|
||||
private record BranchesExhaustiveness(@NotNull RecordExhaustivenessResult result,
|
||||
@NotNull Collection<List<PsiPattern>> branches) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Old implementation for Java 20 PREVIEW
|
||||
*/
|
||||
@NotNull
|
||||
private static List<GroupExhaustiveness> getGroupsExhaustiveness(@NotNull PsiType recordType,
|
||||
@NotNull List<? extends PsiType> recordTypes,
|
||||
@NotNull MultiMap<PsiType, List<PsiPattern>> groupedByType) {
|
||||
MultiMap<PsiType, List<PsiPattern>> deconstructionGroups = getDeconstructionGroupsByType(groupedByType);
|
||||
|
||||
return ContainerUtil.map(deconstructionGroups.entrySet(), deconstructionGroup -> {
|
||||
if (ContainerUtil.exists(deconstructionGroup.getValue(), t -> t == null || t.isEmpty())) {
|
||||
return new GroupExhaustiveness(deconstructionGroup.getKey(),
|
||||
RecordExhaustivenessResult.createNotBeAdded(), deconstructionGroup.getValue());
|
||||
}
|
||||
List<PsiPattern> firstElements = ContainerUtil.map(deconstructionGroup.getValue(), it -> it.get(0));
|
||||
if (ContainerUtil.exists(firstElements, pattern -> pattern instanceof PsiDeconstructionPattern)) {
|
||||
RecordExhaustivenessResult nestedResult = checkRecordExhaustiveness(firstElements);
|
||||
if (!nestedResult.isExhaustive()) {
|
||||
//support only first level deconstruction
|
||||
if (nestedResult.canBeAdded() && nestedResult.missedBranchesByType.size() == 1) {
|
||||
RecordExhaustivenessResult result = RecordExhaustivenessResult.createNotExhaustiveResult();
|
||||
result.addNewBranch(recordType, null, recordTypes);
|
||||
return new GroupExhaustiveness(deconstructionGroup.getKey(), result, deconstructionGroup.getValue());
|
||||
}
|
||||
else {
|
||||
return new GroupExhaustiveness(deconstructionGroup.getKey(), RecordExhaustivenessResult.createNotBeAdded(),
|
||||
deconstructionGroup.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
RecordExhaustivenessResult result = findExhaustiveInGroup(
|
||||
recordType, dropFirst(recordTypes), ContainerUtil.map(deconstructionGroup.getValue(), PatternHighlightingModelJava20Preview::dropFirst)
|
||||
);
|
||||
return new GroupExhaustiveness(deconstructionGroup.getKey(), result, deconstructionGroup.getValue());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Old implementation for Java 20 PREVIEW
|
||||
*/
|
||||
@NotNull
|
||||
private static MultiMap<PsiType, List<PsiPattern>> getDeconstructionGroupsByType(@NotNull MultiMap<PsiType, List<PsiPattern>> groupedByType) {
|
||||
MultiMap<PsiType, List<PsiPattern>> deconstructionGroups = MultiMap.create();
|
||||
Set<PsiType> types = new HashSet<>(groupedByType.keySet());
|
||||
for (PsiType currentType : types) {
|
||||
for (PsiType compareType : groupedByType.keySet()) {
|
||||
if (JavaPsiPatternUtil.dominates(compareType, currentType)) {
|
||||
deconstructionGroups.putValues(currentType, groupedByType.get(compareType));
|
||||
}
|
||||
}
|
||||
}
|
||||
return deconstructionGroups;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Old implementation for Java 20 PREVIEW
|
||||
*/
|
||||
private static <T> List<T> dropFirst(List<T> list) {
|
||||
return list.subList(1, list.size());
|
||||
}
|
||||
|
||||
|
||||
static @NotNull Set<PsiClass> findMissedClassesForSealed(@NotNull PsiType selectorType,
|
||||
@NotNull List<? extends PsiCaseLabelElement> elements) {
|
||||
LinkedHashMap<PsiClass, PsiPattern> patternClasses = findPatternClasses(elements);
|
||||
List<PsiPrimaryPattern> unconditionalPatterns =
|
||||
ContainerUtil.mapNotNull(elements, element -> JavaPsiPatternUtil.findUnconditionalPattern(element));
|
||||
List<PsiTypeTestPattern> typeTestPatterns =
|
||||
ContainerUtil.filterIsInstance(unconditionalPatterns, PsiTypeTestPattern.class);
|
||||
|
||||
PsiClass selectorClass = PsiUtil.resolveClassInClassTypeOnly(TypeConversionUtil.erasure(selectorType));
|
||||
if (selectorClass == null) return Collections.emptySet();
|
||||
Queue<PsiClass> nonVisited = new ArrayDeque<>();
|
||||
nonVisited.add(selectorClass);
|
||||
Set<PsiClass> visited = new SmartHashSet<>();
|
||||
Set<PsiClass> missingClasses = new LinkedHashSet<>();
|
||||
while (!nonVisited.isEmpty()) {
|
||||
PsiClass psiClass = nonVisited.peek();
|
||||
if (psiClass.hasModifierProperty(SEALED) && (psiClass.hasModifierProperty(ABSTRACT) ||
|
||||
psiClass.equals(selectorClass))) {
|
||||
for (PsiClass permittedClass : SwitchBlockHighlightingModel.PatternsInSwitchBlockHighlightingModel.getPermittedClasses(psiClass)) {
|
||||
if (!visited.add(permittedClass)) continue;
|
||||
PsiPattern pattern = patternClasses.get(permittedClass);
|
||||
PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(selectorClass, permittedClass, PsiSubstitutor.EMPTY);
|
||||
PsiType permittedType = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, substitutor);
|
||||
if (pattern == null && (PsiUtil.getLanguageLevel(permittedClass).isLessThan(LanguageLevel.JDK_18) ||
|
||||
TypeConversionUtil.areTypesConvertible(selectorType, permittedType)) ||
|
||||
pattern != null && !JavaPsiPatternUtil.isUnconditionalForType(pattern, TypeUtils.getType(permittedClass), true)) {
|
||||
nonVisited.add(permittedClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
visited.add(psiClass);
|
||||
if (!ContainerUtil.exists(typeTestPatterns,
|
||||
pattern -> JavaPsiPatternUtil.isUnconditionalForType(pattern, TypeUtils.getType(psiClass), true))) {
|
||||
missingClasses.add(psiClass);
|
||||
}
|
||||
}
|
||||
nonVisited.poll();
|
||||
}
|
||||
if (!selectorClass.hasModifierProperty(ABSTRACT)) {
|
||||
missingClasses.add(selectorClass);
|
||||
}
|
||||
return missingClasses;
|
||||
}
|
||||
|
||||
private static @NotNull LinkedHashMap<PsiClass, PsiPattern> findPatternClasses(@NotNull List<? extends PsiCaseLabelElement> elements) {
|
||||
LinkedHashMap<PsiClass, PsiPattern> patternClasses = new LinkedHashMap<>();
|
||||
for (PsiCaseLabelElement element : elements) {
|
||||
PsiPattern pattern = SwitchBlockHighlightingModel.extractPattern(element);
|
||||
if (pattern == null) continue;
|
||||
PsiClass patternClass;
|
||||
patternClass = PsiUtil.resolveClassInClassTypeOnly(JavaPsiPatternUtil.getPatternType(element));
|
||||
if (patternClass != null) {
|
||||
patternClasses.put(patternClass, pattern);
|
||||
Set<PsiClass> classes = SwitchBlockHighlightingModel.returnAllPermittedClasses(patternClass);
|
||||
for (PsiClass aClass : classes) {
|
||||
patternClasses.put(aClass, pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
return patternClasses;
|
||||
}
|
||||
}
|
||||
@@ -1167,8 +1167,7 @@ public class SwitchBlockHighlightingModel {
|
||||
AtomicBoolean reported = new AtomicBoolean();
|
||||
dominatedLabels.forEach((overWhom, who) -> {
|
||||
HighlightInfo.Builder info = createError(overWhom, JavaErrorBundle.message("switch.dominance.of.preceding.label", who.getText()));
|
||||
if (PsiUtil.getLanguageLevel(who).isAtLeast(LanguageLevel.JDK_20_PREVIEW) &&
|
||||
who instanceof PsiKeyword && PsiKeyword.DEFAULT.equals(who.getText()) ||
|
||||
if (who instanceof PsiKeyword && PsiKeyword.DEFAULT.equals(who.getText()) ||
|
||||
isInCaseNullDefaultLabel(who)) {
|
||||
PsiSwitchLabelStatementBase labelStatementBase = PsiTreeUtil.getParentOfType(who, PsiSwitchLabelStatementBase.class);
|
||||
if (labelStatementBase != null) {
|
||||
@@ -1238,7 +1237,7 @@ public class SwitchBlockHighlightingModel {
|
||||
}
|
||||
List<PsiType> sealedTypes = getAbstractSealedTypes(selectorTypes);
|
||||
if (!sealedTypes.isEmpty()) {
|
||||
errorSink.accept(checkSealed(elements, selectorClass));
|
||||
errorSink.accept(checkSealedClassCompleteness(mySelectorType, elements));
|
||||
return;
|
||||
}
|
||||
//records are final; checking intersections are not needed
|
||||
@@ -1255,18 +1254,6 @@ public class SwitchBlockHighlightingModel {
|
||||
}
|
||||
}
|
||||
|
||||
private HighlightInfo.Builder checkSealed(@NotNull List<? extends PsiCaseLabelElement> elements,
|
||||
@Nullable PsiClass selectorClass) {
|
||||
HighlightInfo.Builder info = checkSealedClassCompleteness(mySelectorType, elements);
|
||||
if (info != null) {
|
||||
return info;
|
||||
}
|
||||
if (selectorClass != null && PsiUtil.getLanguageLevel(selectorClass) == LanguageLevel.JDK_20_PREVIEW) {
|
||||
return checkRecordExhaustiveness(elements, mySelectorType);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PsiType> getAbstractSealedTypes(@NotNull List<PsiType> selectorTypes) {
|
||||
return selectorTypes.stream()
|
||||
@@ -1312,9 +1299,7 @@ public class SwitchBlockHighlightingModel {
|
||||
}
|
||||
else if (labelElement instanceof PsiExpression) {
|
||||
boolean isNullType = isNullType(labelElement);
|
||||
if (isNullType &&
|
||||
PsiUtil.getLanguageLevel(labelElement).isAtLeast(LanguageLevel.JDK_20_PREVIEW) &&
|
||||
isInCaseNullDefaultLabel(labelElement)) {
|
||||
if (isNullType && isInCaseNullDefaultLabel(labelElement)) {
|
||||
// JEP 432
|
||||
// A 'case null, default' label dominates all other switch labels.
|
||||
//
|
||||
@@ -1346,26 +1331,22 @@ public class SwitchBlockHighlightingModel {
|
||||
private HighlightInfo.Builder checkSealedClassCompleteness(@NotNull PsiType selectorType,
|
||||
@NotNull List<? extends PsiCaseLabelElement> elements) {
|
||||
Set<PsiClass> missedClasses;
|
||||
if (LanguageLevel.JDK_20_PREVIEW == PsiUtil.getLanguageLevel(myBlock)) {
|
||||
missedClasses = PatternHighlightingModelJava20Preview.findMissedClassesForSealed(selectorType, elements);
|
||||
}else{
|
||||
List<PatternDescription> descriptions = preparePatternDescription(elements);
|
||||
List<PsiEnumConstant> enumConstants = StreamEx.of(elements).map(element -> getEnumConstant(element)).nonNull().toList();
|
||||
List<PsiClass> missedSealedClasses = StreamEx.of(findMissedClasses(selectorType, descriptions, enumConstants, myBlock).missedClasses())
|
||||
.sortedBy(t->t.getQualifiedName())
|
||||
.toList();
|
||||
missedClasses = new LinkedHashSet<>();
|
||||
//if T is intersection types, it is allowed to choose any of them to cover
|
||||
for (PsiClass missedClass : missedSealedClasses) {
|
||||
PsiClassType missedClassType = TypeUtils.getType(missedClass);
|
||||
if (oneOfUnconditional(missedClassType, selectorType)) {
|
||||
missedClasses.clear();
|
||||
missedClasses.add(missedClass);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
missedClasses.add(missedClass);
|
||||
}
|
||||
List<PatternDescription> descriptions = preparePatternDescription(elements);
|
||||
List<PsiEnumConstant> enumConstants = StreamEx.of(elements).map(element -> getEnumConstant(element)).nonNull().toList();
|
||||
List<PsiClass> missedSealedClasses = StreamEx.of(findMissedClasses(selectorType, descriptions, enumConstants, myBlock).missedClasses())
|
||||
.sortedBy(t->t.getQualifiedName())
|
||||
.toList();
|
||||
missedClasses = new LinkedHashSet<>();
|
||||
//if T is intersection types, it is allowed to choose any of them to cover
|
||||
for (PsiClass missedClass : missedSealedClasses) {
|
||||
PsiClassType missedClassType = TypeUtils.getType(missedClass);
|
||||
if (oneOfUnconditional(missedClassType, selectorType)) {
|
||||
missedClasses.clear();
|
||||
missedClasses.add(missedClass);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
missedClasses.add(missedClass);
|
||||
}
|
||||
}
|
||||
if (missedClasses.isEmpty()) return null;
|
||||
|
||||
@@ -8,10 +8,8 @@ import com.intellij.codeInspection.dataFlow.jvm.problems.JvmDfaProblem;
|
||||
import com.intellij.codeInspection.dataFlow.types.DfTypes;
|
||||
import com.intellij.codeInspection.util.InspectionMessage;
|
||||
import com.intellij.java.analysis.JavaAnalysisBundle;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.JavaPsiPatternUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
@@ -352,12 +350,7 @@ public final class NullabilityProblemKind<T extends PsiElement> {
|
||||
PsiCaseLabelElementList labelElementList = labelStatement.getCaseLabelElementList();
|
||||
if (labelElementList == null) continue;
|
||||
for (PsiCaseLabelElement element : labelElementList.getElements()) {
|
||||
if (element instanceof PsiExpression && TypeConversionUtil.isNullType(((PsiExpression)element).getType())) return null;
|
||||
if (PsiUtil.getLanguageLevel(element).isLessThan(LanguageLevel.JDK_20_PREVIEW) &&
|
||||
element instanceof PsiPattern && expressionType != null &&
|
||||
JavaPsiPatternUtil.isUnconditionalForType(element, expressionType)) {
|
||||
return null;
|
||||
}
|
||||
if (element instanceof PsiExpression caseExpression && TypeConversionUtil.isNullType(caseExpression.getType())) return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ import com.intellij.codeInspection.dataFlow.types.DfTypes;
|
||||
import com.intellij.codeInspection.dataFlow.value.*;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaControlTransferValue.Trap;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.impl.source.tree.java.PsiEmptyExpressionImpl;
|
||||
@@ -1114,7 +1113,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
private void processPatternInInstanceof(@NotNull PsiPattern pattern, @NotNull PsiInstanceOfExpression expression,
|
||||
@NotNull PsiType checkType) {
|
||||
boolean potentiallyRedundantInstanceOf = pattern instanceof PsiTypeTestPattern ||
|
||||
JavaPsiPatternUtil.skipParenthesizedPatternDown(pattern) instanceof PsiTypeTestPattern ||
|
||||
pattern instanceof PsiTypeTestPattern ||
|
||||
pattern instanceof PsiDeconstructionPattern dec && JavaPsiPatternUtil.hasUnconditionalComponents(dec);
|
||||
DfaAnchor instanceofAnchor = potentiallyRedundantInstanceOf ? new JavaExpressionAnchor(expression) : null;
|
||||
DeferredOffset endPatternOffset = new DeferredOffset();
|
||||
@@ -1128,10 +1127,6 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
private void processPattern(@NotNull PsiPattern sourcePattern, @Nullable PsiPattern innerPattern,
|
||||
@NotNull PsiType checkType, @Nullable DfaAnchor instanceofAnchor, @NotNull DeferredOffset endPatternOffset) {
|
||||
if (innerPattern == null) return;
|
||||
else if (innerPattern instanceof PsiParenthesizedPattern) {
|
||||
PsiPattern unwrappedPattern = JavaPsiPatternUtil.skipParenthesizedPatternDown(innerPattern);
|
||||
processPattern(sourcePattern, unwrappedPattern, checkType, instanceofAnchor, endPatternOffset);
|
||||
}
|
||||
else if (innerPattern instanceof PsiDeconstructionPattern deconstructionPattern) {
|
||||
PsiPatternVariable variable = deconstructionPattern.getPatternVariable();
|
||||
PsiType patternType = deconstructionPattern.getTypeElement().getType();
|
||||
@@ -1186,10 +1181,7 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
|
||||
@NotNull DeferredOffset endPatternOffset,
|
||||
@NotNull DfaVariableValue patternDfaVar,
|
||||
@Nullable DfaAnchor instanceofAnchor) {
|
||||
boolean java20plus = PsiUtil.getLanguageLevel(myCodeFragment).isAtLeast(LanguageLevel.JDK_20_PREVIEW);
|
||||
if (java20plus
|
||||
? (sourcePattern == innerPattern || !JavaPsiPatternUtil.isUnconditionalForType(innerPattern, checkType))
|
||||
: !JavaPsiPatternUtil.isUnconditionalForType(innerPattern, checkType)) {
|
||||
if (sourcePattern == innerPattern || !JavaPsiPatternUtil.isUnconditionalForType(innerPattern, checkType)) {
|
||||
addPatternTypeTest(innerPattern, instanceofAnchor, endPatternOffset, patternDfaVar);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.siyeh.ig.errorhandling;
|
||||
import com.intellij.codeInspection.options.OptPane;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.JavaPsiPatternUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.Query;
|
||||
@@ -182,7 +181,7 @@ public final class ExceptionFromCatchWhichDoesntWrapInspection extends BaseInspe
|
||||
if (!(pattern instanceof PsiTypeTestPattern)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement parent = JavaPsiPatternUtil.skipParenthesizedPatternUp(pattern.getParent());
|
||||
final PsiElement parent = pattern.getParent();
|
||||
if (parent instanceof PsiInstanceOfExpression instanceOfExpression) {
|
||||
instanceOfExpression.getOperand().accept(this);
|
||||
}
|
||||
|
||||
@@ -488,8 +488,8 @@ public class EquivalenceChecker {
|
||||
if (pattern1 == null || pattern2 == null) {
|
||||
return EXACT_MISMATCH;
|
||||
}
|
||||
pattern1 = JavaPsiPatternUtil.skipParenthesizedPatternDown(pattern1);
|
||||
pattern2 = JavaPsiPatternUtil.skipParenthesizedPatternDown(pattern2);
|
||||
pattern1 = pattern1;
|
||||
pattern2 = pattern2;
|
||||
if (pattern1 instanceof PsiUnnamedPattern && pattern2 instanceof PsiUnnamedPattern) {
|
||||
return EXACT_MATCH;
|
||||
}
|
||||
@@ -624,7 +624,7 @@ public class EquivalenceChecker {
|
||||
|
||||
private static PsiCaseLabelElement skipParenthesizedElementDown(@Nullable PsiCaseLabelElement element) {
|
||||
if (element instanceof PsiPattern) {
|
||||
return JavaPsiPatternUtil.skipParenthesizedPatternDown((PsiPattern)element);
|
||||
return (PsiPattern)element;
|
||||
}
|
||||
if (element instanceof PsiExpression) {
|
||||
return PsiUtil.skipParenthesizedExprDown((PsiExpression)element);
|
||||
|
||||
@@ -147,28 +147,6 @@ public final class ParenthesesUtils {
|
||||
else if (element instanceof PsiLambdaExpression lambdaExpression) {
|
||||
removeParensFromLambdaExpression(lambdaExpression, ignoreClarifyingParentheses);
|
||||
}
|
||||
else if (element instanceof PsiPattern pattern) {
|
||||
removeParensFromPattern(pattern, ignoreClarifyingParentheses);
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeParensFromPattern(PsiPattern pattern, boolean ignoreClarifyingParentheses) {
|
||||
if (pattern instanceof PsiParenthesizedPattern parenthesizedPattern) {
|
||||
final PsiPattern innerPattern = parenthesizedPattern.getPattern();
|
||||
if (innerPattern == null) {
|
||||
return;
|
||||
}
|
||||
CommentTracker commentTracker = new CommentTracker();
|
||||
commentTracker.markUnchanged(innerPattern);
|
||||
PsiPattern newPattern = (PsiPattern)commentTracker.replaceAndRestoreComments(parenthesizedPattern, innerPattern);
|
||||
removeParentheses(newPattern, ignoreClarifyingParentheses);
|
||||
}
|
||||
else if (pattern instanceof PsiDeconstructionPattern deconstructionPattern) {
|
||||
final PsiPattern[] components = deconstructionPattern.getDeconstructionList().getDeconstructionComponents();
|
||||
for (PsiPattern component : components) {
|
||||
removeParentheses(component, ignoreClarifyingParentheses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeParensFromLambdaExpression(PsiLambdaExpression lambdaExpression, boolean ignoreClarifyingParentheses) {
|
||||
@@ -222,10 +200,6 @@ public final class ParenthesesUtils {
|
||||
boolean ignoreClarifyingParentheses) {
|
||||
final PsiExpression operand = instanceofExpression.getOperand();
|
||||
removeParentheses(operand, ignoreClarifyingParentheses);
|
||||
final PsiPrimaryPattern pattern = instanceofExpression.getPattern();
|
||||
if (pattern != null) {
|
||||
removeParensFromPattern(pattern, ignoreClarifyingParentheses);
|
||||
}
|
||||
}
|
||||
|
||||
private static void removeParensFromPolyadicExpression(@NotNull PsiPolyadicExpression polyadicExpression,
|
||||
|
||||
@@ -17,9 +17,9 @@ package com.siyeh.ig.style;
|
||||
|
||||
import com.intellij.codeInspection.CleanupLocalInspectionTool;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
|
||||
import com.intellij.codeInspection.options.OptPane;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
@@ -103,18 +103,6 @@ public final class UnnecessaryParenthesesInspection extends BaseInspection imple
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParenthesizedPattern(@NotNull PsiParenthesizedPattern pattern) {
|
||||
final PsiElement parent = pattern.getParent();
|
||||
if (parent instanceof PsiParenthesizedPattern) {
|
||||
return;
|
||||
}
|
||||
if (!ErrorUtil.containsDeepError(pattern)) {
|
||||
registerError(pattern);
|
||||
}
|
||||
super.visitParenthesizedPattern(pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParenthesizedExpression(@NotNull PsiParenthesizedExpression expression) {
|
||||
final PsiElement parent = expression.getParent();
|
||||
|
||||
@@ -195,7 +195,6 @@ jdk.17.language.level.description=17 - Sealed types, always-strict floating-poin
|
||||
jdk.18.language.level.description=18 - JavaDoc snippets
|
||||
jdk.19.language.level.description=19 - No new language features
|
||||
jdk.20.language.level.description=20 - No new language features
|
||||
jdk.20.preview.language.level.description=20 (Preview) - Record patterns (2nd preview), pattern matching for switch (4th preview)
|
||||
jdk.21.language.level.description=21 - Record patterns, pattern matching for switch
|
||||
jdk.21.preview.language.level.description=21 (Preview) - String templates, unnamed classes and instance main methods etc.
|
||||
jdk.22.language.level.description=22 - Unnamed variables and patterns
|
||||
|
||||
@@ -59,63 +59,15 @@ public enum JavaFeature {
|
||||
ALWAYS_STRICTFP(LanguageLevel.JDK_17, "feature.strictfp"),
|
||||
INNER_NOT_CAPTURE_THIS(LanguageLevel.JDK_18, "feature.no.this.capture"),
|
||||
JAVADOC_SNIPPETS(LanguageLevel.JDK_18, "feature.javadoc.snippets"),
|
||||
PARENTHESIZED_PATTERNS(LanguageLevel.JDK_20_PREVIEW, "feature.parenthesised.patterns"){
|
||||
@Override
|
||||
public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
|
||||
LanguageLevel until = LanguageLevel.JDK_20_PREVIEW;
|
||||
return until == useSiteLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLimited() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
PATTERNS_IN_SWITCH(LanguageLevel.JDK_21, "feature.patterns.in.switch") {
|
||||
@Override
|
||||
public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
|
||||
return super.isSufficient(useSiteLevel) || LanguageLevel.JDK_20_PREVIEW == useSiteLevel;
|
||||
}
|
||||
},
|
||||
PATTERN_GUARDS_AND_RECORD_PATTERNS(LanguageLevel.JDK_21, "feature.pattern.guard.and.record.patterns"){
|
||||
@Override
|
||||
public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
|
||||
return super.isSufficient(useSiteLevel) || LanguageLevel.JDK_20_PREVIEW == useSiteLevel;
|
||||
}
|
||||
},
|
||||
RECORD_PATTERNS_IN_FOR_EACH(LanguageLevel.JDK_20_PREVIEW, "feature.record.patterns.in.for.each"){
|
||||
@Override
|
||||
public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
|
||||
return LanguageLevel.JDK_20_PREVIEW == useSiteLevel.getSupportedLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLimited() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
VIRTUAL_THREADS(LanguageLevel.JDK_20_PREVIEW, "feature.virtual.threads") {
|
||||
@Override
|
||||
public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
|
||||
return LanguageLevel.JDK_20_PREVIEW == useSiteLevel.getSupportedLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLimited() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
FOREIGN_FUNCTIONS(LanguageLevel.JDK_20_PREVIEW, "feature.foreign.functions") {
|
||||
@Override
|
||||
public boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
|
||||
return LanguageLevel.JDK_20_PREVIEW == useSiteLevel.getSupportedLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLimited() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
PATTERNS_IN_SWITCH(LanguageLevel.JDK_21, "feature.patterns.in.switch"),
|
||||
PATTERN_GUARDS_AND_RECORD_PATTERNS(LanguageLevel.JDK_21, "feature.pattern.guard.and.record.patterns"),
|
||||
/**
|
||||
* Was a preview feature in Java 20 Preview.
|
||||
* Keep the implementation, as it could reappear in the future.
|
||||
*/
|
||||
RECORD_PATTERNS_IN_FOR_EACH(LanguageLevel.JDK_X, "feature.record.patterns.in.for.each"),
|
||||
VIRTUAL_THREADS(LanguageLevel.JDK_21, "feature.virtual.threads"),
|
||||
FOREIGN_FUNCTIONS(LanguageLevel.JDK_21, "feature.foreign.functions"),
|
||||
ENUM_QUALIFIED_NAME_IN_SWITCH(LanguageLevel.JDK_21, "feature.enum.qualified.name.in.switch"),
|
||||
STRING_TEMPLATES(LanguageLevel.JDK_21_PREVIEW, "feature.string.templates"),
|
||||
UNNAMED_PATTERNS_AND_VARIABLES(LanguageLevel.JDK_22, "feature.unnamed.vars") {
|
||||
|
||||
@@ -44,7 +44,6 @@ public enum LanguageLevel {
|
||||
JDK_18(JavaPsiBundle.messagePointer("jdk.18.language.level.description"), 18),
|
||||
JDK_19(JavaPsiBundle.messagePointer("jdk.19.language.level.description"), 19),
|
||||
JDK_20(JavaPsiBundle.messagePointer("jdk.20.language.level.description"), 20),
|
||||
JDK_20_PREVIEW(JavaPsiBundle.messagePointer("jdk.20.preview.language.level.description"), 20),
|
||||
JDK_21(JavaPsiBundle.messagePointer("jdk.21.language.level.description"), 21),
|
||||
JDK_21_PREVIEW(JavaPsiBundle.messagePointer("jdk.21.preview.language.level.description"), 21),
|
||||
JDK_22(JavaPsiBundle.messagePointer("jdk.22.language.level.description"), 22),
|
||||
@@ -56,11 +55,13 @@ public enum LanguageLevel {
|
||||
// except the tests that explicitly test the obsolete levels
|
||||
|
||||
@ApiStatus.Obsolete
|
||||
JDK_17_PREVIEW(17, JDK_20_PREVIEW),
|
||||
JDK_17_PREVIEW(17, JDK_21),
|
||||
@ApiStatus.Obsolete
|
||||
JDK_18_PREVIEW(18, JDK_20_PREVIEW),
|
||||
JDK_18_PREVIEW(18, JDK_21),
|
||||
@ApiStatus.Obsolete
|
||||
JDK_19_PREVIEW(19, JDK_20_PREVIEW),
|
||||
JDK_19_PREVIEW(19, JDK_21),
|
||||
@ApiStatus.Obsolete
|
||||
JDK_20_PREVIEW(20, JDK_21),
|
||||
;
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,7 @@ public class BasicPatternParser {
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
public boolean isPattern(final PsiBuilder builder) {
|
||||
PsiBuilder.Marker patternStart = preParsePattern(builder, true);
|
||||
PsiBuilder.Marker patternStart = preParsePattern(builder);
|
||||
if (patternStart == null) {
|
||||
return false;
|
||||
}
|
||||
@@ -56,13 +56,8 @@ public class BasicPatternParser {
|
||||
|
||||
|
||||
@Nullable("when not pattern")
|
||||
PsiBuilder.Marker preParsePattern(final PsiBuilder builder, boolean parensAllowed) {
|
||||
PsiBuilder.Marker preParsePattern(final PsiBuilder builder) {
|
||||
PsiBuilder.Marker patternStart = builder.mark();
|
||||
if (parensAllowed) {
|
||||
while (builder.getTokenType() == JavaTokenType.LPARENTH) {
|
||||
builder.advanceLexer();
|
||||
}
|
||||
}
|
||||
Boolean hasNoModifier = myParser.getDeclarationParser().parseModifierList(builder, PATTERN_MODIFIERS).second;
|
||||
PsiBuilder.Marker type =
|
||||
myParser.getReferenceParser().parseType(builder, BasicReferenceParser.EAT_LAST_DOT | BasicReferenceParser.WILDCARD);
|
||||
@@ -87,16 +82,6 @@ public class BasicPatternParser {
|
||||
}
|
||||
|
||||
PsiBuilder.@NotNull Marker parsePrimaryPattern(final PsiBuilder builder, boolean expectVar) {
|
||||
if (builder.getTokenType() == JavaTokenType.LPARENTH) {
|
||||
PsiBuilder.Marker parenPattern = builder.mark();
|
||||
builder.advanceLexer();
|
||||
parsePattern(builder);
|
||||
if (!expect(builder, JavaTokenType.RPARENTH)) {
|
||||
error(builder, JavaPsiBundle.message("expected.rparen"));
|
||||
}
|
||||
done(parenPattern, myJavaElementTypeContainer.PARENTHESIZED_PATTERN, myWhiteSpaceAndCommentSetHolder);
|
||||
return parenPattern;
|
||||
}
|
||||
return parseTypeOrRecordPattern(builder, expectVar);
|
||||
}
|
||||
|
||||
|
||||
@@ -334,7 +334,7 @@ public class BasicStatementParser {
|
||||
|
||||
@Contract(pure = true)
|
||||
private boolean isRecordPatternInForEach(final PsiBuilder builder) {
|
||||
PsiBuilder.Marker patternStart = myParser.getPatternParser().preParsePattern(builder, false);
|
||||
PsiBuilder.Marker patternStart = myParser.getPatternParser().preParsePattern(builder);
|
||||
if (patternStart == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -211,8 +211,6 @@ public abstract class AbstractBasicJavaElementTypeFactory {
|
||||
|
||||
public final IElementType DECONSTRUCTION_PATTERN_VARIABLE;
|
||||
|
||||
public final IElementType PARENTHESIZED_PATTERN;
|
||||
|
||||
public final IElementType DEFAULT_CASE_LABEL_ELEMENT;
|
||||
|
||||
public final IElementType CASE_LABEL_ELEMENT_LIST;
|
||||
@@ -335,7 +333,6 @@ public abstract class AbstractBasicJavaElementTypeFactory {
|
||||
IElementType DECONSTRUCTION_PATTERN,
|
||||
IElementType DECONSTRUCTION_LIST,
|
||||
IElementType DECONSTRUCTION_PATTERN_VARIABLE,
|
||||
IElementType PARENTHESIZED_PATTERN,
|
||||
IElementType DEFAULT_CASE_LABEL_ELEMENT,
|
||||
IElementType CASE_LABEL_ELEMENT_LIST,
|
||||
ILazyParseableElementType CODE_BLOCK,
|
||||
@@ -448,7 +445,6 @@ public abstract class AbstractBasicJavaElementTypeFactory {
|
||||
this.DECONSTRUCTION_PATTERN = DECONSTRUCTION_PATTERN;
|
||||
this.DECONSTRUCTION_LIST = DECONSTRUCTION_LIST;
|
||||
this.DECONSTRUCTION_PATTERN_VARIABLE = DECONSTRUCTION_PATTERN_VARIABLE;
|
||||
this.PARENTHESIZED_PATTERN = PARENTHESIZED_PATTERN;
|
||||
this.DEFAULT_CASE_LABEL_ELEMENT = DEFAULT_CASE_LABEL_ELEMENT;
|
||||
this.CASE_LABEL_ELEMENT_LIST = CASE_LABEL_ELEMENT_LIST;
|
||||
this.CODE_BLOCK = CODE_BLOCK;
|
||||
|
||||
@@ -84,7 +84,7 @@ public interface BasicElementTypes extends JavaTokenType, JavaDocTokenType, Basi
|
||||
BASIC_YIELD_STATEMENT);
|
||||
|
||||
ParentAwareTokenSet BASIC_JAVA_PATTERN_BIT_SET =
|
||||
ParentAwareTokenSet.create(BASIC_TYPE_TEST_PATTERN, BASIC_PARENTHESIZED_PATTERN, BASIC_DECONSTRUCTION_PATTERN, BASIC_UNNAMED_PATTERN);
|
||||
ParentAwareTokenSet.create(BASIC_TYPE_TEST_PATTERN, BASIC_DECONSTRUCTION_PATTERN, BASIC_UNNAMED_PATTERN);
|
||||
|
||||
ParentAwareTokenSet BASIC_JAVA_CASE_LABEL_ELEMENT_BIT_SET =
|
||||
ParentAwareTokenSet.orSet(BASIC_JAVA_PATTERN_BIT_SET, BASIC_EXPRESSION_BIT_SET, ParentAwareTokenSet.create(
|
||||
|
||||
@@ -16,7 +16,10 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.*;
|
||||
import com.intellij.psi.util.PsiPrecedenceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.CommonJavaRefactoringUtil;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -365,7 +368,7 @@ public class ConvertSwitchToIfIntention extends PsiUpdateModCommandAction<PsiSwi
|
||||
String expressionText,
|
||||
CommentTracker commentTracker) {
|
||||
String patternCondition = null;
|
||||
PsiPattern normalizedPattern = JavaPsiPatternUtil.skipParenthesizedPatternDown(pattern);
|
||||
PsiPattern normalizedPattern = pattern;
|
||||
if (normalizedPattern instanceof PsiTypeTestPattern typeTestPattern) {
|
||||
patternCondition = createIfCondition(typeTestPattern, expressionText, commentTracker);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import com.intellij.modcommand.PsiUpdateModCommandQuickFix;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.pom.java.JavaFeature;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.controlFlow.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -328,8 +327,7 @@ public final class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLoc
|
||||
if (branches.isEmpty()) {
|
||||
return branches;
|
||||
}
|
||||
boolean java20plus = PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_20_PREVIEW);
|
||||
if (!java20plus) {
|
||||
if (!PsiUtil.isAvailable(JavaFeature.PATTERNS_IN_SWITCH, context)) {
|
||||
return branches;
|
||||
}
|
||||
List<SwitchBranch> result = new ArrayList<>();
|
||||
|
||||
@@ -305,10 +305,6 @@ public abstract class JavaElementVisitor extends PsiElementVisitor {
|
||||
visitExpression(expression);
|
||||
}
|
||||
|
||||
public void visitParenthesizedPattern(@NotNull PsiParenthesizedPattern pattern) {
|
||||
visitPattern(pattern);
|
||||
}
|
||||
|
||||
public void visitPattern(@NotNull PsiPattern pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.psi;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface PsiParenthesizedPattern extends PsiPrimaryPattern {
|
||||
/**
|
||||
* @return pattern inside parenthesis or null if pattern is incomplete
|
||||
*/
|
||||
@Nullable
|
||||
PsiPattern getPattern();
|
||||
}
|
||||
@@ -760,9 +760,7 @@ public final class PsiImplUtil {
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiSwitchLabelStatementBase getSwitchLabel(@NotNull PsiCaseLabelElement labelElement) {
|
||||
PsiElement parent = labelElement instanceof PsiParenthesizedPattern
|
||||
? JavaPsiPatternUtil.skipParenthesizedPatternUp(labelElement.getParent())
|
||||
: PsiUtil.skipParenthesizedExprUp(labelElement.getParent());
|
||||
PsiElement parent = PsiUtil.skipParenthesizedExprUp(labelElement.getParent());
|
||||
if (parent instanceof PsiCaseLabelElementList) {
|
||||
PsiElement grand = parent.getParent();
|
||||
if (grand instanceof PsiSwitchLabelStatementBase) {
|
||||
|
||||
@@ -55,7 +55,7 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
|
||||
TRY_STATEMENT, LABELED_STATEMENT, ASSERT_STATEMENT,
|
||||
YIELD_STATEMENT);
|
||||
|
||||
TokenSet JAVA_PATTERN_BIT_SET = TokenSet.create(TYPE_TEST_PATTERN, PARENTHESIZED_PATTERN, DECONSTRUCTION_PATTERN, UNNAMED_PATTERN);
|
||||
TokenSet JAVA_PATTERN_BIT_SET = TokenSet.create(TYPE_TEST_PATTERN, DECONSTRUCTION_PATTERN, UNNAMED_PATTERN);
|
||||
|
||||
TokenSet JAVA_CASE_LABEL_ELEMENT_BIT_SET =
|
||||
TokenSet.orSet(JAVA_PATTERN_BIT_SET, EXPRESSION_BIT_SET, TokenSet.create(DEFAULT_CASE_LABEL_ELEMENT));
|
||||
|
||||
@@ -213,9 +213,6 @@ public interface JavaElementType {
|
||||
IElementType DECONSTRUCTION_PATTERN_VARIABLE =
|
||||
new JavaCompositeElementType("DECONSTRUCTION_PATTERN_VARIABLE", () -> new PsiDeconstructionPatternVariableImpl(),
|
||||
BASIC_DECONSTRUCTION_PATTERN_VARIABLE);
|
||||
IElementType PARENTHESIZED_PATTERN =
|
||||
new JavaCompositeElementType("PARENTHESIZED_PATTERN", () -> new PsiParenthesizedPatternImpl(),
|
||||
BASIC_PARENTHESIZED_PATTERN);
|
||||
IElementType DEFAULT_CASE_LABEL_ELEMENT =
|
||||
new JavaCompositeElementType("DEFAULT_CASE_LABEL_ELEMENT", () -> new PsiDefaultLabelElementImpl(),
|
||||
BASIC_DEFAULT_CASE_LABEL_ELEMENT);
|
||||
|
||||
@@ -124,7 +124,6 @@ public class JavaElementTypeFactory extends AbstractBasicJavaElementTypeFactory
|
||||
JavaElementType.DECONSTRUCTION_PATTERN,
|
||||
JavaElementType.DECONSTRUCTION_LIST,
|
||||
JavaElementType.DECONSTRUCTION_PATTERN_VARIABLE,
|
||||
JavaElementType.PARENTHESIZED_PATTERN,
|
||||
JavaElementType.DEFAULT_CASE_LABEL_ELEMENT,
|
||||
JavaElementType.CASE_LABEL_ELEMENT_LIST,
|
||||
JavaElementType.CODE_BLOCK,
|
||||
|
||||
@@ -15,7 +15,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import static com.intellij.psi.impl.source.tree.JavaElementType.*;
|
||||
|
||||
public class PsiDeconstructionListImpl extends CompositePsiElement implements PsiDeconstructionList {
|
||||
private final TokenSet PRIMARY_PATTERN_SET = TokenSet.create(TYPE_TEST_PATTERN, DECONSTRUCTION_PATTERN, PARENTHESIZED_PATTERN, UNNAMED_PATTERN);
|
||||
private final TokenSet PRIMARY_PATTERN_SET = TokenSet.create(TYPE_TEST_PATTERN, DECONSTRUCTION_PATTERN, UNNAMED_PATTERN);
|
||||
|
||||
public PsiDeconstructionListImpl() {
|
||||
super(DECONSTRUCTION_LIST);
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.Constants;
|
||||
import com.intellij.psi.impl.source.tree.CompositePsiElement;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PsiParenthesizedPatternImpl extends CompositePsiElement implements PsiParenthesizedPattern, Constants {
|
||||
public PsiParenthesizedPatternImpl() {
|
||||
super(PARENTHESIZED_PATTERN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitParenthesizedPattern(this);
|
||||
}
|
||||
else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiParenthesizedPattern";
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PsiPattern getPattern() {
|
||||
return PsiTreeUtil.getChildOfType(this, PsiPattern.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
PsiElement lastParent,
|
||||
@NotNull PsiElement place) {
|
||||
final PsiPattern pattern = getPattern();
|
||||
if (pattern == null) return true;
|
||||
|
||||
return pattern.processDeclarations(processor, state, null, place);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.intellij.psi.impl.source.tree.java;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.pom.java.JavaFeature;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.tree.ChildRole;
|
||||
import com.intellij.psi.impl.source.tree.ElementType;
|
||||
@@ -90,7 +90,7 @@ public class PsiSwitchLabelStatementImpl extends PsiSwitchLabelStatementBaseImpl
|
||||
*/
|
||||
private boolean shouldAnalyzePatternVariablesInCaseLabel(@NotNull PsiElement place) {
|
||||
if (place instanceof PsiCodeBlock) return true;
|
||||
boolean java20plus = PsiUtil.getLanguageLevel(place).isAtLeast(LanguageLevel.JDK_20_PREVIEW);
|
||||
boolean patternInSwitch = PsiUtil.isAvailable(JavaFeature.PATTERNS_IN_SWITCH, place);
|
||||
final AtomicBoolean thisSwitchLabelIsImmediate = new AtomicBoolean();
|
||||
|
||||
PsiTreeUtil.treeWalkUp(place, getParent(), (currentScope, __) -> {
|
||||
@@ -104,7 +104,7 @@ public class PsiSwitchLabelStatementImpl extends PsiSwitchLabelStatementBaseImpl
|
||||
immediateSwitchLabel = PsiTreeUtil.getPrevSiblingOfType(currentScope, PsiSwitchLabelStatementBase.class);
|
||||
}
|
||||
|
||||
while (immediateSwitchLabel != null && !java20plus &&
|
||||
while (immediateSwitchLabel != null && !patternInSwitch &&
|
||||
(PsiTreeUtil.getPrevSiblingOfType(immediateSwitchLabel, PsiStatement.class) instanceof PsiSwitchLabelStatementBase &&
|
||||
isCaseNull(immediateSwitchLabel))) {
|
||||
/*
|
||||
|
||||
@@ -36,7 +36,7 @@ public enum PatternResolveState {
|
||||
for (PsiElement prev = pattern, current = prev.getParent(); prev != parent; prev = current, current = current.getParent()) {
|
||||
if (current instanceof PsiInstanceOfExpression || current instanceof PsiParenthesizedExpression ||
|
||||
current instanceof PsiDeconstructionList || current instanceof PsiDeconstructionPattern ||
|
||||
current instanceof PsiParenthesizedPattern || current instanceof PsiPolyadicExpression &&
|
||||
current instanceof PsiPolyadicExpression &&
|
||||
(((PsiPolyadicExpression)current).getOperationTokenType() == JavaTokenType.ANDAND ||
|
||||
((PsiPolyadicExpression)current).getOperationTokenType() == JavaTokenType.OROR)) {
|
||||
continue;
|
||||
|
||||
@@ -4,7 +4,6 @@ package com.intellij.psi.util;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.VariableKind;
|
||||
@@ -102,30 +101,12 @@ public final class JavaPsiPatternUtil {
|
||||
return "(" + checkType.getText() + ")" + operand.getText();
|
||||
}
|
||||
|
||||
@Contract(value = "null -> null", pure = true)
|
||||
public static @Nullable PsiPattern skipParenthesizedPatternDown(PsiPattern pattern) {
|
||||
while (pattern instanceof PsiParenthesizedPattern) {
|
||||
pattern = ((PsiParenthesizedPattern)pattern).getPattern();
|
||||
}
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public static PsiElement skipParenthesizedPatternUp(PsiElement parent) {
|
||||
while (parent instanceof PsiParenthesizedPattern) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return extracted pattern variable or null if the pattern is incomplete or unknown
|
||||
*/
|
||||
@Contract(value = "null -> null", pure = true)
|
||||
@Nullable
|
||||
public static PsiPatternVariable getPatternVariable(@Nullable PsiCaseLabelElement pattern) {
|
||||
if (pattern instanceof PsiParenthesizedPattern) {
|
||||
return getPatternVariable(((PsiParenthesizedPattern)pattern).getPattern());
|
||||
}
|
||||
if (pattern instanceof PsiTypeTestPattern) {
|
||||
return ((PsiTypeTestPattern)pattern).getPatternVariable();
|
||||
}
|
||||
@@ -138,10 +119,7 @@ public final class JavaPsiPatternUtil {
|
||||
@Contract(value = "null -> null", pure = true)
|
||||
@Nullable
|
||||
public static PsiPrimaryPattern getTypedPattern(@Nullable PsiCaseLabelElement element) {
|
||||
if (element instanceof PsiParenthesizedPattern) {
|
||||
return getTypedPattern(((PsiParenthesizedPattern)element).getPattern());
|
||||
}
|
||||
else if (element instanceof PsiDeconstructionPattern) {
|
||||
if (element instanceof PsiDeconstructionPattern) {
|
||||
return ((PsiDeconstructionPattern)element);
|
||||
}
|
||||
else if (element instanceof PsiTypeTestPattern) {
|
||||
@@ -164,9 +142,6 @@ public final class JavaPsiPatternUtil {
|
||||
PsiPatternVariable variable = ((PsiTypeTestPattern)pattern).getPatternVariable();
|
||||
return variable != null && !variable.isUnnamed();
|
||||
}
|
||||
else if (pattern instanceof PsiParenthesizedPattern) {
|
||||
return containsNamedPatternVariable(((PsiParenthesizedPattern)pattern).getPattern());
|
||||
}
|
||||
else if (pattern instanceof PsiDeconstructionPattern) {
|
||||
PsiDeconstructionPattern deconstructionPattern = (PsiDeconstructionPattern)pattern;
|
||||
return deconstructionPattern.getPatternVariable() != null ||
|
||||
@@ -203,9 +178,6 @@ public final class JavaPsiPatternUtil {
|
||||
|
||||
public static @Nullable PsiTypeElement getPatternTypeElement(@Nullable PsiCaseLabelElement pattern) {
|
||||
if (pattern == null) return null;
|
||||
if (pattern instanceof PsiParenthesizedPattern) {
|
||||
return getPatternTypeElement(((PsiParenthesizedPattern)pattern).getPattern());
|
||||
}
|
||||
else if (pattern instanceof PsiDeconstructionPattern) {
|
||||
return ((PsiDeconstructionPattern)pattern).getTypeElement();
|
||||
}
|
||||
@@ -226,10 +198,7 @@ public final class JavaPsiPatternUtil {
|
||||
@Nullable
|
||||
public static PsiPrimaryPattern findUnconditionalPattern(@Nullable PsiCaseLabelElement pattern) {
|
||||
if (pattern == null || isGuarded(pattern)) return null;
|
||||
if (pattern instanceof PsiParenthesizedPattern) {
|
||||
return findUnconditionalPattern(((PsiParenthesizedPattern)pattern).getPattern());
|
||||
}
|
||||
else if (pattern instanceof PsiDeconstructionPattern || pattern instanceof PsiTypeTestPattern || pattern instanceof PsiUnnamedPattern) {
|
||||
if (pattern instanceof PsiDeconstructionPattern || pattern instanceof PsiTypeTestPattern || pattern instanceof PsiUnnamedPattern) {
|
||||
return (PsiPrimaryPattern)pattern;
|
||||
}
|
||||
return null;
|
||||
@@ -316,15 +285,7 @@ public final class JavaPsiPatternUtil {
|
||||
}
|
||||
|
||||
public static @Nullable PsiDeconstructionPattern findDeconstructionPattern(@Nullable PsiCaseLabelElement element) {
|
||||
if (element instanceof PsiParenthesizedPattern) {
|
||||
return findDeconstructionPattern(((PsiParenthesizedPattern)element).getPattern());
|
||||
}
|
||||
else if (element instanceof PsiDeconstructionPattern) {
|
||||
return (PsiDeconstructionPattern)element;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
return ObjectUtils.tryCast(element, PsiDeconstructionPattern.class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -334,9 +295,7 @@ public final class JavaPsiPatternUtil {
|
||||
@Contract(value = "_,null -> false", pure = true)
|
||||
public static boolean dominatesOverConstant(@NotNull PsiCaseLabelElement who, @Nullable PsiType overWhom) {
|
||||
if (overWhom == null) return false;
|
||||
if (PsiUtil.getLanguageLevel(who) != LanguageLevel.JDK_20_PREVIEW){
|
||||
who = findUnconditionalPattern(who);
|
||||
}
|
||||
who = findUnconditionalPattern(who);
|
||||
PsiType whoType = TypeConversionUtil.erasure(getPatternType(who));
|
||||
if (whoType == null) return false;
|
||||
PsiType overWhomType = null;
|
||||
@@ -492,9 +451,6 @@ public final class JavaPsiPatternUtil {
|
||||
*/
|
||||
public static @Nullable PsiType getContextType(@NotNull PsiPattern pattern) {
|
||||
PsiElement parent = pattern.getParent();
|
||||
while (parent instanceof PsiParenthesizedPattern) {
|
||||
parent = parent.getParent();
|
||||
}
|
||||
if (parent instanceof PsiInstanceOfExpression) {
|
||||
return ((PsiInstanceOfExpression)parent).getOperand().getType();
|
||||
}
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
class Main {
|
||||
record EmptyBox() {}
|
||||
record Point(int x, int y) {}
|
||||
record Rect(Point point1, Point point2) {}
|
||||
record Pair<T, U>(T t, U u) {}
|
||||
record Rec(Object obj) {}
|
||||
|
||||
Point[] getPoints(int x) {
|
||||
return new Point[0];
|
||||
}
|
||||
|
||||
void ok1(Point[] points) {
|
||||
for (Point(int x, int y) : points) {
|
||||
System.out.println(x + y);
|
||||
}
|
||||
}
|
||||
|
||||
void ok2(EmptyBox[] emptyBoxes) {
|
||||
for (EmptyBox() : emptyBoxes) {
|
||||
System.out.println("Fill it up and send it back");
|
||||
}
|
||||
}
|
||||
|
||||
void ok3(List<Point> points) {
|
||||
for (Point(final int a, final int b) : points) {
|
||||
System.out.println(a + b);
|
||||
}
|
||||
}
|
||||
|
||||
void ok4(Iterable<Rect> rectangles) {
|
||||
for (Rect(Point(final int x1, final int y1), final Point point2) : rectangles) {
|
||||
System.out.println(x1 + y1);
|
||||
}
|
||||
}
|
||||
|
||||
void test1() {
|
||||
System.out.println(<error descr="Cannot resolve symbol 'x'">x</error>);
|
||||
for (Point(int x, int y) : getPoints(<error descr="Cannot resolve symbol 'x'">x</error>)) {
|
||||
}
|
||||
System.out.println(<error descr="Cannot resolve symbol 'y'">y</error>);
|
||||
}
|
||||
|
||||
void test2(List<Integer> nums) {
|
||||
for (<error descr="Deconstruction pattern can only be applied to a record, 'java.lang.Integer' is not a record">Integer</error>(int num) : nums) {
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
void test3(Point[] points) {
|
||||
for (Point(int x, <error descr="Incompatible types. Found: 'java.lang.Integer', required: 'int'">Integer y</error>) : points) {
|
||||
System.out.println(x + y);
|
||||
}
|
||||
}
|
||||
|
||||
void test4(Rect[] rectangles) {
|
||||
for (Rect(Point<error descr="Incorrect number of nested patterns: expected 2 but found 1">(int x1)</error>, Point point2): rectangles) {
|
||||
System.out.println(x1 + <error descr="Cannot resolve symbol 'y1'">y1</error>);
|
||||
}
|
||||
}
|
||||
|
||||
void test5(Point[] points) {
|
||||
for (Point(int x, int y, <error descr="Incorrect number of nested patterns: expected 2 but found 3">int z)</error> : points) {
|
||||
System.out.println(x + y + z);
|
||||
}
|
||||
}
|
||||
|
||||
<T> void test6(Set<Pair<String, String>> pairs) {
|
||||
for (<error descr="'Pair<String, String>' cannot be safely cast to 'Pair<T, String>'">Pair<T, String>(var t, var u)</error> : pairs) {}
|
||||
}
|
||||
|
||||
void notExhaustive(Rec[] recs) {
|
||||
for (<error descr="Pattern 'Main.Rec' is not exhaustive on 'Main.Rec'">Rec(String s)</error>: recs) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
|
||||
void testNamedRecordPattern(Object obj, List<Rect> rectangles) {
|
||||
if (obj instanceof Point(int x, int y) <error descr="Identifier is not allowed here">point</error>) {
|
||||
}
|
||||
switch (obj) {
|
||||
case Point(int x, int y) <error descr="Identifier is not allowed here">point</error> -> System.out.println("point");
|
||||
case Rect(Point point1, Point(int x2, int y2) <error descr="Identifier is not allowed here">point2</error>) <error descr="Identifier is not allowed here">rect</error> -> System.out.println("rectangle");
|
||||
}
|
||||
|
||||
for (Rect(Point(int x1, int y1) <error descr="Identifier is not allowed here">point1</error>, Point(int x2, int y2) <error descr="Identifier is not allowed here">point2</error>) : rectangles) {
|
||||
System.out.println("blah blah blah");
|
||||
}
|
||||
}
|
||||
|
||||
void testInappropriateType(Object obj, String text) {
|
||||
for(Point(int x1, int y1) : <error descr="Foreach not applicable to type 'java.lang.Object'">obj</error>){
|
||||
System.out.println(x1);
|
||||
}
|
||||
for (Point(int x1, int y1) : <error descr="Foreach not applicable to type 'java.lang.String'">text</error>){
|
||||
System.out.println(x1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
import java.util.function.*;
|
||||
|
||||
class Test {
|
||||
void test1(Object o, int mode) {
|
||||
switch (o) {
|
||||
case (Integer i) when i == <error descr="Variable used in guarded pattern should be final or effectively final">mode</error> -> System.out.println();
|
||||
default -> {}
|
||||
}
|
||||
|
||||
switch (o) {
|
||||
case (Integer i) when (switch (o) {
|
||||
case Integer ii when ii != <error descr="Variable used in guarded pattern should be final or effectively final">mode</error> -> 2;
|
||||
default -> 1;
|
||||
}) == <error descr="Variable used in guarded pattern should be final or effectively final">mode</error> -> System.out.println();
|
||||
default -> {}
|
||||
}
|
||||
|
||||
switch (o) {
|
||||
case (Integer i) when (i = <error descr="Variable used in guarded pattern should be final or effectively final">mode</error>) > 0 -> System.out.println();
|
||||
default -> {}
|
||||
}
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
void test2(Object o, final int mode) {
|
||||
switch (o) {
|
||||
case (Integer i) when (switch (<error descr="Variable used in guarded pattern should be final or effectively final">o</error>) {
|
||||
case Integer ii when ii != mode -> 2;
|
||||
default -> 1;
|
||||
}) == mode -> o = null;
|
||||
default -> {}
|
||||
}
|
||||
switch (o) {
|
||||
case (Integer i) when (i = mode) > 0 -> System.out.println();
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
void test3(Object o, int mode) {
|
||||
switch (o) {
|
||||
case (Integer i) when i == mode -> System.out.println();
|
||||
default -> {}
|
||||
}
|
||||
switch (o) {
|
||||
case (Integer i) when (switch (o) {
|
||||
case Integer ii when ii != mode -> 2;
|
||||
default -> 1;
|
||||
}) == mode -> System.out.println();
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
void testInstanceofPatterns(Object o, int mode) {
|
||||
if (o instanceof Integer i && (i = mode) > 0) {
|
||||
}
|
||||
mode = 0;
|
||||
}
|
||||
|
||||
void testNested(Object o, Integer in) {
|
||||
switch (o) {
|
||||
case Integer mode when (mode = 42) > 9:
|
||||
switch (o) {
|
||||
case (Integer i) when (i = <error descr="Variable used in guarded pattern should be final or effectively final">mode</error>) > 0 -> System.out.println();
|
||||
default -> System.out.println();
|
||||
}
|
||||
default : break;
|
||||
}
|
||||
String str;
|
||||
str = switch (o) {
|
||||
case Integer mode when (mode = 42) > 9 ->
|
||||
switch (o) {
|
||||
case (Integer i) when (i = <error descr="Variable used in guarded pattern should be final or effectively final">mode</error>) > 0 -> "";
|
||||
default -> "";
|
||||
};
|
||||
default -> "";
|
||||
};
|
||||
str = switch (o) {
|
||||
case Integer mode when (mode = 42) > 9:
|
||||
yield switch (o) {
|
||||
case (Integer i) when (i = <error descr="Variable used in guarded pattern should be final or effectively final">mode</error>) > 0 -> "";
|
||||
default -> "";
|
||||
};
|
||||
default: yield "";
|
||||
};
|
||||
// lambdas
|
||||
str = switch (o) {
|
||||
case Integer i when (i = <error descr="Variable used in guarded pattern should be final or effectively final">in</error>) > 0:
|
||||
yield ((Function<Integer, String>)(x) -> (<error descr="Variable used in lambda expression should be final or effectively final">in</error> = 5) > 0 ? "" : null).apply(in);
|
||||
default:
|
||||
yield "";
|
||||
};
|
||||
Consumer<Integer> c = (mode) -> {
|
||||
switch (o) {
|
||||
case (Integer i) when (i = <error descr="Variable used in guarded pattern should be final or effectively final">in</error>) > 0 -> System.out.println();
|
||||
default -> System.out.println();
|
||||
}
|
||||
<error descr="Variable used in lambda expression should be final or effectively final">in</error> = 1;
|
||||
};
|
||||
// try-with-resources
|
||||
try (<error descr="Variable used as a try-with-resources resource should be final or effectively final">in</error>) {
|
||||
switch (o) {
|
||||
case AutoCloseable ii when (<error descr="Variable used in guarded pattern should be final or effectively final">in</error> = ii) != null: break;
|
||||
default: break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
// double nested
|
||||
switch (o) {
|
||||
case Integer mode when (mode = 42) > 9:
|
||||
switch (o) {
|
||||
case Integer i -> {
|
||||
switch (o) {
|
||||
case Integer ii when ii > <error descr="Variable used in guarded pattern should be final or effectively final">mode</error>:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
default -> System.out.println();
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
str = switch (o) {
|
||||
case Integer mode when (mode) > 9:
|
||||
yield switch (o) {
|
||||
case Integer i -> {
|
||||
yield switch (o) {
|
||||
case Integer ii when ii > mode: yield "";
|
||||
default: yield "";
|
||||
};
|
||||
}
|
||||
default -> "";
|
||||
};
|
||||
default: yield "";
|
||||
};
|
||||
}
|
||||
|
||||
void declaredInWhenExpression(Object obj) {
|
||||
switch (obj) {
|
||||
case Integer i when new Function<Integer, Boolean>() {
|
||||
@Override
|
||||
public Boolean apply(Integer integer) {
|
||||
System.out.println(integer++);
|
||||
int num = 0;
|
||||
System.out.println(++num);
|
||||
return true;
|
||||
}
|
||||
}.apply(42) -> {}
|
||||
default -> {}
|
||||
}
|
||||
|
||||
switch (obj) {
|
||||
case Integer i when switch (i) {
|
||||
case 1 -> {
|
||||
int num = 0;
|
||||
++num;
|
||||
yield num;
|
||||
}
|
||||
default -> 42;
|
||||
} == 42 -> {}
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
class Main {
|
||||
void test(Object o) {
|
||||
if (o instanceof ((String <caret>s) && s.length() > 1)) {
|
||||
if (o instanceof String <caret>s && s.length() > 1) {
|
||||
}
|
||||
s = "fsfsdfsd";
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class Main {
|
||||
void test(Object o) {
|
||||
boolean b = o instanceof ((String <caret>s) && s.length() > 1);
|
||||
boolean b = o instanceof String <caret>s && s.length() > 1;
|
||||
s = "fsfsdfsd"; // unresolved
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
class Main {
|
||||
void test(Object o) {
|
||||
switch (o) {
|
||||
case ((Long <caret>l) && l != null) ->
|
||||
case Long <caret>l when l != null ->
|
||||
System.out.println("Long: " + l);
|
||||
default ->
|
||||
System.out.println();
|
||||
|
||||
@@ -127,7 +127,7 @@ public class Main {
|
||||
|
||||
void test12(Integer integer) {
|
||||
switch (integer) {
|
||||
case 1, 2, <error descr="Invalid case label combination: a case label must consist of either a list of case constants or a single case pattern">Integer i1</error> when i1 > 5:
|
||||
case 1, 2, <error descr="Invalid case label combination: a case label must consist of either a list of case constants or a list of case patterns">Integer i1</error> when i1 > 5:
|
||||
case null:
|
||||
System.out.println("blah blah blah");
|
||||
break;
|
||||
@@ -246,14 +246,14 @@ public class Main {
|
||||
|
||||
void test28(Object obj) {
|
||||
switch (obj) {
|
||||
case Integer i, <error descr="Invalid case label combination: a case label must not consist of more than one case pattern">String str</error> -> {}
|
||||
case <error descr="Invalid case label combination: multiple patterns are allowed only if none of them declare any pattern variables">Integer i</error>, String str -> {}
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
void test28(String s) {
|
||||
switch (s) {
|
||||
case String str, <error descr="Invalid case label combination: a case label must consist of either a list of case constants or a single case pattern">"hello"</error>, "world" -> {}
|
||||
case String str, <error descr="Invalid case label combination: a case label must consist of either a list of case constants or a list of case patterns">"hello"</error>, "world" -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class X {
|
||||
int switchTest(Object obj) {
|
||||
return switch (obj) {
|
||||
case (String <error descr="Patterns in switch are not supported at language level '11'">s</error>) -> 1;
|
||||
case Object(String <error descr="Patterns in switch are not supported at language level '11'">s</error>) -> 1;
|
||||
case Integer <error descr="Patterns in switch are not supported at language level '11'">i</error> when predicate() -> 2;
|
||||
case Integer <error descr="Patterns in switch are not supported at language level '11'">i</error> -> 3;
|
||||
case default -> 4;
|
||||
@@ -20,9 +20,6 @@ class X {
|
||||
if (obj instanceof Integer <error descr="Patterns in 'instanceof' are not supported at language level '11'">i</error> && predicate()) {
|
||||
return 1;
|
||||
}
|
||||
if (obj instanceof (String <error descr="Patterns in 'instanceof' are not supported at language level '11'">s</error>)) {
|
||||
return 3;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class X {
|
||||
int switchTest(Object obj) {
|
||||
return switch (obj) {
|
||||
case (String <error descr="Patterns in switch are not supported at language level '16'">s</error>) -> 1;
|
||||
case Object(String <error descr="Patterns in switch are not supported at language level '16'">s</error>) -> 1;
|
||||
case Integer <error descr="Patterns in switch are not supported at language level '16'">i</error> when predicate() -> 2;
|
||||
case Integer <error descr="Patterns in switch are not supported at language level '16'">i</error> -> 3;
|
||||
case default -> 4;
|
||||
@@ -14,14 +14,13 @@ class X {
|
||||
case <error descr="The label for the default case must only use the 'default' keyword, without 'case'">default</error> -> {}
|
||||
}
|
||||
}
|
||||
|
||||
record R(int x) {}
|
||||
|
||||
int instanceofTest(Object obj) {
|
||||
if (obj instanceof <error descr="Parenthesized patterns are not supported at language level '16'">(Integer i)</error> && predicate()) {
|
||||
if (obj instanceof <error descr="Pattern guards and record patterns are not supported at language level '16'">R(int i)</error> && predicate()) {
|
||||
return 1;
|
||||
}
|
||||
if (obj instanceof <error descr="Parenthesized patterns are not supported at language level '16'">(String s)</error>) {
|
||||
return 3;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
class X {
|
||||
void testDominance1(Object obj) {
|
||||
switch (obj) {
|
||||
default -> System.out.println("default");
|
||||
case <error descr="Label is dominated by a preceding case label 'default'">Integer i</error> -> System.out.println("Integer");
|
||||
case <error descr="Label is dominated by a preceding case label 'default'">String s</error> when s.isEmpty() -> System.out.println("empty String");
|
||||
case <error descr="Label is dominated by a preceding case label 'default'">null</error> -> System.out.println("null");
|
||||
}
|
||||
}
|
||||
|
||||
void testDominance2(Object obj) {
|
||||
switch (obj) {
|
||||
case null, default -> System.out.println("null or default");
|
||||
case <error descr="Label is dominated by a preceding case label 'default'">Integer i</error> -> System.out.println("Integer");
|
||||
case <error descr="Label is dominated by a preceding case label 'default'">String s</error> when s.isEmpty() -> System.out.println("empty String");
|
||||
}
|
||||
}
|
||||
|
||||
void testDominance3(String s) {
|
||||
switch (s) {
|
||||
default -> System.out.println("default");
|
||||
case "blah blah blah" -> System.out.println("blah blah blah");
|
||||
case <error descr="Label is dominated by a preceding case label 'default'">null</error> -> System.out.println("null");
|
||||
}
|
||||
}
|
||||
|
||||
void testDominance4(String s) {
|
||||
switch (s) {
|
||||
case null, default -> System.out.println("null, default");
|
||||
case <error descr="Label is dominated by a preceding case label 'default'">"blah blah blah"</error> -> System.out.println("blah blah blah");
|
||||
}
|
||||
}
|
||||
|
||||
void testUnconditionalPatternAndDefault1(String s) {
|
||||
switch (s) {
|
||||
case null, <error descr="'switch' has both an unconditional pattern and a default label">default</error> -> System.out.println("null, default");
|
||||
case <error descr="'switch' has both an unconditional pattern and a default label">String str</error> -> System.out.println("String");
|
||||
}
|
||||
}
|
||||
|
||||
void testUnconditionalPatternAndDefault2(Integer j) {
|
||||
switch (j) {
|
||||
case <error descr="'switch' has both an unconditional pattern and a default label">Integer i</error> when true -> System.out.println("An integer");
|
||||
<error descr="'switch' has both an unconditional pattern and a default label">default</error> -> System.out.println("default");
|
||||
}
|
||||
}
|
||||
|
||||
void testDuplicateUnconditionalPattern1(Integer j) {
|
||||
switch (j) {
|
||||
case <error descr="Duplicate unconditional pattern">Integer i</error> when true -> System.out.println("An integer");
|
||||
case <error descr="Duplicate unconditional pattern">Number number</error> -> System.out.println("An integer");
|
||||
}
|
||||
}
|
||||
|
||||
void testDuplicateUnconditionalPattern2(Integer j) {
|
||||
switch (j) {
|
||||
case <error descr="Duplicate unconditional pattern">Integer i</error> when true -> System.out.println("An integer");
|
||||
case <error descr="Duplicate unconditional pattern">Integer i</error> -> System.out.println("An integer");
|
||||
}
|
||||
}
|
||||
|
||||
record R1() {}
|
||||
record R2() {}
|
||||
|
||||
void testNoVars(Object obj) {
|
||||
switch(obj) {
|
||||
case R1(), <error descr="Invalid case label combination: a case label must not consist of more than one case pattern">R2()</error> -> {}
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
void testCombination(Integer i) {
|
||||
switch (i) {
|
||||
case Integer a, <error descr="Invalid case label combination: a case label must not consist of more than one case pattern">Integer b</error> when i > 0 -> System.out.println(1);
|
||||
case 1, 2, 3, <error descr="Invalid case label combination: a case label must consist of either a list of case constants or a single case pattern">Integer c</error> when i > 0 -> System.out.println(1);
|
||||
case Integer d, <error descr="Invalid case label combination: a case label must consist of either a list of case constants or a single case pattern">4</error> when i > 0 -> System.out.println(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
class X {
|
||||
int switchTest1(Object obj) {
|
||||
return switch (obj) {
|
||||
case <error descr="Parenthesized patterns are not supported at language level '21'">(String s)</error> -> 1;
|
||||
case Integer i -> 3;
|
||||
case default -> 4;
|
||||
case null -> 10;
|
||||
@@ -47,10 +46,10 @@ class X {
|
||||
}
|
||||
|
||||
int instanceofTest(Object obj) {
|
||||
if (obj instanceof (Integer i<error descr="')' expected"> </error>&& predicate())<error descr="Statement expected"><error descr="Unexpected token">)</error></error> {
|
||||
if (obj instanceof<error descr="')' expected"><error descr="Type expected"> </error></error>(Integer<error descr="')' expected"> </error><error descr="Cannot resolve symbol 'i'">i</error> && predicate()<error descr="Unexpected token">)</error><error descr="Unexpected token">)</error> {
|
||||
return 1;
|
||||
}
|
||||
if (obj instanceof <error descr="Parenthesized patterns are not supported at language level '21'">(String s)</error>) {
|
||||
if (obj instanceof<error descr="')' expected"><error descr="Type expected"> </error></error>(String<error descr="')' expected"> </error><error descr="Cannot resolve symbol 's'">s</error><error descr="Unexpected token">)</error><error descr="Unexpected token">)</error> {
|
||||
return 3;
|
||||
}
|
||||
return 2;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class RecordPatternsAndWhenGuardsInJava18 {
|
||||
void test(Object o) {
|
||||
switch (o) {
|
||||
case MyRecord(int <error descr="Patterns in switch are not supported at language level '18'">x</error>) <error descr="Patterns in switch are not supported at language level '18'">r</error> -> {
|
||||
case MyRecord(int <error descr="Patterns in switch are not supported at language level '18'">x</error>) <error descr="Identifier is not allowed here"><error descr="Patterns in switch are not supported at language level '18'">r</error></error> -> {
|
||||
|
||||
}
|
||||
case String <error descr="Patterns in switch are not supported at language level '18'">s</error> when s.length() > 10 -> {
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
public class SwitchExhaustivenessIn20Java {
|
||||
class A {}
|
||||
class B extends A {}
|
||||
sealed interface I<T> permits C, D {}
|
||||
record C<T>(T t) implements I<T> {}
|
||||
final class D implements I<String> {}
|
||||
record Pair<T>(T x, T y){
|
||||
}
|
||||
void foo(Pair<I<? extends String>> pairI) {
|
||||
switch (<error descr="'switch' statement does not cover all possible input values">pairI</error>) {
|
||||
case Pair<I<? extends String>>(C<? extends CharSequence>(String i), D snd) -> {}
|
||||
case Pair<I<? extends String>>(I<? extends CharSequence> fst, C snd) -> {}
|
||||
case Pair<I<? extends String>>(D fst, I snd) -> {}
|
||||
}
|
||||
}
|
||||
|
||||
void foo2(Pair<I<? extends String>> pairI) {
|
||||
switch (pairI) {
|
||||
case Pair<I<? extends String>>(C<? extends CharSequence>(CharSequence i), D snd) -> {}
|
||||
case Pair<I<? extends String>>(I<? extends CharSequence> fst, C snd) -> {}
|
||||
case Pair<I<? extends String>>(D fst, I snd) -> {}
|
||||
}
|
||||
}
|
||||
|
||||
sealed interface L1 {
|
||||
}
|
||||
|
||||
final class L21 implements L1 {
|
||||
}
|
||||
final class L22 implements L1 {
|
||||
}
|
||||
|
||||
sealed interface Boxed permits Box, Box2 {}
|
||||
|
||||
record Box(L1 value) implements Boxed {}
|
||||
|
||||
record Box2(L1 value) implements Boxed {}
|
||||
|
||||
void foo3(Pair<Box> o) {
|
||||
switch (o) {
|
||||
case Pair(Box(L21 v1), Box(L22 v2)) -> {
|
||||
}
|
||||
case Pair(Box b1, Box b2) -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
void foo4(Pair<Boxed> o) {
|
||||
switch (o) {
|
||||
case Pair<Boxed>(Box(L21 v1), Box2(L22 v2)) -> {
|
||||
}
|
||||
case Pair<Boxed>(Box(Object v1), Box(Object v2)) -> {
|
||||
}
|
||||
case Pair<Boxed>(Box2 b1, Boxed b2) -> {
|
||||
}
|
||||
case Pair<Boxed>(Box b1, Box2 b2) -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
record PairString<T>(T t, String t2){}
|
||||
|
||||
void foo4(PairString<Boxed> o) {
|
||||
switch (o) {
|
||||
case PairString<Boxed>(Box(L21 v1), String t) -> {
|
||||
}
|
||||
case PairString<Boxed>(Box(L22 v2), String t2) -> {
|
||||
}
|
||||
case PairString<Boxed>(Box2 t, String t2) -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
record StringPair<T>(String t2, T t) {
|
||||
|
||||
}
|
||||
|
||||
void foo5(StringPair<Boxed> o) {
|
||||
switch (o) {
|
||||
case StringPair<Boxed>(String t, Box(L21 v1)) -> {
|
||||
}
|
||||
case StringPair<Boxed>(String t2, Box2 t) -> {
|
||||
}
|
||||
case StringPair<Boxed>(String t2, Box t) -> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ class Test {
|
||||
case Object s -> System.out.println(s);
|
||||
}
|
||||
switch (o) {
|
||||
case <error descr="Parenthesized patterns are not supported at language level '21'">(Object s)</error> when s != null -> System.out.println();
|
||||
case Object s when s != null -> System.out.println();
|
||||
default -> System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
// "Replace explicit type with 'var'" "false"
|
||||
class Main {
|
||||
record Point(int x, int y) {}
|
||||
|
||||
void foo(Object obj) {
|
||||
if (obj instanceof Point((((int<caret> x))), int y)) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// "Replace with a null check" "true-preview"
|
||||
class Test {
|
||||
void test(String s) {
|
||||
Object object = s;
|
||||
if(object != null) {
|
||||
System.out.println("always");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
// "Replace with a null check" "true-preview"
|
||||
class Test {
|
||||
void test(String s) {
|
||||
Object object = s;
|
||||
if(object instanceof ((<caret>String s1))) {
|
||||
System.out.println("always");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class ExceptionFromCatchWhichDoesntWrap {
|
||||
void patternVariable() {
|
||||
try {
|
||||
} catch (Exception ex) {
|
||||
if (ex instanceof ((RuntimeException rte))) {
|
||||
if (ex instanceof RuntimeException rte) {
|
||||
throw rte;
|
||||
}
|
||||
}
|
||||
@@ -83,7 +83,7 @@ public class ExceptionFromCatchWhichDoesntWrap {
|
||||
try {
|
||||
} catch (Exception ex) {
|
||||
switch (ex) {
|
||||
case ((RuntimeException rte)) -> throw rte;
|
||||
case RuntimeException rte -> throw rte;
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class MultipleReturnPointsPerMethod
|
||||
}
|
||||
|
||||
void test(List<Box<String>> list) {
|
||||
for(Box(var text) : list){
|
||||
for(<error descr="Record patterns in for-each loops are not supported at language level '20'">Box(var text)</error> : list){
|
||||
int length = text.length();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class Foo {
|
||||
}
|
||||
|
||||
void test3(Rect[] rects) {
|
||||
for (Rect(Point(<warning descr="Unnecessary 'final' on parameter 'x1'">final</warning> int x1, <warning descr="Unnecessary 'final' on parameter 'y1'">final</warning> int y1), <warning descr="Unnecessary 'final' on parameter 'point2'">final</warning> Point point2) : rects) {
|
||||
for (<error descr="Record patterns in for-each loops are not supported at language level '21'">Rect(Point(<warning descr="Unnecessary 'final' on parameter 'x1'">final</warning> int x1, <warning descr="Unnecessary 'final' on parameter 'y1'">final</warning> int y1), <warning descr="Unnecessary 'final' on parameter 'point2'">final</warning> Point point2)</error> : rects) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ public class ForEachPattern {
|
||||
record IntBox(int i) {}
|
||||
void bar1(Iterable<IntBox> i) {
|
||||
int a = 1;
|
||||
for (IntBox(int d) : i) {
|
||||
for (<error descr="Record patterns in for-each loops are not supported at language level '21'">IntBox(int d)</error> : i) {
|
||||
a = 2;
|
||||
}
|
||||
System.out.println(a == 1);
|
||||
@@ -20,7 +20,7 @@ public class ForEachPattern {
|
||||
|
||||
private static void use(List<Point> points) {
|
||||
int a = 0, b = 0;
|
||||
for (Point(int x, int y) : points) {
|
||||
for (<error descr="Record patterns in for-each loops are not supported at language level '21'">Point(int x, int y)</error> : points) {
|
||||
if (x == 1) {
|
||||
a = 1;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class Main {
|
||||
|
||||
void test3(final Object obj) {
|
||||
switch (obj) {
|
||||
case Rect(Point(int <warning descr="Parameter 'x1' can have 'final' modifier">x1</warning>, int y1), Point point2) when (y1 = 42) == x1 -> {
|
||||
case Rect(Point(int <warning descr="Parameter 'x1' can have 'final' modifier">x1</warning>, int y1), Point point2) when (<error descr="Cannot assign a value to variable 'y1', because it is declared outside the guard">y1</error> = 42) == x1 -> {
|
||||
point2 = new Point(0, 0);
|
||||
}
|
||||
default -> {}
|
||||
@@ -34,14 +34,14 @@ class Main {
|
||||
}
|
||||
|
||||
void test5(final Point[] points) {
|
||||
for (Point(int <warning descr="Variable 'x' can have 'final' modifier">x</warning>, int y) : points) {
|
||||
for (<error descr="Record patterns in for-each loops are not supported at language level '21'">Point(int <warning descr="Variable 'x' can have 'final' modifier">x</warning>, int y)</error> : points) {
|
||||
System.out.println(x);
|
||||
y = 42;
|
||||
}
|
||||
}
|
||||
|
||||
void test6(final Rect[] rects) {
|
||||
for (Rect(Point(int x1, int <warning descr="Variable 'y1' can have 'final' modifier">y1</warning>), Point <warning descr="Variable 'point2' can have 'final' modifier">point2</warning>) : rects) {
|
||||
for (<error descr="Record patterns in for-each loops are not supported at language level '21'">Rect(Point(int x1, int <warning descr="Variable 'y1' can have 'final' modifier">y1</warning>), Point <warning descr="Variable 'point2' can have 'final' modifier">point2</warning>)</error> : rects) {
|
||||
x1 = 42;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,18 +6,12 @@ PsiJavaFile:InstanceOfPattern3.java
|
||||
PsiIdentifier:x('x')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiKeyword:instanceof('instanceof')
|
||||
PsiErrorElement:Type expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiErrorElement:Unparsed tokens
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiIdentifier:Foo('Foo')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiParenthesizedPattern
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiTypeTestPattern
|
||||
PsiPatternVariable:v
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:Foo
|
||||
PsiJavaCodeReferenceElement:Foo
|
||||
PsiIdentifier:Foo('Foo')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:v('v')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
PsiIdentifier:v('v')
|
||||
PsiJavaToken:RPARENTH(')')
|
||||
@@ -6,18 +6,12 @@ test.java.file
|
||||
IDENTIFIER
|
||||
WHITE_SPACE
|
||||
INSTANCEOF_KEYWORD
|
||||
ERROR_ELEMENT
|
||||
<empty list>
|
||||
WHITE_SPACE
|
||||
ERROR_ELEMENT
|
||||
LPARENTH
|
||||
IDENTIFIER
|
||||
WHITE_SPACE
|
||||
PARENTHESIZED_PATTERN
|
||||
LPARENTH
|
||||
TYPE_TEST_PATTERN
|
||||
PATTERN_VARIABLE
|
||||
MODIFIER_LIST
|
||||
<empty list>
|
||||
TYPE
|
||||
JAVA_CODE_REFERENCE
|
||||
IDENTIFIER
|
||||
REFERENCE_PARAMETER_LIST
|
||||
<empty list>
|
||||
WHITE_SPACE
|
||||
IDENTIFIER
|
||||
RPARENTH
|
||||
IDENTIFIER
|
||||
RPARENTH
|
||||
@@ -1,28 +1,32 @@
|
||||
PsiJavaFile:SwitchRulesWithPatternIncomplete1.java
|
||||
PsiSwitchLabeledRule
|
||||
PsiSwitchLabelStatement
|
||||
PsiKeyword:case('case')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiCaseLabelElementList
|
||||
PsiParenthesizedPattern
|
||||
PsiParenthesizedExpression:(Integer
|
||||
PsiJavaToken:LPARENTH('(')
|
||||
PsiTypeTestPattern
|
||||
PsiPatternVariable:i
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiTypeElement:Integer
|
||||
PsiJavaCodeReferenceElement:Integer
|
||||
PsiIdentifier:Integer('Integer')
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiIdentifier:i('i')
|
||||
PsiReferenceExpression:Integer
|
||||
PsiReferenceParameterList
|
||||
<empty list>
|
||||
PsiIdentifier:Integer('Integer')
|
||||
PsiErrorElement:')' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:ARROW('->')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiBlockStatement
|
||||
PsiErrorElement:':' or '->' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiExpressionStatement
|
||||
PsiLambdaExpression
|
||||
PsiParameterList:i
|
||||
PsiParameter:i
|
||||
PsiModifierList:
|
||||
<empty list>
|
||||
PsiIdentifier:i('i')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:ARROW('->')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiCodeBlock
|
||||
PsiJavaToken:LBRACE('{')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
PsiJavaToken:RBRACE('}')
|
||||
PsiErrorElement:';' expected
|
||||
<empty list>
|
||||
@@ -1,28 +1,32 @@
|
||||
test.java.file
|
||||
SWITCH_LABELED_RULE
|
||||
SWITCH_LABEL_STATEMENT
|
||||
CASE_KEYWORD
|
||||
WHITE_SPACE
|
||||
CASE_LABEL_ELEMENT_LIST
|
||||
PARENTHESIZED_PATTERN
|
||||
PARENTH_EXPRESSION
|
||||
LPARENTH
|
||||
TYPE_TEST_PATTERN
|
||||
PATTERN_VARIABLE
|
||||
MODIFIER_LIST
|
||||
<empty list>
|
||||
TYPE
|
||||
JAVA_CODE_REFERENCE
|
||||
IDENTIFIER
|
||||
REFERENCE_PARAMETER_LIST
|
||||
<empty list>
|
||||
WHITE_SPACE
|
||||
IDENTIFIER
|
||||
REFERENCE_EXPRESSION
|
||||
REFERENCE_PARAMETER_LIST
|
||||
<empty list>
|
||||
IDENTIFIER
|
||||
ERROR_ELEMENT
|
||||
<empty list>
|
||||
WHITE_SPACE
|
||||
ARROW
|
||||
WHITE_SPACE
|
||||
BLOCK_STATEMENT
|
||||
ERROR_ELEMENT
|
||||
<empty list>
|
||||
WHITE_SPACE
|
||||
EXPRESSION_STATEMENT
|
||||
LAMBDA_EXPRESSION
|
||||
PARAMETER_LIST
|
||||
PARAMETER
|
||||
MODIFIER_LIST
|
||||
<empty list>
|
||||
IDENTIFIER
|
||||
WHITE_SPACE
|
||||
ARROW
|
||||
WHITE_SPACE
|
||||
CODE_BLOCK
|
||||
LBRACE
|
||||
WHITE_SPACE
|
||||
RBRACE
|
||||
RBRACE
|
||||
ERROR_ELEMENT
|
||||
<empty list>
|
||||
@@ -15,7 +15,7 @@ class Use {
|
||||
switch (obj) {
|
||||
case Rect(Point point1, Point point2) when point1.equals(point2) -> {}
|
||||
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2)) rect when x1 == x2 -> System.out.println(point1);
|
||||
case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point2))) -> System.out.println(point2);
|
||||
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2) -> System.out.println(point2);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class Use {
|
||||
switch (obj) {
|
||||
case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {}
|
||||
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1);
|
||||
case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point2, int i))) -> System.out.println(point2);
|
||||
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2, int i) -> System.out.println(point2);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Use {
|
||||
switch (obj) {
|
||||
case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {}
|
||||
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1);
|
||||
case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point2, ((int i))))) -> System.out.println(point2);
|
||||
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2, int i) -> System.out.println(point2);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Use {
|
||||
switch (obj) {
|
||||
case Rect(Point point2, Point point1, int i) when point2.equals(point1) -> {}
|
||||
case Rect(Point(int y1, int x1) point2, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point2);
|
||||
case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point1, ((int i))))) -> System.out.println(point1);
|
||||
case Rect(Point(int x1, int y1), Point(int x2, int y2) point1, int i) -> System.out.println(point1);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Use {
|
||||
switch (obj) {
|
||||
case Rect(Point point1, Point point2, int i) when point1.equals(point2) -> {}
|
||||
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1);
|
||||
case ((Rect(((Point(((int x1)), ((int y1))))), Point(((int x2)), ((int y2))) point2, ((int i))))) -> System.out.println(point2);
|
||||
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2, int i) -> System.out.println(point2);
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Use {
|
||||
switch (obj) {
|
||||
case Rect(int i, Point point2, Point point1) when point1.equals(point2) -> {}
|
||||
case Rect(int i, Point(int y2, int x2), Point(int y1, int x1) point1) rect when x1 == x2 -> System.out.println(point1);
|
||||
case ((Rect(((int i)), Point(((int x2)), ((int y2))) point2, ((Point(((int x1)), ((int y1)))))))) -> System.out.println(point2);
|
||||
case Rect(int i, Point(int x2, int y2) point2, Point(int x1, int y1)) -> System.out.println(point2);
|
||||
default -> {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class Use {
|
||||
switch (obj) {
|
||||
case Rect(Point point1, Point point2, int i) when point2.x() == 42 -> System.out.println(point2);
|
||||
case Rect(Point(int y1, int x1) point1, Point(int y2, int x2), int i) rect when x1 == x2 -> System.out.println(point1);
|
||||
case ((Rect(((Point(((int x1)), ((int y1))))), ((Point(((int x2)), ((int y2))) point2)), ((int i))))) -> System.out.println(point2);
|
||||
case Rect(Point(int x1, int y1), Point(int x2, int y2) point2, int i) -> System.out.println(point2);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class Use {
|
||||
switch (obj) {
|
||||
case Rect(Point p2) when p2.x() == 42 -> System.out.println(p2);
|
||||
case Rect(Point(int y2, int x2)) rect when x1 == x2 -> System.out.println(point1);
|
||||
case ((Rect(((Point(((int x2)), ((int y2))) p2))))) -> System.out.println(p2);
|
||||
case Rect(Point(int x2, int y2) p2) -> System.out.println(p2);
|
||||
default -> throw new IllegalStateException("Unexpected value: " + obj);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
class X {
|
||||
void test(Object obj) {
|
||||
if (<selection>obj instanceof (String s)</selection> && s.length() > 5) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
class X {
|
||||
void test(Object obj) {
|
||||
if (<selection>obj instanceof (String s) && s.length() > 5</selection>) {
|
||||
System.out.println(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
class X {
|
||||
void test(Object obj) {
|
||||
if (<selection>obj instanceof (String s) && s.length() > 5</selection>) {
|
||||
System.out.println("found");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
class X {
|
||||
void test(Object obj) {
|
||||
if (newMethod(obj)) {
|
||||
System.out.println("found");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean newMethod(Object obj) {
|
||||
return obj instanceof (String s) && s.length() > 5;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,6 @@ public class MakeDefaultLastCaseFixTest extends LightQuickFixParameterizedTestCa
|
||||
|
||||
@Override
|
||||
protected LanguageLevel getLanguageLevel() {
|
||||
return LanguageLevel.JDK_20_PREVIEW;
|
||||
return LanguageLevel.JDK_21;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public class MakeVarEffectivelyFinalFixTest extends LightQuickFixParameterizedTe
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_20;
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,7 @@ public class ReplacePrimitiveWithBoxedTypeTest extends LightQuickFixParameterize
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_20;
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ public class ReplaceWithConstantValueFixTest extends LightQuickFixParameterizedT
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_20;
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -16,6 +16,6 @@ public class ReplaceWithTypePatternFixTest extends LightQuickFixParameterizedTes
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_20;
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@ public final class LanguageLevelTest {
|
||||
@SuppressWarnings("UsagesOfObsoleteApi")
|
||||
LanguageLevel jdk17Preview = LanguageLevel.JDK_17_PREVIEW;
|
||||
assertTrue(jdk17Preview.isUnsupported());
|
||||
assertEquals(LanguageLevel.JDK_20_PREVIEW, jdk17Preview.getSupportedLevel());
|
||||
assertEquals(LanguageLevel.JDK_21, jdk17Preview.getSupportedLevel());
|
||||
assertEquals(LanguageLevel.JDK_17, jdk17Preview.getNonPreviewLevel());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
package com.intellij.java.codeInsight.daemon;
|
||||
|
||||
import com.intellij.codeInspection.miscGenerics.RawUseOfParameterizedTypeInspection;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiPatternVariable;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -14,7 +16,7 @@ import java.util.Collection;
|
||||
public class DeconstructionInferenceTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
public void testSimple() {
|
||||
@@ -137,7 +139,7 @@ public class DeconstructionInferenceTest extends LightJavaCodeInsightFixtureTest
|
||||
}
|
||||
}
|
||||
""");
|
||||
myFixture.checkHighlighting();
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_X, () -> myFixture.checkHighlighting());
|
||||
}
|
||||
|
||||
public void testWildcardTypeParameterBound() {
|
||||
@@ -294,6 +296,6 @@ public class DeconstructionInferenceTest extends LightJavaCodeInsightFixtureTest
|
||||
}
|
||||
""");
|
||||
myFixture.enableInspections(new RawUseOfParameterizedTypeInspection());
|
||||
myFixture.checkHighlighting();
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_X, () -> myFixture.checkHighlighting());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ public class JavacQuirksInspectionTest extends LightJavaCodeInsightFixtureTestCa
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -40,47 +40,39 @@ public class LightPatternsForSwitchHighlightingTest extends LightJavaCodeInsight
|
||||
}
|
||||
|
||||
public void testPatternsInSwitchIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
}
|
||||
|
||||
public void testPatternsInSwitchIn20Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testMismatchedDeconstructionIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIllegalFallthroughIn20Java() {
|
||||
//there are no changes in 20->21
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testIllegalFallthroughIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testUnconditionalDestructuringAndDefaultIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSwitchExhaustivenessIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSwitchExhaustivenessForDirectClassesIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSwitchExhaustivenessWithConcreteSealedClassesIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSwitchExhaustivenessForEnumsWithSealedClassesIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
}
|
||||
|
||||
public void testSwitchExhaustivenessIn20Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSwitchExhaustivenessWithSealedIntersection(){
|
||||
@@ -88,7 +80,7 @@ public class LightPatternsForSwitchHighlightingTest extends LightJavaCodeInsight
|
||||
}
|
||||
|
||||
public void testSwitchExhaustivenessWithGenericsIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSwitchSeveralPatternsUnnamed() {
|
||||
@@ -96,11 +88,11 @@ public class LightPatternsForSwitchHighlightingTest extends LightJavaCodeInsight
|
||||
}
|
||||
|
||||
public void testSwitchDominanceIn21Java() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testPatternMatchingInSwitchJava21() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testPatternMatchingWithGuard() {
|
||||
@@ -122,12 +114,8 @@ public class LightPatternsForSwitchHighlightingTest extends LightJavaCodeInsight
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testEffectivelyFinal() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
}
|
||||
|
||||
public void testEffectivelyFinal21() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -69,10 +69,6 @@ public class LightPatternsHighlightingTest extends LightJavaCodeInsightFixtureTe
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_19, this::doTest);
|
||||
}
|
||||
|
||||
public void testRecordPatternsInForEachJava20() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
}
|
||||
|
||||
public void testRecordPatternsInForEachJava21() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, () -> {
|
||||
doTest();
|
||||
@@ -81,16 +77,16 @@ public class LightPatternsHighlightingTest extends LightJavaCodeInsightFixtureTe
|
||||
});
|
||||
}
|
||||
|
||||
public void testDeconstructionInstanceOf20() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
public void testDeconstructionInstanceOf21() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testForEachPatternExhaustiveness() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_X, this::doTest);
|
||||
}
|
||||
|
||||
public void testBoundTypeParameter() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNotAnnotationsInDeconstructionType() {
|
||||
|
||||
@@ -16,6 +16,6 @@ public class SplitSwitchBranchWithSeveralCaseValuesTest extends LightQuickFixPar
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_20;
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ public class GotoDeclarationTest extends LightJavaCodeInsightTestCase {
|
||||
}
|
||||
|
||||
public void testCaseNullAfterPatternMatching() {
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, () -> doTestGoToField());
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, () -> doTestGoToField());
|
||||
}
|
||||
|
||||
public void testCaseNullAfterPatternMatchingExpr() {
|
||||
|
||||
@@ -18,7 +18,7 @@ public class BulkFileAttributesReadInspectionTest extends LightJavaCodeInsightFi
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -8,7 +8,7 @@ import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class CapturingCleaner18InspectionTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
public class CapturingCleaner21InspectionTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
|
||||
public void testCapturingCleaner() {doTest();}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class CapturingCleaner18InspectionTest extends LightJavaCodeInsightFixtur
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -1,53 +0,0 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeInspection;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class DataFlowInspection20Test extends DataFlowInspectionTestCase {
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/inspection/dataFlow/fixture/";
|
||||
}
|
||||
|
||||
public void testSealedClassCast() { doTest(); }
|
||||
public void testCastToSealedInterface() { doTest(); }
|
||||
|
||||
public void testWhenPatterns() {
|
||||
doTest();
|
||||
}
|
||||
public void testSwitchNullability() {
|
||||
doTest();
|
||||
}
|
||||
public void testRecordPatterns() {
|
||||
doTest();
|
||||
}
|
||||
public void testRecordPatternNested() {
|
||||
doTest();
|
||||
}
|
||||
public void testRecordPatternAndWhen() {
|
||||
doTest();
|
||||
}
|
||||
public void testNestedRecordPatterns() {
|
||||
doTest();
|
||||
}
|
||||
public void testSuspiciousLabelElementsJava20() {
|
||||
doTest();
|
||||
}
|
||||
public void testForEachPattern() {
|
||||
myFixture.addClass("""
|
||||
package org.jetbrains.annotations;
|
||||
public @interface Range {
|
||||
long from();
|
||||
long to();
|
||||
}""");
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
@@ -88,4 +88,39 @@ public class DataFlowInspection21Test extends DataFlowInspectionTestCase {
|
||||
public void testChronoRange() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSealedClassCast() { doTest(); }
|
||||
public void testCastToSealedInterface() { doTest(); }
|
||||
|
||||
public void testWhenPatterns() {
|
||||
doTest();
|
||||
}
|
||||
public void testSwitchNullability() {
|
||||
doTest();
|
||||
}
|
||||
public void testRecordPatterns() {
|
||||
doTest();
|
||||
}
|
||||
public void testRecordPatternNested() {
|
||||
doTest();
|
||||
}
|
||||
public void testRecordPatternAndWhen() {
|
||||
doTest();
|
||||
}
|
||||
public void testNestedRecordPatterns() {
|
||||
doTest();
|
||||
}
|
||||
public void testSuspiciousLabelElementsJava20() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testForEachPattern() {
|
||||
myFixture.addClass("""
|
||||
package org.jetbrains.annotations;
|
||||
public @interface Range {
|
||||
long from();
|
||||
long to();
|
||||
}""");
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ import org.junit.platform.suite.api.Suite;
|
||||
DataFlowInspection9Test.class,
|
||||
DataFlowInspection11Test.class,
|
||||
DataFlowInspection16Test.class,
|
||||
DataFlowInspection20Test.class,
|
||||
DataFlowInspection21Test.class,
|
||||
DataFlowInspectionHeavyTest.class,
|
||||
DataFlowInspectionAncientTest.class,
|
||||
|
||||
@@ -66,10 +66,11 @@ public class DefUseTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
public void testFieldCouldBeUsedOutside() { doTest(); }
|
||||
public void testForEachIterationParameter() { doTest(); }
|
||||
public void testPatternVariable() { doTest(); }
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
|
||||
@@ -34,9 +34,9 @@ class DuplicateBranchesInEnhancedSwitchTest : LightJavaCodeInsightFixtureTestCas
|
||||
fun testWhenClause1() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21) { doTest() }
|
||||
fun testWhenClause2() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21) { doTest() }
|
||||
fun testExpressionsWithComments() = doTest()
|
||||
fun testNullDuplicatesPattern() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_20_PREVIEW) { doTest() }
|
||||
fun testPatternDuplicatesNull() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_20_PREVIEW) { doTest() }
|
||||
fun testNullDuplicatesDefault() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_20_PREVIEW) { doTest() }
|
||||
fun testNullDuplicatesPattern() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21) { doTest() }
|
||||
fun testPatternDuplicatesNull() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21) { doTest() }
|
||||
fun testNullDuplicatesDefault() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21) { doTest() }
|
||||
fun testMixedCases() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21_PREVIEW) { doTest() }
|
||||
fun testDominatedUnnamedVariables() = IdeaTestUtil.withLevel(module, LanguageLevel.JDK_21_PREVIEW) { doTest() }
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ public class ForEachWithRecordPatternCanBeUsedInspectionTest extends LightJavaCo
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_20;
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_X;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -179,6 +179,6 @@ public class LocalCanBeFinalTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
|
||||
public void testPatternVariables() {
|
||||
myTool.REPORT_PATTERN_VARIABLES = true;
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_20_PREVIEW, this::doTest);
|
||||
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, this::doTest);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class PatternVariablesCanBeReplacedWithCastInspectionNotPreserveTest extends LightQuickFixParameterizedTestCase {
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_20;
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class PatternVariablesCanBeReplacedWithCastInspectionTest extends LightQuickFixParameterizedTestCase {
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_20;
|
||||
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class RedundantLengthCheckInspectionTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,8 +19,8 @@ class JavaKeywordsTest {
|
||||
assertTrue(JavaLexer.isSoftKeyword("sealed", LanguageLevel.JDK_17))
|
||||
assertFalse(JavaLexer.isKeyword("permits", LanguageLevel.JDK_17))
|
||||
assertTrue(JavaLexer.isSoftKeyword("permits", LanguageLevel.JDK_17))
|
||||
assertFalse(JavaLexer.isKeyword("when", LanguageLevel.JDK_20_PREVIEW))
|
||||
assertTrue(JavaLexer.isSoftKeyword("when", LanguageLevel.JDK_20_PREVIEW))
|
||||
assertFalse(JavaLexer.isKeyword("when", LanguageLevel.JDK_20))
|
||||
assertFalse(JavaLexer.isSoftKeyword("when", LanguageLevel.JDK_20))
|
||||
assertFalse(JavaLexer.isKeyword("when", LanguageLevel.JDK_21))
|
||||
assertTrue(JavaLexer.isSoftKeyword("when", LanguageLevel.JDK_21))
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public class JavaFeatureSpecificSanityTest extends LightJavaCodeInsightFixtureTe
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -53,6 +53,6 @@ public class FindUsagesTargetTest extends LightJavaCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -972,18 +972,6 @@ public class ExtractMethodTest extends LightJavaCodeInsightTestCase {
|
||||
doTestWithLanguageLevel(LanguageLevel.HIGHEST);
|
||||
}
|
||||
|
||||
public void testParenthesizedPatternIntroduced() throws Exception {
|
||||
doExitPointsTest(false);
|
||||
}
|
||||
|
||||
public void testParenthesizedPatternIntroduced2() throws Exception {
|
||||
doExitPointsTest(false);
|
||||
}
|
||||
|
||||
public void testParenthesizedPatternIntroduced3() throws Exception {
|
||||
doTestWithLanguageLevel(LanguageLevel.HIGHEST);
|
||||
}
|
||||
|
||||
public void testRecordPatternIntroduced() throws Exception {
|
||||
doExitPointsTest(false);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class UseOfConcreteClassInspectionTest extends LightJavaInspectionTestCas
|
||||
|
||||
@Override
|
||||
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_20;
|
||||
return JAVA_21;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user