1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.internal.compiler.ASTVisitor; 14 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 15 import org.eclipse.jdt.internal.compiler.codegen.CaseLabel; 16 import org.eclipse.jdt.internal.compiler.codegen.CodeStream; 17 import org.eclipse.jdt.internal.compiler.flow.FlowContext; 18 import org.eclipse.jdt.internal.compiler.flow.FlowInfo; 19 import org.eclipse.jdt.internal.compiler.impl.Constant; 20 import org.eclipse.jdt.internal.compiler.impl.IntConstant; 21 import org.eclipse.jdt.internal.compiler.lookup.Binding; 22 import org.eclipse.jdt.internal.compiler.lookup.BlockScope; 23 import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; 24 import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; 25 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 26 27 public class CaseStatement extends Statement { 28 29 public Expression constantExpression; 30 public CaseLabel targetLabel; 31 32 public CaseStatement(Expression constantExpression, int sourceEnd, int sourceStart) { 33 this.constantExpression = constantExpression; 34 this.sourceEnd = sourceEnd; 35 this.sourceStart = sourceStart; 36 } 37 38 public FlowInfo analyseCode( 39 BlockScope currentScope, 40 FlowContext flowContext, 41 FlowInfo flowInfo) { 42 43 if (this.constantExpression != null) { 44 if (this.constantExpression.constant == Constant.NotAConstant 45 && !this.constantExpression.resolvedType.isEnum()) { 46 currentScope.problemReporter().caseExpressionMustBeConstant(this.constantExpression); 47 } 48 this.constantExpression.analyseCode(currentScope, flowContext, flowInfo); 49 } 50 return flowInfo; 51 } 52 53 public StringBuffer printStatement(int tab, StringBuffer output) { 54 printIndent(tab, output); 55 if (this.constantExpression == null) { 56 output.append("default : "); } else { 58 output.append("case "); this.constantExpression.printExpression(0, output).append(" : "); } 61 return output.append(';'); 62 } 63 64 68 public void generateCode(BlockScope currentScope, CodeStream codeStream) { 69 if ((this.bits & ASTNode.IsReachable) == 0) { 70 return; 71 } 72 int pc = codeStream.position; 73 this.targetLabel.place(); 74 codeStream.recordPositionsFrom(pc, this.sourceStart); 75 } 76 77 80 public void resolve(BlockScope scope) { 81 } 83 84 88 public Constant resolveCase(BlockScope scope, TypeBinding switchExpressionType, SwitchStatement switchStatement) { 89 scope.enclosingCase = this; 92 if (this.constantExpression == null) { 93 if (switchStatement.defaultCase != null) 95 scope.problemReporter().duplicateDefaultCase(this); 96 97 switchStatement.defaultCase = this; 99 return Constant.NotAConstant; 100 } 101 switchStatement.cases[switchStatement.caseCount++] = this; 103 if (switchExpressionType != null && switchExpressionType.isEnum() && (this.constantExpression instanceof SingleNameReference)) { 105 ((SingleNameReference) this.constantExpression).setActualReceiverType((ReferenceBinding)switchExpressionType); 106 } 107 TypeBinding caseType = this.constantExpression.resolveType(scope); 108 if (caseType == null || switchExpressionType == null) return Constant.NotAConstant; 109 if (this.constantExpression.isConstantValueOfTypeAssignableToType(caseType, switchExpressionType) 110 || caseType.isCompatibleWith(switchExpressionType)) { 111 if (caseType.isEnum()) { 112 if (((this.constantExpression.bits & ASTNode.ParenthesizedMASK) >> ASTNode.ParenthesizedSHIFT) != 0) { 113 scope.problemReporter().enumConstantsCannotBeSurroundedByParenthesis(this.constantExpression); 114 } 115 116 if (this.constantExpression instanceof NameReference 117 && (this.constantExpression.bits & ASTNode.RestrictiveFlagMASK) == Binding.FIELD) { 118 NameReference reference = (NameReference) this.constantExpression; 119 FieldBinding field = reference.fieldBinding(); 120 if ((field.modifiers & ClassFileConstants.AccEnum) == 0) { 121 scope.problemReporter().enumSwitchCannotTargetField(reference, field); 122 } else if (reference instanceof QualifiedNameReference) { 123 scope.problemReporter().cannotUseQualifiedEnumConstantInCaseLabel(reference, field); 124 } 125 return IntConstant.fromValue(field.original().id + 1); } 127 } else { 128 return this.constantExpression.constant; 129 } 130 } else if (scope.isBoxingCompatibleWith(caseType, switchExpressionType) 131 || (caseType.isBaseType() && scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5 && !switchExpressionType.isBaseType() 134 && this.constantExpression.isConstantValueOfTypeAssignableToType(caseType, scope.environment().computeBoxingType(switchExpressionType)))) { 135 return this.constantExpression.constant; 137 } 138 scope.problemReporter().typeMismatchError(caseType, switchExpressionType, this.constantExpression); 139 return Constant.NotAConstant; 140 } 141 142 public void traverse(ASTVisitor visitor, BlockScope blockScope) { 143 if (visitor.visit(this, blockScope)) { 144 if (this.constantExpression != null) this.constantExpression.traverse(visitor, blockScope); 145 } 146 visitor.endVisit(this, blockScope); 147 } 148 } 149
| Popular Tags
|