1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.ast;
13 import org.eclipse.jdt.internal.compiler.ASTVisitor;
14 import org.eclipse.jdt.internal.compiler.impl.*;
15 import org.eclipse.jdt.internal.compiler.codegen.*;
16 import org.eclipse.jdt.internal.compiler.flow.*;
17 import org.eclipse.jdt.internal.compiler.lookup.*;
19 public class CaseStatement extends Statement {
21 public Expression constantExpression;
22 public CaseLabel targetLabel;
23 boolean isEnumConstant;
25 public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) {
26 this.constantExpression = constantExpression;
27 this.sourceEnd = sourceEnd;
28 this.sourceStart = sourceStart;
31 public FlowInfo analyseCode(
32 BlockScope currentScope,
33 FlowContext flowContext,
36 if (constantExpression != null) {
37 if (!this.isEnumConstant && constantExpression.constant == NotAConstant) {
38 currentScope.problemReporter().caseExpressionMustBeConstant(constantExpression);
40 this.constantExpression.analyseCode(currentScope, flowContext, flowInfo);
45 public StringBuffer printStatement(int tab, StringBuffer output) {
47 printIndent(tab, output);
48 if (constantExpression == null) {
49 output.append("default : "); //$NON-NLS-1$
51 output.append("case "); //$NON-NLS-1$
52 constantExpression.printExpression(0, output).append(" : "); //$NON-NLS-1$
54 return output.append(';');
58 * Case code generation
61 public void generateCode(BlockScope currentScope, CodeStream codeStream) {
63 if ((bits & IsReachableMASK) == 0) {
66 int pc = codeStream.position;
68 codeStream.recordPositionsFrom(pc, this.sourceStart);
72 * No-op : should use resolveCase(...) instead.
74 public void resolve(BlockScope scope) {
75 // no-op : should use resolveCase(...) instead.
79 * Returns the constant intValue or ordinal for enum constants. If constant is NotAConstant, then answers Float.MIN_VALUE
80 * @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)
82 public Constant resolveCase(
84 TypeBinding switchExpressionType,
85 SwitchStatement switchStatement) {
87 scope.switchCase = this; // record entering in a switch case block
89 if (constantExpression == null) {
90 // remember the default case into the associated switch statement
91 if (switchStatement.defaultCase != null)
92 scope.problemReporter().duplicateDefaultCase(this);
94 // on error the last default will be the selected one ...
95 switchStatement.defaultCase = this;
98 // add into the collection of cases of the associated switch statement
99 switchStatement.cases[switchStatement.caseCount++] = this;
100 // tag constant name with enum type for privileged access to its members
101 if (switchExpressionType.isEnum() && (constantExpression instanceof SingleNameReference)) {
102 ((SingleNameReference) constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType);
104 TypeBinding caseType = constantExpression.resolveType(scope);
105 if (caseType == null || switchExpressionType == null) return NotAConstant;
106 if (constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType)
107 || caseType.isCompatibleWith(switchExpressionType)) {
108 if (caseType.isEnum()) {
109 this.isEnumConstant = true;
110 if (constantExpression instanceof NameReference
111 && (constantExpression.bits & RestrictiveFlagMASK) == Binding.FIELD) {
112 if (constantExpression instanceof QualifiedNameReference) {
113 scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel((QualifiedNameReference)constantExpression);
115 return Constant.fromValue(((NameReference)constantExpression).fieldBinding().id); // ordinal value
118 return constantExpression.constant;
120 } else if (scope.isBoxingCompatibleWith(switchExpressionType, caseType)) {
121 constantExpression.computeConversion(scope, caseType, switchExpressionType);
122 return constantExpression.constant;
124 scope.problemReporter().typeMismatchError(caseType, switchExpressionType, constantExpression);
129 public void traverse(
131 BlockScope blockScope) {
133 if (visitor.visit(this, blockScope)) {
134 if (constantExpression != null) constantExpression.traverse(visitor, blockScope);
136 visitor.endVisit(this, blockScope);