[java-highlighting] IDEA-323955 Record patterns support available only for Java 20 preview. Fix compiler errors and tests

GitOrigin-RevId: 5f856519e56e61818e95cf63766fb6a54c6283ad
This commit is contained in:
Mikhail Pyltsin
2023-07-04 14:12:08 +02:00
committed by intellij-monorepo-bot
parent 770e5e4e90
commit 4bc43b46f4
130 changed files with 830 additions and 845 deletions

View File

@@ -43,8 +43,6 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
import static com.intellij.psi.util.JavaPsiPatternUtil.skipParenthesizedPatternDown;
public final class EvaluatorBuilderImpl implements EvaluatorBuilder {
private static final EvaluatorBuilderImpl ourInstance = new EvaluatorBuilderImpl();
@@ -477,10 +475,7 @@ public final class EvaluatorBuilderImpl implements EvaluatorBuilder {
PsiPrimaryPattern primaryPattern = JavaPsiPatternUtil.getTypedPattern(element);
final Evaluator guardingEvaluator;
final PsiExpression guardingExpression;
if (element instanceof PsiPattern pattern && skipParenthesizedPatternDown(pattern) instanceof PsiGuardedPattern guardedPattern) {
guardingExpression = guardedPattern.getGuardingExpression();
}
else if (element instanceof PsiPatternGuard patternGuard) {
if (element instanceof PsiPatternGuard patternGuard) {
guardingExpression = patternGuard.getGuardingExpression();
}
else {

View File

@@ -127,7 +127,7 @@ feature.local.interfaces=Local interfaces
feature.local.enums=Local enums
feature.inner.statics=Static declarations in inner classes
feature.patterns.in.switch=Patterns in switch
feature.guarded.and.parenthesised.patterns=Guarded and parenthesized patterns
feature.parenthesised.patterns=Parenthesized patterns
feature.pattern.guard.and.record.patterns=Pattern guards and record patterns
feature.record.patterns.in.for.each=Record patterns in for-each loops

View File

@@ -742,8 +742,7 @@ public final class HighlightControlFlowUtil {
if (parent instanceof PsiParameterList && parent.getParent() == lambdaExpression) {
return null;
}
if (PsiTreeUtil.getParentOfType(context, PsiGuardedPattern.class, true, PsiLambdaExpression.class) != null ||
PsiTreeUtil.getParentOfType(context, PsiPatternGuard.class, true, PsiLambdaExpression.class) != null) {
if (PsiTreeUtil.getParentOfType(context, PsiPatternGuard.class, true, PsiLambdaExpression.class) != null) {
return null;
}
if (!isEffectivelyFinal(variable, lambdaExpression, context)) {
@@ -768,9 +767,9 @@ public final class HighlightControlFlowUtil {
*/
@Nullable
private static HighlightInfo.Builder checkFinalUsageInsideGuardedPattern(@NotNull PsiVariable variable, @NotNull PsiJavaCodeReferenceElement context) {
PsiCaseLabelElement refGuardedPattern = PsiTreeUtil.getParentOfType(context, PsiGuardedPattern.class, PsiPatternGuard.class);
PsiCaseLabelElement refGuardedPattern = PsiTreeUtil.getParentOfType(context, PsiPatternGuard.class);
if (refGuardedPattern == null) return null;
PsiCaseLabelElement varGuardedPattern = PsiTreeUtil.getParentOfType(variable, PsiGuardedPattern.class, PsiPatternGuard.class);
PsiCaseLabelElement varGuardedPattern = PsiTreeUtil.getParentOfType(variable, PsiPatternGuard.class);
if (refGuardedPattern != varGuardedPattern && !isEffectivelyFinal(variable, refGuardedPattern, context)) {
String message = JavaErrorBundle.message("guarded.pattern.variable.must.be.final");
HighlightInfo.Builder builder = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(context).descriptionAndTooltip(message);
@@ -862,7 +861,7 @@ public final class HighlightControlFlowUtil {
if (parent instanceof PsiLambdaExpression) {
return parent;
}
if (parent instanceof PsiGuardedPattern || parent instanceof PsiPatternGuard) {
if (parent instanceof PsiPatternGuard) {
return parent;
}
prevParent = parent;

View File

@@ -853,8 +853,8 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) add(GenericsHighlightUtil.checkInstanceOfGenericType(myLanguageLevel, expression));
if (!myHolder.hasErrorResults() &&
myLanguageLevel.isAtLeast(LanguageLevel.JDK_16) &&
// 5.20.2 Removed restriction on pattern instanceof for unconditional patterns (JEP 427)
myLanguageLevel.isLessThan(LanguageLevel.JDK_19_PREVIEW)) {
// 5.20.2 Removed restriction on pattern instanceof for unconditional patterns (JEP 432, 440)
(myLanguageLevel.isLessThan(LanguageLevel.JDK_21) && myLanguageLevel != LanguageLevel.JDK_20_PREVIEW)) {
add(HighlightUtil.checkInstanceOfPatternSupertype(expression));
}
}
@@ -1947,22 +1947,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
@Override
public void visitParenthesizedPattern(@NotNull PsiParenthesizedPattern pattern) {
super.visitParenthesizedPattern(pattern);
add(checkFeature(pattern, HighlightingFeature.GUARDED_AND_PARENTHESIZED_PATTERNS));
}
@Override
public void visitGuardedPattern(@NotNull PsiGuardedPattern pattern) {
super.visitGuardedPattern(pattern);
if (HighlightingFeature.PATTERN_GUARDS_AND_RECORD_PATTERNS.isAvailable(pattern)) {
String message = JavaErrorBundle.message("guarded.patterns.unavailable");
add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(pattern.getNode()).descriptionAndTooltip(message));
}
if (!myHolder.hasErrorResults()) {
add(checkFeature(pattern, HighlightingFeature.GUARDED_AND_PARENTHESIZED_PATTERNS));
}
if (myHolder.hasErrorResults()) return;
PsiExpression guardingExpr = pattern.getGuardingExpression();
add(checkGuardingExpressionHasBooleanType(guardingExpr));
add(checkFeature(pattern, HighlightingFeature.PARENTHESIZED_PATTERNS));
}
@Override

View File

@@ -46,11 +46,11 @@ public enum HighlightingFeature {
LOCAL_INTERFACES(LanguageLevel.JDK_16, "feature.local.interfaces"),
LOCAL_ENUMS(LanguageLevel.JDK_16, "feature.local.enums"),
INNER_STATICS(LanguageLevel.JDK_16, "feature.inner.statics"),
PARENTHESIZED_PATTERNS(LanguageLevel.JDK_20_PREVIEW, "feature.guarded.and.parenthesised.patterns"){
PARENTHESIZED_PATTERNS(LanguageLevel.JDK_20_PREVIEW, "feature.parenthesised.patterns"){
@Override
boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
LanguageLevel until = LanguageLevel.JDK_20_PREVIEW;
return until == level;
return until == useSiteLevel;
}
@Override
@@ -74,7 +74,7 @@ public enum HighlightingFeature {
@Override
boolean isSufficient(@NotNull LanguageLevel useSiteLevel) {
LanguageLevel until = LanguageLevel.JDK_20_PREVIEW;
return until == level;
return until == useSiteLevel;
}

View File

@@ -707,14 +707,14 @@ public class SwitchBlockHighlightingModel {
if (isConstantLabelElement(nextElement)) {
PsiExpression constExpr = ObjectUtils.tryCast(nextElement, PsiExpression.class);
assert constExpr != null;
if ((PsiUtil.getLanguageLevel(constExpr).isAtLeast(LanguageLevel.JDK_19_PREVIEW) ||
if ((PsiUtil.getLanguageLevel(constExpr).isAtLeast(LanguageLevel.JDK_20_PREVIEW) ||
JavaPsiPatternUtil.isUnconditionalForType(currentElement, mySelectorType)) &&
JavaPsiPatternUtil.dominates(currentElement, constExpr.getType())) {
result.put(nextElement, current);
}
}
else if (isNullType(nextElement) && JavaPsiPatternUtil.isUnconditionalForType(currentElement, mySelectorType)
&& PsiUtil.getLanguageLevel(nextElement).isLessThan(LanguageLevel.JDK_19_PREVIEW)) {
&& PsiUtil.getLanguageLevel(nextElement).isLessThan(LanguageLevel.JDK_20_PREVIEW)) {
result.put(nextElement, current);
}
else if (JavaPsiPatternUtil.dominates(currentElement, nextElement)) {

View File

@@ -349,7 +349,7 @@ public final class NullabilityProblemKind<T extends PsiElement> {
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_19_PREVIEW) &&
if (PsiUtil.getLanguageLevel(element).isLessThan(LanguageLevel.JDK_20_PREVIEW) &&
element instanceof PsiPattern && expressionType != null &&
JavaPsiPatternUtil.isUnconditionalForType(element, expressionType)) {
return null;

View File

@@ -1121,24 +1121,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;
if (innerPattern instanceof PsiGuardedPattern guardedPattern) {
PsiPrimaryPattern primaryPattern = guardedPattern.getPrimaryPattern();
processPattern(sourcePattern, primaryPattern, checkType, instanceofAnchor, endPatternOffset);
PsiExpression expression = guardedPattern.getGuardingExpression();
if (expression != null) {
expression.accept(this);
}
else {
addInstruction(new PushValueInstruction(DfTypes.BOOLEAN));
}
DeferredOffset condGotoOffset = new DeferredOffset();
addInstruction(new ConditionalGotoInstruction(condGotoOffset, DfTypes.TRUE));
addInstruction(new PushValueInstruction(DfTypes.FALSE));
addInstruction(new GotoInstruction(endPatternOffset));
condGotoOffset.setOffset(getInstructionCount());
}
else if (innerPattern instanceof PsiParenthesizedPattern) {
PsiPattern unwrappedPattern = JavaPsiPatternUtil.skipParenthesizedPatternDown(innerPattern);
processPattern(sourcePattern, unwrappedPattern, checkType, instanceofAnchor, endPatternOffset);
@@ -1192,8 +1174,8 @@ public class ControlFlowAnalyzer extends JavaElementVisitor {
@NotNull DeferredOffset endPatternOffset,
@NotNull DfaVariableValue patternDfaVar,
@Nullable DfaAnchor instanceofAnchor) {
boolean java19plus = PsiUtil.getLanguageLevel(myCodeFragment).isAtLeast(LanguageLevel.JDK_19_PREVIEW);
if (java19plus
boolean java20plus = PsiUtil.getLanguageLevel(myCodeFragment).isAtLeast(LanguageLevel.JDK_20_PREVIEW);
if (java20plus
? (sourcePattern == innerPattern || !JavaPsiPatternUtil.isUnconditionalForType(innerPattern, checkType))
: !JavaPsiPatternUtil.isUnconditionalForType(innerPattern, checkType)) {
addPatternTypeTest(innerPattern, instanceofAnchor, endPatternOffset, patternDfaVar);

View File

@@ -229,12 +229,7 @@ public class LocalCanBeFinal extends AbstractBaseJavaLocalInspectionTool impleme
else if (context instanceof PsiCaseLabelElementList list) {
if (list.getElementCount() == 1) {
PsiCaseLabelElement element = list.getElements()[0];
if (element instanceof PsiGuardedPattern guardedPattern) {
PsiExpression guardingExpression = guardedPattern.getGuardingExpression();
if (guardingExpression == null) return;
from = flow.getStartOffset(guardingExpression);
}
else if (element instanceof PsiPatternGuard patternGuard) {
if (element instanceof PsiPatternGuard patternGuard) {
PsiExpression guardingExpression = patternGuard.getGuardingExpression();
if (guardingExpression == null) return;
from = flow.getStartOffset(guardingExpression);

View File

@@ -805,7 +805,7 @@ public final class DuplicateBranchesInSwitchInspection extends LocalInspectionTo
if (labelElementList == null) continue;
PsiCaseLabelElement[] elements = labelElementList.getElements();
for (PsiCaseLabelElement element : elements) {
if (PsiTreeUtil.instanceOf(element, PsiGuardedPattern.class, PsiPatternGuard.class) ||
if (PsiTreeUtil.instanceOf(element, PsiPatternGuard.class) ||
element instanceof PsiPattern && (!java20plus || JavaPsiPatternUtil.containsPatternVariable(element))) {
return false;
}

View File

@@ -506,11 +506,6 @@ public final class ExpectedTypesProvider {
processGuard(guard);
}
@Override
public void visitGuardedPattern(@NotNull PsiGuardedPattern pattern) {
processGuard(pattern);
}
private void processGuard(@NotNull PsiCaseLabelElement guard) {
final PsiSwitchBlock switchBlock = PsiTreeUtil.getParentOfType(guard, PsiSwitchBlock.class);
if (switchBlock != null) {

View File

@@ -379,14 +379,6 @@ public class ConvertSwitchToIfIntention extends PsiUpdateModCommandAction<PsiSwi
if (normalizedPattern instanceof PsiTypeTestPattern typeTestPattern) {
return createIfCondition(typeTestPattern, expressionText, commentTracker);
}
else if (normalizedPattern instanceof PsiGuardedPattern guardedPattern) {
PsiPattern primaryPattern = JavaPsiPatternUtil.skipParenthesizedPatternDown(guardedPattern.getPrimaryPattern());
if (!(primaryPattern instanceof PsiTypeTestPattern typeTestPattern)) return null;
String primaryCondition = createIfCondition(typeTestPattern, expressionText, commentTracker);
PsiExpression guardingExpression = guardedPattern.getGuardingExpression();
if (guardingExpression == null) return null;
return primaryCondition + "&&" + commentTracker.textWithComments(guardingExpression);
}
else if (normalizedPattern instanceof PsiDeconstructionPattern deconstructionPattern) {
return createIfCondition(deconstructionPattern, expressionText, commentTracker);
}

View File

@@ -330,7 +330,7 @@ public class EnhancedSwitchMigrationInspection extends AbstractBaseJavaLocalInsp
continue;
}
List<? extends PsiCaseLabelElement> caseExpressions = branch.myCaseExpressions;
if (caseExpressions == null) {
if (caseExpressions == null || caseExpressions.size() == 1) {
result.add(branch);
continue;
}

View File

@@ -667,14 +667,6 @@ public final class JavaSpacePropertyProcessor extends JavaElementVisitor {
}
}
@Override
public void visitGuardedPattern(@NotNull PsiGuardedPattern pattern) {
super.visitGuardedPattern(pattern);
if (myType1 == JavaTokenType.ANDAND || myType2 == JavaTokenType.ANDAND) {
createSpaceInCode(true);
}
}
@Override
public void visitPatternGuard(@NotNull PsiPatternGuard guard) {
if (myType1 == JavaTokenType.WHEN_KEYWORD || myType2 == JavaTokenType.WHEN_KEYWORD) {

View File

@@ -171,10 +171,6 @@ public abstract class JavaElementVisitor extends PsiElementVisitor {
visitStatement(statement);
}
public void visitGuardedPattern(@NotNull PsiGuardedPattern pattern) {
visitPattern(pattern);
}
public void visitIdentifier(@NotNull PsiIdentifier identifier) {
visitJavaToken(identifier);
}

View File

@@ -1,22 +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.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Represents guarded pattern like {@code String s && s.length() > 10 }
*/
public interface PsiGuardedPattern extends PsiPattern {
/**
* @return pattern which is being guarded
*/
@NotNull
PsiPrimaryPattern getPrimaryPattern();
/**
* @return expression which guards the pattern (after {@code &&}) or null if pattern is incomplete
*/
@Nullable
PsiExpression getGuardingExpression();
}

View File

@@ -1655,9 +1655,6 @@ final class ControlFlowAnalyzer extends JavaElementVisitor {
processPattern(deconstructionComponent);
}
}
else if (pattern instanceof PsiGuardedPattern) {
generateExpressionInstructions(((PsiGuardedPattern)pattern).getGuardingExpression());
}
}
@Override

View File

@@ -57,7 +57,7 @@ public interface ElementType extends JavaTokenType, JavaDocTokenType, JavaElemen
CONTINUE_STATEMENT, RETURN_STATEMENT, THROW_STATEMENT, SYNCHRONIZED_STATEMENT, TRY_STATEMENT, LABELED_STATEMENT, ASSERT_STATEMENT,
YIELD_STATEMENT);
TokenSet JAVA_PATTERN_BIT_SET = TokenSet.create(TYPE_TEST_PATTERN, GUARDED_PATTERN, PARENTHESIZED_PATTERN, DECONSTRUCTION_PATTERN);
TokenSet JAVA_PATTERN_BIT_SET = TokenSet.create(TYPE_TEST_PATTERN, PARENTHESIZED_PATTERN, DECONSTRUCTION_PATTERN);
TokenSet JAVA_CASE_LABEL_ELEMENT_BIT_SET = TokenSet.orSet(JAVA_PATTERN_BIT_SET, EXPRESSION_BIT_SET, TokenSet.create(
DEFAULT_CASE_LABEL_ELEMENT, PATTERN_GUARD));

View File

@@ -144,7 +144,6 @@ public interface JavaElementType {
IElementType DECONSTRUCTION_PATTERN_VARIABLE = new JavaCompositeElementType("DECONSTRUCTION_PATTERN_VARIABLE", () -> new PsiDeconstructionPatternVariableImpl());
IElementType PATTERN_GUARD = new JavaCompositeElementType("PATTERN_GUARD", () -> new PsiPatternGuardImpl());
IElementType PARENTHESIZED_PATTERN = new JavaCompositeElementType("PARENTHESIZED_PATTERN", () -> new PsiParenthesizedPatternImpl());
IElementType GUARDED_PATTERN = new JavaCompositeElementType("GUARDED_PATTERN", () -> new PsiGuardedPatternImpl());
IElementType DEFAULT_CASE_LABEL_ELEMENT = new JavaCompositeElementType("DEFAULT_CASE_LABEL_ELEMENT", () -> new PsiDefaultLabelElementImpl());
IElementType CASE_LABEL_ELEMENT_LIST = new JavaCompositeElementType("CASE_LABEL_ELEMENT_LIST", () -> new PsiCaseLabelElementListImpl());

View File

@@ -1,56 +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;
import java.util.Objects;
public class PsiGuardedPatternImpl extends CompositePsiElement implements PsiGuardedPattern, Constants {
public PsiGuardedPatternImpl() {
super(GUARDED_PATTERN);
}
@Override
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof JavaElementVisitor) {
((JavaElementVisitor)visitor).visitGuardedPattern(this);
}
else {
visitor.visitElement(this);
}
}
@Override
public String toString() {
return "PsiGuardedPattern";
}
@Override
public @NotNull PsiPrimaryPattern getPrimaryPattern() {
return Objects.requireNonNull(PsiTreeUtil.getChildOfType(this, PsiPrimaryPattern.class));
}
@Override
public @Nullable PsiExpression getGuardingExpression() {
return PsiTreeUtil.getChildOfType(this, PsiExpression.class);
}
@Override
public boolean processDeclarations(@NotNull PsiScopeProcessor processor,
@NotNull ResolveState state,
PsiElement lastParent,
@NotNull PsiElement place) {
final PsiPrimaryPattern patternVariable = getPrimaryPattern();
if (!patternVariable.processDeclarations(processor, state, null, place)) return false;
final PsiExpression expression = getGuardingExpression();
if (expression == null) return true;
return expression.processDeclarations(processor, state, lastParent, place);
}
}

View File

@@ -122,9 +122,6 @@ public final class JavaPsiPatternUtil {
@Contract(value = "null -> null", pure = true)
@Nullable
public static PsiPatternVariable getPatternVariable(@Nullable PsiCaseLabelElement pattern) {
if (pattern instanceof PsiGuardedPattern) {
return getPatternVariable(((PsiGuardedPattern)pattern).getPrimaryPattern());
}
if (pattern instanceof PsiPatternGuard) {
return getPatternVariable(((PsiPatternGuard)pattern).getPattern());
}
@@ -143,10 +140,7 @@ public final class JavaPsiPatternUtil {
@Contract(value = "null -> null", pure = true)
@Nullable
public static PsiPrimaryPattern getTypedPattern(@Nullable PsiCaseLabelElement element) {
if (element instanceof PsiGuardedPattern) {
return getTypedPattern(((PsiGuardedPattern)element).getPrimaryPattern());
}
else if (element instanceof PsiPatternGuard) {
if (element instanceof PsiPatternGuard) {
return getTypedPattern(((PsiPatternGuard)element).getPattern());
}
else if (element instanceof PsiParenthesizedPattern) {
@@ -174,9 +168,6 @@ public final class JavaPsiPatternUtil {
if (pattern instanceof PsiPatternGuard) {
return containsPatternVariable(((PsiPatternGuard)pattern).getPattern());
}
else if (pattern instanceof PsiGuardedPattern) {
return containsPatternVariable(((PsiGuardedPattern)pattern).getPrimaryPattern());
}
else if (pattern instanceof PsiTypeTestPattern) {
return ((PsiTypeTestPattern)pattern).getPatternVariable() != null;
}
@@ -205,9 +196,6 @@ public final class JavaPsiPatternUtil {
public static @Nullable PsiTypeElement getPatternTypeElement(@Nullable PsiCaseLabelElement pattern) {
if (pattern == null) return null;
if (pattern instanceof PsiGuardedPattern) {
return getPatternTypeElement(((PsiGuardedPattern)pattern).getPrimaryPattern());
}
else if (pattern instanceof PsiPatternGuard) {
return getPatternTypeElement(((PsiPatternGuard)pattern).getPattern());
}
@@ -237,12 +225,6 @@ public final class JavaPsiPatternUtil {
if (!Boolean.TRUE.equals(constVal)) return null;
return findUnconditionalPattern(guarded.getPattern());
}
else if (pattern instanceof PsiGuardedPattern) {
PsiGuardedPattern guarded = (PsiGuardedPattern)pattern;
Object constVal = evaluateConstant(guarded.getGuardingExpression());
if (!Boolean.TRUE.equals(constVal)) return null;
return findUnconditionalPattern(guarded.getPrimaryPattern());
}
else if (pattern instanceof PsiParenthesizedPattern) {
return findUnconditionalPattern(((PsiParenthesizedPattern)pattern).getPattern());
}
@@ -508,7 +490,7 @@ public final class JavaPsiPatternUtil {
*/
public static @Nullable PsiType getContextType(@NotNull PsiPattern pattern) {
PsiElement parent = pattern.getParent();
while (parent instanceof PsiParenthesizedPattern || parent instanceof PsiGuardedPattern) {
while (parent instanceof PsiParenthesizedPattern) {
parent = parent.getParent();
}
if (parent instanceof PsiInstanceOfExpression) {

View File

@@ -23,14 +23,13 @@ public class Test {
<T> void testRawDeconstruction(TypedRecord<T> r) {
if (r instanceof TypedRecord<T>(I t)){ }
if (r instanceof TypedRecord<T>(T t)){ }
if (r instanceof <error descr="Raw deconstruction patterns are not allowed">TypedRecord</error>(I t)){ }
if (r instanceof <error descr="Raw deconstruction patterns are not allowed">TypedRecord</error>(T t)){ }
if (r instanceof TypedRecord(I t)){ }
if (r instanceof TypedRecord(T t)){ }
}
void resolveHighlighting1(Object o){
if (o instanceof Child(A a, B b) c){
if (o instanceof Child(A a, B b)){
System.out.println(a);
System.out.println(c);
}
else {
System.out.println(<error descr="Cannot resolve symbol 'a'">a</error>);
@@ -39,25 +38,22 @@ public class Test {
}
void resolveHighlighting2(Object o){
if (!(o instanceof Child(A a, B b) c)){
if (!(o instanceof Child(A a, B b))){
System.out.println(<error descr="Cannot resolve symbol 'a'">a</error>);
System.out.println(<error descr="Cannot resolve symbol 'c'">c</error>);
}
else {
System.out.println(a);
System.out.println(c);
}
}
void resolveHighlighting3(Object o){
if (!(o instanceof Child(A a, B b) c)) return;
if (!(o instanceof Child(A a, B b))) return;
System.out.println(a);
System.out.println(c);
}
void resolveHighlighting4(Object o){
if (o instanceof Child(A a, B b) c) return;
if (o instanceof Child(A a, B b)) return;
System.out.println(<error descr="Cannot resolve symbol 'a'">a</error>);
System.out.println(<error descr="Cannot resolve symbol 'c'">c</error>);
}
}

View File

@@ -6,7 +6,7 @@ class X {
}
void ifParenthesizedPattern(Object obj) {
if (!(obj instanceof ((String s)))) return;
if (!(obj instanceof String s)) return;
System.out.println(s.trim());
}

View File

@@ -1,17 +0,0 @@
class Main {
private static final boolean TRUE = 1 == 1;
void testParenthesizedPattern(String s) {
if (s instanceof (String s1)) {
System.out.println(s1);
}
}
void testDeepParenthesizedPattern(String s) {
if (s instanceof ( ((( (( String s1)) )) ) )) {
System.out.println(s1);
}
}
}

View File

@@ -44,7 +44,7 @@ class Test {
switch (o) {
case (Integer i) when (switch (o) {
case Integer ii when ii != mode -> 2;
case default -> 1;
default -> 1;
}) == mode -> System.out.println();
default -> {}
}

View File

@@ -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"; // unresolved
}
else {

View File

@@ -1,78 +0,0 @@
record RecordClass(int x) {}
public class FallThrough {
void testFallThough(Integer i, Object o) {
switch (i) {
case 1, <error descr="Illegal fall-through to a pattern">Integer x</error> -> {
}
}
switch (i) {
case 1, <error descr="Illegal fall-through to a pattern">Integer x</error> -> {
}
}
switch (i) {
case null, Integer x -> {
}
}
switch (i) {
case 1, <error descr="Illegal fall-through to a pattern">Integer x when x > 0</error> -> {
}
}
switch (o) {
case String s, <error descr="Illegal fall-through to a pattern">Integer x when x > 0</error> -> {
}
}
switch (o) {
case String s, <error descr="Illegal fall-through to a pattern">RecordClass(int x) r when x > 0</error> -> {
}
}
switch (o) {
case String s, <error descr="Illegal fall-through to a pattern">RecordClass(int x)</error> -> {
}
}
switch (o) {
case null, <error descr="Illegal fall-through to a pattern">RecordClass(int x)</error> -> {}
case default -> {}
}
switch (o) {
case RecordClass(int x) s, <error descr="Illegal fall-through from a pattern">null</error> -> {}
case default -> {}
}
switch (i) {
case 1:
case <error descr="Illegal fall-through to a pattern">Integer x</error>:
System.out.println();
break;
}
switch (i) {
case 1:
case <error descr="Illegal fall-through to a pattern">Integer x when x > 0</error>:
System.out.println();
break;
}
switch (o) {
case String s:
case <error descr="Illegal fall-through to a pattern">Integer x when x > 0</error>:
System.out.println();
break;
}
switch (o) {
case Integer integer:
System.out.println(1);
case <error descr="Illegal fall-through to a pattern">String s when s.isEmpty()</error>:
System.out.println(2);
break;
default:
System.out.println(3);
}
switch (o) {
case String s:
break;
case Integer x when x > 0:
System.out.println();
break;
default:
throw new IllegalStateException("Unexpected value: " + o);
}
}
}

View File

@@ -14,7 +14,7 @@ final class D implements I {}
record TypedRecord<T>(T x) {}
public class Incompatible {
class Incompatible {
Object object;
Integer integer;
@@ -22,15 +22,15 @@ public class Incompatible {
<T extends IntegerRecord> void incompatible() {
switch (object) {
case LongRecord(String s1, <error descr="Incompatible types. Found: 'int', required: 'java.lang.String'">int x</error>, <error descr="Incompatible types. Found: 'int', required: 'java.lang.String'">int y</error>) -> {}
case RecordWithInterface(<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'I'">Integer x</error>, <error descr="Incompatible types. Found: 'java.lang.Integer', required: 'I'">Integer y</error>) s when true -> {}
case RecordWithInterface(<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'I'">Integer x</error>, D y) s when true -> {}
case RecordWithInterface(I x, D y) s when true -> {}
case LongRecord<error descr="Incorrect number of nested patterns: expected 3 but found 2">(String s1, int y)</error> -> {}
case RecordWithInterface<error descr="Incorrect number of nested patterns: expected 2 but found 1">(Integer y)</error> when true -> {}
case RecordWithInterface(<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'I'">Integer x</error>, D y) when true -> {}
case RecordWithInterface(I x, D y) when true -> {}
case <error descr="Deconstruction pattern can only be applied to a record, 'java.lang.Integer' is not a record">Integer</error>(double x) -> {}
case PrimitiveRecord(<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'int'">Integer x</error>) s when true -> {}
case PrimitiveRecord(int x) s when true -> {}
case IntegerRecord(Integer x) s when true -> {}
case IntegerRecord(<error descr="Incompatible types. Found: 'int', required: 'java.lang.Integer'">int x</error>) s when true -> {}
case PrimitiveRecord(<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'int'">Integer x</error>) when true -> {}
case PrimitiveRecord(int x) when true -> {}
case IntegerRecord(Integer x) when true -> {}
case IntegerRecord(<error descr="Incompatible types. Found: 'int', required: 'java.lang.Integer'">int x</error>) when true -> {}
case <error descr="'Object' cannot be safely cast to 'T'">T(Integer x)</error> -> {}
}
@@ -39,12 +39,12 @@ public class Incompatible {
default -> {}
}
switch (typedRecord){
case TypedRecord<I>(I x) s-> {}
case TypedRecord<I>(I x) -> {}
default -> {}
}
switch (typedRecord){
case <error descr="Raw deconstruction patterns are not allowed">TypedRecord</error>(C x) s-> {}
case <error descr="Raw deconstruction patterns are not allowed">TypedRecord</error>(I x) s-> {}
case TypedRecord(C x) -> {}
case TypedRecord(I x) -> {}
case TypedRecord<I>(<error descr="Incompatible types. Found: 'java.lang.Integer', required: 'I'">Integer t</error>) -> {}
case TypedRecord<?>(<error descr="'Object' cannot be safely cast to 'List<Number>'">List<Number> nums</error>) -> {}
case TypedRecord<?>(List<?> list) -> {}
@@ -54,9 +54,9 @@ public class Incompatible {
default -> {}
}
switch (object){
case Top(Child c1, Child(I x, <error descr="Incompatible types. Found: 'int', required: 'I'">int y</error>) c3) c -> { }
case Top(Child c1, <error descr="Incompatible types. Found: 'Wrong', required: 'Child'">Wrong(int y) c3</error>) c -> { }
case Top(Child c1, Child(C a, I i) c3) c -> { }
case Top(Child c1, Child(I x, <error descr="Incompatible types. Found: 'int', required: 'I'">int y</error>)) -> { }
case Top(Child c1, <error descr="Incompatible types. Found: 'Wrong', required: 'Child'">Wrong(int y)</error>) -> { }
case Top(Child c1, Child(C a, I i)) -> { }
default -> {}
}
}

View File

@@ -58,10 +58,10 @@ class Main {
};
switch (o) {
case (Integer i):
case Integer i:
System.out.println("int");
break;
case <error descr="Label is dominated by a preceding case label '(Integer i)'">Integer o1 when o1 != null</error>:
case <error descr="Label is dominated by a preceding case label 'Integer i'">Integer o1 when o1 != null</error>:
System.out.println("num");
break;
default:
@@ -69,8 +69,8 @@ class Main {
break;
}
str = switch (o) {
case (Integer i) -> "num";
case <error descr="Label is dominated by a preceding case label '(Integer i)'">Integer o1 when o1 != null</error> -> "int";
case Integer i -> "num";
case <error descr="Label is dominated by a preceding case label 'Integer i'">Integer o1 when o1 != null</error> -> "int";
default -> "def";
};
@@ -145,16 +145,16 @@ class Main {
};
switch (ii) {
case <error descr="'switch' has both an unconditional pattern and a default label">Object obj</error>, null:
case Object obj, <error descr="Invalid case label combination: 'null' can only be used as a single case label or paired only with 'default'">null</error>:
System.out.println("int");
break;
<error descr="'switch' has both an unconditional pattern and a default label">default</error>:
default:
System.out.println("def");
break;
}
str = switch (ii) {
case <error descr="'switch' has both an unconditional pattern and a default label">Object obj</error>, null -> "int";
<error descr="'switch' has both an unconditional pattern and a default label">default</error> -> "def";
case Object obj, <error descr="Invalid case label combination: 'null' can only be used as a single case label or paired only with 'default'">null</error> -> "int";
default -> "def";
};
switch (ii) {
@@ -214,7 +214,7 @@ class Main {
str = switch (ii) {
case Integer in when in != null -> "";
case <error descr="Label is dominated by a preceding case label 'Integer in when in != null'">1</error> -> "";
case default -> "";
default -> "";
};
switch (d) {
case Day dd when true: break;
@@ -248,7 +248,7 @@ class Main {
case MONDAY, TUESDAY, WEDNESDAY -> "ok";
};
str = switch (d) {
case MONDAY, TUESDAY, default -> "ok";
case MONDAY, TUESDAY, <error descr="Default label not allowed here: 'default' can only be used as a single case label or paired only with 'null'">default</error> -> "ok";
};
switch (d) {

View File

@@ -2,7 +2,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 Integer <error descr="Patterns in switch are not supported at language level '11'">i</error> && predicate() -> 2;
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;
case <error descr="Patterns in switch are not supported at language level '11'">null</error> -> 10;
@@ -17,7 +17,7 @@ class X {
}
int instanceofTest(Object obj) {
if (obj instanceof (Integer <error descr="Patterns in 'instanceof' are not supported at language level '11'">i</error> && predicate())) {
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>)) {

View File

@@ -2,7 +2,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 Integer <error descr="Patterns in switch are not supported at language level '16'">i</error> && predicate() -> 2;
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;
case <error descr="Patterns in switch are not supported at language level '16'">null</error> -> 10;
@@ -16,10 +16,10 @@ class X {
}
int instanceofTest(Object obj) {
if (obj instanceof (<error descr="Guarded and parenthesized patterns are not supported at language level '16'">Integer i && predicate()</error>)) {
if (obj instanceof <error descr="Parenthesized patterns are not supported at language level '16'">(Integer i)</error> && predicate()) {
return 1;
}
if (obj instanceof <error descr="Guarded and parenthesized patterns are not supported at language level '16'">(String s)</error>) {
if (obj instanceof <error descr="Parenthesized patterns are not supported at language level '16'">(String s)</error>) {
return 3;
}
return 2;

View File

@@ -1,15 +1,14 @@
class X {
int switchTest1(Object obj) {
return switch (obj) {
case (String s) -> 1;
case <error descr="Guarded patterns from JEP 406 are not available since Java 19 preview">Integer i && predicate()</error> -> 2;
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;
case <error descr="Cannot resolve symbol 'Point'">Point</error>() -> 5;
case <error descr="Cannot resolve symbol 'Point'">Point</error>(double x, double y) -> 6;
case <error descr="Cannot resolve symbol 'Point'">Point</error>() point -> 7;
case <error descr="Cannot resolve symbol 'Point'">Point</error>(double x, double y) point -> 8;
case <error descr="Cannot resolve symbol 'Point'">Point</error>() <error descr="Identifier is not allowed here">point</error> -> 7;
case <error descr="Cannot resolve symbol 'Point'">Point</error>(double x, double y) <error descr="Identifier is not allowed here">point</error> -> 8;
};
}
@@ -27,7 +26,7 @@ class X {
}
switch (point1) {
case <error descr="Cannot resolve symbol 'Point'">Point</error><?>() point -> {}
case <error descr="Cannot resolve symbol 'Point'">Point</error><?>() <error descr="Identifier is not allowed here">point</error> -> {}
}
switch (point1) {
@@ -35,7 +34,7 @@ class X {
}
switch (point1) {
case <error descr="Cannot resolve symbol 'Point'">Point</error><? extends String>() point -> {}
case <error descr="Cannot resolve symbol 'Point'">Point</error><? extends String>() <error descr="Identifier is not allowed here">point</error> -> {}
}
switch (point2) {
@@ -43,15 +42,15 @@ class X {
}
switch (point2) {
case <error descr="Cannot resolve symbol 'Point'">Point</error><? super String>() point -> {}
case <error descr="Cannot resolve symbol 'Point'">Point</error><? super String>() <error descr="Identifier is not allowed here">point</error> -> {}
}
}
int instanceofTest(Object obj) {
if (obj instanceof (<error descr="Guarded patterns from JEP 406 are not available since Java 19 preview">Integer i && predicate()</error>)) {
if (obj instanceof (Integer i<error descr="')' expected"> </error>&& predicate())<error descr="Statement expected"><error descr="Unexpected token">)</error></error> {
return 1;
}
if (obj instanceof (String s)) {
if (obj instanceof <error descr="Parenthesized patterns are not supported at language level '21'">(String s)</error>) {
return 3;
}
return 2;

View File

@@ -1,7 +1,7 @@
class RecordPatternsAndWhenGuardsInJava18 {
void test(Object o) {
switch (o) {
case MyRecord(int x) r -> {
case MyRecord(int x) -> {
}
case String s when s.length() > 10 -> {

View File

@@ -1,99 +0,0 @@
import java.util.List;
record RecordInterface(I x, I y) {}
interface Super {}
record RecordSuper(int x) implements Super {}
sealed interface I permits C, D {}
final class C implements I {}
final class D implements I {}
class Dominance {
Integer integer;
Object object;
void test(){
switch (integer) {
case Integer i -> {}
case <error descr="Label is dominated by a preceding case label 'Integer i'">1</error> -> {}
default -> {}
}
switch (integer) {
case Integer i when i > 0 -> {}
case <error descr="Label is dominated by a preceding case label 'Integer i when i > 0'">1</error> -> {}
default -> {}
}
switch (integer) {
case 1 -> {}
case Integer i when i > 0 -> {}
default -> {}
}
switch (integer) {
case 1 -> {}
case Integer i -> {}
}
switch (object) {
case CharSequence s -> {}
case <error descr="Label is dominated by a preceding case label 'CharSequence s'">String c</error> -> {}
}
switch (object) {
case CharSequence s -> {}
case <error descr="Label is dominated by a preceding case label 'CharSequence s'">String c when c.length() > 0</error> -> {}
}
switch (object) {
case CharSequence s when true -> {}
case <error descr="Label is dominated by a preceding case label 'CharSequence s when true'">String c</error> -> {}
}
switch (object) {
case CharSequence s when true -> {}
case <error descr="Label is dominated by a preceding case label 'CharSequence s when true'">String c when c.length() > 0</error> -> {}
}
switch (object) {
case RecordInterface(I z, I y) s -> {}
case <error descr="Label is dominated by a preceding case label 'RecordInterface(I z, I y) s'">RecordInterface(C z, D y)</error> -> {}
default -> {}
}
switch (object) {
case RecordInterface(I z, D y) s when true -> {}
case <error descr="Label is dominated by a preceding case label 'RecordInterface(I z, D y) s when true'">RecordInterface(C z, D y)</error> -> {}
default -> {}
}
switch (object) {
case RecordInterface(C z, D y) s when true -> {}
case <error descr="Label is dominated by a preceding case label 'RecordInterface(C z, D y) s when true'">RecordInterface(C z, D y) s when y.hashCode() > 0</error> -> {}
default -> {}
}
switch (object) {
case RecordInterface(C z, D y) s when z.hashCode() > 5 -> {}
case RecordInterface(C z, D y) s when y.hashCode() > 0 -> {}
default -> {}
}
switch (object) {
case RecordInterface(C z, D y) -> {}
case RecordInterface(I z, I y) -> {}
default -> {}
}
switch (object) {
case RecordInterface(I z, D y) -> {}
case RecordInterface(C z, C y) -> {}
default -> {}
}
switch (object) {
case Super i -> {}
case <error descr="Label is dominated by a preceding case label 'Super i'">RecordSuper(int z) q when z > 0</error> -> {}
case default -> {}
}
switch (object) {
case List<?> l -> System.out.println();
case <error descr="Label is dominated by a preceding case label 'List<?> l'">List<?> l
when l.size() == 2</error> -> System.out.println();
default -> throw new IllegalStateException("Unexpected value: " + object);
}
switch (integer) {
case Integer i -> {}
case null -> {}
}
}
}

View File

@@ -0,0 +1,109 @@
import java.util.List;
record RecordInterface(I x, I y) {
}
interface Super {
}
record RecordSuper(int x) implements Super {
}
sealed interface I permits C, D {
}
final class C implements I {
}
final class D implements I {
}
class Dominance {
Integer integer;
Object object;
void test() {
switch (integer) {
case Integer i -> {
}
case <error descr="Label is dominated by a preceding case label 'Integer i'">1</error> -> {
}
default -> {
}
}
switch (integer) {
case Integer i when i > 0 -> {
}
case <error descr="Label is dominated by a preceding case label 'Integer i when i > 0'">1</error> -> {
}
default -> {
}
}
switch (integer) {
case 1 -> {
}
case Integer i when i > 0 -> {
}
default -> {
}
}
switch (integer) {
case 1 -> {
}
case Integer i -> {
}
}
switch (object) {
case CharSequence s -> {
}
case <error descr="Label is dominated by a preceding case label 'CharSequence s'">String c</error> -> {
}
}
switch (object) {
case CharSequence s -> {
}
case <error descr="Label is dominated by a preceding case label 'CharSequence s'">String c when c.length() > 0</error> -> {
}
}
switch (object) {
case CharSequence s when true -> {
}
case <error descr="Label is dominated by a preceding case label 'CharSequence s when true'">String c</error> -> {
}
}
switch (object) {
case CharSequence s when true -> {
}
case <error descr="Label is dominated by a preceding case label 'CharSequence s when true'">String c when c.length() > 0</error> -> {
}
}
switch (object) {
case RecordInterface(C z, D y) -> {
}
case RecordInterface(I z, I y) -> {
}
default -> {
}
}
switch (object) {
case RecordInterface(I z, D y) -> {
}
case RecordInterface(C z, C y) -> {
}
default -> {
}
}
switch (object) {
case List<?> l -> System.out.println();
case <error descr="Label is dominated by a preceding case label 'List<?> l'">List<?> l when l.size() == 2</error> -> System.out.println();
default -> throw new IllegalStateException("Unexpected value: " + object);
}
switch (integer) {
case Integer i -> {
}
case null -> {
}
}
}
}

View File

@@ -19,7 +19,7 @@ record Pair<T>(T x, T y) {}
record Top(Child c1, Child c2) {}
record Child(I x, I y){}
public class Basic {
class Basic {
String o;
Super superInterface;
@@ -64,7 +64,7 @@ public class Basic {
switch (<error descr="'switch' statement does not cover all possible input values">superInterface</error>) {
case SuperChild superChild -> {}
case SuperRecord(C i) -> {}
case SuperRecord(I i) r when i.hashCode() > 0 -> {}
case SuperRecord(I i) when i.hashCode() > 0 -> {}
}
switch (o) { //non-record is completed
case String o -> {}
@@ -112,27 +112,27 @@ public class Basic {
void testNested(Top t){
switch (<error descr="'switch' statement does not cover all possible input values">t</error>){
case Top(Child(I x1, C y1) c1, Child(C x2, I y2) c2) -> {}
case Top(Child(I x1, D y1) c1, Child(I x2, C y2) c2) -> {}
case Top(Child(I x1, C y1), Child(C x2, I y2)) -> {}
case Top(Child(I x1, D y1) , Child(I x2, C y2)) -> {}
}
switch (t){
case Top(Child(I x1, C y1) c1, Child c2) -> {}
case Top(Child(I x1, D y1) c1, Child c2) -> {}
case Top(Child(I x1, C y1) , Child c2) -> {}
case Top(Child(I x1, D y1) , Child c2) -> {}
}
switch (t){
case Top(Child(I x1, C y1) c1, Child(I x2, I y2) c2) -> {}
case Top(Child(I x1, D y1) c1, Child(I x2, I y2) c2) -> {}
case Top(Child(I x1, C y1) , Child(I x2, I y2) ) -> {}
case Top(Child(I x1, D y1) , Child(I x2, I y2) ) -> {}
}
switch (<error descr="'switch' statement does not cover all possible input values">t</error>){
case Top(Child c1, Child(C x2, I y2) c2) -> {}
case Top(Child c1, Child(I x2, C y2) c2) -> {}
case Top(Child c1, Child(C x2, I y2) ) -> {}
case Top(Child c1, Child(I x2, C y2) ) -> {}
}
switch (<error descr="'switch' statement does not cover all possible input values">t</error>){
case Top(Child(I x1, C y1) c1, Child(I x2, I y2) c2) -> {}
case Top(Child(C x1, I y1) c1, Child(I x2, I y2) c2) -> {}
case Top(Child(I x1, C y1) , Child(I x2, I y2) ) -> {}
case Top(Child(C x1, I y1) , Child(I x2, I y2) ) -> {}
}
switch (t){
case Top(Child(I x1, I y1) c1, Child(I x2, I y2) c2) -> {}
case Top(Child(I x1, I y1) , Child(I x2, I y2) ) -> {}
}
}
@@ -195,7 +195,7 @@ public class Basic {
}
}
void emptyObject(Object o) {
void emptyObject0(Object o) {
switch (<error descr="'switch' statement does not have any case clauses">o</error>) { //error
}
}

View File

@@ -1,32 +0,0 @@
record RecordInterface(I x, I y) {}
sealed interface I permits C, D {}
final class C implements I {}
final class D implements I {}
public class Totality {
RecordInterface recordInterface;
void test(){
switch (recordInterface){
case RecordInterface(I x, I y) -> {}
case default -> {}
}
switch (recordInterface){
case RecordInterface(I x, I y) r when true-> {}
case default -> {}
}
switch (recordInterface){
case RecordInterface(I x, I y) -> {}
}
switch (recordInterface){
case <error descr="'switch' has both an unconditional pattern and a default label">RecordInterface r</error> -> {}
<error descr="'switch' has both an unconditional pattern and a default label">default</error> -> {}
}
switch (recordInterface){
case RecordInterface(I x, C y) -> {}
case default -> {}
}
}
}

View File

@@ -0,0 +1,493 @@
import java.util.List;
class Main {
void dominance(Object o, Integer ii, String s, Day d) {
// A switch label that has a pattern case label element p dominates another switch label that has a pattern case label element q if p dominates q
switch (o) {
case List n:
System.out.println("num");
break;
case <error descr="Label is dominated by a preceding case label 'List n'">List i</error>:
System.out.println("int");
break;
default:
System.out.println("def");
break;
}
String str;
str = switch (o) {
case List n -> "num";
case <error descr="Label is dominated by a preceding case label 'List n'">List i</error> -> "int";
default -> "def";
};
switch (o) {
case Number n:
System.out.println("num");
break;
case <error descr="Label is dominated by a preceding case label 'Number n'">Integer i</error>:
System.out.println("int");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case Number n -> "num";
case <error descr="Label is dominated by a preceding case label 'Number n'">Integer i</error> -> "int";
default -> "def";
};
// Dominance permits a guarded pattern to be followed by its unguarded form:
switch (o) {
case Integer o1 when o1 != null:
System.out.println("num");
break;
case Integer i:
System.out.println("int");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case Integer o1 when o1 != null -> "num";
case Integer i -> "int";
default -> "def";
};
switch (o) {
case Integer i:
System.out.println("int");
break;
case <error descr="Label is dominated by a preceding case label 'Integer i'">Integer o1 when o1 != null</error>:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case Integer i -> "num";
case <error descr="Label is dominated by a preceding case label 'Integer i'">Integer o1 when o1 != null</error> -> "int";
default -> "def";
};
switch (o) {
case Integer o1 when o1 > 5:
System.out.println("int");
break;
case Integer o2 when o2 != null:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case Integer o1 when o1 > 5 -> "num";
case Integer o2 when o2 != null -> "int";
default -> "def";
};
switch (o) {
case Number i when Math.random() > 0.5:
System.out.println("int");
break;
case Integer o2 when o2 != null:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case Number i when Math.random() > 0.5 -> "num";
case Integer o2 when o2 != null -> "int";
default -> "def";
};
switch (o) {
case Integer i when true:
System.out.println("int");
break;
case <error descr="Label is dominated by a preceding case label 'Integer i when true'">Integer o2 when o2 != null</error>:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (o) {
case Integer i when true -> "num";
case <error descr="Label is dominated by a preceding case label 'Integer i when true'">Integer o2 when o2 != null</error> -> "int";
default -> "def";
};
// A switch label that has a pattern case label element p that is total for the type of the selector expression
// of the enclosing switch statement or switch expression dominates a switch label that has a null case label element.
switch (ii) {
case <error descr="'switch' has both an unconditional pattern and a default label">Object obj</error>:
System.out.println("int");
break;
case null:
System.out.println("num");
break;
<error descr="'switch' has both an unconditional pattern and a default label">default</error>:
System.out.println("def");
break;
}
str = switch (ii) {
case <error descr="'switch' has both an unconditional pattern and a default label">Object obj</error> -> "num";
case null -> "int";
<error descr="'switch' has both an unconditional pattern and a default label">default</error> -> "def";
};
switch (ii) {
case Object obj, <error descr="Invalid case label combination: 'null' can only be used as a single case label or paired only with 'default'">null</error>:
System.out.println("int");
break;
default:
System.out.println("def");
break;
}
str = switch (ii) {
case <error descr="'switch' has both an unconditional pattern and a default label">Object obj</error> -> "int";
<error descr="'switch' has both an unconditional pattern and a default label">default</error> -> "def";
};
switch (ii) {
case <error descr="'switch' has both an unconditional pattern and a default label">Integer i when true</error>:
System.out.println("int");
break;
case null:
System.out.println("num");
break;
<error descr="'switch' has both an unconditional pattern and a default label">default</error>:
System.out.println("def");
break;
}
str = switch (ii) {
case <error descr="'switch' has both an unconditional pattern and a default label">Integer i when true</error> -> "int";
case null -> "int";
<error descr="'switch' has both an unconditional pattern and a default label">default</error> -> "def";
};
switch (ii) {
case Integer i when Math.random() > 0.5:
System.out.println("int");
break;
case null:
System.out.println("num");
break;
default:
System.out.println("def");
break;
}
str = switch (ii) {
case Integer i when Math.random() > 0.5 -> "int";
case null -> "int";
default -> "def";
};
// A switch label that has a pattern case label element p dominates another switch label that has a constant case label element c
// if either of the following is true:
//the type of c is a primitive type and its wrapper class is a subtype of the erasure of the type of p.
//the type of c is a reference type and is a subtype of the erasure of the type of p.
switch (ii) {
case Integer i:
break;
case <error descr="Label is dominated by a preceding case label 'Integer i'">1</error>:
case <error descr="Label is dominated by a preceding case label 'Integer i'">2</error>:
break;
}
str = switch (s) {
case String sss -> "s";
case <error descr="Label is dominated by a preceding case label 'String sss'">"1"</error>, <error descr="Label is dominated by a preceding case label 'String sss'">"2"</error> -> "1";
};
// any type of pattern (including guarded patterns) dominates constant cases
switch (d) {
case Day dd:
break;
case <error descr="Label is dominated by a preceding case label 'Day dd'">MONDAY</error>:
break;
}
str = switch (ii) {
case Integer in when in != null -> "";
case <error descr="Label is dominated by a preceding case label 'Integer in when in != null'">1</error> -> "";
default -> "";
};
switch (d) {
case Day dd when true:
break;
case <error descr="Label is dominated by a preceding case label 'Day dd when true'">MONDAY</error>:
break;
}
}
void completeness(Day d, I i, I2 i2, I3 i3, AorBorC abc, J1 j, II<Integer> ii) {
// old style switch, no completeness check
switch (d) {
case MONDAY, TUESDAY -> System.out.println("ok");
}
// If the type of the selector expression is an enum type E
String str;
switch (d) {
case Day dd when dd != null:
System.out.println("ok");
case <error descr="Label is dominated by a preceding case label 'Day dd when dd != null'">MONDAY</error>:
System.out.println("mon");
}
switch (<error descr="'switch' statement does not cover all possible input values">d</error>) {
case Day dd when dd != null:
System.out.println("ok");
}
str = switch (<error descr="'switch' expression does not cover all possible input values">d</error>) {
case MONDAY, TUESDAY -> System.out.println("ok");
};
str = switch (d) {
case MONDAY, TUESDAY, WEDNESDAY -> "ok";
};
str = switch (<error descr="'switch' expression does not cover all possible input values">d</error>) {
case MONDAY, TUESDAY -> "ok";
};
switch (d) {
case <error descr="'switch' has both an unconditional pattern and a default label">Day dd when true</error>:
System.out.println("ok");
<error descr="'switch' has both an unconditional pattern and a default label">default</error>: // blah blah blah
System.out.println("mon");
}
;
switch (d) {
case Day dd when dd != null:
System.out.println("ok");
default:
System.out.println("mon");
}
;
// If the type of the selector expression, T, names a sealed interface or a sealed class that is abstract
switch (i) {
case Sub1 s1:
System.out.println("ok");
break;
case Sub2 s2:
System.out.println("ok");
break;
case Sub3 s3:
System.out.println("ok");
break;
}
str = switch (i) {
case Sub1 s1 -> "ok";
case Sub2 s2 -> "ok";
case Sub3 s3 when true -> "ok";
};
switch (<error descr="'switch' statement does not cover all possible input values">i</error>) {
case Sub1 s1:
System.out.println("ok");
break;
case Sub2 s2:
System.out.println("ok");
break;
}
str = switch (<error descr="'switch' expression does not cover all possible input values">i</error>) {
case Sub1 s1 -> "ok";
case Sub2 s2 -> "ok";
}
;
switch (<error descr="'switch' statement does not cover all possible input values">i</error>) {
case Sub1 s1:
System.out.println("ok");
break;
case Sub2 s2:
System.out.println("ok");
break;
case Sub4 s4:
System.out.println("ok");
break;
case Sub6 s6:
System.out.println("ok");
break;
}
str = switch (<error descr="'switch' expression does not cover all possible input values">i</error>) {
case Sub1 s1 -> "ok";
case Sub2 s2 -> "ok";
case Sub4 s4 -> "ok";
case Sub6 s6 -> "ok";
};
switch (<error descr="'switch' statement does not cover all possible input values">i</error>) {
case Sub1 s1:
break;
case Sub2 s2 when Math.random() > 0.5:
break;
case Sub3 s3:
break;
}
str = switch (<error descr="'switch' expression does not cover all possible input values">i</error>) {
case I in when in != null -> "ok";
};
switch (i3) {
case Sub9 s when true:
break;
case Sub11 s:
break;
case Sub12 s when true:
break;
}
str = switch (abc) {
case A a -> "1";
case B b -> "2";
case C c -> "3";
};
str = switch (abc) {
case A a -> "1";
case C c -> "2";
case AorB ab -> "3";
case BorC bc -> "4";
};
switch (j) {
case R1 r1:
break;
case R2 r2:
break;
}
// If the type of the selector expression, T, is not an enum type and also does not name a sealed interface or a sealed class that is abstract
switch (<error descr="'switch' statement does not cover all possible input values">i2</error>) {
case Sub7 s1:
System.out.println("ok");
break;
case Sub8 s2:
System.out.println("ok");
break;
}
str = switch (<error descr="'switch' expression does not cover all possible input values">i2</error>) {
case Sub7 s1 -> "ok";
case Sub8 s2 -> "ok";
};
// empty switches
switch (d) {
}
str = switch (<error descr="'switch' expression does not have any case clauses">d</error>) {
};
switch (<error descr="'switch' statement does not have any case clauses">i</error>) {
}
str = switch (<error descr="'switch' expression does not have any case clauses">i</error>) {
};
switch (<error descr="'switch' statement does not have any case clauses">i2</error>) {
}
str = switch (<error descr="'switch' expression does not have any case clauses">i2</error>) {
};
// 'case AA' is redundant brach here as 'AA' is not castable to II<Integer>, so the code compiles correctly
switch (ii) {
case BB b -> {
}
}
}
}
sealed interface I {
}
enum Day {
MONDAY, TUESDAY, WEDNESDAY
}
final class Sub1 implements I {
}
final class Sub2 implements I {
}
sealed class Sub3 implements I {
}
final class Sub4 extends Sub3 {
}
final class Sub5 {
}
final class Sub6 extends Sub3 {
}
interface I2 {
}
class Sub7 implements I2 {
}
class Sub8 implements I2 {
}
sealed interface I3 {
}
final class Sub9 implements I3 {
}
sealed abstract class Sub10 implements I3 {
}
final class Sub11 extends Sub10 {
}
final class Sub12 extends Sub10 {
}
sealed interface AorBorC {
}
sealed interface AorB extends AorBorC {
}
sealed interface BorC extends AorBorC {
}
sealed interface AorC extends AorBorC {
}
final class A implements AorB, AorC {
}
final class B implements AorB, BorC {
}
final class C implements AorC, BorC {
}
sealed interface J1 {
}
sealed interface J2 extends J1 permits R1 {
}
record R1() implements J1, J2 {
}
record R2() implements J1 {
}
sealed interface II<T> {
}
final class AA implements II<String> {
}
final class BB<T> implements II<Object> {
}

View File

@@ -7,7 +7,7 @@ class Test {
case Object s -> System.out.println(s);
}
switch (o) {
case (Object s) when s != null -> System.out.println();
case <error descr="Parenthesized patterns are not supported at language level '21'">(Object s)</error> when s != null -> System.out.println();
case default -> System.out.println();
}
}

View File

@@ -3,18 +3,16 @@ record Sample(int x, int y){}
public class Test {
void test(Object o, Object o2){
if (o instanceof Sample(int w, int y) s && s.x() > 0 && o2 instanceof Integer i){
if (o instanceof Sample(int w, int y) && o2 instanceof Integer i){
System.out.println(w+y);
System.out.println(s.x());
System.out.println(i);
} else {
System.out.println(<error descr="Cannot resolve symbol 'y'">y</error>);
System.out.println(<error descr="Cannot resolve symbol 's'">s</error>);
}
if (o instanceof Sample(int w, int y) s && (o2 instanceof Integer i || w > 0)){
if (o instanceof Sample(int w, int y) && (o2 instanceof Integer i || w > 0)){
System.out.println(w+y);
System.out.println(s.x());
System.out.println(<error descr="Cannot resolve symbol 'i'">i</error>);
}
}

View File

@@ -5,9 +5,9 @@ public class Test {
void test(Object o, Object o2){
var out = switch (o) {
case String s2 when s2.length() < 1-> s2.toLowerCase();
case Sample(int x, int w) s3 when w > 1 && s3.x() < 0 && x > 1 -> "two" + w;
case Sample(int x, int w) s4 when s4.x() > 0 -> "two" + s4.x() + (w - x);
case Sample(int x, int w) s4 when o2 instanceof String s -> s;
case Sample(int x, int w) when w > 1 && x < 0 && x > 1 -> "two" + w;
case Sample(int x, int w) when x > 0 -> "two" + (w - x);
case Sample(int x, int w) when o2 instanceof String s -> s;
default -> throw new IllegalStateException("Unexpected value: " + <error descr="Cannot resolve symbol 's2'">s2</error>);
};

View File

@@ -4,16 +4,15 @@ public class Test {
void test(Object o, Object o2){
switch (o) {
case Sample(int r, int q) e when (r<0 || e.x()<0):
case Sample(int r, int q) when (r<0 ):
System.out.println(r);
break;
case Integer i when o2 instanceof String str:
System.out.println(str);
System.out.println(i);
break;
case Sample(int r, int q) e:
case Sample(int r, int q):
System.out.println(r);
System.out.println(e.x());
break;
case String s:
System.out.println(<error descr="Cannot resolve symbol 'r'">r</error>);

View File

@@ -7,7 +7,7 @@ abstract class Test {
System.out.println("one");
} else if (o instanceof Integer i && (i > 0)) {
System.out.println("two");
} else if (o instanceof /*1*/ Float /*2*/ /*3*/f && f/*4*/ > 5 && f < 10) {
} else if (o instanceof /*1*/ Float /*2*/ /*3*/f && /*4*/ f > 5 && f < 10) {
System.out.println("two");
} else if (o instanceof Character c) {
System.out.println(c);

View File

@@ -5,8 +5,8 @@ abstract class Test {
void foo(Object o) {
<caret>switch (o) {
case null, String s -> System.out.println("one");
case ((Integer i) && (i > 0)) -> System.out.println("two");
case /*1*/Float/*2*/ /*3*/f && f/*4*/ > 5 && f < 10 -> System.out.println("two");
case Integer i when (i > 0) -> System.out.println("two");
case /*1*/Float/*2*/ /*3*/f when /*4*/ f > 5 && f < 10 -> System.out.println("two");
case Character c -> System.out.println(c);
case Double c -> System.out.println();
default -> {}

View File

@@ -3,7 +3,7 @@ class Foo {
void test(Object obj) {
boolean flag;
switch (obj) {
case String s && flag -> System.out.println(1);
case String s when flag -> System.out.println(1);
default -> System.out.println(2);
}
}

View File

@@ -2,7 +2,7 @@
class Foo {
void test(Object obj) {
switch (obj) {
case String s && flag<caret> -> System.out.println(1);
case String s when flag<caret> -> System.out.println(1);
default -> System.out.println(2);
}
}

View File

@@ -2,7 +2,7 @@
class Main {
void foo(Object obj) {
switch (obj) {
case String s && isEmpty(s) -> {}
case String s when isEmpty(s) -> {}
default -> {}
}
}

View File

@@ -2,7 +2,7 @@
class Main {
void foo(Object obj) {
switch (obj) {
case String s && isEmpt<caret>y(s) -> {}
case String s when isEmpt<caret>y(s) -> {}
default -> {}
}
}

View File

@@ -2,7 +2,7 @@
class Foo {
void test(Object obj, boolean flag) {
switch (obj) {
case String s && flag -> System.out.println(1);
case String s when flag -> System.out.println(1);
default -> System.out.println(2);
}
}

View File

@@ -2,7 +2,7 @@
class Foo {
void test(Object obj) {
switch (obj) {
case String s && flag<caret> -> System.out.println(1);
case String s when flag<caret> -> System.out.println(1);
default -> System.out.println(2);
}
}

View File

@@ -1,6 +1,6 @@
void test(Object obj, boolean flag) {
switch (obj) {
case String s && flag -> System.out.println(1);
case String s when flag -> System.out.println(1);
default -> System.out.println(2);
}
}

View File

@@ -1,12 +0,0 @@
// "Remove switch branch 'default'" "true-preview"
enum Day {
MONDAY, TUESDAY, WEDNESDAY
}
class Test {
int foo(Day d) {
return switch (d) {
case Day dd when true -> 42;
};
}
}

View File

@@ -1,13 +0,0 @@
// "Remove switch label 'default'" "true-preview"
enum Day {
MONDAY, TUESDAY, WEDNESDAY
}
class Test {
int foo(Day d) {
return switch (d) {
case MONDAY -> 42;
case Day dd -> 13;
};
}
}

View File

@@ -3,7 +3,7 @@ class Test {
Integer i = 1;
void test() {
switch (i) {
case Object o:
case Object o:
break;
}
}

View File

@@ -6,7 +6,7 @@ enum Day {
class Test {
int foo(Day d) {
switch (d) {
case default:
default:
System.out.println(13);
}
}

View File

@@ -1,13 +0,0 @@
// "Remove switch branch 'default'" "true-preview"
enum Day {
MONDAY, TUESDAY, WEDNESDAY
}
class Test {
int foo(Day d) {
return switch (d) {
case Day dd when true -> 42;
case <caret>default -> 13;
};
}
}

View File

@@ -1,13 +0,0 @@
// "Remove switch label 'default'" "true-preview"
enum Day {
MONDAY, TUESDAY, WEDNESDAY
}
class Test {
int foo(Day d) {
return switch (d) {
case MONDAY, <caret>default -> 42;
case Day dd -> 13;
};
}
}

View File

@@ -3,10 +3,10 @@ class Test {
Integer i = 1;
void test() {
switch (i) {
case Object o:
break;
case <caret>Integer ii when true:
break;
case Object o:
break;
}
}
}

View File

@@ -9,7 +9,7 @@ class Test {
case <caret>Day dd when true:
System.out.println(42);
break;
case default:
default:
System.out.println(13);
}
}

View File

@@ -3,7 +3,7 @@ class Test {
void test(Number n) {
n = 1;
switch (n) {
case <caret>Integer i && i == 1 -> {
case <caret>Integer i when i == 1 -> {
int j = 1;
System.out.println(i);
}

View File

@@ -3,7 +3,7 @@ class Test {
void test(Number n) {
n = 1;
switch (n) {
case <caret>Integer i && i == 1:
case <caret>Integer i when i == 1:
int j = 1;
System.out.println(i);
break;

View File

@@ -3,7 +3,7 @@ class Test {
void test(Number n) {
n = 1;
switch (n) {
case <caret>Integer i && i == 1 -> System.out.println(i);
case <caret>Integer i when i == 1 -> System.out.println(i);
case Long s -> System.out.println(s);
default -> System.out.println();
}

View File

@@ -3,7 +3,7 @@ class Test {
void test(Number n) {
n = 1;
switch (n) {
case <caret>Integer i && i == 1:
case <caret>Integer i when i == 1:
System.out.println(i);
break;
case Long s:

View File

@@ -3,7 +3,7 @@ class Test {
void test(Number n) {
n = 1;
int result = switch (n) {
case <caret>Integer i && i == 1 -> i;
case <caret>Integer i when i == 1 -> i;
case Long l -> l.intValue();
case default -> 1;
} + 10;

View File

@@ -2,7 +2,7 @@
class Test {
Number n = 1;
int result = switch (n) {
case <caret>Integer i && i == 1 -> i;
case <caret>Integer i when i == 1 -> i;
case Long l -> l.intValue();
case default -> 1;
} + 10;

View File

@@ -6,7 +6,7 @@ class Test {
void test(Number n) {
n = 1;
switch (n) {
case <caret>Integer i && i == 1 -> {
case <caret>Integer i when i == 1 -> {
int rand = ThreadLocalRandom.current().nextInt();
if (rand > 10) {
i = 2;

View File

@@ -4,7 +4,7 @@ class Test {
void test(Number n) {
n = 1;
switch (n) {
case <caret>Integer i && i == 1:
case <caret>Integer i when i == 1:
int rand = ThreadLocalRandom.current().nextInt();
if (rand > 10) {
i = 2;

View File

@@ -5,7 +5,7 @@ class Test {
void test() {
switch (s) {
case <caret>String ss && ss.length() <= 3:
case <caret>String ss when ss.length() <= 3:
System.out.println(1);
break;
case "fsd":

View File

@@ -4,7 +4,7 @@ class Test {
int test() {
return switch (s) {
case <caret>String ss && ss.length() <= 3 -> 1;
case <caret>String ss when ss.length() <= 3 -> 1;
case "fsd" -> 2;
case default -> 3;
};

View File

@@ -4,7 +4,7 @@ class Test {
int test(Number n) {
n = 1;
return 1 + switch (n) {
case <caret>Integer i && i == 1 -> i;
case <caret>Integer i when i == 1 -> i;
case Long l -> l.intValue();
case default -> 1;
};

View File

@@ -1,16 +0,0 @@
// "Split values of 'switch' branch" "true-preview"
class C {
void foo(Object o) {
String s = "";
switch (o) {
case null:
s = "x";
break;
case ((((Number n)) && ((n.intValue() == 42)))):
s = "x";
break;
default:
throw new IllegalStateException("Unexpected value: " + o);
}
}
}

View File

@@ -1,11 +0,0 @@
// "Split values of 'switch' branch" "true-preview"
class C {
void foo(Object o) {
String s = "";
switch (o) {
case null -> s = "x";
case ((((Number n)) && ((n.intValue() == 42)))) -> s = "x";
default -> throw new IllegalStateException("Unexpected value: " + o);
}
}
}

View File

@@ -1,13 +0,0 @@
// "Split values of 'switch' branch" "true-preview"
class C {
void foo(Object o) {
String s = "";
switch (o) {
case ((((Number n)) && ((n.intValue() == 42))))<caret>, null:
s = "x";
break;
default:
throw new IllegalStateException("Unexpected value: " + o);
}
}
}

View File

@@ -1,10 +0,0 @@
// "Split values of 'switch' branch" "true-preview"
class C {
void foo(Object o) {
String s = "";
switch (o) {
case null, ((((Number n)) && ((n.intValue() == 42))))<caret> -> s = "x";
default -> throw new IllegalStateException("Unexpected value: " + o);
}
}
}

View File

@@ -1,10 +0,0 @@
class Main {
private String s = "";
void f(Object o) {
if (o instanceof (CharSequence cs && cs instanceof String s)) {
System.out.println(<caret>s);
}
}
}

View File

@@ -1,11 +0,0 @@
class Main {
private String s = "";
void g(Object o) {
switch (o) {
case Integer i && o instanceof String s:
System.out.println(<caret>s);
};
}
}

View File

@@ -4,7 +4,7 @@ class Test {
switch (d) {
case MONDAY:
break;
case default:
default:
a = -10;
break;
}
@@ -18,7 +18,7 @@ class Test {
switch (d) {
case MONDAY:
break;
case default:
default:
a = 10;
break;
}

View File

@@ -21,7 +21,7 @@ public class InstanceOfPattern {
}
void testNullCheckUnusedPatternVariable(String s) {
if (s instanceof String s1) {
if (s instanceof String s1 && s1.length()==2) {
System.out.println("foo");
}
}

View File

@@ -31,14 +31,14 @@ class Test {
void testParenthesizedPattern1(Object o) {
o = "fsd";
if (<warning descr="Condition 'o instanceof (String s)' is always 'true'">o instanceof (String s)</warning>) {
if (<warning descr="Condition 'o instanceof String s' is always 'true'">o instanceof String s</warning>) {
System.out.println();
}
}
void testParenthesizedPattern2(Object o) {
o = "fsd";
if (<warning descr="Condition 'o instanceof (Integer i)' is always 'false'">o instanceof (Integer i)</warning>) {
if (<warning descr="Condition 'o instanceof Integer i' is always 'false'">o instanceof Integer i</warning>) {
System.out.println();
}
}

View File

@@ -8,7 +8,7 @@ class Test {
void test1(Object o) {
int a;
switch (o) {
case ((String s)): {
case String s: {
if (<warning descr="Condition 's == null' is always 'false'">s == null</warning>) {
System.out.println();
}
@@ -28,7 +28,7 @@ class Test {
void test2(Object o) {
int a;
switch (o) {
case (String s): {
case String s: {
if (<warning descr="Condition 's instanceof CharSequence' is always 'true'">s instanceof CharSequence</warning>) {
System.out.println(s);
}
@@ -57,7 +57,7 @@ class Test {
int test4(String s) {
s = FSD;
return switch (s) {
case (String ss) when (<warning descr="Condition 'ss.length() < 3 || ss.length() == 4' is always 'false'"><warning descr="Condition 'ss.length() < 3' is always 'false'">ss.length() < 3</warning> || <warning descr="Condition 'ss.length() == 4' is always 'false' when reached">ss.length() == 4</warning></warning>) -> 1;
case String ss when (<warning descr="Condition 'ss.length() < 3 || ss.length() == 4' is always 'false'"><warning descr="Condition 'ss.length() < 3' is always 'false'">ss.length() < 3</warning> || <warning descr="Condition 'ss.length() == 4' is always 'false' when reached">ss.length() == 4</warning></warning>) -> 1;
case <warning descr="Switch label 'String ss' is the only reachable in the whole switch">String ss</warning> -> 2;
};
}

View File

@@ -55,7 +55,7 @@ class Test {
switch (i) {
case <warning descr="Switch label '1' is the only reachable in the whole switch">1</warning>:
break;
case (Integer ii):
case Integer ii:
break;
}
}
@@ -106,7 +106,7 @@ class Test {
switch (<warning descr="Unboxing of 'createNullValue()' may produce 'NullPointerException'">createNullValue()</warning>) {
case 1:
break;
case ((Object o)):
case Object o:
break;
}
}
@@ -173,7 +173,7 @@ class Test {
i = 1;
return switch (i) {
case <warning descr="Switch label '1' is the only reachable in the whole switch">1</warning> -> 1;
case (Integer ii) -> 2;
case Integer ii -> 2;
};
}
@@ -212,7 +212,7 @@ class Test {
int nullableCallWithUnconditionalPatternLabelExpr() {
return switch (<warning descr="Unboxing of 'createNullValue()' may produce 'NullPointerException'">createNullValue()</warning>) {
case 1 -> 1;
case ((Object o)) -> 2;
case Object o -> 2;
};
}

View File

@@ -1,7 +1,7 @@
class C {
void foo(Object o) {
switch (o) {
case Point(double x, double y) point -> bar("A");
case Point(double x, double y) -> bar("A");
case Number n -> bar("B");
case null -> bar("A");
default -> bar("C");

View File

@@ -2,7 +2,7 @@ class C {
void foo(Object o) {
switch (o) {
case null -> bar("A");
case Point(double x, double y) point -> bar("A");
case Point(double x, double y) -> bar("A");
case Number n -> bar("B");
default -> bar("C");
}

View File

@@ -2,7 +2,7 @@ class C {
void foo(Object o) {
switch (o) {
case null -> bar("A");
case Point(double x, double y) point when y > x -> bar("A");
case Point(double x, double y) when y > x -> bar("A");
case Number n -> bar("B");
default -> bar("C");
}

View File

@@ -1,10 +1,10 @@
class C {
void foo(Object o) {
switch (o) {
case Point(double x, double y) point when y > x -> bar("A");
case Point(double x, double y) when y > x -> bar("A");
case Number n -> bar("B");
default -> bar("C");
case null -> bar("A");
default -> bar("C");
}
}
void bar(String s){}

View File

@@ -1,33 +0,0 @@
class Main {
int test1(int i) {
return switch ((<warning descr="Casting 'i' to 'Integer' is redundant">Integer</warning>)i) {
default -> 42;
};
}
void test2(int i) {
switch ((<warning descr="Casting 'i' to 'Integer' is redundant">Integer</warning>)i) {
}
}
void test3(int i) {
switch ((Integer)i) {
case Integer integer -> {}
}
}
int test4(int i) {
return switch ((Integer)i) {
case 0 -> 0;
case <error descr="Guarded patterns from JEP 406 are not available since Java 19 preview">Integer integer && Math.random() > 0.5</error> -> 7;
default -> 42;
};
}
int test5(int i) {
return switch ((Integer)i) {
case 0 -> 0;
case null, default -> 42;
};
}
}

View File

@@ -7,7 +7,7 @@ class X {
case Integer i ->
// line contains no height
System.out.println(i + 1);
case String s && !s.isEmpty() ->
case String s when !s.isEmpty() ->
// line contains no code
System.out.println("Goodbye.");
case null -> System.out.println("c");

View File

@@ -5,7 +5,7 @@ class X {
private static void test(@Nullable Object object) {
String r = switch (object) {
case Integer i -> "int = " + i;
case String s && s.length() > 3 -> s.substring(0, 3);
case String s when s.length() > 3 -> s.substring(0, 3);
case null, default -> "default";
};
}

View File

@@ -5,7 +5,8 @@ class X {
private static String test(@Nullable Object object) {
return switch (object) {
case Integer i -> "x = " + i / 2;
case String s, null -> "nullable string";
case String s -> "nullable string";
case null -> "nullable string";
default -> "default";
};
}

View File

@@ -8,7 +8,7 @@ class X {
// line contains no height
System.out.println(i+1);
break;
case String s && !s.isEmpty():
case String s when !s.isEmpty():
// line contains no code
System.out.println("Goodbye.");
break;

View File

@@ -8,7 +8,7 @@ class X {
case Integer i:
r = "int = " + i;
break;
case String s && s.length() > 3:
case String s when s.length() > 3:
r = s.substring(0, 3);
break;
case null:

View File

@@ -16,6 +16,6 @@ public class AddMissingDeconstructionComponentsTest extends LightQuickFixParamet
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_19;
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
}
}

View File

@@ -14,7 +14,7 @@ public class CreateLocalFromUsageTest extends LightQuickFixParameterizedTestCase
@Override
protected void setUp() throws Exception {
super.setUp();
setLanguageLevel(LanguageLevel.JDK_20_PREVIEW);
setLanguageLevel(LanguageLevel.JDK_21);
JavaCodeStyleSettings.getInstance(getProject()).GENERATE_FINAL_LOCALS = getTestName(true).contains("final");
}
}

View File

@@ -14,6 +14,6 @@ public class CreateMissingDeconstructionRecordClassBranchesFixTest extends Light
@Override
protected @NotNull LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_19;
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
}
}

View File

@@ -17,7 +17,7 @@ public class DeleteSwitchLabelFixTest extends LightQuickFixParameterizedTestCase
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_19;
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
}
@Override

View File

@@ -16,6 +16,6 @@ public class RemoveRedundantDeconstructionComponentsTest extends LightQuickFixPa
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return LightJavaCodeInsightFixtureTestCase.JAVA_19;
return LightJavaCodeInsightFixtureTestCase.JAVA_21;
}
}

View File

@@ -12,7 +12,7 @@ public class NormalPatternsCompletionTest extends NormalCompletionTestCase {
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JAVA_19;
return JAVA_21;
}
@NeedsIndex.Full

View File

@@ -153,7 +153,7 @@ public class LightAdvHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testSerializableStuff() { doTest(true); }
public void testDeprecated() { doTest(true); }
public void testJavadoc() { enableInspectionTool(new JavadocDeclarationInspection()); doTest(true); }
public void testExpressionsInSwitch () { IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_19_PREVIEW, () -> doTest(false)); }
public void testExpressionsInSwitch () { IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_21, () -> doTest(false)); }
public void testAccessInner() {
Editor e = createSaveAndOpenFile("x/BeanContextServicesSupport.java",
"package x;\n" +

Some files were not shown because too many files have changed in this diff Show More