X-Git-Url: http://secure.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AssertStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AssertStatement.java index 66a16eb..64705dc 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AssertStatement.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/AssertStatement.java @@ -1,34 +1,37 @@ /******************************************************************************* - * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. + * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * are made available under the terms of the Common Public License v1.0 * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html + * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation - ******************************************************************************/ + *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.ast; -import net.sourceforge.phpdt.internal.compiler.impl.*; -import net.sourceforge.phpdt.internal.compiler.codegen.*; -import net.sourceforge.phpdt.internal.compiler.flow.*; -import net.sourceforge.phpdt.internal.compiler.lookup.*; -import net.sourceforge.phpdt.internal.compiler.IAbstractSyntaxTreeVisitor; +import net.sourceforge.phpdt.internal.compiler.ASTVisitor; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.FieldBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.SourceTypeBinding; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; public class AssertStatement extends Statement { - + public Expression assertExpression, exceptionArgument; // for local variable attribute int preAssertInitStateIndex = -1; + private FieldBinding assertionSyntheticFieldBinding; - - public AssertStatement( - Expression exceptionArgument, - Expression assertExpression, - int startPosition) { - + + public AssertStatement(Expression exceptionArgument, + Expression assertExpression, int startPosition) { + this.assertExpression = assertExpression; this.exceptionArgument = exceptionArgument; sourceStart = startPosition; @@ -42,91 +45,115 @@ public class AssertStatement extends Statement { sourceEnd = assertExpression.sourceEnd; } - public FlowInfo analyseCode( - BlockScope currentScope, - FlowContext flowContext, - FlowInfo flowInfo) { - - Constant constant = assertExpression.constant; - if (constant != NotAConstant && constant.booleanValue() == true) { - return flowInfo; - } + public FlowInfo analyseCode(BlockScope currentScope, + FlowContext flowContext, FlowInfo flowInfo) { + + preAssertInitStateIndex = currentScope.methodScope() + .recordInitializationStates(flowInfo); + + Constant cst = this.assertExpression.optimizedBooleanConstant(); + boolean isOptimizedTrueAssertion = cst != NotAConstant + && cst.booleanValue() == true; + boolean isOptimizedFalseAssertion = cst != NotAConstant + && cst.booleanValue() == false; - preAssertInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo); FlowInfo assertInfo = flowInfo.copy(); - - if (exceptionArgument != null) { - assertInfo = exceptionArgument.analyseCode( - currentScope, - flowContext, - assertExpression.analyseCode(currentScope, flowContext, assertInfo).unconditionalInits()) - .unconditionalInits(); - } else { - assertInfo = assertExpression.analyseCode(currentScope, flowContext, assertInfo).unconditionalInits(); + if (isOptimizedTrueAssertion) { + assertInfo.setReachMode(FlowInfo.UNREACHABLE); } - - // assertion might throw AssertionError (unchecked), which can have consequences in term of - // definitely assigned variables (depending on caught exception in the context) - // DISABLED - AssertionError is unchecked, try statements are already protected against these. - //flowContext.checkExceptionHandlers(currentScope.getJavaLangAssertionError(), this, assertInfo, currentScope); + assertInfo = assertExpression.analyseCode(currentScope, flowContext, + assertInfo).unconditionalInits(); - // only retain potential initializations - flowInfo.addPotentialInitializationsFrom(assertInfo.unconditionalInits()); + if (exceptionArgument != null) { + // only gets evaluated when escaping - results are not taken into + // account + FlowInfo exceptionInfo = exceptionArgument.analyseCode( + currentScope, flowContext, assertInfo.copy()); + + if (!isOptimizedTrueAssertion) { + flowContext.checkExceptionHandlers(currentScope + .getJavaLangAssertionError(), this, exceptionInfo, + currentScope); + } + } // add the assert support in the clinit manageSyntheticAccessIfNecessary(currentScope); - - return flowInfo; + if (isOptimizedFalseAssertion) { + return flowInfo; // if assertions are enabled, the following code + // will be unreachable + } else { + return flowInfo.mergedWith(assertInfo.unconditionalInits()); + } } - public void generateCode(BlockScope currentScope, CodeStream codeStream) { - - if ((bits & IsReachableMASK) == 0) { - return; - } - int pc = codeStream.position; - - if (this.assertionSyntheticFieldBinding != null) { - Label assertionActivationLabel = new Label(codeStream); - codeStream.getstatic(this.assertionSyntheticFieldBinding); - codeStream.ifne(assertionActivationLabel); - Label falseLabel = new Label(codeStream); - assertExpression.generateOptimizedBoolean(currentScope, codeStream, (falseLabel = new Label(codeStream)), null , true); - codeStream.newJavaLangAssertionError(); - codeStream.dup(); - if (exceptionArgument != null) { - exceptionArgument.generateCode(currentScope, codeStream, true); - codeStream.invokeJavaLangAssertionErrorConstructor(exceptionArgument.implicitConversion & 0xF); - } else { - codeStream.invokeJavaLangAssertionErrorDefaultConstructor(); - } - codeStream.athrow(); - falseLabel.place(); - assertionActivationLabel.place(); + // public void generateCode(BlockScope currentScope, CodeStream codeStream) + // { + // + // if ((bits & IsReachableMASK) == 0) { + // return; + // } + // int pc = codeStream.position; + // + // if (this.assertionSyntheticFieldBinding != null) { + // Label assertionActivationLabel = new Label(codeStream); + // codeStream.getstatic(this.assertionSyntheticFieldBinding); + // codeStream.ifne(assertionActivationLabel); + // Label falseLabel = new Label(codeStream); + // assertExpression.generateOptimizedBoolean(currentScope, codeStream, + // (falseLabel = new Label(codeStream)), null , true); + // codeStream.newJavaLangAssertionError(); + // codeStream.dup(); + // if (exceptionArgument != null) { + // exceptionArgument.generateCode(currentScope, codeStream, true); + // codeStream.invokeJavaLangAssertionErrorConstructor(exceptionArgument.implicitConversion + // & 0xF); + // } else { + // codeStream.invokeJavaLangAssertionErrorDefaultConstructor(); + // } + // codeStream.athrow(); + // falseLabel.place(); + // assertionActivationLabel.place(); + // } + // + // // May loose some local variable initializations : affecting the local + // variable attributes + // if (preAssertInitStateIndex != -1) { + // codeStream.removeNotDefinitelyAssignedVariables(currentScope, + // preAssertInitStateIndex); + // } + // codeStream.recordPositionsFrom(pc, this.sourceStart); + // } + public StringBuffer printStatement(int tab, StringBuffer output) { + + printIndent(tab, output); + output.append("assert "); //$NON-NLS-1$ + this.assertExpression.printExpression(0, output); + if (this.exceptionArgument != null) { + output.append(": "); //$NON-NLS-1$ + this.exceptionArgument.printExpression(0, output); } - - // May loose some local variable initializations : affecting the local variable attributes - if (preAssertInitStateIndex != -1) { - codeStream.removeNotDefinitelyAssignedVariables(currentScope, preAssertInitStateIndex); - } - codeStream.recordPositionsFrom(pc, this.sourceStart); + return output.append(';'); } public void resolve(BlockScope scope) { assertExpression.resolveTypeExpecting(scope, BooleanBinding); if (exceptionArgument != null) { - TypeBinding exceptionArgumentType = exceptionArgument.resolveType(scope); - if (exceptionArgumentType != null){ - if (exceptionArgumentType.id == T_void){ - scope.problemReporter().illegalVoidExpression(exceptionArgument); + TypeBinding exceptionArgumentType = exceptionArgument + .resolveType(scope); + if (exceptionArgumentType != null) { + if (exceptionArgumentType.id == T_void) { + scope.problemReporter().illegalVoidExpression( + exceptionArgument); } - exceptionArgument.implicitConversion = (exceptionArgumentType.id << 4) + exceptionArgumentType.id; + exceptionArgument.implicitConversion = (exceptionArgumentType.id << 4) + + exceptionArgumentType.id; } } } - - public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) { + + public void traverse(ASTVisitor visitor, BlockScope scope) { if (visitor.visit(this, scope)) { assertExpression.traverse(visitor, scope); @@ -135,22 +162,32 @@ public class AssertStatement extends Statement { } } visitor.endVisit(this, scope); - } - + } + public void manageSyntheticAccessIfNecessary(BlockScope currentScope) { - // need assertion flag: $assertionsDisabled on outer most source type - ClassScope outerMostClassScope = currentScope.outerMostClassScope(); - SourceTypeBinding sourceTypeBinding = outerMostClassScope.enclosingSourceType(); - this.assertionSyntheticFieldBinding = sourceTypeBinding.addSyntheticField(this, currentScope); + // need assertion flag: $assertionsDisabled on outer most source clas + // (in case of static member of interface, will use the outermost static + // member - bug 22334) + SourceTypeBinding outerMostClass = currentScope.enclosingSourceType(); + while (outerMostClass.isLocalType()) { + ReferenceBinding enclosing = outerMostClass.enclosingType(); + if (enclosing == null || enclosing.isInterface()) + break; + outerMostClass = (SourceTypeBinding) enclosing; + } + + this.assertionSyntheticFieldBinding = outerMostClass.addSyntheticField( + this, currentScope); // find and enable assertion support - TypeDeclaration typeDeclaration = outerMostClassScope.referenceType(); + TypeDeclaration typeDeclaration = outerMostClass.scope.referenceType(); AbstractMethodDeclaration[] methods = typeDeclaration.methods; for (int i = 0, max = methods.length; i < max; i++) { AbstractMethodDeclaration method = methods[i]; if (method.isClinit()) { - ((Clinit) method).addSupportForAssertion(assertionSyntheticFieldBinding); + ((Clinit) method) + .addSupportForAssertion(assertionSyntheticFieldBinding); break; } } @@ -159,7 +196,7 @@ public class AssertStatement extends Statement { public String toString(int tab) { StringBuffer buffer = new StringBuffer(tabString(tab)); - buffer.append("assert"); //$NON-NLS-1$ + buffer.append("assert "); //$NON-NLS-1$ buffer.append(this.assertExpression); if (this.exceptionArgument != null) { buffer.append(":"); //$NON-NLS-1$ @@ -168,5 +205,5 @@ public class AssertStatement extends Statement { } return buffer.toString(); } - -} \ No newline at end of file + +}