1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 14 import org.eclipse.jdt.internal.compiler.codegen.*; 15 import org.eclipse.jdt.internal.compiler.flow.*; 16 import org.eclipse.jdt.internal.compiler.impl.Constant; 17 import org.eclipse.jdt.internal.compiler.lookup.*; 18 import org.eclipse.jdt.internal.compiler.ASTVisitor; 19 20 public class AssertStatement extends Statement { 21 22 public Expression assertExpression, exceptionArgument; 23 24 int preAssertInitStateIndex = -1; 26 private FieldBinding assertionSyntheticFieldBinding; 27 28 public AssertStatement( 29 Expression exceptionArgument, 30 Expression assertExpression, 31 int startPosition) { 32 33 this.assertExpression = assertExpression; 34 this.exceptionArgument = exceptionArgument; 35 sourceStart = startPosition; 36 sourceEnd = exceptionArgument.sourceEnd; 37 } 38 39 public AssertStatement(Expression assertExpression, int startPosition) { 40 41 this.assertExpression = assertExpression; 42 sourceStart = startPosition; 43 sourceEnd = assertExpression.sourceEnd; 44 } 45 46 public FlowInfo analyseCode( 47 BlockScope currentScope, 48 FlowContext flowContext, 49 FlowInfo flowInfo) { 50 51 preAssertInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo); 52 53 Constant cst = this.assertExpression.optimizedBooleanConstant(); 54 boolean isOptimizedTrueAssertion = cst != Constant.NotAConstant && cst.booleanValue() == true; 55 boolean isOptimizedFalseAssertion = cst != Constant.NotAConstant && cst.booleanValue() == false; 56 57 FlowInfo assertRawInfo = assertExpression. 58 analyseCode(currentScope, flowContext, flowInfo.copy()); 59 UnconditionalFlowInfo assertWhenTrueInfo = assertRawInfo.initsWhenTrue(). 60 unconditionalInits(); 61 UnconditionalFlowInfo assertInfo = assertRawInfo.unconditionalCopy(); 62 if (isOptimizedTrueAssertion) { 63 assertInfo.setReachMode(FlowInfo.UNREACHABLE); 64 } 65 66 if (exceptionArgument != null) { 67 FlowInfo exceptionInfo = exceptionArgument.analyseCode(currentScope, flowContext, assertInfo.copy()); 69 70 if (!isOptimizedTrueAssertion){ 71 flowContext.checkExceptionHandlers( 72 currentScope.getJavaLangAssertionError(), 73 this, 74 exceptionInfo, 75 currentScope); 76 } 77 } 78 79 if (!isOptimizedTrueAssertion){ 80 manageSyntheticAccessIfNecessary(currentScope, flowInfo); 82 } 83 if (isOptimizedFalseAssertion) { 84 return flowInfo; } else { 88 return flowInfo.mergedWith(assertInfo.nullInfoLessUnconditionalCopy()). 89 addInitializationsFrom(assertWhenTrueInfo.discardInitializationInfo()); 90 } 93 } 94 95 public void generateCode(BlockScope currentScope, CodeStream codeStream) { 96 97 if ((bits & IsReachable) == 0) { 98 return; 99 } 100 int pc = codeStream.position; 101 102 if (this.assertionSyntheticFieldBinding != null) { 103 BranchLabel assertionActivationLabel = new BranchLabel(codeStream); 104 codeStream.getstatic(this.assertionSyntheticFieldBinding); 105 codeStream.ifne(assertionActivationLabel); 106 107 BranchLabel falseLabel; 108 this.assertExpression.generateOptimizedBoolean(currentScope, codeStream, (falseLabel = new BranchLabel(codeStream)), null , true); 109 codeStream.newJavaLangAssertionError(); 110 codeStream.dup(); 111 if (exceptionArgument != null) { 112 exceptionArgument.generateCode(currentScope, codeStream, true); 113 codeStream.invokeJavaLangAssertionErrorConstructor(exceptionArgument.implicitConversion & 0xF); 114 } else { 115 codeStream.invokeJavaLangAssertionErrorDefaultConstructor(); 116 } 117 codeStream.athrow(); 118 119 if (preAssertInitStateIndex != -1) { 121 codeStream.removeNotDefinitelyAssignedVariables(currentScope, preAssertInitStateIndex); 122 } 123 falseLabel.place(); 124 assertionActivationLabel.place(); 125 } else { 126 if (preAssertInitStateIndex != -1) { 128 codeStream.removeNotDefinitelyAssignedVariables(currentScope, preAssertInitStateIndex); 129 } 130 } 131 codeStream.recordPositionsFrom(pc, this.sourceStart); 132 } 133 134 public void resolve(BlockScope scope) { 135 136 assertExpression.resolveTypeExpecting(scope, TypeBinding.BOOLEAN); 137 if (exceptionArgument != null) { 138 TypeBinding exceptionArgumentType = exceptionArgument.resolveType(scope); 139 if (exceptionArgumentType != null){ 140 int id = exceptionArgumentType.id; 141 switch(id) { 142 case T_void : 143 scope.problemReporter().illegalVoidExpression(exceptionArgument); 144 default: 145 id = T_JavaLangObject; 146 case T_boolean : 147 case T_byte : 148 case T_char : 149 case T_short : 150 case T_double : 151 case T_float : 152 case T_int : 153 case T_long : 154 case T_JavaLangString : 155 exceptionArgument.implicitConversion = (id << 4) + id; 156 } 157 } 158 } 159 } 160 161 public void traverse(ASTVisitor visitor, BlockScope scope) { 162 163 if (visitor.visit(this, scope)) { 164 assertExpression.traverse(visitor, scope); 165 if (exceptionArgument != null) { 166 exceptionArgument.traverse(visitor, scope); 167 } 168 } 169 visitor.endVisit(this, scope); 170 } 171 172 public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) { 173 174 if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) { 175 176 SourceTypeBinding outerMostClass = currentScope.enclosingSourceType(); 179 while (outerMostClass.isLocalType()) { 180 ReferenceBinding enclosing = outerMostClass.enclosingType(); 181 if (enclosing == null || enclosing.isInterface()) break; 182 outerMostClass = (SourceTypeBinding) enclosing; 183 } 184 185 this.assertionSyntheticFieldBinding = outerMostClass.addSyntheticFieldForAssert(currentScope); 186 187 TypeDeclaration typeDeclaration = outerMostClass.scope.referenceType(); 189 AbstractMethodDeclaration[] methods = typeDeclaration.methods; 190 for (int i = 0, max = methods.length; i < max; i++) { 191 AbstractMethodDeclaration method = methods[i]; 192 if (method.isClinit()) { 193 ((Clinit) method).setAssertionSupport(assertionSyntheticFieldBinding, currentScope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5); 194 break; 195 } 196 } 197 } 198 } 199 200 public StringBuffer printStatement(int tab, StringBuffer output) { 201 202 printIndent(tab, output); 203 output.append("assert "); this.assertExpression.printExpression(0, output); 205 if (this.exceptionArgument != null) { 206 output.append(": "); this.exceptionArgument.printExpression(0, output); 208 } 209 return output.append(';'); 210 } 211 212 } 213 | Popular Tags |