diff options
Diffstat (limited to 'org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler')
66 files changed, 2328 insertions, 640 deletions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java index 869dc489a9..c9cba847be 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ASTVisitor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -508,6 +512,9 @@ public abstract class ASTVisitor { public void endVisit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) { // do nothing by default } + public void endVisit(SwitchExpression switchExpression, BlockScope scope) { + // do nothing by default + } public boolean visit( AllocationExpression allocationExpression, BlockScope scope) { @@ -999,4 +1006,7 @@ public abstract class ASTVisitor { public boolean visit(IntersectionCastTypeReference intersectionCastTypeReference, BlockScope scope) { return true; // do nothing by default, keep traversing } + public boolean visit(SwitchExpression switchExpression, BlockScope blockScope) { + return true; // do nothing by default, keep traversing + } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java index 78b31ccf23..9ec29d3e13 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ASTNode.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Matt McCutchen - partial fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=122995 @@ -108,7 +112,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds { public final static int Bit18 = 0x20000; // non null (expression) | onDemand (import reference) public final static int Bit19 = 0x40000; // didResolve (parameterized qualified type ref/parameterized single type ref) | empty (javadoc return statement) | needReceiverGenericCast (msg/fieldref) public final static int Bit20 = 0x80000; // contains syntax errors (method declaration, type declaration, field declarations, initializer), typeref: <> name ref: lambda capture) - public final static int Bit21 = 0x100000; + public final static int Bit21 = 0x100000; // for all declarations that can contain type references that have type annotations | insideExpressionStatement public final static int Bit22 = 0x200000; // parenthesis count (expression) | used (import reference) shadows outer local (local declarations) public final static int Bit23 = 0x400000; // parenthesis count (expression) | second or later declarator in declaration (local declarations) public final static int Bit24 = 0x800000; // parenthesis count (expression) @@ -325,7 +329,7 @@ public abstract class ASTNode implements TypeConstants, TypeIds { public static final int IsDiamond = Bit20; // this is only used for method invocation as the expression inside an expression statement - public static final int InsideExpressionStatement = Bit5; + public static final int InsideExpressionStatement = Bit21; // for annotation reference, signal if annotation was created from a default: public static final int IsSynthetic = ASTNode.Bit7; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java index 08869f0104..ece451e2c2 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BranchStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -32,6 +36,12 @@ public BranchStatement(char[] label, int sourceStart,int sourceEnd) { this.sourceEnd = sourceEnd; } +protected void generateExpressionResultCode(BlockScope currentScope, CodeStream codeStream) { + // do nothing here +} +protected void adjustStackSize(BlockScope currentScope, CodeStream codeStream) { + // do nothing here +} /** * Branch code generation * @@ -42,6 +52,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { if ((this.bits & ASTNode.IsReachable) == 0) { return; } + generateExpressionResultCode(currentScope, codeStream); int pc = codeStream.position; // generation of code responsible for invoking the finally @@ -62,6 +73,7 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream) { } } codeStream.goto_(this.targetLabel); + adjustStackSize(currentScope, codeStream); codeStream.recordPositionsFrom(pc, this.sourceStart); SubRoutineStatement.reenterAllExceptionHandlers(this.subroutines, -1, codeStream); if (this.initStateIndex != -1) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java index b17194ac06..7d1e82adab 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/BreakStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for @@ -16,15 +20,19 @@ package org.eclipse.jdt.internal.compiler.ast; import org.eclipse.jdt.internal.compiler.ASTVisitor; +import org.eclipse.jdt.internal.compiler.codegen.CodeStream; import org.eclipse.jdt.internal.compiler.flow.*; import org.eclipse.jdt.internal.compiler.lookup.*; public class BreakStatement extends BranchStatement { + public Expression expression; + public SwitchExpression switchExpression; + public boolean isImplicit; + public BreakStatement(char[] label, int sourceStart, int e) { super(label, sourceStart, e); } - @Override public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { @@ -40,11 +48,19 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl if (this.label == null) { currentScope.problemReporter().invalidBreak(this); } else { - currentScope.problemReporter().undefinedLabel(this); + if (this.switchExpression == null) + currentScope.problemReporter().undefinedLabel(this); } return flowInfo; // pretend it did not break since no actual target } + if (this.switchExpression != null && this.expression != null) { + flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo); + this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo); + if (flowInfo.reachMode() == FlowInfo.REACHABLE && currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) + checkAgainstNullAnnotation(currentScope, flowContext, flowInfo, this.expression); + } + targetContext.recordAbruptExit(); targetContext.expireNullCheckedFieldInfo(); @@ -89,17 +105,72 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl } return FlowInfo.DEAD_END; } +@Override +protected void generateExpressionResultCode(BlockScope currentScope, CodeStream codeStream) { + if (this.label == null && this.expression != null) { + this.expression.generateCode(currentScope, codeStream, this.switchExpression != null); + } +} +@Override +protected void adjustStackSize(BlockScope currentScope, CodeStream codeStream) { + if (this.label == null && this.expression != null && this.switchExpression != null) { + TypeBinding postConversionType = this.expression.postConversionType(currentScope); + switch(postConversionType.id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.decrStackSize(2); + break; + case TypeIds.T_void : + break; + default : + codeStream.decrStackSize(1); + break; + } + } +} +@Override +public void resolve(BlockScope scope) { + super.resolve(scope); + if (this.expression != null && (this.switchExpression != null || this.isImplicit)) { + if (this.switchExpression == null && this.isImplicit && !this.expression.statementExpression()) { + if (scope.compilerOptions().enablePreviewFeatures) { + /* JLS 12 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; + } + } + this.expression.resolveType(scope); + } else if (this.expression == null && this.switchExpression != null) { + scope.problemReporter().switchExpressionBreakMissingValue(this); + } +} + +@Override +public TypeBinding resolveExpressionType(BlockScope scope) { + return this.expression != null ? this.expression.resolveType(scope) : null; +} @Override public StringBuffer printStatement(int tab, StringBuffer output) { - printIndent(tab, output).append("break"); //$NON-NLS-1$ - if (this.label != null) output.append(' ').append(this.label); + if (!this.isImplicit) // implicit for SwitchLabeledExpressions + printIndent(tab, output).append("break"); //$NON-NLS-1$ + if (this.label != null) + output.append(' ').append(this.label); + if (this.expression != null) { + output.append(' '); + this.expression.printExpression(tab, output); + } return output.append(';'); } @Override public void traverse(ASTVisitor visitor, BlockScope blockscope) { - visitor.visit(this, blockscope); + if (visitor.visit(this, blockscope)) { + if (this.expression != null) + this.expression.traverse(visitor, blockscope); + } visitor.endVisit(this, blockscope); } @Override diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java index 85e0f21105..5ad0916539 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/CaseStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2011 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,11 +8,18 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.compiler.ast; +import java.util.ArrayList; +import java.util.List; + import org.eclipse.jdt.internal.compiler.ASTVisitor; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.BranchLabel; @@ -21,6 +28,7 @@ import org.eclipse.jdt.internal.compiler.flow.FlowContext; import org.eclipse.jdt.internal.compiler.flow.FlowInfo; import org.eclipse.jdt.internal.compiler.impl.Constant; import org.eclipse.jdt.internal.compiler.impl.IntConstant; +//import org.eclipse.jdt.internal.compiler.impl.IntConstant; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; @@ -31,6 +39,8 @@ public class CaseStatement extends Statement { public Expression constantExpression; public BranchLabel targetLabel; + public Expression[] constantExpressions; // case with multiple expressions + public boolean isExpr = false; public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) { this.constantExpression = constantExpression; @@ -43,13 +53,23 @@ public FlowInfo analyseCode( BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { - - if (this.constantExpression != null) { - if (this.constantExpression.constant == Constant.NotAConstant - && !this.constantExpression.resolvedType.isEnum()) { - currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression); + if (this.constantExpressions != null && this.constantExpressions.length > 1) { + for (Expression e : this.constantExpressions) { + if (e.constant == Constant.NotAConstant + && !e.resolvedType.isEnum()) { + currentScope.problemReporter().caseExpressionMustBeConstant(e); + } + this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); + } + + } else { + if (this.constantExpression != null) { + if (this.constantExpression.constant == Constant.NotAConstant + && !this.constantExpression.resolvedType.isEnum()) { + currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression); + } + this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); } - this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); } return flowInfo; } @@ -58,10 +78,19 @@ public FlowInfo analyseCode( public StringBuffer printStatement(int tab, StringBuffer output) { printIndent(tab, output); if (this.constantExpression == null) { - output.append("default :"); //$NON-NLS-1$ + output.append("default "); //$NON-NLS-1$ + output.append(this.isExpr ? "->" : ":"); //$NON-NLS-1$ //$NON-NLS-2$ } else { output.append("case "); //$NON-NLS-1$ - this.constantExpression.printExpression(0, output).append(" :"); //$NON-NLS-1$ + if (this.constantExpressions != null && this.constantExpressions.length > 0) { + for (int i = 0, l = this.constantExpressions.length; i < l; ++i) { + this.constantExpressions[i].printExpression(0, output); + if (i < l -1) output.append(','); + } + } else { + this.constantExpression.printExpression(0, output); + } + output.append(this.isExpr ? " ->" : " :"); //$NON-NLS-1$ //$NON-NLS-2$ } return output; } @@ -90,10 +119,10 @@ public void resolve(BlockScope scope) { /** * Returns the constant intValue or ordinal for enum constants. If constant is NotAConstant, then answers Float.MIN_VALUE - * @see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement) + * see org.eclipse.jdt.internal.compiler.ast.Statement#resolveCase(org.eclipse.jdt.internal.compiler.lookup.BlockScope, org.eclipse.jdt.internal.compiler.lookup.TypeBinding, org.eclipse.jdt.internal.compiler.ast.SwitchStatement) */ @Override -public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { +public Constant[] resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { // switchExpressionType maybe null in error case scope.enclosingCase = this; // record entering in a switch case block @@ -104,26 +133,55 @@ public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, // on error the last default will be the selected one ... switchStatement.defaultCase = this; - return Constant.NotAConstant; + return Constant.NotAConstantList; } // add into the collection of cases of the associated switch statement switchStatement.cases[switchStatement.caseCount++] = this; - // tag constant name with enum type for privileged access to its members if (switchExpressionType != null && switchExpressionType.isEnum() && (this.constantExpression instanceof SingleNameReference)) { ((SingleNameReference) this.constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType); } TypeBinding caseType = this.constantExpression.resolveType(scope); - if (caseType == null || switchExpressionType == null) return Constant.NotAConstant; - if (this.constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType) + if (caseType == null || switchExpressionType == null) return Constant.NotAConstantList; + // tag constant name with enum type for privileged access to its members + + if (this.constantExpressions != null && this.constantExpressions.length > 1) { + List<Constant> cases = new ArrayList<>(); + for (Expression e : this.constantExpressions) { + if (e != this.constantExpression) { + if (switchExpressionType.isEnum() && (e instanceof SingleNameReference)) { + ((SingleNameReference) e).setActualReceiverType((ReferenceBinding)switchExpressionType); + } + e.resolveType(scope); + } + Constant con = resolveConstantExpression(scope, caseType, switchExpressionType, switchStatement, e); + if (con != Constant.NotAConstant) { + cases.add(con); + } + } + if (cases.size() > 0) { + return cases.toArray(new Constant[cases.size()]); + } + } else { + return new Constant[] { resolveConstantExpression(scope, caseType, switchExpressionType, switchStatement, this.constantExpression) }; + } + return Constant.NotAConstantList; +} +public Constant resolveConstantExpression(BlockScope scope, + TypeBinding caseType, + TypeBinding switchExpressionType, + SwitchStatement switchStatement, + Expression expression) { + + if (expression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType) || caseType.isCompatibleWith(switchExpressionType)) { if (caseType.isEnum()) { - if (((this.constantExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) { - scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(this.constantExpression); + if (((expression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) { + scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(expression); } - if (this.constantExpression instanceof NameReference - && (this.constantExpression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) { - NameReference reference = (NameReference) this.constantExpression; + if (expression instanceof NameReference + && (expression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) { + NameReference reference = (NameReference) expression; FieldBinding field = reference.fieldBinding(); if ((field.modifiers & ClassFileConstants.AccEnum) == 0) { scope.problemReporter().enumSwitchCannotTargetField(reference, field); @@ -133,11 +191,11 @@ public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, return IntConstant.fromValue(field.original().id + 1); // (ordinal value + 1) zero should not be returned see bug 141810 } } else { - return this.constantExpression.constant; + return expression.constant; } - } else if (isBoxingCompatible(caseType, switchExpressionType, this.constantExpression, scope)) { + } else if (isBoxingCompatible(caseType, switchExpressionType, expression, scope)) { // constantExpression.computeConversion(scope, caseType, switchExpressionType); - do not report boxing/unboxing conversion - return this.constantExpression.constant; + return expression.constant; } scope.problemReporter().typeMismatchError(caseType, switchExpressionType, this.constantExpression, switchStatement.expression); return Constant.NotAConstant; @@ -146,7 +204,14 @@ public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, @Override public void traverse(ASTVisitor visitor, BlockScope blockScope) { if (visitor.visit(this, blockScope)) { - if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope); + if (this.constantExpressions != null && this.constantExpressions.length > 1) { + for (Expression e : this.constantExpressions) { + e.traverse(visitor, blockScope); + } + } else { + if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope); + } + } visitor.endVisit(this, blockScope); } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java index df72bd0422..00632c91e7 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ConditionalExpression.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2016 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephen Herrmann <stephan@cs.tu-berlin.de> - Contributions for @@ -223,14 +227,8 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, // is there a chance of null (or non-null)? -> potentially null etc. // https://bugs.eclipse.org/bugs/show_bug.cgi?id=133125 - int status = 0; int combinedStatus = this.ifTrueNullStatus|this.ifFalseNullStatus; - if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0) - status |= FlowInfo.POTENTIALLY_NULL; - if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0) - status |= FlowInfo.POTENTIALLY_NON_NULL; - if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0) - status |= FlowInfo.POTENTIALLY_UNKNOWN; + int status = Expression.computeNullStatus(0, combinedStatus); if (status > 0) this.nullStatus = status; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java index 56b6f8feaf..5b8054c57d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Expression.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for @@ -732,6 +736,15 @@ public void computeConversion(Scope scope, TypeBinding runtimeType, TypeBinding } } +public static int computeNullStatus(int status, int combinedStatus) { + if ((combinedStatus & (FlowInfo.NULL|FlowInfo.POTENTIALLY_NULL)) != 0) + status |= FlowInfo.POTENTIALLY_NULL; + if ((combinedStatus & (FlowInfo.NON_NULL|FlowInfo.POTENTIALLY_NON_NULL)) != 0) + status |= FlowInfo.POTENTIALLY_NON_NULL; + if ((combinedStatus & (FlowInfo.UNKNOWN|FlowInfo.POTENTIALLY_UNKNOWN)) != 0) + status |= FlowInfo.POTENTIALLY_UNKNOWN; + return status; +} /** * Expression statements are plain expressions, however they generate like * normal expressions with no value required. @@ -1057,6 +1070,10 @@ public void resolve(BlockScope scope) { this.resolveType(scope); return; } +@Override +public TypeBinding resolveExpressionType(BlockScope scope) { + return resolveType(scope); +} /** * Resolve the type of this expression in the context of a blockScope @@ -1161,6 +1178,12 @@ public boolean forcedToBeRaw(ReferenceContext referenceContext) { if (ternary.valueIfTrue.forcedToBeRaw(referenceContext) || ternary.valueIfFalse.forcedToBeRaw(referenceContext)) { return true; } + } else if (this instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) this; + for (Expression e : se.resultExpressions) { + if (e.forcedToBeRaw(referenceContext)) + return true; + } } return false; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java index 8498b31c09..c42d4039ca 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2011, 2016 GK Software AG and others. + * Copyright (c) 2011, 2019 GK Software AG and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * Nikolay Metchev (nikolaymetchev@gmail.com) - Contributions for @@ -180,6 +184,14 @@ public class FakedTrackingVariable extends LocalDeclaration { return falseTrackingVariable; } return getCloseTrackingVariable(((ConditionalExpression)expression).valueIfTrue, flowInfo, flowContext); + } else if (expression instanceof SwitchExpression) { + for (Expression re : ((SwitchExpression) expression).resultExpressions) { + FakedTrackingVariable fakedTrackingVariable = getCloseTrackingVariable(re, flowInfo, flowContext); + if (fakedTrackingVariable != null) { + return fakedTrackingVariable; + } + } + return null; } else break; @@ -242,12 +254,21 @@ public class FakedTrackingVariable extends LocalDeclaration { } } + private static boolean containsAllocation(SwitchExpression location) { + for (Expression re : location.resultExpressions) { + if (containsAllocation(re)) + return true; + } + return false; + } private static boolean containsAllocation(ASTNode location) { if (location instanceof AllocationExpression) return true; if (location instanceof ConditionalExpression) { ConditionalExpression conditional = (ConditionalExpression) location; return containsAllocation(conditional.valueIfTrue) || containsAllocation(conditional.valueIfFalse); + } else if (location instanceof SwitchExpression) { + return containsAllocation((SwitchExpression) location); } if (location instanceof CastExpression) return containsAllocation(((CastExpression) location).expression); @@ -260,6 +281,8 @@ public class FakedTrackingVariable extends LocalDeclaration { preConnectTrackerAcrossAssignment(location, local, flowInfo, (AllocationExpression) expression, closeTracker); } else if (expression instanceof ConditionalExpression) { preConnectTrackerAcrossAssignment(location, local, flowInfo, (ConditionalExpression) expression, closeTracker); + } else if (expression instanceof SwitchExpression) { + preConnectTrackerAcrossAssignment(location, local, flowInfo, (SwitchExpression) expression, closeTracker); } else if (expression instanceof CastExpression) { preConnectTrackerAcrossAssignment(location, local, ((CastExpression) expression).expression, flowInfo); } @@ -272,6 +295,13 @@ public class FakedTrackingVariable extends LocalDeclaration { } private static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, FlowInfo flowInfo, + SwitchExpression se, FakedTrackingVariable closeTracker) { + for (Expression re : se.resultExpressions) { + preConnectTrackerAcrossAssignment(location, local, flowInfo, closeTracker, re); + } + } + + private static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, FlowInfo flowInfo, AllocationExpression allocationExpression, FakedTrackingVariable closeTracker) { allocationExpression.closeTracker = closeTracker; if (allocationExpression.arguments != null && allocationExpression.arguments.length > 0) { @@ -456,7 +486,7 @@ public class FakedTrackingVariable extends LocalDeclaration { rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE|FOREACH_ELEMENT_VAR); } } else { - if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression) { + if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression || rhs instanceof SwitchExpression) { if (rhsTrackVar == disconnectedTracker) return; // b.: self wrapper: res = new Wrap(res); -> done! if (local.closeTracker == rhsTrackVar diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java index 1cd7e21e71..b67c1a4af6 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for @@ -245,6 +249,14 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl } if (candidate != null) return candidate; } + if (e instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression)e; + se.collectResultExpressions(); + for (Expression re : se.resultExpressions) { + Expression candidate = findPolyExpression(re); + if (candidate != null) return candidate; + } + } return null; } @@ -357,6 +369,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl && variableType != null && variableType.isValidBinding()) { resolveAnnotationsEarly = this.initialization instanceof Invocation || this.initialization instanceof ConditionalExpression + || this.initialization instanceof SwitchExpression || this.initialization instanceof ArrayInitializer; } if (resolveAnnotationsEarly) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java index 4c47725f64..41b38880cf 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2016 GK Software AG and others. + * Copyright (c) 2013, 2019 GK Software AG and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * Till Brychcy - Contributions for @@ -159,6 +163,19 @@ public class NullAnnotationMatching { if (status1 == status2) return status1; return nullStatus; // if both branches disagree use the precomputed & merged nullStatus + } else if (expression instanceof SwitchExpression && expression.isPolyExpression()) { + // drill into all the branches: + SwitchExpression se = ((SwitchExpression) expression); + Expression[] resExprs = se.resultExpressions.toArray(new Expression[0]); + Expression re = resExprs[0]; + int status0 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, re.nullStatus(flowInfo, flowContext), re, re.resolvedType); + boolean identicalStatus = true; + for (int i = 1, l = resExprs.length; i < l; ++i) { + re = resExprs[i]; + int otherStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, re.nullStatus(flowInfo, flowContext), re, re.resolvedType); + identicalStatus &= status0 == otherStatus; + } + return identicalStatus ? status0 : nullStatus; // if not all branches agree use the precomputed & merged nullStatus } lhsTagBits = var.type.tagBits & TagBits.AnnotationNullMASK; NullAnnotationMatching annotationStatus = analyse(var.type, providedType, null, null, nullStatus, expression, CheckMode.COMPATIBLE); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java index d5b9f6fea0..56b3ca3987 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/ReturnStatement.java @@ -90,7 +90,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl flowInfo = this.expression.analyseCode(currentScope, flowContext, flowInfo); this.expression.checkNPEbyUnboxing(currentScope, flowContext, flowInfo); if (flowInfo.reachMode() == FlowInfo.REACHABLE && currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) - checkAgainstNullAnnotation(currentScope, flowContext, flowInfo); + checkAgainstNullAnnotation(currentScope, flowContext, flowInfo, this.expression); if (currentScope.compilerOptions().analyseResourceLeaks) { FakedTrackingVariable trackingVariable = FakedTrackingVariable.getCloseTrackingVariable(this.expression, flowInfo, flowContext); if (trackingVariable != null) { @@ -182,29 +182,6 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl public boolean doesNotCompleteNormally() { return true; } -void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) { - int nullStatus = this.expression.nullStatus(flowInfo, flowContext); - long tagBits; - MethodBinding methodBinding = null; - boolean useTypeAnnotations = scope.environment().usesNullTypeAnnotations(); - try { - methodBinding = scope.methodScope().referenceMethodBinding(); - tagBits = (useTypeAnnotations) ? methodBinding.returnType.tagBits : methodBinding.tagBits; - } catch (NullPointerException npe) { - // chain of references in try-block has several potential nulls; - // any null means we cannot perform the following check - return; - } - if (useTypeAnnotations) { - checkAgainstNullTypeAnnotation(scope, methodBinding.returnType, this.expression, flowContext, flowInfo); - } else if (nullStatus != FlowInfo.NON_NULL) { - // if we can't prove non-null check against declared null-ness of the enclosing method: - if ((tagBits & TagBits.AnnotationNonNull) != 0) { - flowContext.recordNullityMismatch(scope, this.expression, this.expression.resolvedType, methodBinding.returnType, flowInfo, nullStatus, null); - } - } -} - /** * Retrun statement code generation * diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java index 35967ab8fd..a4a9abb523 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SingleNameReference.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann <stephan@cs.tu-berlin.de> - Contributions for @@ -63,6 +67,7 @@ public class SingleNameReference extends NameReference implements OperatorIds { public char[] token; public MethodBinding[] syntheticAccessors; // [0]=read accessor [1]=write accessor public TypeBinding genericCast; + public boolean isLabel;// flagging for break expression when expression is SwitchExpression - java 12 preview-feature public SingleNameReference(char[] source, long pos) { super(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java index 5bfb045288..56991a493b 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Statement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for @@ -176,7 +180,16 @@ void analyseOneArgument18(BlockScope currentScope, FlowContext flowContext, Flow ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfTrue, flowInfo, ce.ifTrueNullStatus, expectedNonNullness, originalExpected); ce.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, ce.valueIfFalse, flowInfo, ce.ifFalseNullStatus, expectedNonNullness, originalExpected); return; + } else if (argument instanceof SwitchExpression && argument.isPolyExpression()) { + SwitchExpression se = (SwitchExpression) argument; + for (int i = 0; i < se.resultExpressions.size(); i++) { + se.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, + se.resultExpressions.get(i), flowInfo, + se.resultExpressionNullStatus.get(i), expectedNonNullness, originalExpected); + } + return; } + int nullStatus = argument.nullStatus(flowInfo, flowContext); internalAnalyseOneArgument18(currentScope, flowContext, expectedType, argument, flowInfo, nullStatus, expectedNonNullness, originalExpected); @@ -204,6 +217,28 @@ void internalAnalyseOneArgument18(BlockScope currentScope, FlowContext flowConte flowContext.recordNullityMismatch(currentScope, argument, argument.resolvedType, expectedType, flowInfo, nullStatus, annotationStatus); } } +/* package */ void checkAgainstNullAnnotation(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo, Expression expr) { + int nullStatus = expr.nullStatus(flowInfo, flowContext); + long tagBits; + MethodBinding methodBinding = null; + boolean useTypeAnnotations = scope.environment().usesNullTypeAnnotations(); + try { + methodBinding = scope.methodScope().referenceMethodBinding(); + tagBits = (useTypeAnnotations) ? methodBinding.returnType.tagBits : methodBinding.tagBits; + } catch (NullPointerException npe) { + // chain of references in try-block has several potential nulls; + // any null means we cannot perform the following check + return; + } + if (useTypeAnnotations) { + checkAgainstNullTypeAnnotation(scope, methodBinding.returnType, expr, flowContext, flowInfo); + } else if (nullStatus != FlowInfo.NON_NULL) { + // if we can't prove non-null check against declared null-ness of the enclosing method: + if ((tagBits & TagBits.AnnotationNonNull) != 0) { + flowContext.recordNullityMismatch(scope, expr, expr.resolvedType, methodBinding.returnType, flowInfo, nullStatus, null); + } + } +} protected void checkAgainstNullTypeAnnotation(BlockScope scope, TypeBinding requiredType, Expression expression, FlowContext flowContext, FlowInfo flowInfo) { if (expression instanceof ConditionalExpression && expression.isPolyExpression()) { @@ -212,6 +247,14 @@ protected void checkAgainstNullTypeAnnotation(BlockScope scope, TypeBinding requ internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfTrue, ce.ifTrueNullStatus, flowContext, flowInfo); internalCheckAgainstNullTypeAnnotation(scope, requiredType, ce.valueIfFalse, ce.ifFalseNullStatus, flowContext, flowInfo); return; + } else if (expression instanceof SwitchExpression && expression.isPolyExpression()) { + SwitchExpression se = (SwitchExpression) expression; + for (int i = 0; i < se.resultExpressions.size(); i++) { + internalCheckAgainstNullTypeAnnotation(scope, requiredType, + se.resultExpressions.get(i), + se.resultExpressionNullStatus.get(i), flowContext, flowInfo); + } + return; } int nullStatus = expression.nullStatus(flowInfo, flowContext); internalCheckAgainstNullTypeAnnotation(scope, requiredType, expression, nullStatus, flowContext, flowInfo); @@ -423,11 +466,19 @@ public abstract void resolve(BlockScope scope); /** * Returns case constant associated to this statement (NotAConstant if none) + * parameter statement has to be either a SwitchStatement or a SwitchExpression */ -public Constant resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) { +public Constant[] resolveCase(BlockScope scope, TypeBinding testType, SwitchStatement switchStatement) { // statement within a switch that are not case are treated as normal statement.... resolve(scope); - return Constant.NotAConstant; + return new Constant[] {Constant.NotAConstant}; +} +/** + * Returns the resolved expression if any associated to this statement - used + * parameter statement has to be either a SwitchStatement or a SwitchExpression + */ +public TypeBinding resolveExpressionType(BlockScope scope) { + return null; } /** * Implementation of {@link org.eclipse.jdt.internal.compiler.lookup.InvocationSite#invocationTargetType} diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java new file mode 100644 index 0000000000..0860ac3f0c --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java @@ -0,0 +1,696 @@ +/******************************************************************************* + * Copyright (c) 2018, 2019 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.compiler.ast; + +import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.ASSIGNMENT_CONTEXT; +import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.INVOCATION_CONTEXT; +import static org.eclipse.jdt.internal.compiler.ast.ExpressionContext.VANILLA_CONTEXT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.stream.Collectors; + +import org.eclipse.jdt.internal.compiler.ASTVisitor; +import org.eclipse.jdt.internal.compiler.codegen.CodeStream; +import org.eclipse.jdt.internal.compiler.flow.FlowContext; +import org.eclipse.jdt.internal.compiler.flow.FlowInfo; +import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.impl.Constant; +import org.eclipse.jdt.internal.compiler.lookup.Binding; +import org.eclipse.jdt.internal.compiler.lookup.BlockScope; +import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; +import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; +import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; +import org.eclipse.jdt.internal.compiler.lookup.PolyTypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.Scope; +import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; +import org.eclipse.jdt.internal.compiler.lookup.TypeIds; + +public class SwitchExpression extends SwitchStatement implements IPolyExpression { + + /* package */ TypeBinding expectedType; + private ExpressionContext expressionContext = VANILLA_CONTEXT; + private boolean isPolyExpression = false; + private TypeBinding[] originalValueResultExpressionTypes; + private TypeBinding[] finalValueResultExpressionTypes; + + private int nullStatus = FlowInfo.UNKNOWN; + public List<Expression> resultExpressions; + public boolean resolveAll; + /* package */ List<Integer> resultExpressionNullStatus; + private static Map<TypeBinding, TypeBinding[]> type_map; + + static { + type_map = new HashMap<TypeBinding, TypeBinding[]>(); + type_map.put(TypeBinding.CHAR, new TypeBinding[] {TypeBinding.CHAR, TypeBinding.BYTE, TypeBinding.INT}); + type_map.put(TypeBinding.SHORT, new TypeBinding[] {TypeBinding.SHORT, TypeBinding.BYTE, TypeBinding.INT}); + type_map.put(TypeBinding.BYTE, new TypeBinding[] {TypeBinding.BYTE, TypeBinding.INT}); + } + + @Override + public void setExpressionContext(ExpressionContext context) { + this.expressionContext = context; + } + + @Override + public void setExpectedType(TypeBinding expectedType) { + this.expectedType = expectedType; + } + + @Override + public ExpressionContext getExpressionContext() { + return this.expressionContext; + } + @Override + protected boolean ignoreMissingDefaultCase(CompilerOptions compilerOptions, boolean isEnumSwitch) { + return isEnumSwitch; // mandatory error if not enum in switch expressions + } + @Override + protected void reportMissingEnumConstantCase(BlockScope upperScope, FieldBinding enumConstant) { + upperScope.problemReporter().missingEnumConstantCase(this, enumConstant); + } + @Override + protected int getFallThroughState(Statement stmt, BlockScope blockScope) { + if (stmt instanceof Expression || stmt instanceof ThrowStatement) + return BREAKING; + if (this.switchLabeledRules // do this check for every block if '->' (Switch Labeled Rules) + && stmt instanceof Block) { + Block block = (Block) stmt; + if (block.doesNotCompleteNormally()) { + return BREAKING; + } + //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. + blockScope.problemReporter().switchExpressionSwitchLabeledBlockCompletesNormally(block); + } + return FALLTHROUGH; + } + @Override + public boolean checkNPE(BlockScope skope, FlowContext flowContext, FlowInfo flowInfo, int ttlForFieldCheck) { + if ((this.nullStatus & FlowInfo.NULL) != 0) + skope.problemReporter().expressionNullReference(this); + else if ((this.nullStatus & FlowInfo.POTENTIALLY_NULL) != 0) + skope.problemReporter().expressionPotentialNullReference(this); + return true; // all checking done + } + + private void computeNullStatus(FlowInfo flowInfo, FlowContext flowContext) { + boolean precomputed = this.resultExpressionNullStatus.size() > 0; + if (!precomputed) + this.resultExpressionNullStatus.add(this.resultExpressions.get(0).nullStatus(flowInfo, flowContext)); int status = this.resultExpressions.get(0).nullStatus(flowInfo, flowContext); + int combinedStatus = status; + boolean identicalStatus = true; + for (int i = 1, l = this.resultExpressions.size(); i < l; ++i) { + if (!precomputed) + this.resultExpressionNullStatus.add(this.resultExpressions.get(i).nullStatus(flowInfo, flowContext)); + int tmp = this.resultExpressions.get(i).nullStatus(flowInfo, flowContext); + identicalStatus &= status == tmp; + combinedStatus |= tmp; + } + if (identicalStatus) { + this.nullStatus = status; + return; + } + status = Expression.computeNullStatus(0, combinedStatus); + if (status > 0) + this.nullStatus = status; + } + + @Override + protected void completeNormallyCheck(BlockScope blockScope) { + if (this.switchLabeledRules) return; // already taken care in getFallThroughState() + int sz = this.statements != null ? this.statements.length : 0; + if (sz == 0) 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 && !lastNonCaseStmt.doesNotCompleteNormally()) { + blockScope.problemReporter().switchExpressionLastStatementCompletesNormally(lastNonCaseStmt); + } + if (firstTrailingCaseStmt != null) { + blockScope.problemReporter().switchExpressionTrailingSwitchLabels(firstTrailingCaseStmt); + } + } + @Override + public Expression[] getPolyExpressions() { + List<Expression> polys = new ArrayList<>(); + for (Expression e : this.resultExpressions) { + Expression[] ea = e.getPolyExpressions(); + if (ea == null || ea.length ==0) continue; + polys.addAll(Arrays.asList(ea)); + } + return polys.toArray(new Expression[0]); + } + @Override + public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method) { + for (Expression e : this.resultExpressions) { + if (!e.isPertinentToApplicability(targetType, method)) + return false; + } + return true; + } + @Override + public boolean isPotentiallyCompatibleWith(TypeBinding targetType, Scope scope1) { + for (Expression e : this.resultExpressions) { + if (!e.isPotentiallyCompatibleWith(targetType, scope1)) + return false; + } + return true; + } + @Override + public boolean isFunctionalType() { + for (Expression e : this.resultExpressions) { + if (e.isFunctionalType()) // return true even for one functional type + return true; + } + return false; + } + @Override + public int nullStatus(FlowInfo flowInfo, FlowContext flowContext) { + if ((this.implicitConversion & TypeIds.BOXING) != 0) + return FlowInfo.NON_NULL; + return this.nullStatus; + } + @Override + protected void statementGenerateCode(BlockScope currentScope, CodeStream codeStream, Statement statement) { + if (!(statement instanceof Expression) + || statement instanceof Assignment + || statement instanceof MessageSend + || (statement instanceof SwitchStatement && !(statement instanceof SwitchExpression))) { + super.statementGenerateCode(currentScope, codeStream, statement); + return; + } + Expression expression1 = (Expression) statement; + expression1.generateCode(currentScope, codeStream, true /* valueRequired */); + } + @Override + public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + super.generateCode(currentScope, codeStream); + if (!valueRequired) { + // switch expression is saved to a variable that is not used. We need to pop the generated value from the stack + switch(postConversionType(currentScope).id) { + case TypeIds.T_long : + case TypeIds.T_double : + codeStream.pop2(); + break; + case TypeIds.T_void : + break; + default : + codeStream.pop(); + break; + } + } + } + protected boolean computeConversions(BlockScope blockScope, TypeBinding targetType) { + boolean ok = true; + for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) { + ok &= computeConversionsResultExpressions(blockScope, targetType, this.originalValueResultExpressionTypes[i], this.resultExpressions.get(i)); + } + return ok; + } + private boolean computeConversionsResultExpressions(BlockScope blockScope, TypeBinding targetType, TypeBinding resultExpressionType, + Expression resultExpression) { + if (resultExpressionType != null && resultExpressionType.isValidBinding()) { + if (resultExpression.isConstantValueOfTypeAssignableToType(resultExpressionType, targetType) + || resultExpressionType.isCompatibleWith(targetType)) { + + resultExpression.computeConversion(blockScope, targetType, resultExpressionType); + if (resultExpressionType.needsUncheckedConversion(targetType)) { + blockScope.problemReporter().unsafeTypeConversion(resultExpression, resultExpressionType, targetType); + } + if (resultExpression instanceof CastExpression + && (resultExpression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) { + CastExpression.checkNeedForAssignedCast(blockScope, targetType, (CastExpression) resultExpression); + } + } else if (isBoxingCompatible(resultExpressionType, targetType, resultExpression, blockScope)) { + resultExpression.computeConversion(blockScope, targetType, resultExpressionType); + if (resultExpression instanceof CastExpression + && (resultExpression.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == 0) { + CastExpression.checkNeedForAssignedCast(blockScope, targetType, (CastExpression) resultExpression); + } + } else { + blockScope.problemReporter().typeMismatchError(resultExpressionType, targetType, resultExpression, null); + return false; + } + } + return true; + } + /* package */ void collectResultExpressions() { + if (this.resultExpressions != null) + return; // already calculated. + + class ResultExpressionsCollector extends ASTVisitor { + Stack<SwitchExpression> targetSwitchExpressions; + public ResultExpressionsCollector(SwitchExpression se) { + if (this.targetSwitchExpressions == null) + this.targetSwitchExpressions = new Stack<>(); + this.targetSwitchExpressions.push(se); + } + @Override + public boolean visit(SwitchExpression switchExpression, BlockScope blockScope) { + if (switchExpression.resultExpressions == null) + switchExpression.resultExpressions = new ArrayList<>(0); + this.targetSwitchExpressions.push(switchExpression); + return true; + } + @Override + public void endVisit(SwitchExpression switchExpression, BlockScope blockScope) { + this.targetSwitchExpressions.pop(); + } + @Override + public boolean visit(BreakStatement breakStatement, BlockScope blockScope) { + SwitchExpression targetSwitchExpression = this.targetSwitchExpressions.peek(); + if (breakStatement.expression != null) { + targetSwitchExpression.resultExpressions.add(breakStatement.expression); + breakStatement.switchExpression = this.targetSwitchExpressions.peek(); + breakStatement.label = null; // not a label, but an expression + if (breakStatement.expression instanceof SingleNameReference) { + ((SingleNameReference) breakStatement.expression).isLabel = false; + } + } else { + // flag an error while resolving + breakStatement.switchExpression = targetSwitchExpression; + } + return true; + } + @Override + public boolean visit(DoStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(ForStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(ForeachStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(SwitchStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(TypeDeclaration stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(WhileStatement stmt, BlockScope blockScope) { + return false; + } + @Override + public boolean visit(CaseStatement caseStatement, BlockScope blockScope) { + return true; // do nothing by default, keep traversing + } + } + this.resultExpressions = new ArrayList<>(0); // indicates processed + int l = this.statements == null ? 0 : this.statements.length; + for (int i = 0; i < l; ++i) { + Statement stmt = this.statements[i]; + if (stmt instanceof CaseStatement) { + CaseStatement caseStatement = (CaseStatement) stmt; + if (!caseStatement.isExpr) continue; + stmt = this.statements[++i]; + if (stmt instanceof Expression) { + this.resultExpressions.add((Expression) stmt); + continue; + } else if (stmt instanceof ThrowStatement) { + // TODO: Throw Expression Processing. Anything to be done here for resolve? + continue; + } + } + // break statement and block statement of SwitchLabelRule or block statement of ':' + ResultExpressionsCollector reCollector = new ResultExpressionsCollector(this); + stmt.traverse(reCollector, this.scope); + } + } + @Override + public TypeBinding resolveType(BlockScope upperScope) { + try { + int resultExpressionsCount; + if (this.constant != Constant.NotAConstant) { + this.constant = Constant.NotAConstant; + + // tag break statements and (alongwith in the same pass) collect the result expressions + collectResultExpressions(); + + // A switch expression is a poly expression if it appears in an assignment context or an invocation context (5.2, 5.3). + // Otherwise, it is a standalone expression. + if (this.expressionContext == ASSIGNMENT_CONTEXT || this.expressionContext == INVOCATION_CONTEXT) { + for (Expression e : this.resultExpressions) { + //Where a poly switch expression appears in a context of a particular kind with target type T, + //its result expressions similarly appear in a context of the same kind with target type T. + e.setExpressionContext(this.expressionContext); + e.setExpectedType(this.expectedType); + } + } + + resolve(upperScope); + + if (this.statements == null || this.statements.length == 0) { + // Report Error JLS 12 15.28.1 The switch block must not be empty. + upperScope.problemReporter().switchExpressionEmptySwitchBlock(this); + return null; + } + + resultExpressionsCount = this.resultExpressions != null ? this.resultExpressions.size() : 0; + if (resultExpressionsCount == 0) { + // Report Error JLS 12 15.28.1 + // It is a compile-time error if a switch expression has no result expressions. + upperScope.problemReporter().switchExpressionNoResultExpressions(this); + return null; + } + + if (this.originalValueResultExpressionTypes == null) { + this.originalValueResultExpressionTypes = new TypeBinding[resultExpressionsCount]; + this.finalValueResultExpressionTypes = new TypeBinding[resultExpressionsCount]; + for (int i = 0; i < resultExpressionsCount; ++i) { + this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] = + this.resultExpressions.get(i).resolvedType; + } + } + if (isPolyExpression()) { //The type of a poly switch expression is the same as its target type. + if (this.expectedType == null || !this.expectedType.isProperType(true)) { + return new PolyTypeBinding(this); + } + return this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null; + } + // fall through + } else { + // re-resolving of poly expression: + resultExpressionsCount = this.resultExpressions != null ? this.resultExpressions.size() : 0; + for (int i = 0; i < resultExpressionsCount; i++) { + Expression resultExpr = this.resultExpressions.get(i); + if (resultExpr.resolvedType == null || resultExpr.resolvedType.kind() == Binding.POLY_TYPE) { + this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] = + resultExpr.resolveTypeExpecting(upperScope, this.expectedType); + } + // This is a kludge and only way completion can tell this node to resolve all + // resultExpressions. Ideal solution is to remove all other expressions except + // the one that contain the completion node. + if (this.resolveAll) continue; + if (resultExpr.resolvedType == null || !resultExpr.resolvedType.isValidBinding()) + return this.resolvedType = null; + } + this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null; + // fall through + } + + if (resultExpressionsCount == 1) + return this.resolvedType = this.originalValueResultExpressionTypes[0]; + + boolean typeUniformAcrossAllArms = true; + TypeBinding tmp = this.originalValueResultExpressionTypes[0]; + for (int i = 1, l = this.originalValueResultExpressionTypes.length; i < l; ++i) { + TypeBinding originalType = this.originalValueResultExpressionTypes[i]; + if (originalType != null && TypeBinding.notEquals(tmp, originalType)) { + typeUniformAcrossAllArms = false; + break; + } + } + // If the result expressions all have the same type (which may be the null type), + // then that is the type of the switch expression. + if (typeUniformAcrossAllArms) { + tmp = this.originalValueResultExpressionTypes[0]; + for (int i = 1; i < resultExpressionsCount; ++i) { + if (this.originalValueResultExpressionTypes[i] != null) + tmp = NullAnnotationMatching.moreDangerousType(tmp, this.originalValueResultExpressionTypes[i]); + } + return this.resolvedType = tmp; + } + + boolean typeBbolean = true; + for (TypeBinding t : this.originalValueResultExpressionTypes) { + if (t != null) + typeBbolean &= t.id == T_boolean || t.id == T_JavaLangBoolean; + } + LookupEnvironment env = this.scope.environment(); + /* + * Otherwise, if the type of each result expression is boolean or Boolean, + * an unboxing conversion (5.1.8) is applied to each result expression of type Boolean, + * and the switch expression has type boolean. + */ + if (typeBbolean) { + for (int i = 0; i < resultExpressionsCount; ++i) { + if (this.originalValueResultExpressionTypes[i].id == T_boolean) continue; + this.finalValueResultExpressionTypes[i] = env.computeBoxingType(this.originalValueResultExpressionTypes[i]); + this.resultExpressions.get(i).computeConversion(this.scope, this.finalValueResultExpressionTypes[i], this.originalValueResultExpressionTypes[i]); + } + return this.resolvedType = TypeBinding.BOOLEAN; + } + + /* + * Otherwise, if the type of each result expression is convertible to a numeric type (5.1.8), the type + * of the switch expression is given by numeric promotion (5.6.3) applied to the result expressions. + */ + boolean typeNumeric = true; + TypeBinding resultNumeric = null; + HashSet<TypeBinding> typeSet = new HashSet<>(); + /* JLS 12 5.6.3 Switch Numeric Promotion + * When a switch expression applies numeric promotion to a set of result expressions, each of which + * must denote a value that is convertible to a numeric type, the following rules apply, in order: + * If any result expression is of a reference type, it is subjected to unboxing conversion (5.1.8). + */ + for (int i = 0; i < resultExpressionsCount; ++i) { + TypeBinding originalType = this.originalValueResultExpressionTypes[i]; + if (originalType == null) continue; + tmp = originalType.isNumericType() ? originalType : env.computeBoxingType(originalType); + if (!tmp.isNumericType()) { + typeNumeric = false; + break; + } + typeSet.add(TypeBinding.wellKnownType(this.scope, tmp.id)); + } + if (typeNumeric) { + /* If any result expression is of type double, then other result expressions that are not of type double + * are widened to double. + * Otherwise, if any result expression is of type float, then other result expressions that are not of + * type float are widened to float. + * Otherwise, if any result expression is of type long, then other result expressions that are not of + * type long are widened to long. + */ + TypeBinding[] dfl = new TypeBinding[]{// do not change the order JLS 12 5.6.3 + TypeBinding.DOUBLE, + TypeBinding.FLOAT, + TypeBinding.LONG}; + for (TypeBinding binding : dfl) { + if (typeSet.contains(binding)) { + resultNumeric = binding; + break; + } + } + + /* Otherwise, if any result expression is of type int and is not a constant expression, the other + * result expressions that are not of type int are widened to int. + */ + resultNumeric = resultNumeric != null ? resultNumeric : check_nonconstant_int(); + + resultNumeric = resultNumeric != null ? resultNumeric : // one among the first few rules applied. + getResultNumeric(typeSet, this.originalValueResultExpressionTypes); // check the rest + typeSet = null; // hey gc! + for (int i = 0; i < resultExpressionsCount; ++i) { + // auto-unboxing and/or widening/narrrowing JLS 12 5.6.3 + this.resultExpressions.get(i).computeConversion(this.scope, + resultNumeric, this.originalValueResultExpressionTypes[i]); + this.finalValueResultExpressionTypes[i] = resultNumeric; + } + // After the conversion(s), if any, value set conversion (5.1.13) is then applied to each result expression. + return this.resolvedType = resultNumeric; + } + + /* Otherwise, boxing conversion (5.1.7) is applied to each result expression that has a primitive type, + * after which the type of the switch expression is the result of applying capture conversion (5.1.10) + * to the least upper bound (4.10.4) of the types of the result expressions. + */ + for (int i = 0; i < resultExpressionsCount; ++i) { + TypeBinding finalType = this.finalValueResultExpressionTypes[i]; + if (finalType != null && finalType.isBaseType()) + this.finalValueResultExpressionTypes[i] = env.computeBoxingType(finalType); + } + TypeBinding commonType = this.scope.lowerUpperBound(this.finalValueResultExpressionTypes); + if (commonType != null) { + for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) { + if (this.originalValueResultExpressionTypes[i] == null) continue; + this.resultExpressions.get(i).computeConversion(this.scope, commonType, this.originalValueResultExpressionTypes[i]); + this.finalValueResultExpressionTypes[i] = commonType; + } + return this.resolvedType = commonType.capture(this.scope, this.sourceStart, this.sourceEnd); + } + this.scope.problemReporter().switchExpressionIncompatibleResultExpressions(this); + return null; + } finally { + if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block + } + } + private TypeBinding check_nonconstant_int() { + for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) { + Expression e = this.resultExpressions.get(i); + TypeBinding type = this.originalValueResultExpressionTypes[i]; + if (type != null && type.id == T_int && e.constant == Constant.NotAConstant) + return TypeBinding.INT; + } + return null; + } + private boolean areAllIntegerResultExpressionsConvertibleToTargetType(TypeBinding targetType) { + for (int i = 0, l = this.resultExpressions.size(); i < l; ++i) { + Expression e = this.resultExpressions.get(i); + TypeBinding t = this.originalValueResultExpressionTypes[i]; + if (!TypeBinding.equalsEquals(t, TypeBinding.INT)) continue; + if (!e.isConstantValueOfTypeAssignableToType(t, targetType)) + return false; + } + return true; + } + @Override + public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { + flowInfo = super.analyseCode(currentScope, flowContext, flowInfo); + this.resultExpressionNullStatus = new ArrayList<>(0); + final CompilerOptions compilerOptions = currentScope.compilerOptions(); + if (compilerOptions.enableSyntacticNullAnalysisForFields) { + for (Expression re : this.resultExpressions) { + this.resultExpressionNullStatus.add(re.nullStatus(flowInfo, flowContext)); + // wipe information that was meant only for this result expression: + flowContext.expireNullCheckedFieldInfo(); + } + } + computeNullStatus(flowInfo, flowContext); + return flowInfo; + } + private TypeBinding check_csb(Set<TypeBinding> typeSet, TypeBinding candidate) { + if (!typeSet.contains(candidate)) + return null; + + TypeBinding[] allowedTypes = SwitchExpression.type_map.get(candidate); + Set<TypeBinding> allowedSet = Arrays.stream(allowedTypes).collect(Collectors.toSet()); + + if (!allowedSet.containsAll(typeSet)) + return null; + + return areAllIntegerResultExpressionsConvertibleToTargetType(candidate) ? + candidate : null; + } + private TypeBinding getResultNumeric(Set<TypeBinding> typeSet, TypeBinding[] armTypes) { + // note: if an expression has a type integer, then it will be a constant + // since non-constant integers are already processed before reaching here. + + /* + * Otherwise, if any result expression is of type char, and every other result expression is either of + * type char, or of type byte, or a constant expression of type int with a value that is representable + * in the type char, then the byte results are widened to char and the int results are narrowed to char. + */ + + /* Otherwise, if any result expression is of type short, and every other result expression is either of + * type short, or of type byte, or a constant expression of type int with a value that is representable + * in the type short, then the byte results are widened to short and the int results are narrowed to + * short. + */ + /* Otherwise, if any result expression is of type byte, and every other result expression is either of + * type byte or a constant expression of type int with a value that is representable in the type byte, + * then the int results are narrowed to byte. + */ + + // DO NOT Change the order below [as per JLS 12 5.6.3 item 2, sub-items 5,6 and 7]. + TypeBinding[] csb = new TypeBinding[] {TypeBinding.CHAR, TypeBinding.SHORT, TypeBinding.BYTE}; + for (TypeBinding c : csb) { + TypeBinding result = check_csb(typeSet, c); + if (result != null) + return result; + } + /* Otherwise, all the result expressions that are not of type int are widened to int. */ + return TypeBinding.INT; + } + @Override + public boolean isPolyExpression() { + if (this.isPolyExpression) + return true; + // JLS 12 15.28.1 A switch expression is a poly expression if it appears in an assignment context or + // an invocation context (5.2, 5.3). Otherwise, it is a standalone expression. + return this.isPolyExpression = this.expressionContext == ASSIGNMENT_CONTEXT || + this.expressionContext == INVOCATION_CONTEXT; + } + @Override + public boolean isCompatibleWith(TypeBinding left, Scope skope) { + if (!isPolyExpression()) + return super.isCompatibleWith(left, skope); + + for (Expression e : this.resultExpressions) { + if (!e.isCompatibleWith(left, skope)) + return false; + } + return true; + } + @Override + public boolean isBoxingCompatibleWith(TypeBinding targetType, Scope skope) { + if (!isPolyExpression()) + return super.isBoxingCompatibleWith(targetType, skope); + + for (Expression e : this.resultExpressions) { + if (!(e.isCompatibleWith(targetType, skope) || e.isBoxingCompatibleWith(targetType, skope))) + return false; + } + return true; + } + @Override + public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t, Scope skope) { + if (super.sIsMoreSpecific(s, t, skope)) + return true; + if (!isPolyExpression()) + return false; + for (Expression e : this.resultExpressions) { + if (!e.sIsMoreSpecific(s, t, skope)) + return false; + } + return true; + } + @Override + public TypeBinding expectedType() { + return this.expectedType; + } + @Override + public void traverse( + ASTVisitor visitor, + BlockScope blockScope) { + + if (visitor.visit(this, blockScope)) { + this.expression.traverse(visitor, blockScope); + if (this.statements != null) { + int statementsLength = this.statements.length; + for (int i = 0; i < statementsLength; i++) + this.statements[i].traverse(visitor, this.scope); + } + } + visitor.endVisit(this, blockScope); + } +}
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java index 15dbd6bfda..8670e38554 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/SwitchStatement.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2017 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contributions for @@ -43,7 +47,7 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeIds; import org.eclipse.jdt.internal.compiler.problem.ProblemSeverities; @SuppressWarnings("rawtypes") -public class SwitchStatement extends Statement { +public class SwitchStatement extends Expression { public Expression expression; public Statement[] statements; @@ -55,12 +59,15 @@ public class SwitchStatement extends Statement { public int blockStart; public int caseCount; int[] constants; + int[] constMapping; String[] stringConstants; + public boolean switchLabeledRules = false; // true if case ->, false if case : // fallthrough public final static int CASE = 0; public final static int FALLTHROUGH = 1; public final static int ESCAPING = 2; + public final static int BREAKING = 3; // for switch on strings private static final char[] SecretStringVariableName = " switchDispatchString".toCharArray(); //$NON-NLS-1$ @@ -76,6 +83,38 @@ public class SwitchStatement extends Statement { int duplicateCaseStatementsCounter = 0; private LocalVariableBinding dispatchStringCopy = null; + protected int getFallThroughState(Statement stmt, BlockScope blockScope) { + if (this.switchLabeledRules) { + if (stmt instanceof Expression || stmt instanceof ThrowStatement) + return BREAKING; + + if (stmt instanceof Block) { + Block block = (Block) stmt; + if (block.doesNotCompleteNormally()) { + return BREAKING; + } + // else add an implicit break + BreakStatement breakStatement = new BreakStatement(null, block.sourceEnd -1, block.sourceEnd); + breakStatement.isImplicit = true; + + int l = block.statements == null ? 0 : block.statements.length; + if (l == 0) { + block.statements = new Statement[] {breakStatement}; + block.scope = this.scope; // (upper scope) see Block.resolve() for similar + } else { + Statement[] newArray = new Statement[l + 1]; + System.arraycopy(block.statements, 0, newArray, 0, l); + newArray[l] = breakStatement; + block.statements = newArray; + } + return BREAKING; + } + } + return FALLTHROUGH; + } + protected void completeNormallyCheck(BlockScope blockScope) { + // do nothing + } @Override public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) { try { @@ -120,7 +159,7 @@ public class SwitchStatement extends Statement { complaintLevel = initialComplaintLevel; // reset complaint fallThroughState = CASE; } else { - fallThroughState = FALLTHROUGH; // reset below if needed + fallThroughState = getFallThroughState(statement, currentScope); // reset below if needed } if ((complaintLevel = statement.complainIfUnreachable(caseInits, this.scope, complaintLevel, true)) < Statement.COMPLAINED_UNREACHABLE) { caseInits = statement.analyseCode(this.scope, switchContext, caseInits); @@ -130,6 +169,7 @@ public class SwitchStatement extends Statement { switchContext.expireNullCheckedFieldInfo(); } } + completeNormallyCheck(currentScope); } final TypeBinding resolvedTypeBinding = this.expression.resolvedType; @@ -199,33 +239,60 @@ public class SwitchStatement extends Statement { "case " + this.hashCode + ":(" + this.string + ")\n"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ } } - + /* + * With multi constant case statements, the number of case statements (hence branch labels) + * and number of constants (hence hashcode labels) could be different. For e.g: + + switch(s) { + case "FB", "c": + System.out.println("A/C"); + break; + case "Ea": + System.out.println("B"); + break; + + With the above code, we will have + 2 branch labels for FB and c + 3 stringCases for FB, c and Ea + 2 hashCodeCaseLabels one for FB, Ea and one for c + + Should produce something like this: + lookupswitch { // 2 + 99: 32 + 2236: 44 + default: 87 + + "FB" and "Ea" producing the same hashcode values, but still belonging in different case statements. + First, produce the two branch labels pertaining to the case statements + And the three string cases and use the this.constMapping to get the correct branch label. + */ final boolean hasCases = this.caseCount != 0; - - StringSwitchCase [] stringCases = new StringSwitchCase[this.caseCount]; // may have to shrink later if multiple strings hash to same code. + int constSize = hasCases ? this.stringConstants.length : 0; BranchLabel[] sourceCaseLabels = new BranchLabel[this.caseCount]; - CaseLabel [] hashCodeCaseLabels = new CaseLabel[this.caseCount]; - this.constants = new int[this.caseCount]; // hashCode() values. for (int i = 0, max = this.caseCount; i < max; i++) { this.cases[i].targetLabel = (sourceCaseLabels[i] = new BranchLabel(codeStream)); // A branch label, not a case label. sourceCaseLabels[i].tagBits |= BranchLabel.USED; - stringCases[i] = new StringSwitchCase(this.stringConstants[i].hashCode(), this.stringConstants[i], sourceCaseLabels[i]); + } + StringSwitchCase [] stringCases = new StringSwitchCase[constSize]; // may have to shrink later if multiple strings hash to same code. + CaseLabel [] hashCodeCaseLabels = new CaseLabel[constSize]; + this.constants = new int[constSize]; // hashCode() values. + for (int i = 0; i < constSize; i++) { + stringCases[i] = new StringSwitchCase(this.stringConstants[i].hashCode(), this.stringConstants[i], sourceCaseLabels[this.constMapping[i]]); hashCodeCaseLabels[i] = new CaseLabel(codeStream); hashCodeCaseLabels[i].tagBits |= BranchLabel.USED; - } Arrays.sort(stringCases); int uniqHashCount = 0; int lastHashCode = 0; - for (int i = 0, length = this.caseCount; i < length; ++i) { + for (int i = 0, length = constSize; i < length; ++i) { int hashCode = stringCases[i].hashCode; if (i == 0 || hashCode != lastHashCode) { lastHashCode = this.constants[uniqHashCount++] = hashCode; } } - if (uniqHashCount != this.caseCount) { // multiple keys hashed to the same value. + if (uniqHashCount != constSize) { // multiple keys hashed to the same value. System.arraycopy(this.constants, 0, this.constants = new int[uniqHashCount], 0, uniqHashCount); System.arraycopy(hashCodeCaseLabels, 0, hashCodeCaseLabels = new CaseLabel[uniqHashCount], 0, uniqHashCount); } @@ -252,7 +319,7 @@ public class SwitchStatement extends Statement { codeStream.invokeStringHashCode(); if (hasCases) { codeStream.lookupswitch(defaultCaseLabel, this.constants, sortedIndexes, hashCodeCaseLabels); - for (int i = 0, j = 0, max = this.caseCount; i < max; i++) { + for (int i = 0, j = 0, max = constSize; i < max; i++) { int hashCode = stringCases[i].hashCode; if (i == 0 || hashCode != lastHashCode) { lastHashCode = hashCode; @@ -291,7 +358,7 @@ public class SwitchStatement extends Statement { } } } - statement.generateCode(this.scope, codeStream); + statementGenerateCode(currentScope, codeStream, statement); } } @@ -312,6 +379,13 @@ public class SwitchStatement extends Statement { defaultCaseLabel.place(); defaultBranchLabel.place(); } + if (this.expectedType() != null) { + TypeBinding expectedType = this.expectedType().erasure(); + boolean optimizedGoto = codeStream.lastAbruptCompletion == -1; + // if the last bytecode was an optimized goto (value is already on the stack) or an enum switch without default case, then we need to adjust the + // stack depth to reflect the fact that there is an value on the stack (return type of the switch expression) + codeStream.recordExpressionType(expectedType, optimizedGoto ? 0 : 1, optimizedGoto); + } codeStream.recordPositionsFrom(pc, this.sourceStart); } finally { if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block @@ -339,6 +413,7 @@ public class SwitchStatement extends Statement { // prepare the labels and constants this.breakLabel.initialize(codeStream); + int constantCount = this.constants == null ? 0 : this.constants.length; CaseLabel[] caseLabels = new CaseLabel[this.caseCount]; for (int i = 0, max = this.caseCount; i < max; i++) { this.cases[i].targetLabel = (caseLabels[i] = new CaseLabel(codeStream)); @@ -351,19 +426,20 @@ public class SwitchStatement extends Statement { this.defaultCase.targetLabel = defaultLabel; } - final TypeBinding resolvedType = this.expression.resolvedType; + final TypeBinding resolvedType1 = this.expression.resolvedType; boolean valueRequired = false; - if (resolvedType.isEnum()) { + if (resolvedType1.isEnum()) { // go through the translation table codeStream.invoke(Opcodes.OPC_invokestatic, this.synthetic, null /* default declaringClass */); this.expression.generateCode(currentScope, codeStream, true); // get enum constant ordinal() - codeStream.invokeEnumOrdinal(resolvedType.constantPoolName()); + codeStream.invokeEnumOrdinal(resolvedType1.constantPoolName()); codeStream.iaload(); if (!hasCases) { // we can get rid of the generated ordinal value codeStream.pop(); } + valueRequired = hasCases; } else { valueRequired = this.expression.constant == Constant.NotAConstant || hasCases; // generate expression @@ -371,18 +447,18 @@ public class SwitchStatement extends Statement { } // generate the appropriate switch table/lookup bytecode if (hasCases) { - int[] sortedIndexes = new int[this.caseCount]; + int[] sortedIndexes = new int[constantCount]; // we sort the keys to be able to generate the code for tableswitch or lookupswitch - for (int i = 0; i < this.caseCount; i++) { + for (int i = 0; i < constantCount; i++) { sortedIndexes[i] = i; } int[] localKeysCopy; - System.arraycopy(this.constants, 0, (localKeysCopy = new int[this.caseCount]), 0, this.caseCount); - CodeStream.sort(localKeysCopy, 0, this.caseCount - 1, sortedIndexes); + System.arraycopy(this.constants, 0, (localKeysCopy = new int[constantCount]), 0, constantCount); + CodeStream.sort(localKeysCopy, 0, constantCount - 1, sortedIndexes); - int max = localKeysCopy[this.caseCount - 1]; + int max = localKeysCopy[constantCount - 1]; int min = localKeysCopy[0]; - if ((long) (this.caseCount * 2.5) > ((long) max - (long) min)) { + if ((long) (constantCount * 2.5) > ((long) max - (long) min)) { // work-around 1.3 VM bug, if max>0x7FFF0000, must use lookup bytecode // see http://dev.eclipse.org/bugs/show_bug.cgi?id=21557 @@ -396,6 +472,7 @@ public class SwitchStatement extends Statement { max, this.constants, sortedIndexes, + this.constMapping, caseLabels); } } else { @@ -411,7 +488,7 @@ public class SwitchStatement extends Statement { if (this.statements != null) { for (int i = 0, maxCases = this.statements.length; i < maxCases; i++) { Statement statement = this.statements[i]; - if ((caseIndex < this.caseCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case + if ((caseIndex < constantCount) && (statement == this.cases[caseIndex])) { // statements[i] is a case this.scope.enclosingCase = this.cases[caseIndex]; // record entering in a switch case block if (this.preSwitchInitStateIndex != -1) { codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex); @@ -425,9 +502,30 @@ public class SwitchStatement extends Statement { } } } - statement.generateCode(this.scope, codeStream); + statementGenerateCode(currentScope, codeStream, statement); } } + boolean enumInSwitchExpression = resolvedType1.isEnum() && this instanceof SwitchExpression; + boolean isEnumSwitchWithoutDefaultCase = this.defaultCase == null && enumInSwitchExpression; + if (isEnumSwitchWithoutDefaultCase) { + // we want to force an line number entry to get an end position after the switch statement + if (this.preSwitchInitStateIndex != -1) { + codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.preSwitchInitStateIndex); + } + defaultLabel.place(); + /* a default case is not needed for enum if all enum values are used in the switch expression + * we need to handle the default case to throw an error (IncompatibleClassChangeError) in order + * to make the stack map consistent. All cases will return a value on the stack except the missing default + * case. + * There is no returned value for the default case so we handle it with an exception thrown. An + * IllegalClassChangeError seems legitimate as this would mean the enum type has been recompiled with more + * enum constants and the class that is using the switch on the enum has not been recompiled + */ + codeStream.newJavaLangIncompatibleClassChangeError(); + codeStream.dup(); + codeStream.invokeJavaLangIncompatibleClassChangeErrorDefaultConstructor(); + codeStream.athrow(); + } // May loose some local variable initializations : affecting the local variable attributes if (this.mergedInitStateIndex != -1) { codeStream.removeNotDefinitelyAssignedVariables(currentScope, this.mergedInitStateIndex); @@ -438,18 +536,35 @@ public class SwitchStatement extends Statement { } // place the trailing labels (for break and default case) this.breakLabel.place(); - if (this.defaultCase == null) { + if (this.defaultCase == null && !enumInSwitchExpression) { // we want to force an line number entry to get an end position after the switch statement codeStream.recordPositionsFrom(codeStream.position, this.sourceEnd, true); defaultLabel.place(); } + if (this instanceof SwitchExpression) { + TypeBinding switchResolveType = this.resolvedType; + if (this.expectedType() != null) { + switchResolveType = this.expectedType().erasure(); + } + boolean optimizedGoto = codeStream.lastAbruptCompletion == -1; + // if the last bytecode was an optimized goto (value is already on the stack) or an enum switch without default case, then we need to adjust the + // stack depth to reflect the fact that there is an value on the stack (return type of the switch expression) + codeStream.recordExpressionType(switchResolveType, optimizedGoto ? 0 : 1, optimizedGoto || isEnumSwitchWithoutDefaultCase); + } codeStream.recordPositionsFrom(pc, this.sourceStart); } finally { if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block } } + protected void statementGenerateCode(BlockScope currentScope, CodeStream codeStream, Statement statement) { + statement.generateCode(this.scope, codeStream); + } @Override + public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { + generateCode(currentScope, codeStream); // redirecting to statement part + } + @Override public StringBuffer printStatement(int indent, StringBuffer output) { printIndent(indent, output).append("switch ("); //$NON-NLS-1$ @@ -519,32 +634,52 @@ public class SwitchStatement extends Statement { this.cases = new CaseStatement[length = this.statements.length]; if (!isStringSwitch) { this.constants = new int[length]; + this.constMapping = new int[length]; } else { this.stringConstants = new String[length]; + this.constMapping = new int[length]; } int counter = 0; for (int i = 0; i < length; i++) { - Constant constant; + Constant[] constantsList; final Statement statement = this.statements[i]; - if ((constant = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstant) { - if (!isStringSwitch) { - int key = constant.intValue(); - //----check for duplicate case statement------------ - for (int j = 0; j < counter; j++) { - if (this.constants[j] == key) { - reportDuplicateCase((CaseStatement) statement, this.cases[j], length); + if (!(statement instanceof CaseStatement)) { + statement.resolve(this.scope); + continue; + } + if ((constantsList = statement.resolveCase(this.scope, expressionType, this)) != Constant.NotAConstantList) { + for (Constant con : constantsList) { + if (con == Constant.NotAConstant) + continue; + if (!isStringSwitch) { + int key = con.intValue(); + //----check for duplicate case statement------------ + for (int j = 0; j < counter; j++) { + if (this.constants[j] == key) { + reportDuplicateCase((CaseStatement) statement, this.cases[j], length); + } } - } - this.constants[counter++] = key; - } else { - String key = constant.stringValue(); - //----check for duplicate case statement------------ - for (int j = 0; j < counter; j++) { - if (this.stringConstants[j].equals(key)) { - reportDuplicateCase((CaseStatement) statement, this.cases[j], length); + if (this.constants.length == counter) { + System.arraycopy(this.constants, 0, this.constants = new int[counter+1], 0, counter); + System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter+1], 0, counter); + } + this.constants[counter] = key; + this.constMapping[counter++] = this.caseCount - 1; + } else { + String key = con.stringValue(); + //----check for duplicate case statement------------ + for (int j = 0; j < counter; j++) { + if (this.stringConstants[j].equals(key)) { + reportDuplicateCase((CaseStatement) statement, this.cases[j], length); + } + } + if (this.stringConstants.length == counter) { + System.arraycopy(this.stringConstants, 0, this.stringConstants = new String[counter+1], 0, counter); + System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter+1], 0, counter); } + this.stringConstants[counter] = key; + this.constMapping[counter++] = this.caseCount - 1; } - this.stringConstants[counter++] = key; } } } @@ -554,15 +689,17 @@ public class SwitchStatement extends Statement { } else { System.arraycopy(this.stringConstants, 0, this.stringConstants = new String[counter], 0, counter); } + System.arraycopy(this.constMapping, 0, this.constMapping = new int[counter], 0, counter); } } else { if ((this.bits & UndocumentedEmptyBlock) != 0) { upperScope.problemReporter().undocumentedEmptyBlock(this.blockStart, this.sourceEnd); } } + reportMixingCaseTypes(); // check default case for all kinds of switch: if (this.defaultCase == null) { - if (compilerOptions.getSeverity(CompilerOptions.MissingDefaultCase) == ProblemSeverities.Ignore) { + if (ignoreMissingDefaultCase(compilerOptions, isEnumSwitch)) { if (isEnumSwitch) { upperScope.methodScope().hasMissingSwitchDefault = true; } @@ -574,21 +711,21 @@ public class SwitchStatement extends Statement { if (isEnumSwitch && compilerOptions.complianceLevel >= ClassFileConstants.JDK1_5) { if (this.defaultCase == null || compilerOptions.reportMissingEnumCaseDespiteDefault) { int constantCount = this.constants == null ? 0 : this.constants.length; // could be null if no case statement - if (constantCount == this.caseCount - && this.caseCount != ((ReferenceBinding)expressionType).enumConstantCount()) { + if (constantCount >= this.caseCount + && constantCount != ((ReferenceBinding)expressionType).enumConstantCount()) { FieldBinding[] enumFields = ((ReferenceBinding)expressionType.erasure()).fields(); for (int i = 0, max = enumFields.length; i <max; i++) { FieldBinding enumConstant = enumFields[i]; if ((enumConstant.modifiers & ClassFileConstants.AccEnum) == 0) continue; findConstant : { - for (int j = 0; j < this.caseCount; j++) { + for (int j = 0; j < constantCount; j++) { if ((enumConstant.id + 1) == this.constants[j]) // zero should not be returned see bug 141810 break findConstant; } // enum constant did not get referenced from switch boolean suppress = (this.defaultCase != null && (this.defaultCase.bits & DocumentedCasesOmitted) != 0); if (!suppress) { - upperScope.problemReporter().missingEnumConstantCase(this, enumConstant); + reportMissingEnumConstantCase(upperScope, enumConstant); } } } @@ -599,7 +736,29 @@ public class SwitchStatement extends Statement { if (this.scope != null) this.scope.enclosingCase = null; // no longer inside switch case block } } + protected void reportMissingEnumConstantCase(BlockScope upperScope, FieldBinding enumConstant) { + upperScope.problemReporter().missingEnumConstantCase(this, enumConstant); + } + protected boolean ignoreMissingDefaultCase(CompilerOptions compilerOptions, boolean isEnumSwitch) { + return compilerOptions.getSeverity(CompilerOptions.MissingDefaultCase) == ProblemSeverities.Ignore; + } + private void reportMixingCaseTypes() { + if (this.caseCount == 0) { + this.switchLabeledRules = this.defaultCase != null ? this.defaultCase.isExpr : this.switchLabeledRules; + return; + } + boolean isExpr = this.switchLabeledRules = this.cases[0].isExpr; + 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 CaseStatement duplicate, final CaseStatement original, int length) { if (this.duplicateCaseStatements == null) { this.scope.problemReporter().duplicateCase(original); @@ -675,4 +834,9 @@ public class SwitchStatement extends Statement { } return false; } + + @Override + public StringBuffer printExpression(int indent, StringBuffer output) { + return printStatement(indent, output); + } } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java index bfcdf5e888..8093adc10c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/classfmt/ClassFileConstants.java @@ -6,6 +6,10 @@ * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -128,9 +132,10 @@ public interface ClassFileConstants { int MAJOR_VERSION_9 = 53; int MAJOR_VERSION_10 = 54; int MAJOR_VERSION_11 = 55; + int MAJOR_VERSION_12 = 56; int MAJOR_VERSION_0 = 44; - int MAJOR_LATEST_VERSION = MAJOR_VERSION_11; + int MAJOR_LATEST_VERSION = MAJOR_VERSION_12; int MINOR_VERSION_0 = 0; int MINOR_VERSION_1 = 1; @@ -152,6 +157,7 @@ public interface ClassFileConstants { long JDK9 = ((long)ClassFileConstants.MAJOR_VERSION_9 << 16) + ClassFileConstants.MINOR_VERSION_0; long JDK10 = ((long)ClassFileConstants.MAJOR_VERSION_10 << 16) + ClassFileConstants.MINOR_VERSION_0; long JDK11 = ((long)ClassFileConstants.MAJOR_VERSION_11 << 16) + ClassFileConstants.MINOR_VERSION_0; + long JDK12 = ((long)ClassFileConstants.MAJOR_VERSION_12 << 16) + ClassFileConstants.MINOR_VERSION_0; public static long getLatestJDKLevel() { return ((long)ClassFileConstants.MAJOR_LATEST_VERSION << 16) + ClassFileConstants.MINOR_VERSION_0; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java index 0c43198eea..5f4cc19307 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java @@ -4567,7 +4567,16 @@ public void invokeJavaLangAssertionErrorDefaultConstructor() { ConstantPool.Init, ConstantPool.DefaultConstructorSignature); } - +public void invokeJavaLangIncompatibleClassChangeErrorDefaultConstructor() { + // invokespecial: java.lang.IncompatibleClassChangeError.<init>()V + invoke( + Opcodes.OPC_invokespecial, + 1, // receiverAndArgsSize + 0, // return type size + ConstantPool.JavaLangIncompatibleClassChangeErrorConstantPoolName, + ConstantPool.Init, + ConstantPool.DefaultConstructorSignature); +} public void invokeJavaLangClassDesiredAssertionStatus() { // invokevirtual: java.lang.Class.desiredAssertionStatus()Z; invoke( @@ -6142,7 +6151,19 @@ public void newJavaLangError() { this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new; writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName)); } - +public void newJavaLangIncompatibleClassChangeError() { + // new: java.lang.Error + this.countLabels = 0; + this.stackDepth++; + if (this.stackDepth > this.stackMax) + this.stackMax = this.stackDepth; + if (this.classFileOffset + 2 >= this.bCodeStream.length) { + resizeByteArray(); + } + this.position++; + this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_new; + writeUnsignedShort(this.constantPool.literalIndexForType(ConstantPool.JavaLangIncompatibleClassChangeErrorConstantPoolName)); +} public void newNoClassDefFoundError() { // new: java.lang.NoClassDefFoundError this.countLabels = 0; @@ -6297,7 +6318,9 @@ public void record(LocalVariableBinding local) { public void recordExpressionType(TypeBinding typeBinding) { // nothing to do } - +public void recordExpressionType(TypeBinding typeBinding, int delta, boolean adjustStackDepth) { + // nothing to do +} public void recordPositionsFrom(int startPC, int sourcePos) { this.recordPositionsFrom(startPC, sourcePos, false); } @@ -6895,7 +6918,7 @@ public void swap() { this.bCodeStream[this.classFileOffset++] = Opcodes.OPC_swap; } -public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) { +public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, int[] mapping, CaseLabel[] casesLabel) { this.countLabels = 0; this.stackDepth--; int length = casesLabel.length; @@ -6926,7 +6949,7 @@ public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, i int index; int key = keys[index = sortedIndexes[j - low]]; if (key == i) { - casesLabel[index].branch(); + casesLabel[mapping[index]].branch(); j++; if (i == high) break; // if high is maxint, then avoids wrapping to minint. } else { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java index 276c999ed2..700a70daa5 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/ConstantPool.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -167,6 +167,7 @@ public class ConstantPool implements ClassFileConstants, TypeIds { public static final char[] JavaLangDoubleConstantPoolName = "java/lang/Double".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangEnumConstantPoolName = "java/lang/Enum".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangErrorConstantPoolName = "java/lang/Error".toCharArray(); //$NON-NLS-1$ + public static final char[] JavaLangIncompatibleClassChangeErrorConstantPoolName = "java/lang/IncompatibleClassChangeError".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangExceptionConstantPoolName = "java/lang/Exception".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangFloatConstantPoolName = "java/lang/Float".toCharArray(); //$NON-NLS-1$ public static final char[] JavaLangIntegerConstantPoolName = "java/lang/Integer".toCharArray(); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java index 039f188d76..f49b793159 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/codegen/StackMapFrameCodeStream.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2016 IBM Corporation and others. + * Copyright (c) 2006, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -91,10 +91,17 @@ public class StackMapFrameCodeStream extends CodeStream { StringBuffer buffer = new StringBuffer(); buffer.append('(').append(this.pc).append(',').append(this.delta); if (this.typeBinding != null) { - buffer - .append(',') - .append(this.typeBinding.qualifiedPackageName()) - .append(this.typeBinding.qualifiedSourceName()); + if (this.typeBinding.isBaseType()) { + buffer + .append(',') + .append(this.typeBinding.qualifiedSourceName()); + } else { + buffer + .append(',') + .append(this.typeBinding.qualifiedPackageName()) + .append('.') + .append(this.typeBinding.qualifiedSourceName()); + } } buffer.append(')'); return String.valueOf(buffer); @@ -226,6 +233,7 @@ public void addFramePosition(int pc) { public void optimizeBranch(int oldPosition, BranchLabel lbl) { super.optimizeBranch(oldPosition, lbl); removeFramePosition(oldPosition); + removeStackMapMarkers(oldPosition); } public void removeFramePosition(int pc) { Integer entry = Integer.valueOf(pc); @@ -237,6 +245,17 @@ public void removeFramePosition(int pc) { } } } +public void removeStackMapMarkers(int markerOldPosition) { + if (this.stackDepthMarkers != null) { + for (int i = this.stackDepthMarkers.size() - 1; i >= 0; i--) { + StackDepthMarker marker = (StackDepthMarker) this.stackDepthMarkers.get(i); + if (marker.pc == markerOldPosition) { + this.stackDepthMarkers.remove(i); + break; + } + } + } +} @Override public void addVariable(LocalVariableBinding localBinding) { if (localBinding.initializationPCs == null) { @@ -284,6 +303,26 @@ public void decrStackSize(int offset) { public void recordExpressionType(TypeBinding typeBinding) { addStackDepthMarker(this.position, 0, typeBinding); } +@Override +public void recordExpressionType(TypeBinding typeBinding, int delta, boolean adjustStackDepth) { + addStackDepthMarker(this.position, delta, typeBinding); + if (adjustStackDepth) { + // optimized goto + // the break label already adjusted the stack depth (-1 or -2 depending on the return type) + // we need to adjust back to what it was + switch(typeBinding.id) { + case TypeIds.T_long : + case TypeIds.T_double : + this.stackDepth+=2; + break; + case TypeIds.T_void : + break; + default : + this.stackDepth++; + break; + } + } +} /** * Macro for building a class descriptor object */ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java index 0aaaa13246..c23712a80a 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/CompilerOptions.java @@ -6,6 +6,10 @@ * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * SPDX-License-Identifier: EPL-2.0 * * Contributors: @@ -202,7 +206,8 @@ public class CompilerOptions { public static final String OPTION_ReportAPILeak = "org.eclipse.jdt.core.compiler.problem.APILeak"; //$NON-NLS-1$ public static final String OPTION_ReportUnstableAutoModuleName = "org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName"; //$NON-NLS-1$ - public static final String OPTION_EnablePreviews = "org.eclipse.jdt.core.compiler.problem.EnablePreviews"; //$NON-NLS-1$ + public static final String OPTION_EnablePreviews = "org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures"; //$NON-NLS-1$ + public static final String OPTION_ReportPreviewFeatures = "org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures"; //$NON-NLS-1$ /** * Possible values for configurable options @@ -224,6 +229,11 @@ public class CompilerOptions { public static final String VERSION_9 = "9"; //$NON-NLS-1$ public static final String VERSION_10 = "10"; //$NON-NLS-1$ public static final String VERSION_11 = "11"; //$NON-NLS-1$ + public static final String VERSION_12 = "12"; //$NON-NLS-1$ + /* + * Note: Whenever a new version is added, make sure getLatestVersion() + * is updated with it. + */ public static final String ERROR = "error"; //$NON-NLS-1$ public static final String WARNING = "warning"; //$NON-NLS-1$ public static final String INFO = "info"; //$NON-NLS-1$ @@ -333,8 +343,7 @@ public class CompilerOptions { public static final int UsingTerminallyDeprecatedAPI = IrritantSet.GROUP2 | ASTNode.Bit24; public static final int APILeak = IrritantSet.GROUP2 | ASTNode.Bit25; public static final int UnstableAutoModuleName = IrritantSet.GROUP2 | ASTNode.Bit26; - // Dummy feature, but - //public static final int DummyPreviewFeatureWarning = IrritantSet.GROUP2 | ASTNode.Bit27; + public static final int PreviewFeatureUsed = IrritantSet.GROUP2 | ASTNode.Bit27; // Severity level for handlers @@ -583,6 +592,12 @@ public class CompilerOptions { } /** + * Return the latest Java language version supported by the Eclipse compiler + */ + public static String getLatestVersion() { + return VERSION_12; + } + /** * Return the most specific option key controlling this irritant. Note that in some case, some irritant is controlled by * other master options (e.g. javadoc, deprecation, etc.). * This information is intended for grouping purpose (several problems governed by a rule) @@ -758,6 +773,8 @@ public class CompilerOptions { return OPTION_ReportAPILeak; case UnstableAutoModuleName: return OPTION_ReportUnstableAutoModuleName; + case PreviewFeatureUsed: + return OPTION_ReportPreviewFeatures; } return null; } @@ -998,6 +1015,7 @@ public class CompilerOptions { OPTION_ReportUnlikelyCollectionMethodArgumentType, OPTION_ReportUnlikelyEqualsArgumentType, OPTION_ReportAPILeak, + OPTION_ReportPreviewFeatures }; return result; } @@ -1099,8 +1117,8 @@ public class CompilerOptions { return "exports"; //$NON-NLS-1$ case UnstableAutoModuleName: return "module"; //$NON-NLS-1$ - //case DummyPreviewFeatureWarning: - // return "preview"; //$NON-NLS-1$ + case PreviewFeatureUsed: + return "preview"; //$NON-NLS-1$ } return null; } @@ -1351,6 +1369,7 @@ public class CompilerOptions { optionsMap.put(OPTION_ReportAPILeak, getSeverityString(APILeak)); optionsMap.put(OPTION_ReportUnstableAutoModuleName, getSeverityString(UnstableAutoModuleName)); optionsMap.put(OPTION_EnablePreviews, this.enablePreviewFeatures ? ENABLED : DISABLED); + optionsMap.put(OPTION_ReportPreviewFeatures, getSeverityString(PreviewFeatureUsed)); return optionsMap; } @@ -2070,6 +2089,8 @@ public class CompilerOptions { this.enablePreviewFeatures = false; } } + if ((optionValue = optionsMap.get(OPTION_ReportPreviewFeatures)) != null) + updateSeverity(PreviewFeatureUsed, optionValue); } private String[] stringToNameList(String optionValue) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java index 3cda404aa0..29a45a3928 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/Constant.java @@ -21,6 +21,7 @@ import org.eclipse.jdt.internal.compiler.util.Messages; public abstract class Constant implements TypeIds, OperatorIds { public static final Constant NotAConstant = DoubleConstant.fromValue(Double.NaN); + public static final Constant[] NotAConstantList = new Constant[] {DoubleConstant.fromValue(Double.NaN)}; public boolean booleanValue() { throw new ShouldNotImplement(Messages.bind(Messages.constant_cannotCastedInto, new String[] { typeName(), "boolean" })); //$NON-NLS-1$ diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java index 735f553600..a12103c4ab 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/impl/IrritantSet.java @@ -77,7 +77,7 @@ public class IrritantSet { public static final IrritantSet MODULE = new IrritantSet(CompilerOptions.UnstableAutoModuleName); public static final IrritantSet JAVADOC = new IrritantSet(CompilerOptions.InvalidJavadoc); - public static final IrritantSet PREVIEW = new IrritantSet(0); + public static final IrritantSet PREVIEW = new IrritantSet(CompilerOptions.PreviewFeatureUsed); public static final IrritantSet COMPILER_DEFAULT_ERRORS = new IrritantSet(0); // no optional error by default public static final IrritantSet COMPILER_DEFAULT_WARNINGS = new IrritantSet(0); // see static initializer below public static final IrritantSet COMPILER_DEFAULT_INFOS = new IrritantSet(0); // As of now, no default values @@ -135,7 +135,8 @@ public class IrritantSet { |CompilerOptions.UnlikelyCollectionMethodArgumentType |CompilerOptions.UsingTerminallyDeprecatedAPI |CompilerOptions.APILeak - |CompilerOptions.UnstableAutoModuleName); + |CompilerOptions.UnstableAutoModuleName + |CompilerOptions.PreviewFeatureUsed); // default errors IF AnnotationBasedNullAnalysis is enabled: COMPILER_DEFAULT_ERRORS.set( CompilerOptions.NullSpecViolation @@ -190,7 +191,6 @@ public class IrritantSet { UNLIKELY_ARGUMENT_TYPE .set(CompilerOptions.UnlikelyEqualsArgumentType); - //PREVIEW.set(CompilerOptions.DummyPreviewFeatureWarning); } // Internal state diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java index 75717b1937..cb9dd27c90 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2017 GK Software AG. + * Copyright (c) 2013, 2019 GK Software AG. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * Lars Vogel <Lars.Vogel@vogella.com> - Contributions for @@ -30,6 +34,7 @@ import org.eclipse.jdt.internal.compiler.ast.Invocation; import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression; +import org.eclipse.jdt.internal.compiler.ast.SwitchExpression; import org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18.SuspendedInferenceRecord; @@ -144,6 +149,14 @@ class ConstraintExpressionFormula extends ConstraintFormula { new ConstraintExpressionFormula(conditional.valueIfTrue, this.right, this.relation, this.isSoft), new ConstraintExpressionFormula(conditional.valueIfFalse, this.right, this.relation, this.isSoft) }; + } else if (this.left instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) this.left; + ConstraintFormula[] cfs = new ConstraintFormula[se.resultExpressions.size()]; + int i = 0; + for (Expression re : se.resultExpressions) { + cfs[i++] = new ConstraintExpressionFormula(re, this.right, this.relation, this.isSoft); + } + return cfs; } else if (this.left instanceof LambdaExpression) { LambdaExpression lambda = (LambdaExpression) this.left; BlockScope scope = lambda.enclosingScope; @@ -522,6 +535,13 @@ class ConstraintExpressionFormula extends ConstraintFormula { variables.addAll(new ConstraintExpressionFormula(expr.valueIfTrue, this.right, COMPATIBLE).inputVariables(context)); variables.addAll(new ConstraintExpressionFormula(expr.valueIfFalse, this.right, COMPATIBLE).inputVariables(context)); return variables; + } else if (this.left instanceof SwitchExpression && this.left.isPolyExpression()) { + SwitchExpression expr = (SwitchExpression) this.left; + Set<InferenceVariable> variables = new HashSet<>(); + for (Expression re : expr.resultExpressions) { + variables.addAll(new ConstraintExpressionFormula(re, this.right, COMPATIBLE).inputVariables(context)); + } + return variables; } return EMPTY_VARIABLE_LIST; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java index f65f5f4319..563081f03a 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013, 2018 GK Software AG, and others. + * Copyright (c) 2013, 2019 GK Software AG, and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * Stephan Herrmann - initial API and implementation * IBM Corporation - Bug fixes @@ -32,6 +36,7 @@ import org.eclipse.jdt.internal.compiler.ast.FunctionalExpression; import org.eclipse.jdt.internal.compiler.ast.Invocation; import org.eclipse.jdt.internal.compiler.ast.LambdaExpression; import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression; +import org.eclipse.jdt.internal.compiler.ast.SwitchExpression; import org.eclipse.jdt.internal.compiler.ast.Wildcard; import org.eclipse.jdt.internal.compiler.lookup.TypeConstants.BoundCheckStatus; import org.eclipse.jdt.internal.compiler.util.Sorting; @@ -573,6 +578,15 @@ public class InferenceContext18 { if (addJDK_8153748ConstraintsFromExpression(ce.valueIfTrue, parameter, method, substitution) == ReductionResult.FALSE) return ReductionResult.FALSE; return addJDK_8153748ConstraintsFromExpression(ce.valueIfFalse, parameter, method, substitution); + } else if (argument instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) argument; + ReductionResult result = ReductionResult.FALSE; + for (Expression re : se.resultExpressions) { + result = addJDK_8153748ConstraintsFromExpression(re, parameter, method, substitution); + if (result == ReductionResult.FALSE) + break; + } + return result; } return null; } @@ -709,6 +723,13 @@ public class InferenceContext18 { ConditionalExpression ce = (ConditionalExpression) expri; return addConstraintsToC_OneExpr(ce.valueIfTrue, c, fsi, substF, method) && addConstraintsToC_OneExpr(ce.valueIfFalse, c, fsi, substF, method); + } else if (expri instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) expri; + for (Expression re : se.resultExpressions) { + if (!addConstraintsToC_OneExpr(re, c, fsi, substF, method)) + return false; + } + return true; } return true; } @@ -950,6 +971,13 @@ public class InferenceContext18 { } else if (expri instanceof ConditionalExpression) { ConditionalExpression cond = (ConditionalExpression) expri; return checkExpression(cond.valueIfTrue, u, r1, v, r2) && checkExpression(cond.valueIfFalse, u, r1, v, r2); + } else if (expri instanceof SwitchExpression) { + SwitchExpression se = (SwitchExpression) expri; + for (Expression re : se.resultExpressions) { + if (!checkExpression(re, u, r1, v, r2)) + return false; + } + return true; } else { return false; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java index 3817b6db1a..373a684717 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocParser.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -640,6 +644,9 @@ public class JavadocParser extends AbstractCommentParser { } else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName, 0, length)) { this.tagValue = TAG_SINCE_VALUE; this.tagWaitingForDescription = this.tagValue; + } else if (length == TAG_SYSTEM_PROPERTY_LENGTH && CharOperation.equals(TAG_SYSTEM_PROPERTY, tagName, 0, length)) { + this.tagValue = TAG_SYSTEM_PROPERTY_VALUE; + this.tagWaitingForDescription = this.tagValue; } break; case 't': diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java index 10f540e36f..1e92374e21 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/JavadocTagConstants.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2018 IBM Corporation and others. + * Copyright (c) 2000, 2019 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -44,6 +48,7 @@ public interface JavadocTagConstants { public static final char[] TAG_SINCE = "since".toCharArray(); //$NON-NLS-1$ public static final char[] TAG_VERSION = "version".toCharArray(); //$NON-NLS-1$ public static final char[] TAG_CATEGORY = "category".toCharArray(); //$NON-NLS-1$ + public static final char[] TAG_SYSTEM_PROPERTY = "systemProperty".toCharArray(); //$NON-NLS-1$ public static final char[] TAG_USES = "uses".toCharArray(); //$NON-NLS-1$ public static final char[] TAG_PROVIDES = "provides".toCharArray(); //$NON-NLS-1$ @@ -68,6 +73,7 @@ public interface JavadocTagConstants { public static final int TAG_CODE_LENGTH = TAG_CODE.length; public static final int TAG_LITERAL_LENGTH = TAG_LITERAL.length; public static final int TAG_DOC_ROOT_LENGTH = TAG_DOC_ROOT.length; + public static final int TAG_SYSTEM_PROPERTY_LENGTH = TAG_SYSTEM_PROPERTY.length; public static final int TAG_USES_LENGTH = TAG_USES.length; public static final int TAG_PROVIDES_LENGTH = TAG_PROVIDES.length; @@ -93,6 +99,7 @@ public interface JavadocTagConstants { public static final int TAG_CODE_VALUE = 18; public static final int TAG_LITERAL_VALUE = 19; public static final int TAG_DOC_ROOT_VALUE = 20; + public static final int TAG_SYSTEM_PROPERTY_VALUE=21; public static final int TAG_USES_VALUE=21; public static final int TAG_PROVIDES_VALUE=22; public static final int TAG_OTHERS_VALUE = 100; @@ -119,6 +126,7 @@ public interface JavadocTagConstants { TAG_CODE, /* 18 */ TAG_LITERAL, /* 19 */ TAG_DOC_ROOT, /* 20 */ + TAG_SYSTEM_PROPERTY /* 21 */ }; // tags expected positions @@ -162,6 +170,8 @@ public interface JavadocTagConstants { // since 10 {}, // since 11 + {}, + //since 12 {} }; public static final char[][][] INLINE_TAGS = { @@ -188,7 +198,9 @@ public interface JavadocTagConstants { // since 10 {}, // since 11 - {} + {}, + //since 12 + {TAG_SYSTEM_PROPERTY} }; public final static int INLINE_TAGS_LENGTH = INLINE_TAGS.length; public final static int BLOCK_TAGS_LENGTH = BLOCK_TAGS.length; @@ -197,7 +209,6 @@ public interface JavadocTagConstants { public final static short TAG_TYPE_NONE = 0; public final static short TAG_TYPE_INLINE = 1; public final static short TAG_TYPE_BLOCK = 2; - public static final short[] JAVADOC_TAG_TYPE = { TAG_TYPE_NONE, // NO_TAG_VALUE = 0; TAG_TYPE_BLOCK, // TAG_DEPRECATED_VALUE = 1; @@ -219,7 +230,8 @@ public interface JavadocTagConstants { TAG_TYPE_BLOCK, // TAG_VERSION_VALUE = 17; TAG_TYPE_INLINE, // TAG_CODE_VALUE = 18; TAG_TYPE_INLINE, // TAG_LITERAL_VALUE = 19; - TAG_TYPE_INLINE // TAG_DOC_ROOT_VALUE = 20; + TAG_TYPE_INLINE, // TAG_DOC_ROOT_VALUE = 20; + TAG_TYPE_INLINE // TAG_DOC_ROOT_VALUE = 21 }; /* * Tags usage @@ -235,6 +247,7 @@ public interface JavadocTagConstants { TAG_LINKPLAIN, TAG_DOC_ROOT, TAG_VALUE, + TAG_SYSTEM_PROPERTY }; public static final char[][] COMPILATION_UNIT_TAGS = {}; public static final char[][] CLASS_TAGS = { @@ -251,7 +264,8 @@ public interface JavadocTagConstants { TAG_DOC_ROOT, TAG_VALUE, TAG_CODE, - TAG_LITERAL + TAG_LITERAL, + TAG_SYSTEM_PROPERTY }; public static final char[][] FIELD_TAGS = { TAG_SEE, @@ -265,7 +279,8 @@ public interface JavadocTagConstants { TAG_DOC_ROOT, TAG_VALUE, TAG_CODE, - TAG_LITERAL + TAG_LITERAL, + TAG_SYSTEM_PROPERTY }; public static final char[][] METHOD_TAGS = { TAG_SEE, @@ -283,7 +298,8 @@ public interface JavadocTagConstants { TAG_DOC_ROOT, TAG_VALUE, TAG_CODE, - TAG_LITERAL + TAG_LITERAL, + TAG_SYSTEM_PROPERTY }; public static final char[][] MODULE_TAGS = { TAG_SEE, diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java index a9e213965a..63c98f070d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Parser.java @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Tom Tromey - patch for readTable(String) as described in http://bugs.eclipse.org/bugs/show_bug.cgi?id=32196 @@ -52,6 +56,7 @@ import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.codegen.ConstantPool; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; +import org.eclipse.jdt.internal.compiler.impl.IrritantSet; import org.eclipse.jdt.internal.compiler.impl.ReferenceContext; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; @@ -941,6 +946,7 @@ protected int valueLambdaNestDepth = -1; private int stateStackLengthStack[] = new int[0]; protected boolean parsingJava8Plus; protected boolean parsingJava9Plus; +protected boolean parsingJava12Plus; protected boolean parsingJava11Plus; protected int unstackedAct = ERROR_ACTION; private boolean haltOnSyntaxError = false; @@ -960,6 +966,7 @@ public Parser(ProblemReporter problemReporter, boolean optimizeStringLiterals) { initializeScanner(); this.parsingJava8Plus = this.options.sourceLevel >= ClassFileConstants.JDK1_8; this.parsingJava9Plus = this.options.sourceLevel >= ClassFileConstants.JDK9; + this.parsingJava12Plus = this.options.sourceLevel >= ClassFileConstants.JDK12; this.parsingJava11Plus = this.options.sourceLevel >= ClassFileConstants.JDK11; this.astLengthStack = new int[50]; this.expressionLengthStack = new int[30]; @@ -2198,10 +2205,30 @@ protected void consumeBlockStatements() { concatNodeLists(); } protected void consumeCaseLabel() { - // SwitchLabel ::= 'case' ConstantExpression ':' - this.expressionLengthPtr--; - Expression expression = this.expressionStack[this.expressionPtr--]; - CaseStatement caseStatement = new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]); +// // SwitchLabel ::= 'case' ConstantExpression ':' +// this.expressionLengthPtr--; +// Expression expression = this.expressionStack[this.expressionPtr--]; +// CaseStatement caseStatement = new CaseStatement(expression, expression.sourceEnd, this.intStack[this.intPtr--]); +// // Look for $fall-through$ tag in leading comment for case statement +// if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) { +// caseStatement.bits |= ASTNode.DocumentedFallthrough; +// } +// pushOnAstStack(caseStatement); + Expression[] constantExpressions = null; + int length = 0; + if ((length = this.expressionLengthStack[this.expressionLengthPtr--]) != 0) { + this.expressionPtr -= length; + System.arraycopy( + this.expressionStack, + this.expressionPtr + 1, + constantExpressions = new Expression[length], + 0, + length); + } else { + // TODO : ERROR + } + CaseStatement caseStatement = new CaseStatement(constantExpressions[0], constantExpressions[length - 1].sourceEnd, this.intStack[this.intPtr--]); + caseStatement.constantExpressions = constantExpressions; // Look for $fall-through$ tag in leading comment for case statement if (hasLeadingTagComment(FALL_THROUGH_TAG, caseStatement.sourceStart)) { caseStatement.bits |= ASTNode.DocumentedFallthrough; @@ -7167,1319 +7194,1359 @@ protected void consumeRule(int act) { consumeSwitchBlockStatements() ; break; - case 388 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); } //$NON-NLS-1$ + case 389 : if (DEBUG) { System.out.println("SwitchBlockStatement ::= SwitchLabels BlockStatements"); } //$NON-NLS-1$ consumeSwitchBlockStatement() ; break; - case 390 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); } //$NON-NLS-1$ + case 391 : if (DEBUG) { System.out.println("SwitchLabels ::= SwitchLabels SwitchLabel"); } //$NON-NLS-1$ consumeSwitchLabels() ; break; - case 391 : if (DEBUG) { System.out.println("SwitchLabel ::= case ConstantExpression COLON"); } //$NON-NLS-1$ + case 392 : if (DEBUG) { System.out.println("SwitchLabel ::= SwitchLabelCaseLhs COLON"); } //$NON-NLS-1$ consumeCaseLabel(); break; - case 392 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); } //$NON-NLS-1$ + case 393 : if (DEBUG) { System.out.println("SwitchLabel ::= default COLON"); } //$NON-NLS-1$ consumeDefaultLabel(); break; - case 393 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); } //$NON-NLS-1$ + case 396 : if (DEBUG) { System.out.println("SwitchExpression ::= switch LPAREN Expression RPAREN..."); } //$NON-NLS-1$ + consumeSwitchExpression() ; + break; + + case 399 : if (DEBUG) { System.out.println("SwitchLabeledRule ::= SwitchLabeledThrowStatement"); } //$NON-NLS-1$ + consumeSwitchLabeledRule(); + break; + + case 400 : if (DEBUG) { System.out.println("SwitchLabeledExpression ::= SwitchLabelExpr Expression"); } //$NON-NLS-1$ + consumeSwitchLabeledExpression(); + break; + + case 401 : if (DEBUG) { System.out.println("SwitchLabeledBlock ::= SwitchLabelExpr Block"); } //$NON-NLS-1$ + consumeSwitchLabeledBlock(); + break; + + case 402 : if (DEBUG) { System.out.println("SwitchLabeledThrowStatement ::= SwitchLabelExpr..."); } //$NON-NLS-1$ + consumeSwitchLabeledThrowStatement(); + break; + + case 403 : if (DEBUG) { System.out.println("SwitchLabelExpr ::= default ARROW"); } //$NON-NLS-1$ + consumeDefaultLabelExpr(); + break; + + case 404 : if (DEBUG) { System.out.println("SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr..."); } //$NON-NLS-1$ + consumeCaseLabelExpr(); + break; + + case 405 : if (DEBUG) { System.out.println("SwitchLabelCaseLhs ::= case ConstantExpressions"); } //$NON-NLS-1$ + consumeSwitchLabelCaseLhs(); + break; + + case 406 : if (DEBUG) { System.out.println("WhileStatement ::= while LPAREN Expression RPAREN..."); } //$NON-NLS-1$ consumeStatementWhile() ; break; - case 394 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); } //$NON-NLS-1$ + case 407 : if (DEBUG) { System.out.println("WhileStatementNoShortIf ::= while LPAREN Expression..."); } //$NON-NLS-1$ consumeStatementWhile() ; break; - case 395 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); } //$NON-NLS-1$ + case 408 : if (DEBUG) { System.out.println("DoStatement ::= do Statement while LPAREN Expression..."); } //$NON-NLS-1$ consumeStatementDo() ; break; - case 396 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); } //$NON-NLS-1$ + case 409 : if (DEBUG) { System.out.println("ForStatement ::= for LPAREN ForInitopt SEMICOLON..."); } //$NON-NLS-1$ consumeStatementFor() ; break; - case 397 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); } //$NON-NLS-1$ + case 410 : if (DEBUG) { System.out.println("ForStatementNoShortIf ::= for LPAREN ForInitopt..."); } //$NON-NLS-1$ consumeStatementFor() ; break; - case 398 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); } //$NON-NLS-1$ + case 411 : if (DEBUG) { System.out.println("ForInit ::= StatementExpressionList"); } //$NON-NLS-1$ consumeForInit() ; break; - case 402 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); } //$NON-NLS-1$ + case 415 : if (DEBUG) { System.out.println("StatementExpressionList ::= StatementExpressionList..."); } //$NON-NLS-1$ consumeStatementExpressionList() ; break; - case 403 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); } //$NON-NLS-1$ + case 416 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression SEMICOLON"); } //$NON-NLS-1$ consumeSimpleAssertStatement() ; break; - case 404 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); } //$NON-NLS-1$ + case 417 : if (DEBUG) { System.out.println("AssertStatement ::= assert Expression COLON Expression"); } //$NON-NLS-1$ consumeAssertStatement() ; break; - case 405 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); } //$NON-NLS-1$ + case 418 : if (DEBUG) { System.out.println("BreakStatement ::= break SEMICOLON"); } //$NON-NLS-1$ consumeStatementBreak() ; break; - case 406 : if (DEBUG) { System.out.println("BreakStatement ::= break Identifier SEMICOLON"); } //$NON-NLS-1$ + case 419 : if (DEBUG) { System.out.println("BreakStatement ::= break Expression SEMICOLON"); } //$NON-NLS-1$ consumeStatementBreakWithLabel() ; break; - case 407 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); } //$NON-NLS-1$ + case 420 : if (DEBUG) { System.out.println("ContinueStatement ::= continue SEMICOLON"); } //$NON-NLS-1$ consumeStatementContinue() ; break; - case 408 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); } //$NON-NLS-1$ + case 421 : if (DEBUG) { System.out.println("ContinueStatement ::= continue Identifier SEMICOLON"); } //$NON-NLS-1$ consumeStatementContinueWithLabel() ; break; - case 409 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); } //$NON-NLS-1$ + case 422 : if (DEBUG) { System.out.println("ReturnStatement ::= return Expressionopt SEMICOLON"); } //$NON-NLS-1$ consumeStatementReturn() ; break; - case 410 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); } //$NON-NLS-1$ + case 423 : if (DEBUG) { System.out.println("ThrowStatement ::= throw Expression SEMICOLON"); } //$NON-NLS-1$ consumeStatementThrow(); break; - case 411 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); } //$NON-NLS-1$ + case 424 : if (DEBUG) { System.out.println("ThrowExpression ::= throw Expression"); } //$NON-NLS-1$ + consumeThrowExpression() ; + break; + + case 425 : if (DEBUG) { System.out.println("SynchronizedStatement ::= OnlySynchronized LPAREN..."); } //$NON-NLS-1$ consumeStatementSynchronized(); break; - case 412 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); } //$NON-NLS-1$ + case 426 : if (DEBUG) { System.out.println("OnlySynchronized ::= synchronized"); } //$NON-NLS-1$ consumeOnlySynchronized(); break; - case 413 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); } //$NON-NLS-1$ + case 427 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catches"); } //$NON-NLS-1$ consumeStatementTry(false, false); break; - case 414 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); } //$NON-NLS-1$ + case 428 : if (DEBUG) { System.out.println("TryStatement ::= try TryBlock Catchesopt Finally"); } //$NON-NLS-1$ consumeStatementTry(true, false); break; - case 415 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ + case 429 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ consumeStatementTry(false, true); break; - case 416 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ + case 430 : if (DEBUG) { System.out.println("TryStatementWithResources ::= try ResourceSpecification"); } //$NON-NLS-1$ consumeStatementTry(true, true); break; - case 417 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); } //$NON-NLS-1$ + case 431 : if (DEBUG) { System.out.println("ResourceSpecification ::= LPAREN Resources ;opt RPAREN"); } //$NON-NLS-1$ consumeResourceSpecification(); break; - case 418 : if (DEBUG) { System.out.println(";opt ::="); } //$NON-NLS-1$ + case 432 : if (DEBUG) { System.out.println(";opt ::="); } //$NON-NLS-1$ consumeResourceOptionalTrailingSemiColon(false); break; - case 419 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); } //$NON-NLS-1$ + case 433 : if (DEBUG) { System.out.println(";opt ::= SEMICOLON"); } //$NON-NLS-1$ consumeResourceOptionalTrailingSemiColon(true); break; - case 420 : if (DEBUG) { System.out.println("Resources ::= Resource"); } //$NON-NLS-1$ + case 434 : if (DEBUG) { System.out.println("Resources ::= Resource"); } //$NON-NLS-1$ consumeSingleResource(); break; - case 421 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); } //$NON-NLS-1$ + case 435 : if (DEBUG) { System.out.println("Resources ::= Resources TrailingSemiColon Resource"); } //$NON-NLS-1$ consumeMultipleResources(); break; - case 422 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); } //$NON-NLS-1$ + case 436 : if (DEBUG) { System.out.println("TrailingSemiColon ::= SEMICOLON"); } //$NON-NLS-1$ consumeResourceOptionalTrailingSemiColon(true); break; - case 423 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); } //$NON-NLS-1$ + case 437 : if (DEBUG) { System.out.println("Resource ::= Type PushModifiers VariableDeclaratorId..."); } //$NON-NLS-1$ consumeResourceAsLocalVariableDeclaration(); break; - case 424 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); } //$NON-NLS-1$ + case 438 : if (DEBUG) { System.out.println("Resource ::= Modifiers Type PushRealModifiers..."); } //$NON-NLS-1$ consumeResourceAsLocalVariableDeclaration(); break; - case 425 : if (DEBUG) { System.out.println("Resource ::= Name"); } //$NON-NLS-1$ + case 439 : if (DEBUG) { System.out.println("Resource ::= Name"); } //$NON-NLS-1$ consumeResourceAsLocalVariable(); break; - case 426 : if (DEBUG) { System.out.println("Resource ::= FieldAccess"); } //$NON-NLS-1$ + case 440 : if (DEBUG) { System.out.println("Resource ::= FieldAccess"); } //$NON-NLS-1$ consumeResourceAsFieldAccess(); break; - case 428 : if (DEBUG) { System.out.println("ExitTryBlock ::="); } //$NON-NLS-1$ + case 442 : if (DEBUG) { System.out.println("ExitTryBlock ::="); } //$NON-NLS-1$ consumeExitTryBlock(); break; - case 430 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); } //$NON-NLS-1$ + case 444 : if (DEBUG) { System.out.println("Catches ::= Catches CatchClause"); } //$NON-NLS-1$ consumeCatches(); break; - case 431 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); } //$NON-NLS-1$ + case 445 : if (DEBUG) { System.out.println("CatchClause ::= catch LPAREN CatchFormalParameter RPAREN"); } //$NON-NLS-1$ consumeStatementCatch() ; break; - case 433 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); } //$NON-NLS-1$ + case 447 : if (DEBUG) { System.out.println("PushLPAREN ::= LPAREN"); } //$NON-NLS-1$ consumeLeftParen(); break; - case 434 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); } //$NON-NLS-1$ + case 448 : if (DEBUG) { System.out.println("PushRPAREN ::= RPAREN"); } //$NON-NLS-1$ consumeRightParen(); break; - case 439 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); } //$NON-NLS-1$ + case 453 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= this"); } //$NON-NLS-1$ consumePrimaryNoNewArrayThis(); break; - case 440 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); } //$NON-NLS-1$ + case 454 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Expression_NotName..."); } //$NON-NLS-1$ consumePrimaryNoNewArray(); break; - case 441 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); } //$NON-NLS-1$ + case 455 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PushLPAREN Name PushRPAREN"); } //$NON-NLS-1$ consumePrimaryNoNewArrayWithName(); break; - case 444 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); } //$NON-NLS-1$ + case 458 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT this"); } //$NON-NLS-1$ consumePrimaryNoNewArrayNameThis(); break; - case 445 : if (DEBUG) { System.out.println("QualifiedSuperReceiver ::= Name DOT super"); } //$NON-NLS-1$ + case 459 : if (DEBUG) { System.out.println("QualifiedSuperReceiver ::= Name DOT super"); } //$NON-NLS-1$ consumeQualifiedSuperReceiver(); break; - case 446 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); } //$NON-NLS-1$ + case 460 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name DOT class"); } //$NON-NLS-1$ consumePrimaryNoNewArrayName(); break; - case 447 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); } //$NON-NLS-1$ + case 461 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= Name Dims DOT class"); } //$NON-NLS-1$ consumePrimaryNoNewArrayArrayType(); break; - case 448 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); } //$NON-NLS-1$ + case 462 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType Dims DOT class"); } //$NON-NLS-1$ consumePrimaryNoNewArrayPrimitiveArrayType(); break; - case 449 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); } //$NON-NLS-1$ + case 463 : if (DEBUG) { System.out.println("PrimaryNoNewArray ::= PrimitiveType DOT class"); } //$NON-NLS-1$ consumePrimaryNoNewArrayPrimitiveType(); break; - case 455 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); } //$NON-NLS-1$ + case 469 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); } //$NON-NLS-1$ consumeReferenceExpressionTypeArgumentsAndTrunk(false); break; - case 456 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); } //$NON-NLS-1$ + case 470 : if (DEBUG) { System.out.println("ReferenceExpressionTypeArgumentsAndTrunk0 ::=..."); } //$NON-NLS-1$ consumeReferenceExpressionTypeArgumentsAndTrunk(true); break; - case 457 : if (DEBUG) { System.out.println("ReferenceExpression ::= PrimitiveType Dims COLON_COLON"); } //$NON-NLS-1$ + case 471 : if (DEBUG) { System.out.println("ReferenceExpression ::= PrimitiveType Dims COLON_COLON"); } //$NON-NLS-1$ consumeReferenceExpressionTypeForm(true); break; - case 458 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name Dimsopt COLON_COLON..."); } //$NON-NLS-1$ + case 472 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name Dimsopt COLON_COLON..."); } //$NON-NLS-1$ consumeReferenceExpressionTypeForm(false); break; - case 459 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name BeginTypeArguments..."); } //$NON-NLS-1$ + case 473 : if (DEBUG) { System.out.println("ReferenceExpression ::= Name BeginTypeArguments..."); } //$NON-NLS-1$ consumeReferenceExpressionGenericTypeForm(); break; - case 460 : if (DEBUG) { System.out.println("ReferenceExpression ::= Primary COLON_COLON..."); } //$NON-NLS-1$ + case 474 : if (DEBUG) { System.out.println("ReferenceExpression ::= Primary COLON_COLON..."); } //$NON-NLS-1$ consumeReferenceExpressionPrimaryForm(); break; - case 461 : if (DEBUG) { System.out.println("ReferenceExpression ::= QualifiedSuperReceiver..."); } //$NON-NLS-1$ + case 475 : if (DEBUG) { System.out.println("ReferenceExpression ::= QualifiedSuperReceiver..."); } //$NON-NLS-1$ consumeReferenceExpressionPrimaryForm(); break; - case 462 : if (DEBUG) { System.out.println("ReferenceExpression ::= super COLON_COLON..."); } //$NON-NLS-1$ + case 476 : if (DEBUG) { System.out.println("ReferenceExpression ::= super COLON_COLON..."); } //$NON-NLS-1$ consumeReferenceExpressionSuperForm(); break; - case 463 : if (DEBUG) { System.out.println("NonWildTypeArgumentsopt ::="); } //$NON-NLS-1$ + case 477 : if (DEBUG) { System.out.println("NonWildTypeArgumentsopt ::="); } //$NON-NLS-1$ consumeEmptyTypeArguments(); break; - case 465 : if (DEBUG) { System.out.println("IdentifierOrNew ::= Identifier"); } //$NON-NLS-1$ + case 479 : if (DEBUG) { System.out.println("IdentifierOrNew ::= Identifier"); } //$NON-NLS-1$ consumeIdentifierOrNew(false); break; - case 466 : if (DEBUG) { System.out.println("IdentifierOrNew ::= new"); } //$NON-NLS-1$ + case 480 : if (DEBUG) { System.out.println("IdentifierOrNew ::= new"); } //$NON-NLS-1$ consumeIdentifierOrNew(true); break; - case 467 : if (DEBUG) { System.out.println("LambdaExpression ::= LambdaParameters ARROW LambdaBody"); } //$NON-NLS-1$ + case 481 : if (DEBUG) { System.out.println("LambdaExpression ::= LambdaParameters ARROW LambdaBody"); } //$NON-NLS-1$ consumeLambdaExpression(); break; - case 468 : if (DEBUG) { System.out.println("NestedLambda ::="); } //$NON-NLS-1$ + case 482 : if (DEBUG) { System.out.println("NestedLambda ::="); } //$NON-NLS-1$ consumeNestedLambda(); break; - case 469 : if (DEBUG) { System.out.println("LambdaParameters ::= Identifier NestedLambda"); } //$NON-NLS-1$ + case 483 : if (DEBUG) { System.out.println("LambdaParameters ::= Identifier NestedLambda"); } //$NON-NLS-1$ consumeTypeElidedLambdaParameter(false); break; - case 475 : if (DEBUG) { System.out.println("TypeElidedFormalParameterList ::=..."); } //$NON-NLS-1$ + case 489 : if (DEBUG) { System.out.println("TypeElidedFormalParameterList ::=..."); } //$NON-NLS-1$ consumeFormalParameterList(); break; - case 476 : if (DEBUG) { System.out.println("TypeElidedFormalParameter ::= Modifiersopt Identifier"); } //$NON-NLS-1$ + case 490 : if (DEBUG) { System.out.println("TypeElidedFormalParameter ::= Modifiersopt Identifier"); } //$NON-NLS-1$ consumeTypeElidedLambdaParameter(true); break; - case 479 : if (DEBUG) { System.out.println("ElidedLeftBraceAndReturn ::="); } //$NON-NLS-1$ + case 493 : if (DEBUG) { System.out.println("ElidedLeftBraceAndReturn ::="); } //$NON-NLS-1$ consumeElidedLeftBraceAndReturn(); break; - case 480 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); } //$NON-NLS-1$ + case 494 : if (DEBUG) { System.out.println("AllocationHeader ::= new ClassType LPAREN..."); } //$NON-NLS-1$ consumeAllocationHeader(); break; - case 481 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); } //$NON-NLS-1$ + case 495 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionWithTypeArguments(); break; - case 482 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); } //$NON-NLS-1$ + case 496 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= new ClassType..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpression(); break; - case 483 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ + case 497 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; break; - case 484 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ + case 498 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::= Primary DOT new..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualified() ; break; - case 485 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ + case 499 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualified() ; break; - case 486 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ + case 500 : if (DEBUG) { System.out.println("ClassInstanceCreationExpression ::=..."); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() ; break; - case 487 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); } //$NON-NLS-1$ + case 501 : if (DEBUG) { System.out.println("EnterInstanceCreationArgumentList ::="); } //$NON-NLS-1$ consumeEnterInstanceCreationArgumentList(); break; - case 488 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT new"); } //$NON-NLS-1$ + case 502 : if (DEBUG) { System.out.println("ClassInstanceCreationExpressionName ::= Name DOT new"); } //$NON-NLS-1$ consumeClassInstanceCreationExpressionName() ; break; - case 489 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); } //$NON-NLS-1$ + case 503 : if (DEBUG) { System.out.println("UnqualifiedClassBodyopt ::="); } //$NON-NLS-1$ consumeClassBodyopt(); break; - case 491 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ + case 505 : if (DEBUG) { System.out.println("UnqualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ consumeEnterAnonymousClassBody(false); break; - case 492 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); } //$NON-NLS-1$ + case 506 : if (DEBUG) { System.out.println("QualifiedClassBodyopt ::="); } //$NON-NLS-1$ consumeClassBodyopt(); break; - case 494 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ + case 508 : if (DEBUG) { System.out.println("QualifiedEnterAnonymousClassBody ::="); } //$NON-NLS-1$ consumeEnterAnonymousClassBody(true); break; - case 496 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); } //$NON-NLS-1$ + case 510 : if (DEBUG) { System.out.println("ArgumentList ::= ArgumentList COMMA Expression"); } //$NON-NLS-1$ consumeArgumentList(); break; - case 497 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); } //$NON-NLS-1$ + case 511 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new PrimitiveType..."); } //$NON-NLS-1$ consumeArrayCreationHeader(); break; - case 498 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); } //$NON-NLS-1$ + case 512 : if (DEBUG) { System.out.println("ArrayCreationHeader ::= new ClassOrInterfaceType..."); } //$NON-NLS-1$ consumeArrayCreationHeader(); break; - case 499 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ + case 513 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ consumeArrayCreationExpressionWithoutInitializer(); break; - case 500 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); } //$NON-NLS-1$ + case 514 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new PrimitiveType"); } //$NON-NLS-1$ consumeArrayCreationExpressionWithInitializer(); break; - case 501 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ + case 515 : if (DEBUG) { System.out.println("ArrayCreationWithoutArrayInitializer ::= new..."); } //$NON-NLS-1$ consumeArrayCreationExpressionWithoutInitializer(); break; - case 502 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); } //$NON-NLS-1$ + case 516 : if (DEBUG) { System.out.println("ArrayCreationWithArrayInitializer ::= new..."); } //$NON-NLS-1$ consumeArrayCreationExpressionWithInitializer(); break; - case 504 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); } //$NON-NLS-1$ + case 518 : if (DEBUG) { System.out.println("DimWithOrWithOutExprs ::= DimWithOrWithOutExprs..."); } //$NON-NLS-1$ consumeDimWithOrWithOutExprs(); break; - case 506 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= TypeAnnotationsopt LBRACKET..."); } //$NON-NLS-1$ + case 520 : if (DEBUG) { System.out.println("DimWithOrWithOutExpr ::= TypeAnnotationsopt LBRACKET..."); } //$NON-NLS-1$ consumeDimWithOrWithOutExpr(); break; - case 507 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); } //$NON-NLS-1$ + case 521 : if (DEBUG) { System.out.println("Dims ::= DimsLoop"); } //$NON-NLS-1$ consumeDims(); break; - case 510 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); } //$NON-NLS-1$ + case 524 : if (DEBUG) { System.out.println("OneDimLoop ::= LBRACKET RBRACKET"); } //$NON-NLS-1$ consumeOneDimLoop(false); break; - case 511 : if (DEBUG) { System.out.println("OneDimLoop ::= TypeAnnotations LBRACKET RBRACKET"); } //$NON-NLS-1$ + case 525 : if (DEBUG) { System.out.println("OneDimLoop ::= TypeAnnotations LBRACKET RBRACKET"); } //$NON-NLS-1$ consumeOneDimLoop(true); break; - case 512 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); } //$NON-NLS-1$ + case 526 : if (DEBUG) { System.out.println("FieldAccess ::= Primary DOT Identifier"); } //$NON-NLS-1$ consumeFieldAccess(false); break; - case 513 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); } //$NON-NLS-1$ + case 527 : if (DEBUG) { System.out.println("FieldAccess ::= super DOT Identifier"); } //$NON-NLS-1$ consumeFieldAccess(true); break; - case 514 : if (DEBUG) { System.out.println("FieldAccess ::= QualifiedSuperReceiver DOT Identifier"); } //$NON-NLS-1$ + case 528 : if (DEBUG) { System.out.println("FieldAccess ::= QualifiedSuperReceiver DOT Identifier"); } //$NON-NLS-1$ consumeFieldAccess(false); break; - case 515 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ + case 529 : if (DEBUG) { System.out.println("MethodInvocation ::= Name LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ consumeMethodInvocationName(); break; - case 516 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); } //$NON-NLS-1$ + case 530 : if (DEBUG) { System.out.println("MethodInvocation ::= Name DOT OnlyTypeArguments..."); } //$NON-NLS-1$ consumeMethodInvocationNameWithTypeArguments(); break; - case 517 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); } //$NON-NLS-1$ + case 531 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT OnlyTypeArguments..."); } //$NON-NLS-1$ consumeMethodInvocationPrimaryWithTypeArguments(); break; - case 518 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); } //$NON-NLS-1$ + case 532 : if (DEBUG) { System.out.println("MethodInvocation ::= Primary DOT Identifier LPAREN..."); } //$NON-NLS-1$ consumeMethodInvocationPrimary(); break; - case 519 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); } //$NON-NLS-1$ + case 533 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); } //$NON-NLS-1$ consumeMethodInvocationPrimary(); break; - case 520 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); } //$NON-NLS-1$ + case 534 : if (DEBUG) { System.out.println("MethodInvocation ::= QualifiedSuperReceiver DOT..."); } //$NON-NLS-1$ consumeMethodInvocationPrimaryWithTypeArguments(); break; - case 521 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); } //$NON-NLS-1$ + case 535 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT OnlyTypeArguments..."); } //$NON-NLS-1$ consumeMethodInvocationSuperWithTypeArguments(); break; - case 522 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); } //$NON-NLS-1$ + case 536 : if (DEBUG) { System.out.println("MethodInvocation ::= super DOT Identifier LPAREN..."); } //$NON-NLS-1$ consumeMethodInvocationSuper(); break; - case 523 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); } //$NON-NLS-1$ + case 537 : if (DEBUG) { System.out.println("ArrayAccess ::= Name LBRACKET Expression RBRACKET"); } //$NON-NLS-1$ consumeArrayAccess(true); break; - case 524 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); } //$NON-NLS-1$ + case 538 : if (DEBUG) { System.out.println("ArrayAccess ::= PrimaryNoNewArray LBRACKET Expression..."); } //$NON-NLS-1$ consumeArrayAccess(false); break; - case 525 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); } //$NON-NLS-1$ + case 539 : if (DEBUG) { System.out.println("ArrayAccess ::= ArrayCreationWithArrayInitializer..."); } //$NON-NLS-1$ consumeArrayAccess(false); break; - case 527 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); } //$NON-NLS-1$ + case 541 : if (DEBUG) { System.out.println("PostfixExpression ::= Name"); } //$NON-NLS-1$ consumePostfixExpression(); break; - case 530 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); } //$NON-NLS-1$ + case 544 : if (DEBUG) { System.out.println("PostIncrementExpression ::= PostfixExpression PLUS_PLUS"); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS,true); break; - case 531 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); } //$NON-NLS-1$ + case 545 : if (DEBUG) { System.out.println("PostDecrementExpression ::= PostfixExpression..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS,true); break; - case 532 : if (DEBUG) { System.out.println("PushPosition ::="); } //$NON-NLS-1$ + case 546 : if (DEBUG) { System.out.println("PushPosition ::="); } //$NON-NLS-1$ consumePushPosition(); break; - case 535 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); } //$NON-NLS-1$ + case 549 : if (DEBUG) { System.out.println("UnaryExpression ::= PLUS PushPosition UnaryExpression"); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS); break; - case 536 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); } //$NON-NLS-1$ + case 550 : if (DEBUG) { System.out.println("UnaryExpression ::= MINUS PushPosition UnaryExpression"); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS); break; - case 538 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); } //$NON-NLS-1$ + case 552 : if (DEBUG) { System.out.println("PreIncrementExpression ::= PLUS_PLUS PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS,false); break; - case 539 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); } //$NON-NLS-1$ + case 553 : if (DEBUG) { System.out.println("PreDecrementExpression ::= MINUS_MINUS PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS,false); break; - case 541 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); } //$NON-NLS-1$ + case 555 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= TWIDDLE PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.TWIDDLE); break; - case 542 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); } //$NON-NLS-1$ + case 556 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus ::= NOT PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.NOT); break; - case 544 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); } //$NON-NLS-1$ + case 558 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN PrimitiveType Dimsopt..."); } //$NON-NLS-1$ consumeCastExpressionWithPrimitiveType(); break; - case 545 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ + case 559 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ consumeCastExpressionWithGenericsArray(); break; - case 546 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ + case 560 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name..."); } //$NON-NLS-1$ consumeCastExpressionWithQualifiedGenericsArray(); break; - case 547 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); } //$NON-NLS-1$ + case 561 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name PushRPAREN..."); } //$NON-NLS-1$ consumeCastExpressionLL1(); break; - case 548 : if (DEBUG) { System.out.println("CastExpression ::= BeginIntersectionCast PushLPAREN..."); } //$NON-NLS-1$ + case 562 : if (DEBUG) { System.out.println("CastExpression ::= BeginIntersectionCast PushLPAREN..."); } //$NON-NLS-1$ consumeCastExpressionLL1WithBounds(); break; - case 549 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims..."); } //$NON-NLS-1$ + case 563 : if (DEBUG) { System.out.println("CastExpression ::= PushLPAREN Name Dims..."); } //$NON-NLS-1$ consumeCastExpressionWithNameArray(); break; - case 550 : if (DEBUG) { System.out.println("AdditionalBoundsListOpt ::="); } //$NON-NLS-1$ + case 564 : if (DEBUG) { System.out.println("AdditionalBoundsListOpt ::="); } //$NON-NLS-1$ consumeZeroAdditionalBounds(); break; - case 554 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); } //$NON-NLS-1$ + case 568 : if (DEBUG) { System.out.println("OnlyTypeArgumentsForCastExpression ::= OnlyTypeArguments"); } //$NON-NLS-1$ consumeOnlyTypeArgumentsForCastExpression(); break; - case 555 : if (DEBUG) { System.out.println("InsideCastExpression ::="); } //$NON-NLS-1$ + case 569 : if (DEBUG) { System.out.println("InsideCastExpression ::="); } //$NON-NLS-1$ consumeInsideCastExpression(); break; - case 556 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); } //$NON-NLS-1$ + case 570 : if (DEBUG) { System.out.println("InsideCastExpressionLL1 ::="); } //$NON-NLS-1$ consumeInsideCastExpressionLL1(); break; - case 557 : if (DEBUG) { System.out.println("InsideCastExpressionLL1WithBounds ::="); } //$NON-NLS-1$ + case 571 : if (DEBUG) { System.out.println("InsideCastExpressionLL1WithBounds ::="); } //$NON-NLS-1$ consumeInsideCastExpressionLL1WithBounds (); break; - case 558 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); } //$NON-NLS-1$ + case 572 : if (DEBUG) { System.out.println("InsideCastExpressionWithQualifiedGenerics ::="); } //$NON-NLS-1$ consumeInsideCastExpressionWithQualifiedGenerics(); break; - case 560 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ + case 574 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MULTIPLY); break; - case 561 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ + case 575 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.DIVIDE); break; - case 562 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ + case 576 : if (DEBUG) { System.out.println("MultiplicativeExpression ::= MultiplicativeExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.REMAINDER); break; - case 564 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); } //$NON-NLS-1$ + case 578 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression PLUS..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.PLUS); break; - case 565 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); } //$NON-NLS-1$ + case 579 : if (DEBUG) { System.out.println("AdditiveExpression ::= AdditiveExpression MINUS..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MINUS); break; - case 567 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); } //$NON-NLS-1$ + case 581 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression LEFT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LEFT_SHIFT); break; - case 568 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); } //$NON-NLS-1$ + case 582 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression RIGHT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); break; - case 569 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ + case 583 : if (DEBUG) { System.out.println("ShiftExpression ::= ShiftExpression UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; - case 571 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); } //$NON-NLS-1$ + case 585 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS); break; - case 572 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); } //$NON-NLS-1$ + case 586 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression GREATER..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER); break; - case 573 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); } //$NON-NLS-1$ + case 587 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression LESS_EQUAL"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS_EQUAL); break; - case 574 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); } //$NON-NLS-1$ + case 588 : if (DEBUG) { System.out.println("RelationalExpression ::= RelationalExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER_EQUAL); break; - case 576 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); } //$NON-NLS-1$ + case 590 : if (DEBUG) { System.out.println("InstanceofExpression ::= InstanceofExpression instanceof"); } //$NON-NLS-1$ consumeInstanceOfExpression(); break; - case 578 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); } //$NON-NLS-1$ + case 592 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression EQUAL_EQUAL..."); } //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); break; - case 579 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); } //$NON-NLS-1$ + case 593 : if (DEBUG) { System.out.println("EqualityExpression ::= EqualityExpression NOT_EQUAL..."); } //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.NOT_EQUAL); break; - case 581 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); } //$NON-NLS-1$ + case 595 : if (DEBUG) { System.out.println("AndExpression ::= AndExpression AND EqualityExpression"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND); break; - case 583 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); } //$NON-NLS-1$ + case 597 : if (DEBUG) { System.out.println("ExclusiveOrExpression ::= ExclusiveOrExpression XOR..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.XOR); break; - case 585 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); } //$NON-NLS-1$ + case 599 : if (DEBUG) { System.out.println("InclusiveOrExpression ::= InclusiveOrExpression OR..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR); break; - case 587 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); } //$NON-NLS-1$ + case 601 : if (DEBUG) { System.out.println("ConditionalAndExpression ::= ConditionalAndExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND_AND); break; - case 589 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ + case 603 : if (DEBUG) { System.out.println("ConditionalOrExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR_OR); break; - case 591 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ + case 605 : if (DEBUG) { System.out.println("ConditionalExpression ::= ConditionalOrExpression..."); } //$NON-NLS-1$ consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; break; - case 594 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); } //$NON-NLS-1$ + case 608 : if (DEBUG) { System.out.println("Assignment ::= PostfixExpression AssignmentOperator..."); } //$NON-NLS-1$ consumeAssignment(); break; - case 596 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); } //$NON-NLS-1$ + case 610 : if (DEBUG) { System.out.println("Assignment ::= InvalidArrayInitializerAssignement"); } //$NON-NLS-1$ ignoreExpressionAssignment(); break; - case 597 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); } //$NON-NLS-1$ + case 611 : if (DEBUG) { System.out.println("AssignmentOperator ::= EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(EQUAL); break; - case 598 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); } //$NON-NLS-1$ + case 612 : if (DEBUG) { System.out.println("AssignmentOperator ::= MULTIPLY_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(MULTIPLY); break; - case 599 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); } //$NON-NLS-1$ + case 613 : if (DEBUG) { System.out.println("AssignmentOperator ::= DIVIDE_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(DIVIDE); break; - case 600 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); } //$NON-NLS-1$ + case 614 : if (DEBUG) { System.out.println("AssignmentOperator ::= REMAINDER_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(REMAINDER); break; - case 601 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); } //$NON-NLS-1$ + case 615 : if (DEBUG) { System.out.println("AssignmentOperator ::= PLUS_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(PLUS); break; - case 602 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); } //$NON-NLS-1$ + case 616 : if (DEBUG) { System.out.println("AssignmentOperator ::= MINUS_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(MINUS); break; - case 603 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); } //$NON-NLS-1$ + case 617 : if (DEBUG) { System.out.println("AssignmentOperator ::= LEFT_SHIFT_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(LEFT_SHIFT); break; - case 604 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ + case 618 : if (DEBUG) { System.out.println("AssignmentOperator ::= RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(RIGHT_SHIFT); break; - case 605 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ + case 619 : if (DEBUG) { System.out.println("AssignmentOperator ::= UNSIGNED_RIGHT_SHIFT_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(UNSIGNED_RIGHT_SHIFT); break; - case 606 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); } //$NON-NLS-1$ + case 620 : if (DEBUG) { System.out.println("AssignmentOperator ::= AND_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(AND); break; - case 607 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); } //$NON-NLS-1$ + case 621 : if (DEBUG) { System.out.println("AssignmentOperator ::= XOR_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(XOR); break; - case 608 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); } //$NON-NLS-1$ + case 622 : if (DEBUG) { System.out.println("AssignmentOperator ::= OR_EQUAL"); } //$NON-NLS-1$ consumeAssignmentOperator(OR); break; - case 609 : if (DEBUG) { System.out.println("Expression ::= AssignmentExpression"); } //$NON-NLS-1$ + case 623 : if (DEBUG) { System.out.println("Expression ::= AssignmentExpression"); } //$NON-NLS-1$ consumeExpression(); break; - case 612 : if (DEBUG) { System.out.println("Expressionopt ::="); } //$NON-NLS-1$ + case 626 : if (DEBUG) { System.out.println("Expressionopt ::="); } //$NON-NLS-1$ consumeEmptyExpression(); break; - case 617 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); } //$NON-NLS-1$ + case 629 : if (DEBUG) { System.out.println("ConstantExpressions ::= ConstantExpressions COMMA..."); } //$NON-NLS-1$ + consumeConstantExpressions(); + break; + + case 633 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::="); } //$NON-NLS-1$ consumeEmptyClassBodyDeclarationsopt(); break; - case 618 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ + case 634 : if (DEBUG) { System.out.println("ClassBodyDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ consumeClassBodyDeclarationsopt(); break; - case 619 : if (DEBUG) { System.out.println("Modifiersopt ::="); } //$NON-NLS-1$ + case 635 : if (DEBUG) { System.out.println("Modifiersopt ::="); } //$NON-NLS-1$ consumeDefaultModifiers(); break; - case 620 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); } //$NON-NLS-1$ + case 636 : if (DEBUG) { System.out.println("Modifiersopt ::= Modifiers"); } //$NON-NLS-1$ consumeModifiers(); break; - case 621 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); } //$NON-NLS-1$ + case 637 : if (DEBUG) { System.out.println("BlockStatementsopt ::="); } //$NON-NLS-1$ consumeEmptyBlockStatementsopt(); break; - case 623 : if (DEBUG) { System.out.println("Dimsopt ::="); } //$NON-NLS-1$ + case 639 : if (DEBUG) { System.out.println("Dimsopt ::="); } //$NON-NLS-1$ consumeEmptyDimsopt(); break; - case 625 : if (DEBUG) { System.out.println("ArgumentListopt ::="); } //$NON-NLS-1$ + case 641 : if (DEBUG) { System.out.println("ArgumentListopt ::="); } //$NON-NLS-1$ consumeEmptyArgumentListopt(); break; - case 629 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); } //$NON-NLS-1$ + case 645 : if (DEBUG) { System.out.println("FormalParameterListopt ::="); } //$NON-NLS-1$ consumeFormalParameterListopt(); break; - case 633 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); } //$NON-NLS-1$ + case 649 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::="); } //$NON-NLS-1$ consumeEmptyInterfaceMemberDeclarationsopt(); break; - case 634 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ + case 650 : if (DEBUG) { System.out.println("InterfaceMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ consumeInterfaceMemberDeclarationsopt(); break; - case 635 : if (DEBUG) { System.out.println("NestedType ::="); } //$NON-NLS-1$ + case 651 : if (DEBUG) { System.out.println("NestedType ::="); } //$NON-NLS-1$ consumeNestedType(); break; - case 636 : if (DEBUG) { System.out.println("ForInitopt ::="); } //$NON-NLS-1$ + case 652 : if (DEBUG) { System.out.println("ForInitopt ::="); } //$NON-NLS-1$ consumeEmptyForInitopt(); break; - case 638 : if (DEBUG) { System.out.println("ForUpdateopt ::="); } //$NON-NLS-1$ + case 654 : if (DEBUG) { System.out.println("ForUpdateopt ::="); } //$NON-NLS-1$ consumeEmptyForUpdateopt(); break; - case 642 : if (DEBUG) { System.out.println("Catchesopt ::="); } //$NON-NLS-1$ + case 658 : if (DEBUG) { System.out.println("Catchesopt ::="); } //$NON-NLS-1$ consumeEmptyCatchesopt(); break; - case 644 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); } //$NON-NLS-1$ + case 660 : if (DEBUG) { System.out.println("EnumDeclaration ::= EnumHeader EnumBody"); } //$NON-NLS-1$ consumeEnumDeclaration(); break; - case 645 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); } //$NON-NLS-1$ + case 661 : if (DEBUG) { System.out.println("EnumHeader ::= EnumHeaderName ClassHeaderImplementsopt"); } //$NON-NLS-1$ consumeEnumHeader(); break; - case 646 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); } //$NON-NLS-1$ + case 662 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier"); } //$NON-NLS-1$ consumeEnumHeaderName(); break; - case 647 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); } //$NON-NLS-1$ + case 663 : if (DEBUG) { System.out.println("EnumHeaderName ::= Modifiersopt enum Identifier..."); } //$NON-NLS-1$ consumeEnumHeaderNameWithTypeParameters(); break; - case 648 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); } //$NON-NLS-1$ + case 664 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumBodyDeclarationsopt RBRACE"); } //$NON-NLS-1$ consumeEnumBodyNoConstants(); break; - case 649 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); } //$NON-NLS-1$ + case 665 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE COMMA EnumBodyDeclarationsopt..."); } //$NON-NLS-1$ consumeEnumBodyNoConstants(); break; - case 650 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); } //$NON-NLS-1$ + case 666 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants COMMA..."); } //$NON-NLS-1$ consumeEnumBodyWithConstants(); break; - case 651 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); } //$NON-NLS-1$ + case 667 : if (DEBUG) { System.out.println("EnumBody ::= LBRACE EnumConstants..."); } //$NON-NLS-1$ consumeEnumBodyWithConstants(); break; - case 653 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); } //$NON-NLS-1$ + case 669 : if (DEBUG) { System.out.println("EnumConstants ::= EnumConstants COMMA EnumConstant"); } //$NON-NLS-1$ consumeEnumConstants(); break; - case 654 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); } //$NON-NLS-1$ + case 670 : if (DEBUG) { System.out.println("EnumConstantHeaderName ::= Modifiersopt Identifier"); } //$NON-NLS-1$ consumeEnumConstantHeaderName(); break; - case 655 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); } //$NON-NLS-1$ + case 671 : if (DEBUG) { System.out.println("EnumConstantHeader ::= EnumConstantHeaderName..."); } //$NON-NLS-1$ consumeEnumConstantHeader(); break; - case 656 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); } //$NON-NLS-1$ + case 672 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader ForceNoDiet..."); } //$NON-NLS-1$ consumeEnumConstantWithClassBody(); break; - case 657 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); } //$NON-NLS-1$ + case 673 : if (DEBUG) { System.out.println("EnumConstant ::= EnumConstantHeader"); } //$NON-NLS-1$ consumeEnumConstantNoClassBody(); break; - case 658 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ + case 674 : if (DEBUG) { System.out.println("Arguments ::= LPAREN ArgumentListopt RPAREN"); } //$NON-NLS-1$ consumeArguments(); break; - case 659 : if (DEBUG) { System.out.println("Argumentsopt ::="); } //$NON-NLS-1$ + case 675 : if (DEBUG) { System.out.println("Argumentsopt ::="); } //$NON-NLS-1$ consumeEmptyArguments(); break; - case 661 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); } //$NON-NLS-1$ + case 677 : if (DEBUG) { System.out.println("EnumDeclarations ::= SEMICOLON ClassBodyDeclarationsopt"); } //$NON-NLS-1$ consumeEnumDeclarations(); break; - case 662 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); } //$NON-NLS-1$ + case 678 : if (DEBUG) { System.out.println("EnumBodyDeclarationsopt ::="); } //$NON-NLS-1$ consumeEmptyEnumDeclarations(); break; - case 664 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); } //$NON-NLS-1$ + case 680 : if (DEBUG) { System.out.println("EnhancedForStatement ::= EnhancedForStatementHeader..."); } //$NON-NLS-1$ consumeEnhancedForStatement(); break; - case 665 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); } //$NON-NLS-1$ + case 681 : if (DEBUG) { System.out.println("EnhancedForStatementNoShortIf ::=..."); } //$NON-NLS-1$ consumeEnhancedForStatement(); break; - case 666 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); } //$NON-NLS-1$ + case 682 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Type..."); } //$NON-NLS-1$ consumeEnhancedForStatementHeaderInit(false); break; - case 667 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); } //$NON-NLS-1$ + case 683 : if (DEBUG) { System.out.println("EnhancedForStatementHeaderInit ::= for LPAREN Modifiers"); } //$NON-NLS-1$ consumeEnhancedForStatementHeaderInit(true); break; - case 668 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); } //$NON-NLS-1$ + case 684 : if (DEBUG) { System.out.println("EnhancedForStatementHeader ::=..."); } //$NON-NLS-1$ consumeEnhancedForStatementHeader(); break; - case 669 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); } //$NON-NLS-1$ + case 685 : if (DEBUG) { System.out.println("SingleStaticImportDeclaration ::=..."); } //$NON-NLS-1$ consumeImportDeclaration(); break; - case 670 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); } //$NON-NLS-1$ + case 686 : if (DEBUG) { System.out.println("SingleStaticImportDeclarationName ::= import static Name"); } //$NON-NLS-1$ consumeSingleStaticImportDeclarationName(); break; - case 671 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$ + case 687 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclaration ::=..."); } //$NON-NLS-1$ consumeImportDeclaration(); break; - case 672 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); } //$NON-NLS-1$ + case 688 : if (DEBUG) { System.out.println("StaticImportOnDemandDeclarationName ::= import static..."); } //$NON-NLS-1$ consumeStaticImportOnDemandDeclarationName(); break; - case 673 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ + case 689 : if (DEBUG) { System.out.println("TypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ consumeTypeArguments(); break; - case 674 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ + case 690 : if (DEBUG) { System.out.println("OnlyTypeArguments ::= LESS TypeArgumentList1"); } //$NON-NLS-1$ consumeOnlyTypeArguments(); break; - case 676 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ + case 692 : if (DEBUG) { System.out.println("TypeArgumentList1 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ consumeTypeArgumentList1(); break; - case 678 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); } //$NON-NLS-1$ + case 694 : if (DEBUG) { System.out.println("TypeArgumentList ::= TypeArgumentList COMMA TypeArgument"); } //$NON-NLS-1$ consumeTypeArgumentList(); break; - case 679 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); } //$NON-NLS-1$ + case 695 : if (DEBUG) { System.out.println("TypeArgument ::= ReferenceType"); } //$NON-NLS-1$ consumeTypeArgument(); break; - case 683 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); } //$NON-NLS-1$ + case 699 : if (DEBUG) { System.out.println("ReferenceType1 ::= ReferenceType GREATER"); } //$NON-NLS-1$ consumeReferenceType1(); break; - case 684 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ + case 700 : if (DEBUG) { System.out.println("ReferenceType1 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ consumeTypeArgumentReferenceType1(); break; - case 686 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ + case 702 : if (DEBUG) { System.out.println("TypeArgumentList2 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ consumeTypeArgumentList2(); break; - case 689 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); } //$NON-NLS-1$ + case 705 : if (DEBUG) { System.out.println("ReferenceType2 ::= ReferenceType RIGHT_SHIFT"); } //$NON-NLS-1$ consumeReferenceType2(); break; - case 690 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ + case 706 : if (DEBUG) { System.out.println("ReferenceType2 ::= ClassOrInterface LESS..."); } //$NON-NLS-1$ consumeTypeArgumentReferenceType2(); break; - case 692 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ + case 708 : if (DEBUG) { System.out.println("TypeArgumentList3 ::= TypeArgumentList COMMA..."); } //$NON-NLS-1$ consumeTypeArgumentList3(); break; - case 695 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ + case 711 : if (DEBUG) { System.out.println("ReferenceType3 ::= ReferenceType UNSIGNED_RIGHT_SHIFT"); } //$NON-NLS-1$ consumeReferenceType3(); break; - case 696 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION"); } //$NON-NLS-1$ + case 712 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION"); } //$NON-NLS-1$ consumeWildcard(); break; - case 697 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION WildcardBounds"); } //$NON-NLS-1$ + case 713 : if (DEBUG) { System.out.println("Wildcard ::= TypeAnnotationsopt QUESTION WildcardBounds"); } //$NON-NLS-1$ consumeWildcardWithBounds(); break; - case 698 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); } //$NON-NLS-1$ + case 714 : if (DEBUG) { System.out.println("WildcardBounds ::= extends ReferenceType"); } //$NON-NLS-1$ consumeWildcardBoundsExtends(); break; - case 699 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); } //$NON-NLS-1$ + case 715 : if (DEBUG) { System.out.println("WildcardBounds ::= super ReferenceType"); } //$NON-NLS-1$ consumeWildcardBoundsSuper(); break; - case 700 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION GREATER"); } //$NON-NLS-1$ + case 716 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION GREATER"); } //$NON-NLS-1$ consumeWildcard1(); break; - case 701 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ + case 717 : if (DEBUG) { System.out.println("Wildcard1 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ consumeWildcard1WithBounds(); break; - case 702 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); } //$NON-NLS-1$ + case 718 : if (DEBUG) { System.out.println("WildcardBounds1 ::= extends ReferenceType1"); } //$NON-NLS-1$ consumeWildcardBounds1Extends(); break; - case 703 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); } //$NON-NLS-1$ + case 719 : if (DEBUG) { System.out.println("WildcardBounds1 ::= super ReferenceType1"); } //$NON-NLS-1$ consumeWildcardBounds1Super(); break; - case 704 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION RIGHT_SHIFT"); } //$NON-NLS-1$ + case 720 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION RIGHT_SHIFT"); } //$NON-NLS-1$ consumeWildcard2(); break; - case 705 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ + case 721 : if (DEBUG) { System.out.println("Wildcard2 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ consumeWildcard2WithBounds(); break; - case 706 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); } //$NON-NLS-1$ + case 722 : if (DEBUG) { System.out.println("WildcardBounds2 ::= extends ReferenceType2"); } //$NON-NLS-1$ consumeWildcardBounds2Extends(); break; - case 707 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); } //$NON-NLS-1$ + case 723 : if (DEBUG) { System.out.println("WildcardBounds2 ::= super ReferenceType2"); } //$NON-NLS-1$ consumeWildcardBounds2Super(); break; - case 708 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ + case 724 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ consumeWildcard3(); break; - case 709 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ + case 725 : if (DEBUG) { System.out.println("Wildcard3 ::= TypeAnnotationsopt QUESTION..."); } //$NON-NLS-1$ consumeWildcard3WithBounds(); break; - case 710 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); } //$NON-NLS-1$ + case 726 : if (DEBUG) { System.out.println("WildcardBounds3 ::= extends ReferenceType3"); } //$NON-NLS-1$ consumeWildcardBounds3Extends(); break; - case 711 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); } //$NON-NLS-1$ + case 727 : if (DEBUG) { System.out.println("WildcardBounds3 ::= super ReferenceType3"); } //$NON-NLS-1$ consumeWildcardBounds3Super(); break; - case 712 : if (DEBUG) { System.out.println("TypeParameterHeader ::= TypeAnnotationsopt Identifier"); } //$NON-NLS-1$ + case 728 : if (DEBUG) { System.out.println("TypeParameterHeader ::= TypeAnnotationsopt Identifier"); } //$NON-NLS-1$ consumeTypeParameterHeader(); break; - case 713 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); } //$NON-NLS-1$ + case 729 : if (DEBUG) { System.out.println("TypeParameters ::= LESS TypeParameterList1"); } //$NON-NLS-1$ consumeTypeParameters(); break; - case 715 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ + case 731 : if (DEBUG) { System.out.println("TypeParameterList ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ consumeTypeParameterList(); break; - case 717 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ + case 733 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ consumeTypeParameterWithExtends(); break; - case 718 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ + case 734 : if (DEBUG) { System.out.println("TypeParameter ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ consumeTypeParameterWithExtendsAndBounds(); break; - case 720 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); } //$NON-NLS-1$ + case 736 : if (DEBUG) { System.out.println("AdditionalBoundList ::= AdditionalBoundList..."); } //$NON-NLS-1$ consumeAdditionalBoundList(); break; - case 721 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); } //$NON-NLS-1$ + case 737 : if (DEBUG) { System.out.println("AdditionalBound ::= AND ReferenceType"); } //$NON-NLS-1$ consumeAdditionalBound(); break; - case 723 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ + case 739 : if (DEBUG) { System.out.println("TypeParameterList1 ::= TypeParameterList COMMA..."); } //$NON-NLS-1$ consumeTypeParameterList1(); break; - case 724 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); } //$NON-NLS-1$ + case 740 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader GREATER"); } //$NON-NLS-1$ consumeTypeParameter1(); break; - case 725 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ + case 741 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ consumeTypeParameter1WithExtends(); break; - case 726 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ + case 742 : if (DEBUG) { System.out.println("TypeParameter1 ::= TypeParameterHeader extends..."); } //$NON-NLS-1$ consumeTypeParameter1WithExtendsAndBounds(); break; - case 728 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); } //$NON-NLS-1$ + case 744 : if (DEBUG) { System.out.println("AdditionalBoundList1 ::= AdditionalBoundList..."); } //$NON-NLS-1$ consumeAdditionalBoundList1(); break; - case 729 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); } //$NON-NLS-1$ + case 745 : if (DEBUG) { System.out.println("AdditionalBound1 ::= AND ReferenceType1"); } //$NON-NLS-1$ consumeAdditionalBound1(); break; - case 735 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); } //$NON-NLS-1$ + case 751 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= PLUS PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.PLUS); break; - case 736 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); } //$NON-NLS-1$ + case 752 : if (DEBUG) { System.out.println("UnaryExpression_NotName ::= MINUS PushPosition..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.MINUS); break; - case 739 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); } //$NON-NLS-1$ + case 755 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= TWIDDLE..."); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.TWIDDLE); break; - case 740 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); } //$NON-NLS-1$ + case 756 : if (DEBUG) { System.out.println("UnaryExpressionNotPlusMinus_NotName ::= NOT PushPosition"); } //$NON-NLS-1$ consumeUnaryExpression(OperatorIds.NOT); break; - case 743 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ + case 759 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MULTIPLY); break; - case 744 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); } //$NON-NLS-1$ + case 760 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name MULTIPLY..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.MULTIPLY); break; - case 745 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ + case 761 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.DIVIDE); break; - case 746 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); } //$NON-NLS-1$ + case 762 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name DIVIDE..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.DIVIDE); break; - case 747 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ + case 763 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.REMAINDER); break; - case 748 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); } //$NON-NLS-1$ + case 764 : if (DEBUG) { System.out.println("MultiplicativeExpression_NotName ::= Name REMAINDER..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.REMAINDER); break; - case 750 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ + case 766 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.PLUS); break; - case 751 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); } //$NON-NLS-1$ + case 767 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name PLUS..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.PLUS); break; - case 752 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ + case 768 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.MINUS); break; - case 753 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); } //$NON-NLS-1$ + case 769 : if (DEBUG) { System.out.println("AdditiveExpression_NotName ::= Name MINUS..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.MINUS); break; - case 755 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ + case 771 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LEFT_SHIFT); break; - case 756 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); } //$NON-NLS-1$ + case 772 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name LEFT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LEFT_SHIFT); break; - case 757 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ + case 773 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.RIGHT_SHIFT); break; - case 758 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); } //$NON-NLS-1$ + case 774 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name RIGHT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.RIGHT_SHIFT); break; - case 759 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ + case 775 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= ShiftExpression_NotName..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; - case 760 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); } //$NON-NLS-1$ + case 776 : if (DEBUG) { System.out.println("ShiftExpression_NotName ::= Name UNSIGNED_RIGHT_SHIFT..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.UNSIGNED_RIGHT_SHIFT); break; - case 762 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ + case 778 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS); break; - case 763 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); } //$NON-NLS-1$ + case 779 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LESS); break; - case 764 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ + case 780 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= ShiftExpression_NotName"); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER); break; - case 765 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); } //$NON-NLS-1$ + case 781 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.GREATER); break; - case 766 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ + case 782 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.LESS_EQUAL); break; - case 767 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); } //$NON-NLS-1$ + case 783 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name LESS_EQUAL..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.LESS_EQUAL); break; - case 768 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ + case 784 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.GREATER_EQUAL); break; - case 769 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); } //$NON-NLS-1$ + case 785 : if (DEBUG) { System.out.println("RelationalExpression_NotName ::= Name GREATER_EQUAL..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.GREATER_EQUAL); break; - case 771 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); } //$NON-NLS-1$ + case 787 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::= Name instanceof..."); } //$NON-NLS-1$ consumeInstanceOfExpressionWithName(); break; - case 772 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); } //$NON-NLS-1$ + case 788 : if (DEBUG) { System.out.println("InstanceofExpression_NotName ::=..."); } //$NON-NLS-1$ consumeInstanceOfExpression(); break; - case 774 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ + case 790 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.EQUAL_EQUAL); break; - case 775 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); } //$NON-NLS-1$ + case 791 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name EQUAL_EQUAL..."); } //$NON-NLS-1$ consumeEqualityExpressionWithName(OperatorIds.EQUAL_EQUAL); break; - case 776 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ + case 792 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::=..."); } //$NON-NLS-1$ consumeEqualityExpression(OperatorIds.NOT_EQUAL); break; - case 777 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); } //$NON-NLS-1$ + case 793 : if (DEBUG) { System.out.println("EqualityExpression_NotName ::= Name NOT_EQUAL..."); } //$NON-NLS-1$ consumeEqualityExpressionWithName(OperatorIds.NOT_EQUAL); break; - case 779 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); } //$NON-NLS-1$ + case 795 : if (DEBUG) { System.out.println("AndExpression_NotName ::= AndExpression_NotName AND..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND); break; - case 780 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); } //$NON-NLS-1$ + case 796 : if (DEBUG) { System.out.println("AndExpression_NotName ::= Name AND EqualityExpression"); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.AND); break; - case 782 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ + case 798 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.XOR); break; - case 783 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); } //$NON-NLS-1$ + case 799 : if (DEBUG) { System.out.println("ExclusiveOrExpression_NotName ::= Name XOR AndExpression"); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.XOR); break; - case 785 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ + case 801 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR); break; - case 786 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); } //$NON-NLS-1$ + case 802 : if (DEBUG) { System.out.println("InclusiveOrExpression_NotName ::= Name OR..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.OR); break; - case 788 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); } //$NON-NLS-1$ + case 804 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.AND_AND); break; - case 789 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); } //$NON-NLS-1$ + case 805 : if (DEBUG) { System.out.println("ConditionalAndExpression_NotName ::= Name AND_AND..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.AND_AND); break; - case 791 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); } //$NON-NLS-1$ + case 807 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::=..."); } //$NON-NLS-1$ consumeBinaryExpression(OperatorIds.OR_OR); break; - case 792 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); } //$NON-NLS-1$ + case 808 : if (DEBUG) { System.out.println("ConditionalOrExpression_NotName ::= Name OR_OR..."); } //$NON-NLS-1$ consumeBinaryExpressionWithName(OperatorIds.OR_OR); break; - case 794 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); } //$NON-NLS-1$ + case 810 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::=..."); } //$NON-NLS-1$ consumeConditionalExpression(OperatorIds.QUESTIONCOLON) ; break; - case 795 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); } //$NON-NLS-1$ + case 811 : if (DEBUG) { System.out.println("ConditionalExpression_NotName ::= Name QUESTION..."); } //$NON-NLS-1$ consumeConditionalExpressionWithName(OperatorIds.QUESTIONCOLON) ; break; - case 799 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ + case 815 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderName() ; break; - case 800 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ + case 816 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= Modifiers AT..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; break; - case 801 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ + case 817 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderNameWithTypeParameters() ; break; - case 802 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ + case 818 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeaderName ::= AT..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeaderName() ; break; - case 803 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); } //$NON-NLS-1$ + case 819 : if (DEBUG) { System.out.println("AnnotationTypeDeclarationHeader ::=..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclarationHeader() ; break; - case 804 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); } //$NON-NLS-1$ + case 820 : if (DEBUG) { System.out.println("AnnotationTypeDeclaration ::=..."); } //$NON-NLS-1$ consumeAnnotationTypeDeclaration() ; break; - case 806 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); } //$NON-NLS-1$ + case 822 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::="); } //$NON-NLS-1$ consumeEmptyAnnotationTypeMemberDeclarationsopt() ; break; - case 807 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ + case 823 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarationsopt ::= NestedType..."); } //$NON-NLS-1$ consumeAnnotationTypeMemberDeclarationsopt() ; break; - case 809 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); } //$NON-NLS-1$ + case 825 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclarations ::=..."); } //$NON-NLS-1$ consumeAnnotationTypeMemberDeclarations() ; break; - case 810 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); } //$NON-NLS-1$ + case 826 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt..."); } //$NON-NLS-1$ consumeMethodHeaderNameWithTypeParameters(true); break; - case 811 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ + case 827 : if (DEBUG) { System.out.println("AnnotationMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ consumeMethodHeaderName(true); break; - case 812 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); } //$NON-NLS-1$ + case 828 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::="); } //$NON-NLS-1$ consumeEmptyMethodHeaderDefaultValue() ; break; - case 813 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); } //$NON-NLS-1$ + case 829 : if (DEBUG) { System.out.println("AnnotationMethodHeaderDefaultValueopt ::= DefaultValue"); } //$NON-NLS-1$ consumeMethodHeaderDefaultValue(); break; - case 814 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); } //$NON-NLS-1$ + case 830 : if (DEBUG) { System.out.println("AnnotationMethodHeader ::= AnnotationMethodHeaderName..."); } //$NON-NLS-1$ consumeMethodHeader(); break; - case 815 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); } //$NON-NLS-1$ + case 831 : if (DEBUG) { System.out.println("AnnotationTypeMemberDeclaration ::=..."); } //$NON-NLS-1$ consumeAnnotationTypeMemberDeclaration() ; break; - case 823 : if (DEBUG) { System.out.println("AnnotationName ::= AT UnannotatableName"); } //$NON-NLS-1$ + case 839 : if (DEBUG) { System.out.println("AnnotationName ::= AT UnannotatableName"); } //$NON-NLS-1$ consumeAnnotationName() ; break; - case 824 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ + case 840 : if (DEBUG) { System.out.println("NormalAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ consumeNormalAnnotation(false) ; break; - case 825 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); } //$NON-NLS-1$ + case 841 : if (DEBUG) { System.out.println("MemberValuePairsopt ::="); } //$NON-NLS-1$ consumeEmptyMemberValuePairsopt() ; break; - case 828 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); } //$NON-NLS-1$ + case 844 : if (DEBUG) { System.out.println("MemberValuePairs ::= MemberValuePairs COMMA..."); } //$NON-NLS-1$ consumeMemberValuePairs() ; break; - case 829 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); } //$NON-NLS-1$ + case 845 : if (DEBUG) { System.out.println("MemberValuePair ::= SimpleName EQUAL EnterMemberValue..."); } //$NON-NLS-1$ consumeMemberValuePair() ; break; - case 830 : if (DEBUG) { System.out.println("EnterMemberValue ::="); } //$NON-NLS-1$ + case 846 : if (DEBUG) { System.out.println("EnterMemberValue ::="); } //$NON-NLS-1$ consumeEnterMemberValue() ; break; - case 831 : if (DEBUG) { System.out.println("ExitMemberValue ::="); } //$NON-NLS-1$ + case 847 : if (DEBUG) { System.out.println("ExitMemberValue ::="); } //$NON-NLS-1$ consumeExitMemberValue() ; break; - case 833 : if (DEBUG) { System.out.println("MemberValue ::= Name"); } //$NON-NLS-1$ + case 849 : if (DEBUG) { System.out.println("MemberValue ::= Name"); } //$NON-NLS-1$ consumeMemberValueAsName() ; break; - case 836 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ + case 852 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ consumeMemberValueArrayInitializer() ; break; - case 837 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ + case 853 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ consumeMemberValueArrayInitializer() ; break; - case 838 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ + case 854 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ consumeEmptyMemberValueArrayInitializer() ; break; - case 839 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ + case 855 : if (DEBUG) { System.out.println("MemberValueArrayInitializer ::=..."); } //$NON-NLS-1$ consumeEmptyMemberValueArrayInitializer() ; break; - case 840 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); } //$NON-NLS-1$ + case 856 : if (DEBUG) { System.out.println("EnterMemberValueArrayInitializer ::="); } //$NON-NLS-1$ consumeEnterMemberValueArrayInitializer() ; break; - case 842 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); } //$NON-NLS-1$ + case 858 : if (DEBUG) { System.out.println("MemberValues ::= MemberValues COMMA MemberValue"); } //$NON-NLS-1$ consumeMemberValues() ; break; - case 843 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); } //$NON-NLS-1$ + case 859 : if (DEBUG) { System.out.println("MarkerAnnotation ::= AnnotationName"); } //$NON-NLS-1$ consumeMarkerAnnotation(false) ; break; - case 844 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); } //$NON-NLS-1$ + case 860 : if (DEBUG) { System.out.println("SingleMemberAnnotationMemberValue ::= MemberValue"); } //$NON-NLS-1$ consumeSingleMemberAnnotationMemberValue() ; break; - case 845 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ + case 861 : if (DEBUG) { System.out.println("SingleMemberAnnotation ::= AnnotationName LPAREN..."); } //$NON-NLS-1$ consumeSingleMemberAnnotation(false) ; break; - case 846 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); } //$NON-NLS-1$ + case 862 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt TypeParameters"); } //$NON-NLS-1$ consumeRecoveryMethodHeaderNameWithTypeParameters(); break; - case 847 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ + case 863 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= Modifiersopt Type..."); } //$NON-NLS-1$ consumeRecoveryMethodHeaderName(); break; - case 848 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault..."); } //$NON-NLS-1$ + case 864 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault..."); } //$NON-NLS-1$ consumeRecoveryMethodHeaderNameWithTypeParameters(); break; - case 849 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault Type"); } //$NON-NLS-1$ + case 865 : if (DEBUG) { System.out.println("RecoveryMethodHeaderName ::= ModifiersWithDefault Type"); } //$NON-NLS-1$ consumeRecoveryMethodHeaderName(); break; - case 850 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ + case 866 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ consumeMethodHeader(); break; - case 851 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ + case 867 : if (DEBUG) { System.out.println("RecoveryMethodHeader ::= RecoveryMethodHeaderName..."); } //$NON-NLS-1$ consumeMethodHeader(); break; @@ -9015,12 +9082,21 @@ protected void consumeStatementBreakWithLabel() { // BreakStatement ::= 'break' Identifier ';' // break pushs a position on this.intStack in case there is no label - pushOnAstStack( - new BreakStatement( - this.identifierStack[this.identifierPtr--], - this.intStack[this.intPtr--], - this.endStatementPosition)); - this.identifierLengthPtr--; + // add the compliance check + if (this.expressionLengthStack[this.expressionLengthPtr--] != 0) { + Expression expr = this.expressionStack[this.expressionPtr--]; + char[] labelOrExpr = expr instanceof Literal ? + ((Literal) expr).source() : expr instanceof SingleNameReference ? ((SingleNameReference) expr).token : null; + BreakStatement breakStatement = new BreakStatement( + labelOrExpr, + this.intStack[this.intPtr--], + this.endStatementPosition); + pushOnAstStack(breakStatement); + breakStatement.expression = expr; // need to figure out later whether this is a label or an expression. + if (expr instanceof SingleNameReference) { + ((SingleNameReference) expr).isLabel = true; + } + } } protected void consumeStatementCatch() { // CatchClause ::= 'catch' '(' FormalParameter ')' Block @@ -9198,25 +9274,25 @@ protected void consumeStatementReturn() { pushOnAstStack(new ReturnStatement(null, this.intStack[this.intPtr--], this.endStatementPosition)); } } -protected void consumeStatementSwitch() { - // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock - +private void createSwitchStatementOrExpression(boolean isStmt) { + //OpenBlock just makes the semantic action blockStart() //the block is inlined but a scope need to be created //if some declaration occurs. + this.nestedType--; int length; - SwitchStatement switchStatement = new SwitchStatement(); + SwitchStatement switchStatement = isStmt ? new SwitchStatement() : new SwitchExpression(); this.expressionLengthPtr--; switchStatement.expression = this.expressionStack[this.expressionPtr--]; if ((length = this.astLengthStack[this.astLengthPtr--]) != 0) { this.astPtr -= length; System.arraycopy( - this.astStack, - this.astPtr + 1, - switchStatement.statements = new Statement[length], - 0, - length); + this.astStack, + this.astPtr + 1, + switchStatement.statements = new Statement[length], + 0, + length); } switchStatement.explicitDeclarations = this.realBlockStack[this.realBlockPtr--]; pushOnAstStack(switchStatement); @@ -9225,7 +9301,11 @@ protected void consumeStatementSwitch() { switchStatement.sourceEnd = this.endStatementPosition; if (length == 0 && !containsComment(switchStatement.blockStart, switchStatement.sourceEnd)) { switchStatement.bits |= ASTNode.UndocumentedEmptyBlock; - } + } +} +protected void consumeStatementSwitch() { + // SwitchStatement ::= 'switch' OpenBlock '(' Expression ')' SwitchBlock + createSwitchStatementOrExpression(true); } protected void consumeStatementSynchronized() { // SynchronizedStatement ::= OnlySynchronized '(' Expression ')' Block @@ -9422,6 +9502,7 @@ protected void consumeStaticOnly() { protected void consumeSwitchBlock() { // SwitchBlock ::= '{' SwitchBlockStatements SwitchLabels '}' concatNodeLists(); + } protected void consumeSwitchBlockStatement() { // SwitchBlockStatement ::= SwitchLabels BlockStatements @@ -9435,6 +9516,109 @@ protected void consumeSwitchLabels() { // SwitchLabels ::= SwitchLabels SwitchLabel optimizedConcatNodeLists(); } +protected void consumeSwitchLabelCaseLhs() { +// System.out.println("consumeSwitchLabelCaseLhs"); +} +protected void consumeCaseLabelExpr() { +// SwitchLabelExpr ::= SwitchLabelCaseLhs BeginCaseExpr '->' + consumeCaseLabel(); + CaseStatement caseStatement = (CaseStatement) this.astStack[this.astPtr]; + if (!this.parsingJava12Plus) { +// problemReporter().caseStatementWithArrowNotBelow12(caseStatement); + problemReporter().previewFeatureNotSupported(caseStatement.sourceStart, caseStatement.sourceEnd, "Case Labels with '->'", CompilerOptions.VERSION_12); //$NON-NLS-1$ + } else if (!this.options.enablePreviewFeatures){ + problemReporter().previewFeatureNotEnabled(caseStatement.sourceStart, caseStatement.sourceEnd, "Case Labels with '->'"); //$NON-NLS-1$ + } else { + if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) { + problemReporter().previewFeatureUsed(caseStatement.sourceStart, caseStatement.sourceEnd); + } + } + caseStatement.isExpr = true; +} +protected void consumeDefaultLabelExpr() { +// SwitchLabelDefaultExpr ::= 'default' '->' + consumeDefaultLabel(); + CaseStatement defaultStatement = (CaseStatement) this.astStack[this.astPtr]; + if (!this.parsingJava12Plus) { +// problemReporter().caseStatementWithArrowNotBelow12(defaultStatement); + problemReporter().previewFeatureNotSupported(defaultStatement.sourceStart, defaultStatement.sourceEnd, "Case Labels with '->'", CompilerOptions.VERSION_12); //$NON-NLS-1$ + } else if (!this.options.enablePreviewFeatures){ + problemReporter().previewFeatureNotEnabled(defaultStatement.sourceStart, defaultStatement.sourceEnd, "Case Labels with '->'"); //$NON-NLS-1$ + } else { + if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) { + problemReporter().previewFeatureUsed(defaultStatement.sourceStart, defaultStatement.sourceEnd); + } + } + defaultStatement.isExpr = true; +} +protected void consumeSwitchExpression() { +// SwitchExpression ::= 'switch' '(' Expression ')' OpenBlock SwitchExpressionBlock + createSwitchStatementOrExpression(false); + if (this.astLengthStack[this.astLengthPtr--] != 0) { + SwitchExpression s = (SwitchExpression) this.astStack[this.astPtr--]; + + if (!this.parsingJava12Plus) { + problemReporter().previewFeatureNotSupported(s.sourceStart, s.sourceEnd, "Switch Expressions", CompilerOptions.VERSION_12); //$NON-NLS-1$ + } else if (!this.options.enablePreviewFeatures) { + problemReporter().previewFeatureNotEnabled(s.sourceStart, s.sourceEnd, "Switch Expressions"); //$NON-NLS-1$ + } else { + if (this.options.isAnyEnabled(IrritantSet.PREVIEW)) { + problemReporter().previewFeatureUsed(s.sourceStart, s.sourceEnd); + } + } + + pushOnExpressionStack(s); + } +} +protected void consumeSwitchExprThrowDefaultArm() { +// SwitchExprThrowDefaultArm ::= SwitchLabelDefaultExpr Expression ';' + consumeStatementThrow(); +// pushSwitchLabeledRule(SwitchLabeledRule.RULE_KIND.DEFAULT_THROW); +} +protected void consumeConstantExpression() { + // do nothing for now. +} +protected void consumeConstantExpressions() { + concatExpressionLists(); +} +protected void consumeSwitchLabeledRules() { + concatNodeLists(); +} +protected void consumeSwitchLabeledRule() { +// SwitchLabeledRule ::= SwitchLabeledExpression +// SwitchLabeledRule ::= SwitchLabeledBlock +// SwitchLabeledRule ::= SwitchLabeledThrowStatement +// concatNodeLists(); + + // do nothing explicit here +} +protected void consumeSwitchLabeledRuleToBlockStatement() { + // do nothing +} +protected void consumeSwitchLabeledExpression() { + consumeExpressionStatement(); + Expression expr = (Expression) this.astStack[this.astPtr]; + BreakStatement breakStatement = new BreakStatement( + null, + expr.sourceStart, + this.endStatementPosition); + breakStatement.isImplicit = true; + breakStatement.expression = expr; + this.astStack[this.astPtr] = breakStatement; + concatNodeLists(); +} +protected void consumeSwitchLabeledBlock() { + concatNodeLists(); +} +protected void consumeSwitchLabeledThrowStatement() { + // TODO: Semicolon not there - so we call this early + consumeStatementThrow(); + concatNodeLists(); +} +protected void consumeThrowExpression() { + // do nothing +} +protected boolean caseFlagSet = false; protected void consumeToken(int type) { /* remember the last consumed value */ /* try to minimize the number of build values */ @@ -9458,11 +9642,16 @@ protected void consumeToken(int type) { //System.out.println(this.scanner.toStringAction(type)); switch (type) { case TokenNameARROW: - consumeLambdaHeader(); + if (!this.caseFlagSet && this.scanner.lookBack[0] != TokenNamedefault) + consumeLambdaHeader(); + this.caseFlagSet = false; break; case TokenNameCOLON_COLON: this.colonColonStart = this.scanner.currentPosition - 2; break; + case TokenNameBeginCaseExpr: + this.caseFlagSet = true; + break; case TokenNameBeginLambda: flushCommentsDefinedPriorTo(this.scanner.currentPosition); break; @@ -9674,7 +9863,6 @@ protected void consumeToken(int type) { case TokenNamethrow : case TokenNamedo : case TokenNameif : - case TokenNameswitch : case TokenNametry : case TokenNamewhile : case TokenNamebreak : @@ -9689,6 +9877,11 @@ protected void consumeToken(int type) { case TokenNameprovides: pushOnIntStack(this.scanner.startPosition); break; + case TokenNameswitch : + consumeNestedType(); + this.nestedMethod[this.nestedType] ++; + pushOnIntStack(this.scanner.startPosition); + break; case TokenNamenew : // https://bugs.eclipse.org/bugs/show_bug.cgi?id=40954 resetModifiers(); diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java index 20d477f5c0..da927b5490 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ParserBasicInformation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2014 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -19,22 +23,22 @@ public interface ParserBasicInformation { public final static int - ERROR_SYMBOL = 128, + ERROR_SYMBOL = 129, MAX_NAME_LENGTH = 41, - NUM_STATES = 1152, + NUM_STATES = 1166, - NT_OFFSET = 128, - SCOPE_UBOUND = 290, - SCOPE_SIZE = 291, - LA_STATE_OFFSET = 16451, + NT_OFFSET = 129, + SCOPE_UBOUND = 297, + SCOPE_SIZE = 298, + LA_STATE_OFFSET = 16966, MAX_LA = 1, - NUM_RULES = 851, - NUM_TERMINALS = 128, - NUM_NON_TERMINALS = 388, - NUM_SYMBOLS = 516, - START_STATE = 895, - EOFT_SYMBOL = 60, - EOLT_SYMBOL = 60, - ACCEPT_ACTION = 16450, - ERROR_ACTION = 16451; + NUM_RULES = 867, + NUM_TERMINALS = 129, + NUM_NON_TERMINALS = 397, + NUM_SYMBOLS = 526, + START_STATE = 1124, + EOFT_SYMBOL = 61, + EOLT_SYMBOL = 61, + ACCEPT_ACTION = 16965, + ERROR_ACTION = 16966; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java index 43e2477015..05fd504e2d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Stephan Herrmann - Contribution for bug 186342 - [compiler][null] Using annotations for null checking @@ -106,6 +110,7 @@ public class Scanner implements TerminalTokens { public boolean wasAcr = false; public boolean fakeInModule = false; + boolean inCase = false; /** * The current context of the scanner w.r.t restricted keywords * @@ -1158,7 +1163,12 @@ public void ungetToken(int unambiguousToken) { } this.nextToken = unambiguousToken; } - +private void updateCase(int token) { + if (token == TokenNamecase) + this.inCase = true; + if (token == TokenNameCOLON || token == TokenNameARROW) + this.inCase = false; +} public int getNextToken() throws InvalidInputException { int token; @@ -1179,13 +1189,14 @@ public int getNextToken() throws InvalidInputException { if (this.activeParser == null) { // anybody interested in the grammatical structure of the program should have registered. return token; } - if (token == TokenNameLPAREN || token == TokenNameLESS || token == TokenNameAT) { + if (token == TokenNameLPAREN || token == TokenNameLESS || token == TokenNameAT || token == TokenNameARROW) { token = disambiguatedToken(token); } else if (token == TokenNameELLIPSIS) { this.consumingEllipsisAnnotations = false; } this.lookBack[0] = this.lookBack[1]; this.lookBack[1] = token; + updateCase(token); return token; } protected int getNextToken0() throws InvalidInputException { @@ -4824,7 +4835,11 @@ int disambiguatedRestrictedKeyword(int restrictedKeywordToken) { } int disambiguatedToken(int token) { final VanguardParser parser = getVanguardParser(); - if (token == TokenNameLPAREN && maybeAtLambdaOrCast()) { + if (token == TokenNameARROW && this.inCase) { + this.nextToken = TokenNameARROW; + this.inCase = false; + return TokenNameBeginCaseExpr; + } else if (token == TokenNameLPAREN && maybeAtLambdaOrCast()) { if (parser.parse(Goal.LambdaParameterListGoal) == VanguardParser.SUCCESS) { this.nextToken = TokenNameLPAREN; return TokenNameBeginLambda; diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java index c9bf5ce3bc..d20a4d224c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/ScannerHelper.java @@ -47,6 +47,7 @@ public class ScannerHelper { private static long[][][] Tables8; private static long[][][] Tables9; private static long[][][] Tables11; + private static long[][][] Tables12; public final static int MAX_OBVIOUS = 128; public final static int[] OBVIOUS_IDENT_CHAR_NATURES = new int[MAX_OBVIOUS]; @@ -151,6 +152,9 @@ static void initializeTable19() { static void initializeTableJava11() { Tables11 = initializeTables("unicode10"); //$NON-NLS-1$ } +static void initializeTableJava12() { + Tables12 = initializeTables("unicode11"); //$NON-NLS-1$ +} static long[][][] initializeTables(String unicode_path) { long[][][] tempTable = new long[2][][]; tempTable[START_INDEX] = new long[3][]; @@ -290,12 +294,18 @@ public static boolean isJavaIdentifierPart(long complianceLevel, int codePoint) initializeTable19(); } return isJavaIdentifierPart0(codePoint, Tables9); - } else { + } else if (complianceLevel <= ClassFileConstants.JDK11) { // java 11 supports Unicode 10 if (Tables11 == null) { initializeTableJava11(); } return isJavaIdentifierPart0(codePoint, Tables11); + } else { + // java 12 supports Unicode 11 + if (Tables12 == null) { + initializeTableJava12(); + } + return isJavaIdentifierPart0(codePoint, Tables12); } } public static boolean isJavaIdentifierPart(long complianceLevel, char high, char low) { @@ -351,12 +361,19 @@ public static boolean isJavaIdentifierStart(long complianceLevel, int codePoint) initializeTable19(); } return isJavaIdentifierStart0(codePoint, Tables9); - } else { + } else if (complianceLevel <= ClassFileConstants.JDK11) { // java 11 supports Unicode 10 if (Tables11 == null) { initializeTableJava11(); } return isJavaIdentifierStart0(codePoint, Tables11); + } else { + + // java 12 supports Unicode 11 + if (Tables12 == null) { + initializeTableJava12(); + } + return isJavaIdentifierStart0(codePoint, Tables12); } } private static int toCodePoint(char high, char low) { diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java index e7f6bb9d22..12c16dba22 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/TerminalTokens.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2013 IBM Corporation and others. + * Copyright (c) 2000, 2018 IBM Corporation and others. * * This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 @@ -8,6 +8,9 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. * * Contributors: * IBM Corporation - initial API and implementation @@ -39,75 +42,75 @@ public interface TerminalTokens { TokenNameCOMMENT_JAVADOC = 1003; int TokenNameIdentifier = 22, - TokenNameabstract = 51, - TokenNameassert = 73, - TokenNameboolean = 97, - TokenNamebreak = 74, - TokenNamebyte = 98, - TokenNamecase = 99, - TokenNamecatch = 100, - TokenNamechar = 101, - TokenNameclass = 66, - TokenNamecontinue = 75, - TokenNameconst = 126, - TokenNamedefault = 71, - TokenNamedo = 76, - TokenNamedouble = 102, - TokenNameelse = 111, - TokenNameenum = 69, - TokenNameextends = 85, - TokenNamefalse = 39, - TokenNamefinal = 52, - TokenNamefinally = 109, - TokenNamefloat = 103, - TokenNamefor = 77, - TokenNamegoto = 127, - TokenNameif = 78, - TokenNameimplements = 122, - TokenNameimport = 104, + TokenNameabstract = 52, + TokenNameassert = 76, + TokenNameboolean = 99, + TokenNamebreak = 77, + TokenNamebyte = 100, + TokenNamecase = 101, + TokenNamecatch = 102, + TokenNamechar = 103, + TokenNameclass = 67, + TokenNamecontinue = 78, + TokenNameconst = 127, + TokenNamedefault = 73, + TokenNamedo = 79, + TokenNamedouble = 104, + TokenNameelse = 112, + TokenNameenum = 71, + TokenNameextends = 86, + TokenNamefalse = 38, + TokenNamefinal = 53, + TokenNamefinally = 111, + TokenNamefloat = 105, + TokenNamefor = 80, + TokenNamegoto = 128, + TokenNameif = 81, + TokenNameimplements = 123, + TokenNameimport = 106, TokenNameinstanceof = 17, - TokenNameint = 105, - TokenNameinterface = 68, - TokenNamelong = 106, - TokenNamenative = 53, + TokenNameint = 107, + TokenNameinterface = 70, + TokenNamelong = 108, + TokenNamenative = 54, TokenNamenew = 36, - TokenNamenull = 40, - TokenNamepackage = 84, - TokenNameprivate = 54, - TokenNameprotected = 55, - TokenNamepublic = 56, - TokenNamereturn = 79, - TokenNameshort = 107, - TokenNamestatic = 38, - TokenNamestrictfp = 57, + TokenNamenull = 39, + TokenNamepackage = 85, + TokenNameprivate = 55, + TokenNameprotected = 56, + TokenNamepublic = 57, + TokenNamereturn = 82, + TokenNameshort = 109, + TokenNamestatic = 48, + TokenNamestrictfp = 58, TokenNamesuper = 34, - TokenNameswitch = 80, + TokenNameswitch = 51, TokenNamesynchronized = 50, TokenNamethis = 35, - TokenNamethrow = 81, - TokenNamethrows = 119, - TokenNametransient = 58, - TokenNametrue = 41, - TokenNametry = 82, - TokenNamevoid = 108, - TokenNamevolatile = 59, - TokenNamewhile = 72, - TokenNamemodule = 112, - TokenNameopen = 113, - TokenNamerequires = 114, - TokenNametransitive = 120, - TokenNameexports = 115, - TokenNameopens = 116, - TokenNameto = 123, - TokenNameuses = 117, - TokenNameprovides = 118, - TokenNamewith = 124, - TokenNameIntegerLiteral = 42, - TokenNameLongLiteral = 43, - TokenNameFloatingPointLiteral = 44, - TokenNameDoubleLiteral = 45, - TokenNameCharacterLiteral = 46, - TokenNameStringLiteral = 47, + TokenNamethrow = 74, + TokenNamethrows = 120, + TokenNametransient = 59, + TokenNametrue = 40, + TokenNametry = 83, + TokenNamevoid = 110, + TokenNamevolatile = 60, + TokenNamewhile = 75, + TokenNamemodule = 113, + TokenNameopen = 114, + TokenNamerequires = 115, + TokenNametransitive = 121, + TokenNameexports = 116, + TokenNameopens = 117, + TokenNameto = 124, + TokenNameuses = 118, + TokenNameprovides = 119, + TokenNamewith = 125, + TokenNameIntegerLiteral = 41, + TokenNameLongLiteral = 42, + TokenNameFloatingPointLiteral = 43, + TokenNameDoubleLiteral = 44, + TokenNameCharacterLiteral = 45, + TokenNameStringLiteral = 46, TokenNamePLUS_PLUS = 2, TokenNameMINUS_MINUS = 3, TokenNameEQUAL_EQUAL = 19, @@ -117,53 +120,54 @@ public interface TerminalTokens { TokenNameLEFT_SHIFT = 18, TokenNameRIGHT_SHIFT = 14, TokenNameUNSIGNED_RIGHT_SHIFT = 16, - TokenNamePLUS_EQUAL = 86, - TokenNameMINUS_EQUAL = 87, - TokenNameMULTIPLY_EQUAL = 88, - TokenNameDIVIDE_EQUAL = 89, - TokenNameAND_EQUAL = 90, - TokenNameOR_EQUAL = 91, - TokenNameXOR_EQUAL = 92, - TokenNameREMAINDER_EQUAL = 93, - TokenNameLEFT_SHIFT_EQUAL = 94, - TokenNameRIGHT_SHIFT_EQUAL = 95, - TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 96, + TokenNamePLUS_EQUAL = 87, + TokenNameMINUS_EQUAL = 88, + TokenNameMULTIPLY_EQUAL = 89, + TokenNameDIVIDE_EQUAL = 90, + TokenNameAND_EQUAL = 91, + TokenNameOR_EQUAL = 92, + TokenNameXOR_EQUAL = 93, + TokenNameREMAINDER_EQUAL = 94, + TokenNameLEFT_SHIFT_EQUAL = 95, + TokenNameRIGHT_SHIFT_EQUAL = 96, + TokenNameUNSIGNED_RIGHT_SHIFT_EQUAL = 97, TokenNameOR_OR = 31, TokenNameAND_AND = 30, TokenNamePLUS = 4, TokenNameMINUS = 5, - TokenNameNOT = 62, + TokenNameNOT = 63, TokenNameREMAINDER = 9, - TokenNameXOR = 23, + TokenNameXOR = 24, TokenNameAND = 21, TokenNameMULTIPLY = 8, - TokenNameOR = 27, - TokenNameTWIDDLE = 63, + TokenNameOR = 28, + TokenNameTWIDDLE = 64, TokenNameDIVIDE = 10, TokenNameGREATER = 15, TokenNameLESS = 11, - TokenNameLPAREN = 24, + TokenNameLPAREN = 23, TokenNameRPAREN = 25, - TokenNameLBRACE = 48, + TokenNameLBRACE = 49, TokenNameRBRACE = 33, TokenNameLBRACKET = 6, - TokenNameRBRACKET = 64, + TokenNameRBRACKET = 66, TokenNameSEMICOLON = 26, TokenNameQUESTION = 29, - TokenNameCOLON = 61, + TokenNameCOLON = 62, TokenNameCOMMA = 32, TokenNameDOT = 1, - TokenNameEQUAL = 70, + TokenNameEQUAL = 72, TokenNameAT = 37, - TokenNameELLIPSIS = 121, - TokenNameARROW = 110, + TokenNameELLIPSIS = 122, + TokenNameARROW = 98, TokenNameCOLON_COLON = 7, - TokenNameBeginLambda = 49, + TokenNameBeginLambda = 47, TokenNameBeginIntersectionCast = 65, - TokenNameBeginTypeArguments = 83, - TokenNameElidedSemicolonAndRightBrace = 67, - TokenNameAT308 = 28, - TokenNameAT308DOTDOTDOT = 125, - TokenNameEOF = 60, - TokenNameERROR = 128; + TokenNameBeginTypeArguments = 84, + TokenNameElidedSemicolonAndRightBrace = 68, + TokenNameAT308 = 27, + TokenNameAT308DOTDOTDOT = 126, + TokenNameBeginCaseExpr = 69, + TokenNameEOF = 61, + TokenNameERROR = 129; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc Binary files differindex 274fa5063e..2bd646ecc7 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser1.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc Binary files differindex 4865baaaa5..a49d7119ed 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser10.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc Binary files differindex 37144d48aa..ef79d1de51 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser11.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc Binary files differindex 867a099f38..e9fa8cd3c9 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser12.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc Binary files differindex 2c1fbd338b..4af7a4ffad 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser13.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc Binary files differindex 07b4bf6bbf..24432a187f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser14.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc Binary files differindex 56d678fa71..b84e8bb579 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser15.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc Binary files differindex 9e8f5966ee..c5f0e8a576 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser16.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc Binary files differindex 353090ba35..3cf316c2f2 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser17.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc Binary files differindex 266bf1bcf6..f25fe9aa0d 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser18.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc index df3f4df043..68c3b12f49 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser19.rsc @@ -1,2 +1,2 @@ -ooF!!m yF!!@@@@00m!!!!=== y##""!!Cd=!!!#!c =}H0II000lab
-U EFFnDGBU=E%%S"#
\ No newline at end of file +ppH!!o zH!!BBBB11o!!!!>>> z##""!!Df!!!#!e >~K1LL1>11ncd
+V GHHbEJFICV>G%%T"#
\ No newline at end of file diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc Binary files differindex 3a3cedb52a..7ae8abeab0 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser2.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc Binary files differindex 8bdb123d8b..87ff0c441f 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser20.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc Binary files differindex 3031ff9f42..05ba22c1de 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser21.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc Binary files differindex 518ee2acf0..ad9e312e73 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser22.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc Binary files differindex c8dd03c345..76da0d61db 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser23.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc Binary files differindex ec7d7e618c..5b4675f3c8 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser24.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc Binary files differindex 95008983e9..add45284a4 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser3.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc Binary files differindex a1145dcb17..aa09c17fd2 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser4.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc Binary files differindex f56c662a2d..b4b627b5f6 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser5.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc Binary files differindex 28c6b22efb..ed603bb9f3 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser6.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc Binary files differindex 30e76fa77b..379d8cdd01 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser7.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc Binary files differindex e594f6b593..4e9607b325 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser8.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc Binary files differindex 4b693991e9..9670813691 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/parser9.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props index 5268fd66d3..64eb6d9eba 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/readableNames.props @@ -84,6 +84,7 @@ ConditionalOrExpression=Expression ConditionalOrExpression_NotName=Expression ConstantDeclaration=ConstantDeclaration ConstantExpression=ConstantExpression +ConstantExpressions=ConstantExpressions ConstructorDeclaration=ConstructorDeclaration ConstructorHeader=ConstructorDeclaration ConstructorHeaderName=ConstructorHeaderName @@ -296,10 +297,18 @@ StaticOnly=StaticOnly SwitchBlock=SwitchBlock SwitchBlockStatement=SwitchBlockStatement SwitchBlockStatements=SwitchBlockStatements +SwitchExpression=SwitchExpression SwitchLabel=SwitchLabel +SwitchLabelCaseLhs=SwitchLabelCaseLhs +SwitchLabelExpr=SwitchLabelDefaultExpr +SwitchLabeledBlock=SwitchLabeledBlock +SwitchLabeledExpression=SwitchLabeledExpression +SwitchLabeledRule=SwitchLabeledRule +SwitchLabeledThrowStatement=SwitchLabeledThrowStatement SwitchLabels=SwitchLabels SwitchStatement=SwitchStatement SynchronizedStatement=SynchronizedStatement +ThrowExpression=ThrowExpression ThrowStatement=ThrowStatement TrailingSemiColon=; TryBlock=Block diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc Binary files differnew file mode 100644 index 0000000000..f434660ef0 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part0.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc Binary files differnew file mode 100644 index 0000000000..abb590ba3d --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part1.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc Binary files differnew file mode 100644 index 0000000000..c8241e80d5 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part14.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc Binary files differnew file mode 100644 index 0000000000..ab6b33ed48 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/part2.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc Binary files differnew file mode 100644 index 0000000000..1cd786208c --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start0.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc Binary files differnew file mode 100644 index 0000000000..2ca6b51f99 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start1.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc Binary files differnew file mode 100644 index 0000000000..ab6b33ed48 --- /dev/null +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/unicode11/start2.rsc diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java index 1a47e1d8c2..d9361bf5db 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/ProblemReporter.java @@ -7,7 +7,11 @@ * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 - * + * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation * Benjamin Muskalla - Contribution for bug 239066 @@ -154,6 +158,7 @@ import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression; import org.eclipse.jdt.internal.compiler.ast.ReturnStatement; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.SwitchExpression; import org.eclipse.jdt.internal.compiler.ast.SwitchStatement; import org.eclipse.jdt.internal.compiler.ast.ThisReference; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; @@ -662,6 +667,8 @@ public static int getIrritant(int problemID) { return CompilerOptions.APILeak; case IProblem.UnstableAutoModuleName: return CompilerOptions.UnstableAutoModuleName; + case IProblem.PreviewFeatureUsed: + return CompilerOptions.PreviewFeatureUsed; } return 0; } @@ -806,6 +813,8 @@ public static int getProblemCategory(int severity, int problemID) { return CategorizedProblem.CAT_MEMBER; if ((problemID & IProblem.ModuleRelated) != 0) return CategorizedProblem.CAT_MODULE; + if ((problemID & IProblem.Compliance) != 0) + return CategorizedProblem.CAT_COMPLIANCE; } return CategorizedProblem.CAT_INTERNAL; } @@ -6060,7 +6069,8 @@ public boolean expressionNonNullComparison(Expression expr, boolean checkForNull || expr instanceof ThisReference) { // fall through to bottom } else if (expr instanceof Literal - || expr instanceof ConditionalExpression) { + || expr instanceof ConditionalExpression + || expr instanceof SwitchExpression) { if (expr instanceof NullLiteral) { needImplementation(location); // reported as nonnull?? return false; @@ -6479,13 +6489,28 @@ public void notAFunctionalInterface(TypeDeclaration type) { type.sourceStart, type.sourceEnd); } + public void missingEnumConstantCase(SwitchStatement switchStatement, FieldBinding enumConstant) { + missingEnumConstantCase(switchStatement.defaultCase, enumConstant, switchStatement.expression); +} +public void missingEnumConstantCase(SwitchExpression switchExpression, FieldBinding enumConstant) { + missingSwitchExpressionEnumConstantCase(switchExpression.defaultCase, enumConstant, switchExpression.expression); +} +private void missingSwitchExpressionEnumConstantCase(CaseStatement defaultCase, FieldBinding enumConstant, ASTNode expression) { + this.handle( + IProblem.SwitchExpressionMissingEnumConstantCase, + new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) }, + new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) }, + expression.sourceStart, + expression.sourceEnd); +} +private void missingEnumConstantCase(CaseStatement defaultCase, FieldBinding enumConstant, ASTNode expression) { this.handle( - switchStatement.defaultCase == null ? IProblem.MissingEnumConstantCase : IProblem.MissingEnumConstantCaseDespiteDefault, - new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) }, - new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) }, - switchStatement.expression.sourceStart, - switchStatement.expression.sourceEnd); + defaultCase == null ? IProblem.MissingEnumConstantCase : IProblem.MissingEnumConstantCaseDespiteDefault, + new String[] {new String(enumConstant.declaringClass.readableName()), new String(enumConstant.name) }, + new String[] {new String(enumConstant.declaringClass.shortReadableName()), new String(enumConstant.name) }, + expression.sourceStart, + expression.sourceEnd); } public void missingDefaultCase(SwitchStatement switchStatement, boolean isEnumSwitch, TypeBinding expressionType) { if (isEnumSwitch) { @@ -6497,7 +6522,8 @@ public void missingDefaultCase(SwitchStatement switchStatement, boolean isEnumSw switchStatement.expression.sourceEnd); } else { this.handle( - IProblem.MissingDefaultCase, + switchStatement instanceof SwitchExpression ? + IProblem.SwitchExpressionMissingDefaultCase : IProblem.MissingDefaultCase, NoArgument, NoArgument, switchStatement.expression.sourceStart, @@ -9249,6 +9275,32 @@ public void problemNotAnalysed(Expression token, String optionKey) { token.sourceStart, token.sourceEnd); } +public void previewFeatureNotEnabled(int sourceStart, int sourceEnd, String featureName) { + String[] args = new String[] {featureName}; + this.handle( + IProblem.PreviewFeatureDisabled, + args, + args, + sourceStart, + sourceEnd); +} +public void previewFeatureUsed(int sourceStart, int sourceEnd) { + this.handle( + IProblem.PreviewFeatureUsed, + NoArgument, + NoArgument, + sourceStart, + sourceEnd); +} +public void previewFeatureNotSupported(int sourceStart, int sourceEnd, String featureName, String sourceLevel) { + String[] args = new String[] {featureName, sourceLevel}; + this.handle( + IProblem.PreviewFeatureNotSupported, + args, + args, + sourceStart, + sourceEnd); +} public void useAssertAsAnIdentifier(int sourceStart, int sourceEnd) { this.handle( IProblem.UseAssertAsAnIdentifier, @@ -10989,4 +11041,69 @@ public void autoModuleWithUnstableName(ModuleReference moduleReference) { moduleReference.sourceStart, moduleReference.sourceEnd); } +public void switchExpressionIncompatibleResultExpressions(SwitchExpression expression) { + TypeBinding type = expression.resultExpressions.get(0).resolvedType; + this.handle( + IProblem.SwitchExpressionsIncompatibleResultExpressionTypes, + new String[] {new String(type.readableName())}, + new String[] {new String(type.shortReadableName())}, + expression.sourceStart, + expression.sourceEnd); +} +public void switchExpressionEmptySwitchBlock(SwitchExpression expression) { + this.handle( + IProblem.SwitchExpressionsEmptySwitchBlock, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void switchExpressionNoResultExpressions(SwitchExpression expression) { + this.handle( + IProblem.SwitchExpressionsNoResultExpression, + NoArgument, + NoArgument, + expression.sourceStart, + expression.sourceEnd); +} +public void switchExpressionSwitchLabeledBlockCompletesNormally(Block block) { + this.handle( + IProblem.SwitchExpressionSwitchLabeledBlockCompletesNormally, + NoArgument, + NoArgument, + block.sourceStart, + block.sourceEnd); +} +public void switchExpressionLastStatementCompletesNormally(Statement stmt) { + this.handle( + IProblem.SwitchExpressionSwitchLabeledBlockCompletesNormally, + NoArgument, + NoArgument, + stmt.sourceStart, + stmt.sourceEnd); +} +public void switchExpressionTrailingSwitchLabels(Statement stmt) { + this.handle( + IProblem.SwitchExpressionTrailingSwitchLabels, + NoArgument, + NoArgument, + stmt.sourceStart, + stmt.sourceEnd); +} +public void switchExpressionMixedCase(ASTNode statement) { + this.handle( + IProblem.switchMixedCase, + NoArgument, + NoArgument, + statement.sourceStart, + statement.sourceEnd); +} +public void switchExpressionBreakMissingValue(ASTNode statement) { + this.handle( + IProblem.SwitchExpressionBreakMissingValue, + NoArgument, + NoArgument, + statement.sourceStart, + statement.sourceEnd); +} } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties index b4a85c9569..37dff5d64c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/problem/messages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2000, 2018 IBM Corporation and others. +# Copyright (c) 2000, 2019 IBM Corporation and others. # # This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 @@ -7,7 +7,10 @@ # https://www.eclipse.org/legal/epl-2.0/ # # SPDX-License-Identifier: EPL-2.0 -# +# +# This is an implementation of an early-draft specification developed under the Java +# Community Process (JCP) and is made available for testing and evaluation purposes +# only. The code is not compatible with any specification of the JCP. # # Contributors: # IBM Corporation - initial API and implementation @@ -879,6 +882,9 @@ 1100 = Problem detected during type inference: {0} #1101 is already used up but deprecated 1102 = At least one of the problems in category ''{0}'' is not analysed due to a compiler option being ignored +1103 = {0} is a preview feature and disabled by default. Use --enable-preview to enable +1104 = You are using a preview language feature that may or may not be supported in a future release +1105 = The preview feature {0} is only available with source level {1} and above # more programming problems: 1200 = Unlikely argument type {0} for {1} on a {2} @@ -967,6 +973,20 @@ 1511 = 'var' is not allowed here 1512 = 'var' cannot be mixed with non-var parameters +# Switch-Expressions +1600 = Incompatible switch results expressions {0} +1601 = A switch expression should have a non-empty switch block +1602 = A switch expression should have at least one result expression +1603 = A switch labeled block in a switch expression should not complete normally +1604 = The last statement of a switch block in a switch expression should not complete normally +1605 = Trailing switch labels are not allowed in a switch expression. +1606 = Mixing of different kinds of case statements '->' and ':' is not allowed within a switch +1607 = A switch expression should have a default case +1608 = Switch expressions are allowed only at source level 12 or above +1609 = Switch Case Labels with '->' are allowed only at source level 12 or above +1610 = Break of a switch expression should have a value +1611 = A Switch expression should cover all possible values + ### ELABORATIONS ## Access restrictions 78592 = The type ''{1}'' is not API (restriction on classpath entry ''{0}'') diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java index 51bfc33171..5d9b78bb81 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/JRTUtil.java @@ -8,6 +8,10 @@ * * SPDX-License-Identifier: EPL-2.0 * + * This is an implementation of an early-draft specification developed under the Java + * Community Process (JCP) and is made available for testing and evaluation purposes + * only. The code is not compatible with any specification of the JCP. + * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ @@ -75,7 +79,7 @@ public class JRTUtil { * how the JRT needs to be processed, for e.g., clients can skip a particular module * by returning FileVisitResult.SKIP_SUBTREE */ - public FileVisitResult visitModule(T mod) throws IOException; + public FileVisitResult visitModule(T path, String name) throws IOException; } static abstract class AbstractFileVisitor<T> implements FileVisitor<T> { @@ -180,6 +184,16 @@ public class JRTUtil { public static boolean hasCompilationUnit(File jrt, String qualifiedPackageName, String moduleName) { return getJrtSystem(jrt).hasClassFile(qualifiedPackageName, moduleName); } + /* + * Returns only the file name after removing trailing '/' if any for folders + */ + public static String sanitizedFileName(Path path) { + String p = path.getFileName().toString(); + if (p.length() > 1 && p.charAt(p.length() - 1) == '/') { + return p.substring(0, p.length() - 1); + } + return p; + } /** * Tries to read all bytes of the file denoted by path, * returns null if the file could not be found or if the read was interrupted. @@ -253,10 +267,7 @@ class JrtFileSystemWithOlderRelease extends JrtFileSystem { List<String> sub = new ArrayList<>(); try (DirectoryStream<java.nio.file.Path> stream = Files.newDirectoryStream(releasePath)) { for (final java.nio.file.Path subdir: stream) { - String r = subdir.getFileName().toString(); - if (r.endsWith("/")) { //$NON-NLS-1$ - r = r.substring(0, r.length() - 1); - } + String r = JRTUtil.sanitizedFileName(subdir); if (r.contains(this.releaseInHex)) { sub.add(r); } else { @@ -292,7 +303,7 @@ class JrtFileSystemWithOlderRelease extends JrtFileSystem { return FileVisitResult.SKIP_SUBTREE; } return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ? FileVisitResult.CONTINUE - : visitor.visitModule(dir); + : visitor.visitModule(dir, JRTUtil.sanitizedFileName(mod)); } if ((notify & JRTUtil.NOTIFY_PACKAGES) == 0) { // client is not interested in packages @@ -466,7 +477,7 @@ class JrtFileSystem { byte[] getClassfileContent(String fileName, String module) throws IOException, ClassFormatException { byte[] content = null; if (module != null) { - content = getClassfileBytes(fileName, new String(module.toCharArray())); + content = getClassfileBytes(fileName, module); } else { String[] modules = getModules(fileName); for (String mod : modules) { @@ -543,7 +554,7 @@ class JrtFileSystem { return FileVisitResult.SKIP_SUBTREE; } return ((notify & JRTUtil.NOTIFY_MODULES) == 0) ? - FileVisitResult.CONTINUE : visitor.visitModule(mod); + FileVisitResult.CONTINUE : visitor.visitModule(dir, JRTUtil.sanitizedFileName(mod)); } if ((notify & JRTUtil.NOTIFY_PACKAGES) == 0) { // We are dealing with a module or not client is not interested in packages |