X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/WhileStatement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/WhileStatement.java index 20377b0..d1eb28b 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/WhileStatement.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/WhileStatement.java @@ -1,20 +1,24 @@ /******************************************************************************* - * 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.IAbstractSyntaxTreeVisitor; -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.ASTVisitor; +import net.sourceforge.phpdt.internal.compiler.codegen.Label; +import net.sourceforge.phpdt.internal.compiler.flow.FlowContext; +import net.sourceforge.phpdt.internal.compiler.flow.FlowInfo; +import net.sourceforge.phpdt.internal.compiler.flow.LoopingFlowContext; +import net.sourceforge.phpdt.internal.compiler.impl.Constant; +import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; +import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; + public class WhileStatement extends Statement { @@ -39,31 +43,43 @@ public class WhileStatement extends Statement { FlowInfo flowInfo) { breakLabel = new Label(); - continueLabel = new Label(); + continueLabel = new Label(); + + Constant cst = this.condition.constant; + boolean isConditionTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isConditionFalse = cst != NotAConstant && cst.booleanValue() == false; + cst = this.condition.optimizedBooleanConstant(); + boolean isConditionOptimizedTrue = cst != NotAConstant && cst.booleanValue() == true; + boolean isConditionOptimizedFalse = cst != NotAConstant && cst.booleanValue() == false; + preCondInitStateIndex = currentScope.methodScope().recordInitializationStates(flowInfo); LoopingFlowContext condLoopContext; FlowInfo postCondInfo = - condition.analyseCode( + this.condition.analyseCode( currentScope, (condLoopContext = new LoopingFlowContext(flowContext, this, null, null, currentScope)), flowInfo); LoopingFlowContext loopingContext; - if ((action == null) || action.isEmptyBlock()) { - condLoopContext.complainOnFinalAssignmentsInLoop(currentScope, postCondInfo); - if ((condition.constant != NotAConstant) - && (condition.constant.booleanValue() == true)) { - return FlowInfo.DeadEnd; - } else { - FlowInfo mergedInfo = postCondInfo.initsWhenFalse().unconditionalInits(); - mergedInitStateIndex = - currentScope.methodScope().recordInitializationStates(mergedInfo); - return mergedInfo; - } - } else { + FlowInfo actionInfo; +// if (action == null +// || (action.isEmptyBlock() && currentScope.environment().options.complianceLevel <= CompilerOptions.JDK1_3)) { +// condLoopContext.complainOnFinalAssignmentsInLoop(currentScope, postCondInfo); +// if (isConditionTrue) { +// return FlowInfo.DEAD_END; +// } else { +// FlowInfo mergedInfo = postCondInfo.initsWhenFalse().unconditionalInits(); +// if (isConditionOptimizedTrue){ +// mergedInfo.setReachMode(FlowInfo.UNREACHABLE); +// } +// mergedInitStateIndex = +// currentScope.methodScope().recordInitializationStates(mergedInfo); +// return mergedInfo; +// } +// } else { // in case the condition was inlined to false, record the fact that there is no way to reach any // statement inside the looping action loopingContext = @@ -73,36 +89,37 @@ public class WhileStatement extends Statement { breakLabel, continueLabel, currentScope); - FlowInfo actionInfo = - ((condition.constant != Constant.NotAConstant) - && (condition.constant.booleanValue() == false)) - ? FlowInfo.DeadEnd - : postCondInfo.initsWhenTrue().copy(); + if (isConditionFalse) { + actionInfo = FlowInfo.DEAD_END; + } else { + actionInfo = postCondInfo.initsWhenTrue().copy(); + if (isConditionOptimizedFalse){ + actionInfo.setReachMode(FlowInfo.UNREACHABLE); + } + } // for computing local var attributes condIfTrueInitStateIndex = currentScope.methodScope().recordInitializationStates( postCondInfo.initsWhenTrue()); - if (!actionInfo.complainIfUnreachable(action, currentScope)) { + if (!actionInfo.complainIfUnreachable(action, currentScope, false)) { actionInfo = action.analyseCode(currentScope, loopingContext, actionInfo); } // code generation can be optimized when no need to continue in the loop - if (((actionInfo == FlowInfo.DeadEnd) || actionInfo.isFakeReachable()) - && ((loopingContext.initsOnContinue == FlowInfo.DeadEnd) - || loopingContext.initsOnContinue.isFakeReachable())) { + if (!actionInfo.isReachable() && !loopingContext.initsOnContinue.isReachable()) { continueLabel = null; } else { + // TODO: (philippe) should simplify in one Loop context condLoopContext.complainOnFinalAssignmentsInLoop(currentScope, postCondInfo); loopingContext.complainOnFinalAssignmentsInLoop(currentScope, actionInfo); } - } +// } // infinite loop FlowInfo mergedInfo; - if ((condition.constant != Constant.NotAConstant) - && (condition.constant.booleanValue() == true)) { + if (isConditionOptimizedTrue) { mergedInitStateIndex = currentScope.methodScope().recordInitializationStates( mergedInfo = loopingContext.initsOnBreak); @@ -113,6 +130,9 @@ public class WhileStatement extends Statement { mergedInfo = postCondInfo.initsWhenFalse().unconditionalInits().mergedWith( loopingContext.initsOnBreak); + if (isConditionOptimizedTrue && continueLabel == null){ + mergedInfo.setReachMode(FlowInfo.UNREACHABLE); + } mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo); return mergedInfo; @@ -121,86 +141,98 @@ public class WhileStatement extends Statement { /** * While code generation * - * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope - * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream + * @param currentScope net.sourceforge.phpdt.internal.compiler.lookup.BlockScope + * @param codeStream net.sourceforge.phpdt.internal.compiler.codegen.CodeStream */ - public void generateCode(BlockScope currentScope, CodeStream codeStream) { - - if ((bits & IsReachableMASK) == 0) { - return; - } - int pc = codeStream.position; - breakLabel.codeStream = codeStream; - - // generate condition - if (continueLabel == null) { - // no need to reverse condition - if (condition.constant == NotAConstant) { - condition.generateOptimizedBoolean( - currentScope, - codeStream, - null, - breakLabel, - true); - } - } else { - continueLabel.codeStream = codeStream; - if (!(((condition.constant != NotAConstant) - && (condition.constant.booleanValue() == true)) - || (action == null) - || action.isEmptyBlock())) { - int jumpPC = codeStream.position; - codeStream.goto_(continueLabel); - codeStream.recordPositionsFrom(jumpPC, condition.sourceStart); - } - } - // generate the action - Label actionLabel; - (actionLabel = new Label(codeStream)).place(); - if (action != null) { - // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect - if (condIfTrueInitStateIndex != -1) { - // insert all locals initialized inside the condition into the action generated prior to the condition - codeStream.addDefinitelyAssignedVariables( - currentScope, - condIfTrueInitStateIndex); - } - action.generateCode(currentScope, codeStream); - // May loose some local variable initializations : affecting the local variable attributes - if (preCondInitStateIndex != -1) { - codeStream.removeNotDefinitelyAssignedVariables( - currentScope, - preCondInitStateIndex); - } +// public void generateCode(BlockScope currentScope, CodeStream codeStream) { +// +// if ((bits & IsReachableMASK) == 0) { +// return; +// } +// int pc = codeStream.position; +// breakLabel.codeStream = codeStream; +// +// // generate condition +// if (continueLabel == null) { +// // no need to reverse condition +// if (condition.constant == NotAConstant) { +// condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// null, +// breakLabel, +// true); +// } +// } else { +// continueLabel.codeStream = codeStream; +// if (!(((condition.constant != NotAConstant) +// && (condition.constant.booleanValue() == true)) +// || (action == null) +// || action.isEmptyBlock())) { +// int jumpPC = codeStream.position; +// codeStream.goto_(continueLabel); +// codeStream.recordPositionsFrom(jumpPC, condition.sourceStart); +// } +// } +// // generate the action +// Label actionLabel; +// (actionLabel = new Label(codeStream)).place(); +// if (action != null) { +// // Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect +// if (condIfTrueInitStateIndex != -1) { +// // insert all locals initialized inside the condition into the action generated prior to the condition +// codeStream.addDefinitelyAssignedVariables( +// currentScope, +// condIfTrueInitStateIndex); +// } +// action.generateCode(currentScope, codeStream); +// // May loose some local variable initializations : affecting the local variable attributes +// if (preCondInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// preCondInitStateIndex); +// } +// +// } +// // output condition and branch back to the beginning of the repeated action +// if (continueLabel != null) { +// continueLabel.place(); +// condition.generateOptimizedBoolean( +// currentScope, +// codeStream, +// actionLabel, +// null, +// true); +// } +// breakLabel.place(); +// +// // May loose some local variable initializations : affecting the local variable attributes +// if (mergedInitStateIndex != -1) { +// codeStream.removeNotDefinitelyAssignedVariables( +// currentScope, +// mergedInitStateIndex); +// } +// codeStream.recordPositionsFrom(pc, this.sourceStart); +// } + public void resetStateForCodeGeneration() { + if (this.breakLabel != null) { + this.breakLabel.resetStateForCodeGeneration(); } - // output condition and branch back to the beginning of the repeated action - if (continueLabel != null) { - continueLabel.place(); - condition.generateOptimizedBoolean( - currentScope, - codeStream, - actionLabel, - null, - true); + if (this.continueLabel != null) { + this.continueLabel.resetStateForCodeGeneration(); } - breakLabel.place(); - - // May loose some local variable initializations : affecting the local variable attributes - if (mergedInitStateIndex != -1) { - codeStream.removeNotDefinitelyAssignedVariables( - currentScope, - mergedInitStateIndex); - } - codeStream.recordPositionsFrom(pc, this.sourceStart); } + public StringBuffer printStatement(int tab, StringBuffer output) { - public void resetStateForCodeGeneration() { - - this.breakLabel.resetStateForCodeGeneration(); - this.continueLabel.resetStateForCodeGeneration(); + printIndent(tab, output).append("while ("); //$NON-NLS-1$ + condition.printExpression(0, output).append(')'); + if (action == null) + output.append(';'); + else + action.printStatement(tab + 1, output); + return output; } - public void resolve(BlockScope scope) { TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding); @@ -223,7 +255,7 @@ public class WhileStatement extends Statement { } public void traverse( - IAbstractSyntaxTreeVisitor visitor, + ASTVisitor visitor, BlockScope blockScope) { if (visitor.visit(this, blockScope)) { @@ -233,4 +265,4 @@ public class WhileStatement extends Statement { } visitor.endVisit(this, blockScope); } -} \ No newline at end of file +}