public Expression constantExpression;
public CaseLabel targetLabel;
+ boolean isEnumConstant;
+
public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) {
this.constantExpression = constantExpression;
this.sourceEnd = sourceEnd;
FlowInfo flowInfo) {
if (constantExpression != null) {
- if (constantExpression.constant == NotAConstant) {
+ if (!this.isEnumConstant && constantExpression.constant == NotAConstant) {
currentScope.problemReporter().caseExpressionMustBeConstant(constantExpression);
}
this.constantExpression.analyseCode(currentScope, flowContext, flowInfo);
// no-op : should use resolveCase(...) instead.
}
+ /**
+ * 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)
+ */
public Constant resolveCase(
BlockScope scope,
- TypeBinding switchType,
+ TypeBinding switchExpressionType,
SwitchStatement switchStatement) {
scope.switchCase = this; // record entering in a switch case block
// on error the last default will be the selected one ...
switchStatement.defaultCase = this;
- return null;
+ return NotAConstant;
}
// 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.isEnum() && (constantExpression instanceof SingleNameReference)) {
+ ((SingleNameReference) constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType);
+ }
TypeBinding caseType = constantExpression.resolveType(scope);
- if (caseType == null || switchType == null) return null;
- if (constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchType))
- return constantExpression.constant;
- if (caseType.isCompatibleWith(switchType))
+ if (caseType == null || switchExpressionType == null) return NotAConstant;
+ if (constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType)
+ || caseType.isCompatibleWith(switchExpressionType)) {
+ if (caseType.isEnum()) {
+ this.isEnumConstant = true;
+ if (constantExpression instanceof NameReference
+ && (constantExpression.bits & RestrictiveFlagMASK) == Binding.FIELD) {
+ if (constantExpression instanceof QualifiedNameReference) {
+ scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel((QualifiedNameReference)constantExpression);
+ }
+ return Constant.fromValue(((NameReference)constantExpression).fieldBinding().id); // ordinal value
+ }
+ } else {
+ return constantExpression.constant;
+ }
+ } else if (scope.isBoxingCompatibleWith(switchExpressionType, caseType)) {
+ constantExpression.computeConversion(scope, caseType, switchExpressionType);
return constantExpression.constant;
- scope.problemReporter().typeMismatchErrorActualTypeExpectedType(
- constantExpression,
- caseType,
- switchType);
- return null;
+ }
+ scope.problemReporter().typeMismatchError(caseType, switchExpressionType, constantExpression);
+ return NotAConstant;
}