/*******************************************************************************
- * 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 {
FlowContext flowContext,
FlowInfo flowInfo) {
- Constant constant = assertExpression.constant;
- if (constant != NotAConstant && constant.booleanValue() == true) {
- return 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;
+
FlowInfo assertInfo = flowInfo.copy();
-
+ if (isOptimizedTrueAssertion) {
+ assertInfo.setReachMode(FlowInfo.UNREACHABLE);
+ }
+ assertInfo = assertExpression.analyseCode(currentScope, flowContext, assertInfo).unconditionalInits();
+
if (exceptionArgument != null) {
- assertInfo = exceptionArgument.analyseCode(
- currentScope,
- flowContext,
- assertExpression.analyseCode(currentScope, flowContext, assertInfo).unconditionalInits())
- .unconditionalInits();
- } else {
- assertInfo = assertExpression.analyseCode(currentScope, flowContext, assertInfo).unconditionalInits();
+ // 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);
+ }
}
- // 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);
-
- // only retain potential initializations
- flowInfo.addPotentialInitializationsFrom(assertInfo.unconditionalInits());
-
// 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);
}
}
- public void traverse(IAbstractSyntaxTreeVisitor visitor, BlockScope scope) {
+ public void traverse(ASTVisitor visitor, BlockScope scope) {
if (visitor.visit(this, scope)) {
assertExpression.traverse(visitor, 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 <clinit> 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];
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$
return buffer.toString();
}
-}
\ No newline at end of file
+}