diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java index 55276ed108a..42d2fd9d5de 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/core/compiler/IProblem.java @@ -2325,35 +2325,55 @@ public interface IProblem { int SwitchExpressionsYieldNoResultExpression = Internal + 1702; /** @since 3.21 */ int SwitchExpressionaYieldSwitchLabeledBlockCompletesNormally = Internal + 1703; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldLastStatementCompletesNormally = Internal + 1704; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldTrailingSwitchLabels = Internal + 1705; /** @since 3.21 */ int SwitchPreviewMixedCase = Syntax + 1706; /** @since 3.21 */ int SwitchExpressionsYieldMissingDefaultCase = Syntax + 1707; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldMissingValue = Syntax + 1708; /** @since 3.21 */ int SwitchExpressionsYieldMissingEnumConstantCase = Syntax + 1709; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldIllegalLastStatement = Internal + 1710; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldBreakNotAllowed = Syntax + 1711; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldUnqualifiedMethodWarning = Syntax + 1712; /** @since 3.21 */ int SwitchExpressionsYieldUnqualifiedMethodError = Syntax + 1713; /** @since 3.21 */ int SwitchExpressionsYieldOutsideSwitchExpression = Syntax + 1714; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldRestrictedGeneralWarning = Internal + 1715; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldIllegalStatement = Internal + 1716; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldTypeDeclarationWarning = Internal + 1717; - /** @since 3.21 */ + /** @since 3.21 + * @deprecated no longer issued - will be removed + */ int SwitchExpressionsYieldTypeDeclarationError = Internal + 1718; /** @since 3.22 */ int MultiConstantCaseLabelsNotSupported = Syntax + 1719; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java index 9c3a03016a8..a157727a96e 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java @@ -46,7 +46,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl } return flowInfo; // pretend it did not break since no actual target } else if (targetContext == FlowContext.NonLocalGotoThroughSwitchContext) { // JLS 13 14.15 - currentScope.problemReporter().switchExpressionsBreakOutOfSwitchExpression(this); + currentScope.problemReporter().breakOutOfSwitchExpression(this); return flowInfo; // pretend it did not break since no actual target } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java index 77cb7cc0f05..7188e517e84 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java @@ -43,7 +43,7 @@ public class CaseStatement extends Statement { public BranchLabel targetLabel; public Expression[] constantExpressions; // case with multiple expressions - if you want a under-the-hood view, use peeledLabelExpressions() public BranchLabel[] targetLabels; // for multiple expressions - public boolean isExpr = false; + public boolean isSwitchRule = false; public SwitchStatement swich; // owning switch public int typeSwitchIndex; // for the first pattern among this.constantExpressions @@ -177,6 +177,16 @@ public String toString() { */ public ResolvedCase[] resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { this.swich = switchStatement; + + if (this.isSwitchRule) + this.swich.switchBits |= SwitchStatement.LabeledRules; + else + this.swich.switchBits |= SwitchStatement.LabeledBlockStatementGroup; + + if ((this.swich.switchBits & (SwitchStatement.LabeledRules | SwitchStatement.LabeledBlockStatementGroup)) == (SwitchStatement.LabeledRules | SwitchStatement.LabeledBlockStatementGroup)) { + scope.problemReporter().arrowColonMixup(this); + } + scope.enclosingCase = this; // record entering in a switch case block if (this.constantExpressions == Expression.NO_EXPRESSIONS) { checkDuplicateDefault(scope, switchStatement, this); @@ -461,16 +471,15 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { public StringBuilder printStatement(int tab, StringBuilder output) { printIndent(tab, output); if (this.constantExpressions == Expression.NO_EXPRESSIONS) { - output.append("default "); //$NON-NLS-1$ - output.append(this.isExpr ? "->" : ":"); //$NON-NLS-1$ //$NON-NLS-2$ + output.append("default"); //$NON-NLS-1$ } else { output.append("case "); //$NON-NLS-1$ for (int i = 0, l = this.constantExpressions.length; i < l; ++i) { this.constantExpressions[i].printExpression(0, output); if (i < l -1) output.append(','); } - output.append(this.isExpr ? " ->" : " :"); //$NON-NLS-1$ //$NON-NLS-2$ } + output.append(this.isSwitchRule ? " ->" : " :"); //$NON-NLS-1$ //$NON-NLS-2$ return output; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java index deb1a05b16c..0caa1678c89 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ContinueStatement.java @@ -46,7 +46,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl } return flowInfo; // pretend it did not continue since no actual target } else if (targetContext == FlowContext.NonLocalGotoThroughSwitchContext) { - currentScope.problemReporter().switchExpressionsContinueOutOfSwitchExpression(this); + currentScope.problemReporter().continueOutOfSwitchExpression(this); return flowInfo; // pretend it did not continue since no actual target } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java index 3b20f500409..7932215dd15 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/MessageSend.java @@ -312,7 +312,7 @@ private void yieldQualifiedCheck(BlockScope currentScope) { return; if (!CharOperation.equals(this.selector, TypeConstants.YIELD)) return; - currentScope.problemReporter().switchExpressionsYieldUnqualifiedMethodError(this); + currentScope.problemReporter().unqualifiedYieldMethod(this); } private void recordCallingClose(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Expression closeTarget) { if (closeTarget.isThis() || closeTarget.isSuper()) { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java index c51f4c0dac1..722ede5980f 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java @@ -161,7 +161,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl currentScope.problemReporter().cannotReturnInInitializer(this); return FlowInfo.DEAD_END; } else if (traversedContext.associatedNode instanceof SwitchExpression) { - currentScope.problemReporter().switchExpressionsReturnWithinSwitchExpression(this); + currentScope.problemReporter().returnOutOfSwitchExpression(this); return FlowInfo.DEAD_END; } } while ((traversedContext = traversedContext.getLocalParent()) != null); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java index 87a4e74995a..0d89b5d91a8 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java @@ -125,53 +125,11 @@ private void computeNullStatus(FlowInfo flowInfo, FlowContext flowContext) { this.nullStatus = status; } - @Override - protected void completeNormallyCheck(BlockScope blockScope) { - int sz = this.statements != null ? this.statements.length : 0; - if (sz == 0) return; - /* JLS 12 15.28.1 Given a switch expression, if the switch block consists of switch labeled rules - * then it is a compile-time error if any switch labeled block can complete normally. - */ - if ((this.switchBits & LabeledRules) != 0) { - for (Statement stmt : this.statements) { - if (!(stmt instanceof Block)) - continue; - if (stmt.canCompleteNormally()) - blockScope.problemReporter().switchExpressionLastStatementCompletesNormally(stmt); - } - return; - } - /* JLS 12 15.28.1 - * If, on the other hand, the switch block consists of switch labeled statement groups, then it is a - * compile-time error if either the last statement in the switch block can complete normally, or the - * switch block includes one or more switch labels at the end. - */ - Statement lastNonCaseStmt = null; - Statement firstTrailingCaseStmt = null; - for (int i = sz - 1; i >= 0; i--) { - Statement stmt = this.statements[sz - 1]; - if (stmt instanceof CaseStatement) - firstTrailingCaseStmt = stmt; - else { - lastNonCaseStmt = stmt; - break; - } - } - if (lastNonCaseStmt != null) { - if (lastNonCaseStmt.canCompleteNormally()) - blockScope.problemReporter().switchExpressionLastStatementCompletesNormally(lastNonCaseStmt); - else if (lastNonCaseStmt instanceof ContinueStatement || lastNonCaseStmt instanceof ReturnStatement) { - blockScope.problemReporter().switchExpressionIllegalLastStatement(lastNonCaseStmt); - } - } - if (firstTrailingCaseStmt != null) { - blockScope.problemReporter().switchExpressionTrailingSwitchLabels(firstTrailingCaseStmt); - } - } @Override protected boolean needToCheckFlowInAbsenceOfDefaultBranch() { // JLS 12 16.1.8 return (this.switchBits & LabeledRules) == 0; } + @Override public Expression[] getPolyExpressions() { List polys = new ArrayList<>(); @@ -379,7 +337,7 @@ public TypeBinding resolveType(BlockScope upperScope) { resultExpressionsCount = this.resultExpressions.size(); if (resultExpressionsCount == 0) { - upperScope.problemReporter().switchExpressionNoResultExpressions(this); + upperScope.problemReporter().unyieldingSwitchExpression(this); return this.resolvedType = null; } @@ -397,7 +355,6 @@ public TypeBinding resolveType(BlockScope upperScope) { } return this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null; } - // fall through } else { // re-resolving of poly expression: resultExpressionsCount = this.resultExpressions.size(); @@ -418,7 +375,6 @@ public TypeBinding resolveType(BlockScope upperScope) { if (yieldErrors) return this.resolvedType = null; this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null; - // fall through } boolean uniformYield = true; @@ -541,7 +497,7 @@ public TypeBinding resolveType(BlockScope upperScope) { } return this.resolvedType = commonType.capture(this.scope, this.sourceStart, this.sourceEnd); } - this.scope.problemReporter().switchExpressionIncompatibleResultExpressions(this); + this.scope.problemReporter().incompatibleSwitchExpressionResults(this); return null; } finally { if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block @@ -569,6 +525,18 @@ private boolean areAllIntegerResultExpressionsConvertibleToTargetType(TypeBindin @Override public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { flowInfo = super.analyseCode(currentScope, flowContext, flowInfo); + // 15.28.1 + if ((this.switchBits & LabeledRules) != 0) { + for (Statement stmt : this.statements) { + if (stmt instanceof Block && stmt.canCompleteNormally()) + currentScope.problemReporter().switchExpressionBlockCompletesNormally(stmt); + } + } else { + Statement ultimateStmt = this.statements[this.statements.length - 1]; // length guaranteed > 0 + if (ultimateStmt.canCompleteNormally()) + currentScope.problemReporter().switchExpressionBlockCompletesNormally(ultimateStmt); + } + this.resultExpressionNullStatus = new ArrayList<>(0); final CompilerOptions compilerOptions = currentScope.compilerOptions(); if (compilerOptions.enableSyntacticNullAnalysisForFields) { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java index 5adc2ec3154..a53c29c6bb4 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java @@ -105,6 +105,7 @@ public static record SingletonBootstrap(String id, char[] selector, char[] signa public final static int TotalPattern = ASTNode.Bit3; public final static int Exhaustive = ASTNode.Bit4; public final static int QualifiedEnum = ASTNode.Bit5; + public final static int LabeledBlockStatementGroup = ASTNode.Bit6; // for switch on strings private static final char[] SecretStringVariableName = " switchDispatchString".toCharArray(); //$NON-NLS-1$ @@ -402,9 +403,6 @@ protected int getFallThroughState(Statement stmt, BlockScope blockScope) { } return FALLTHROUGH; } - protected void completeNormallyCheck(BlockScope blockScope) { - // do nothing - } protected boolean needToCheckFlowInAbsenceOfDefaultBranch() { return !this.isExhaustive(); } @@ -493,7 +491,6 @@ else if ((statement.bits & ASTNode.DocumentedFallthrough) == 0) { // the case is } } } - completeNormallyCheck(currentScope); } final TypeBinding resolvedTypeBinding = this.expression.resolvedType; @@ -1266,7 +1263,6 @@ && defaultFound && isExhaustive()) { if (this.dispatchPatternCopy == null) { addSecretPatternSwitchVariables(upperScope); } - reportMixingCaseTypes(); complainIfNotExhaustiveSwitch(upperScope, expressionType, compilerOptions); @@ -1501,26 +1497,7 @@ protected boolean ignoreMissingDefaultCase(CompilerOptions compilerOptions) { public boolean isTrulyExpression() { return false; } - private void reportMixingCaseTypes() { - if (this.caseCount == 0) { - if (this.defaultCase != null && this.defaultCase.isExpr) - this.switchBits |= LabeledRules; - return; - } - if (this.cases[0] == null) - return; - boolean isExpr = this.cases[0].isExpr; - if (isExpr) this.switchBits |= LabeledRules; - for (int i = 1, l = this.caseCount; i < l; ++i) { - if (this.cases[i].isExpr != isExpr) { - this.scope.problemReporter().switchExpressionMixedCase(this.cases[i]); - return; - } - } - if (this.defaultCase != null && this.defaultCase.isExpr != isExpr) { - this.scope.problemReporter().switchExpressionMixedCase(this.defaultCase); - } - } + private void reportDuplicateCase(final Statement duplicate, final Statement original, int length) { diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java index 6b94f33ffce..0172477734c 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java @@ -207,27 +207,20 @@ public void resolve(BlockScope scope) { this.switchExpression = scope.enclosingSwitchExpression(); if (this.switchExpression != null) { this.switchExpression.resultExpressions.add(this.expression); - if (this.switchExpression.expressionContext == ASSIGNMENT_CONTEXT || this.switchExpression.expressionContext == INVOCATION_CONTEXT) { // poly switch expression + if (this.switchExpression.expressionContext == ASSIGNMENT_CONTEXT || this.switchExpression.expressionContext == INVOCATION_CONTEXT) { // When switch expression is poly ... this.expression.setExpressionContext(this.switchExpression.expressionContext); // result expressions feature in same context ... this.expression.setExpectedType(this.switchExpression.expectedType); // ... with the same target type } } } - if (this.switchExpression != null || this.isImplicit) { - if (this.switchExpression == null && this.isImplicit && !this.expression.statementExpression()) { - if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK14) { - /* JLS 13 14.11.2 - Switch labeled rules in switch statements differ from those in switch expressions (15.28). - In switch statements they must be switch labeled statement expressions, ... */ - scope.problemReporter().invalidExpressionAsStatement(this.expression); - return; - } - } - } else { - if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK14) { - scope.problemReporter().switchExpressionsYieldOutsideSwitchExpression(this); + if (this.isImplicit) { + if (this.switchExpression == null && !this.expression.statementExpression()) { + scope.problemReporter().invalidExpressionAsStatement(this.expression); + return; } + } else if (this.switchExpression == null) { + scope.problemReporter().yieldOutsideSwitchExpression(this); } TypeBinding type = this.expression.resolveType(scope); if (this.switchExpression != null && type != null) @@ -236,12 +229,10 @@ Switch labeled rules in switch statements differ from those in switch expression @Override public StringBuilder printStatement(int tab, StringBuilder output) { - if (!this.isImplicit) - printIndent(tab, output).append("yield"); //$NON-NLS-1$ if (this.isImplicit) { this.expression.print(tab, output); } else { - output.append(' '); + printIndent(tab, output).append("yield "); //$NON-NLS-1$ this.expression.printExpression(tab, output); } return output.append(';'); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java index dd17bdc6e42..d8b236d3972 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/parser/Parser.java @@ -9470,7 +9470,7 @@ protected void consumeCaseLabelExpr() { if (!this.parsingJava14Plus) { problemReporter().arrowInCaseStatementsNotSupported(caseStatement); } - caseStatement.isExpr = true; + caseStatement.isSwitchRule = true; } protected void consumeDefaultLabelExpr() { // SwitchLabelDefaultExpr ::= 'default' '->' @@ -9479,7 +9479,7 @@ protected void consumeDefaultLabelExpr() { if (!this.parsingJava14Plus) { problemReporter().arrowInCaseStatementsNotSupported(defaultStatement); } - defaultStatement.isExpr = true; + defaultStatement.isSwitchRule = true; } protected void consumeSwitchExpression() { // SwitchExpression ::= 'switch' '(' Expression ')' OpenBlock SwitchExpressionBlock diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java index f76bd42c7f8..92b95029525 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java @@ -1669,9 +1669,6 @@ public int computeSeverity(int problemID){ switch (problemID) { case IProblem.VarargsConflict : - case IProblem.SwitchExpressionsYieldUnqualifiedMethodWarning: - case IProblem.SwitchExpressionsYieldRestrictedGeneralWarning: - case IProblem.SwitchExpressionsYieldTypeDeclarationWarning: case IProblem.StrictfpNotRequired: return ProblemSeverities.Warning; case IProblem.TypeCollidesWithPackage : @@ -11671,7 +11668,7 @@ public void moduleDoesNotReadOther(ImportReference importReference, ModuleBindin importReference.sourceStart, importReference.sourceEnd); } -public void switchExpressionIncompatibleResultExpressions(SwitchExpression expression) { +public void incompatibleSwitchExpressionResults(SwitchExpression expression) { TypeBinding type = expression.resultExpressions.get(0).resolvedType; this.handle( IProblem.SwitchExpressionsYieldIncompatibleResultExpressionTypes, @@ -11680,7 +11677,7 @@ public void switchExpressionIncompatibleResultExpressions(SwitchExpression expre expression.sourceStart, expression.sourceEnd); } -public void switchExpressionNoResultExpressions(SwitchExpression expression) { +public void unyieldingSwitchExpression(SwitchExpression expression) { this.handle( IProblem.SwitchExpressionsYieldNoResultExpression, NoArgument, @@ -11688,15 +11685,7 @@ public void switchExpressionNoResultExpressions(SwitchExpression expression) { expression.sourceStart, expression.sourceEnd); } -public void switchExpressionSwitchLabeledBlockCompletesNormally(Block block) { - this.handle( - IProblem.SwitchExpressionaYieldSwitchLabeledBlockCompletesNormally, - NoArgument, - NoArgument, - block.sourceEnd - 1, - block.sourceEnd); -} -public void switchExpressionLastStatementCompletesNormally(Statement stmt) { +public void switchExpressionBlockCompletesNormally(Statement stmt) { this.handle( IProblem.SwitchExpressionaYieldSwitchLabeledBlockCompletesNormally, NoArgument, @@ -11704,23 +11693,7 @@ public void switchExpressionLastStatementCompletesNormally(Statement stmt) { stmt.sourceEnd - 1, stmt.sourceEnd); } -public void switchExpressionIllegalLastStatement(Statement stmt) { - this.handle( - IProblem.SwitchExpressionsYieldIllegalLastStatement, - NoArgument, - NoArgument, - stmt.sourceStart, - stmt.sourceEnd); -} -public void switchExpressionTrailingSwitchLabels(Statement stmt) { - this.handle( - IProblem.SwitchExpressionsYieldTrailingSwitchLabels, - NoArgument, - NoArgument, - stmt.sourceStart, - stmt.sourceEnd); -} -public void switchExpressionMixedCase(ASTNode statement) { +public void arrowColonMixup(ASTNode statement) { this.handle( IProblem.SwitchPreviewMixedCase, NoArgument, @@ -11728,24 +11701,7 @@ public void switchExpressionMixedCase(ASTNode statement) { statement.sourceStart, statement.sourceEnd); } -// Is this redundant ?? See switchExpressionsBreakOutOfSwitchExpression -public void switchExpressionBreakNotAllowed(ASTNode statement) { - this.handle( - IProblem.SwitchExpressionsYieldBreakNotAllowed, - NoArgument, - NoArgument, - statement.sourceStart, - statement.sourceEnd); -} -public void switchExpressionsYieldUnqualifiedMethodWarning(ASTNode statement) { - this.handle( - IProblem.SwitchExpressionsYieldUnqualifiedMethodWarning, - NoArgument, - NoArgument, - statement.sourceStart, - statement.sourceEnd); -} -public void switchExpressionsYieldUnqualifiedMethodError(ASTNode statement) { +public void unqualifiedYieldMethod(ASTNode statement) { this.handle( IProblem.SwitchExpressionsYieldUnqualifiedMethodError, NoArgument, @@ -11753,7 +11709,7 @@ public void switchExpressionsYieldUnqualifiedMethodError(ASTNode statement) { statement.sourceStart, statement.sourceEnd); } -public void switchExpressionsYieldOutsideSwitchExpression(ASTNode statement) { +public void yieldOutsideSwitchExpression(ASTNode statement) { this.handle( IProblem.SwitchExpressionsYieldOutsideSwitchExpression, NoArgument, @@ -11761,38 +11717,6 @@ public void switchExpressionsYieldOutsideSwitchExpression(ASTNode statement) { statement.sourceStart, statement.sourceEnd); } -public void switchExpressionsYieldRestrictedGeneralWarning(ASTNode statement) { - this.handle( - IProblem.SwitchExpressionsYieldRestrictedGeneralWarning, - NoArgument, - NoArgument, - statement.sourceStart, - statement.sourceEnd); -} -public void switchExpressionsYieldIllegalStatement(ASTNode statement) { - this.handle( - IProblem.SwitchExpressionsYieldIllegalStatement, - NoArgument, - NoArgument, - statement.sourceStart, - statement.sourceEnd); -} -public void switchExpressionsYieldTypeDeclarationWarning(ASTNode statement) { - this.handle( - IProblem.SwitchExpressionsYieldTypeDeclarationWarning, - NoArgument, - NoArgument, - statement.sourceStart, - statement.sourceEnd); -} -public void switchExpressionsYieldTypeDeclarationError(ASTNode statement) { - this.handle( - IProblem.SwitchExpressionsYieldTypeDeclarationError, - NoArgument, - NoArgument, - statement.sourceStart, - statement.sourceEnd); -} public void multiConstantCaseLabelsNotSupported(ASTNode statement) { this.handle( IProblem.MultiConstantCaseLabelsNotSupported, @@ -11817,7 +11741,7 @@ public void switchExpressionsNotSupported(ASTNode statement) { statement.sourceStart, statement.sourceEnd); } -public void switchExpressionsBreakOutOfSwitchExpression(ASTNode statement) { +public void breakOutOfSwitchExpression(ASTNode statement) { this.handle( IProblem.SwitchExpressionsBreakOutOfSwitchExpression, NoArgument, @@ -11825,7 +11749,7 @@ public void switchExpressionsBreakOutOfSwitchExpression(ASTNode statement) { statement.sourceStart, statement.sourceEnd); } -public void switchExpressionsContinueOutOfSwitchExpression(ASTNode statement) { +public void continueOutOfSwitchExpression(ASTNode statement) { this.handle( IProblem.SwitchExpressionsContinueOutOfSwitchExpression, NoArgument, @@ -11833,7 +11757,7 @@ public void switchExpressionsContinueOutOfSwitchExpression(ASTNode statement) { statement.sourceStart, statement.sourceEnd); } -public void switchExpressionsReturnWithinSwitchExpression(ASTNode statement) { +public void returnOutOfSwitchExpression(ASTNode statement) { this.handle( IProblem.SwitchExpressionsReturnWithinSwitchExpression, NoArgument, diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties index e1828361424..4eed8042326 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/problem/messages.properties @@ -1033,27 +1033,29 @@ ###[obsolete] 1701 = A switch expression should have a non-empty switch block 1702 = A switch expression should have at least one result expression 1703 = A switch labeled block in a switch expression should not complete normally -1704 = The last statement of a switch block in a switch expression should not complete normally -1705 = Trailing switch labels are not allowed in a switch expression. -1706 = Mixing of different kinds of case statements '->' and ':' is not allowed within a switch +###[obsolete] 1704 = The last statement of a switch block in a switch expression should not complete normally +###[obsolete] 1705 = Trailing switch labels are not allowed in a switch expression. +1706 = Mixing of '->' and ':' case statement styles is not allowed within a switch 1707 = A switch expression should have a default case -1708 = yield of a switch expression should have a value +###[obsolete] 1708 = yield of a switch expression should have a value 1709 = A Switch expression should cover all possible values -1710 = 'continue' or 'return' cannot be the last statement in a Switch expression case body -1711 = break out of switch expression not allowed -1712 = yield may be disallowed in future - qualify method calls to avoid this message +###[obsolete] 1710 = 'continue' or 'return' cannot be the last statement in a Switch expression case body +###[obsolete] 1711 = break out of switch expression not allowed +###[obsolete] 1712 = yield may be disallowed in future - qualify method calls to avoid this message 1713 = restricted identifier yield not allowed here - method calls need to be qualified 1714 = yield outside of switch expression -1715 = yield is a restricted keyword and may be disallowed in future -1716 = yield statement is illegal here -1717 = yield may be a restricted identifier in future and may be disallowed as a type name -1718 = yield is a restricted identifier and cannot be used as type name +###[obsolete] 1715 = yield is a restricted keyword and may be disallowed in future +###[obsolete] 1716 = yield statement is illegal here +###[obsolete] 1717 = yield may be a restricted identifier in future and may be disallowed as a type name +###[obsolete] 1718 = yield is a restricted identifier and cannot be used as type name 1719 = Multi-constant case labels supported from Java 14 onwards only 1720 = Arrow in case statement supported from Java 14 onwards only 1721 = Switch Expressions are supported from Java 14 onwards only 1722 = Breaking out of switch expressions not permitted 1723 = Continue out of switch expressions not permitted 1724 = Return within switch expressions not permitted + + # Java 15 Preview - begin # Records 1730 = Illegal modifier for the record {0}; only public, private, protected, static, final and strictfp are permitted diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java index 94eebc7c376..a2f376fcb39 100644 --- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java +++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/SwitchExpressionsYieldTest.java @@ -2145,11 +2145,6 @@ public void testBug544073_076() { " continue;\n" + " ^^^^^^^^^\n" + "Continue out of switch expressions not permitted\n" + - "----------\n" + - "2. ERROR in X.java (at line 11)\n" + - " continue;\n" + - " ^^^^^^^^^\n" + - "'continue' or 'return' cannot be the last statement in a Switch expression case body\n" + "----------\n"); } public void testBug544073_077() { @@ -2182,11 +2177,6 @@ public void testBug544073_077() { " return 2;\n" + " ^^^^^^^^^\n" + "Return within switch expressions not permitted\n" + - "----------\n" + - "2. ERROR in X.java (at line 11)\n" + - " return 2;\n" + - " ^^^^^^^^^\n" + - "'continue' or 'return' cannot be the last statement in a Switch expression case body\n" + "----------\n"); } public void testBug544073_078() { @@ -3338,6 +3328,11 @@ public void testBug552764_001() { " default -> 3;\n" + " ^^^^^^^\n" + "Arrow in case statement supported from Java 14 onwards only\n" + + "----------\n" + + "2. ERROR in X.java (at line 4)\n" + + " default -> 3;\n" + + " ^\n" + + "Invalid expression as statement\n" + "----------\n"; this.runNegativeTest( testFiles, @@ -8060,4 +8055,36 @@ static void foo(Class c, int v) { "class [LX;\n42"); } + // test mixing of -> and : in the same switch + public void testMixingCaseStyles() { + if (this.complianceLevel < ClassFileConstants.JDK14) + return; + this.runNegativeTest( + new String[] { + "X.java", + """ + public class X { + public static void main(String[] args) { + int i = switch(args.length) { + case 2: yield 2; + default -> 1; + case 1 : yield 2; + }; + } + } + """ + }, + "----------\n" + + "1. ERROR in X.java (at line 5)\n" + + " default -> 1;\n" + + " ^^^^^^^\n" + + "Mixing of '->' and ':' case statement styles is not allowed within a switch\n" + + "----------\n" + + "2. ERROR in X.java (at line 6)\n" + + " case 1 : yield 2;\n" + + " ^^^^^^\n" + + "Mixing of '->' and ':' case statement styles is not allowed within a switch\n" + + "----------\n"); + } + } diff --git a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java index 3676a045096..f000a77a8c0 100644 --- a/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java +++ b/org.eclipse.jdt.core/dom/org/eclipse/jdt/core/dom/ASTConverter.java @@ -1459,10 +1459,10 @@ public SwitchCase convert(org.eclipse.jdt.internal.compiler.ast.CaseStatement st } } if (this.ast.apiLevel >= AST.JLS14_INTERNAL) { - switchCase.setSwitchLabeledRule(statement.isExpr); + switchCase.setSwitchLabeledRule(statement.isSwitchRule); } switchCase.setSourceRange(statement.sourceStart, statement.sourceEnd - statement.sourceStart + 1); - if (statement.isExpr) { + if (statement.isSwitchRule) { retrieveArrowPosition(switchCase); } else { retrieveColonPosition(switchCase);