X-Git-Url: http://secure.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 d1eb28b..ec7dd3e 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 @@ -19,14 +19,18 @@ 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 { - + public Expression condition; + public Statement action; + private Label breakLabel, continueLabel; + int preCondInitStateIndex = -1; + int condIfTrueInitStateIndex = -1; + int mergedInitStateIndex = -1; public WhileStatement(Expression condition, Statement action, int s, int e) { @@ -37,184 +41,192 @@ public class WhileStatement extends Statement { sourceEnd = e; } - public FlowInfo analyseCode( - BlockScope currentScope, - FlowContext flowContext, - FlowInfo flowInfo) { + public FlowInfo analyseCode(BlockScope currentScope, + FlowContext flowContext, 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; +// 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); + boolean isConditionOptimizedTrue = cst != NotAConstant + && cst.booleanValue() == true; + boolean isConditionOptimizedFalse = cst != NotAConstant + && cst.booleanValue() == false; + + preCondInitStateIndex = currentScope.methodScope() + .recordInitializationStates(flowInfo); LoopingFlowContext condLoopContext; - FlowInfo postCondInfo = - this.condition.analyseCode( - currentScope, - (condLoopContext = - new LoopingFlowContext(flowContext, this, null, null, currentScope)), - flowInfo); + FlowInfo postCondInfo = this.condition.analyseCode(currentScope, + (condLoopContext = new LoopingFlowContext(flowContext, this, + null, null, currentScope)), flowInfo); LoopingFlowContext loopingContext; 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 = - new LoopingFlowContext( - flowContext, - this, - breakLabel, - continueLabel, - currentScope); - if (isConditionFalse) { - actionInfo = FlowInfo.DEAD_END; - } else { - actionInfo = postCondInfo.initsWhenTrue().copy(); - if (isConditionOptimizedFalse){ - actionInfo.setReachMode(FlowInfo.UNREACHABLE); - } + // 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 = new LoopingFlowContext(flowContext, this, breakLabel, + continueLabel, currentScope); + 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()); + // for computing local var attributes + condIfTrueInitStateIndex = currentScope.methodScope() + .recordInitializationStates(postCondInfo.initsWhenTrue()); - if (!actionInfo.complainIfUnreachable(action, currentScope, false)) { - actionInfo = action.analyseCode(currentScope, loopingContext, actionInfo); - } + 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.isReachable() && !loopingContext.initsOnContinue.isReachable()) { - continueLabel = null; - } else { - // TODO: (philippe) should simplify in one Loop context - condLoopContext.complainOnFinalAssignmentsInLoop(currentScope, postCondInfo); - loopingContext.complainOnFinalAssignmentsInLoop(currentScope, actionInfo); - } -// } + // code generation can be optimized when no need to continue in the loop + 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 (isConditionOptimizedTrue) { - mergedInitStateIndex = - currentScope.methodScope().recordInitializationStates( - mergedInfo = loopingContext.initsOnBreak); + mergedInitStateIndex = currentScope.methodScope() + .recordInitializationStates( + mergedInfo = loopingContext.initsOnBreak); return mergedInfo; } // end of loop: either condition false or break - mergedInfo = - postCondInfo.initsWhenFalse().unconditionalInits().mergedWith( - loopingContext.initsOnBreak); - if (isConditionOptimizedTrue && continueLabel == null){ + mergedInfo = postCondInfo.initsWhenFalse().unconditionalInits() + .mergedWith(loopingContext.initsOnBreak); + if (isConditionOptimizedTrue && continueLabel == null) { mergedInfo.setReachMode(FlowInfo.UNREACHABLE); } - mergedInitStateIndex = - currentScope.methodScope().recordInitializationStates(mergedInfo); + mergedInitStateIndex = currentScope.methodScope() + .recordInitializationStates(mergedInfo); return mergedInfo; } /** * While code generation - * - * @param currentScope net.sourceforge.phpdt.internal.compiler.lookup.BlockScope - * @param codeStream net.sourceforge.phpdt.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); -// } -// -// } -// // 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 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(); @@ -223,6 +235,7 @@ public class WhileStatement extends Statement { this.continueLabel.resetStateForCodeGeneration(); } } + public StringBuffer printStatement(int tab, StringBuffer output) { printIndent(tab, output).append("while ("); //$NON-NLS-1$ @@ -230,12 +243,14 @@ public class WhileStatement extends Statement { if (action == null) output.append(';'); else - action.printStatement(tab + 1, output); + action.printStatement(tab + 1, output); return output; } + public void resolve(BlockScope scope) { - TypeBinding type = condition.resolveTypeExpecting(scope, BooleanBinding); + TypeBinding type = condition + .resolveTypeExpecting(scope, BooleanBinding); condition.implicitWidening(type, type); if (action != null) action.resolve(scope); @@ -244,7 +259,7 @@ public class WhileStatement extends Statement { public String toString(int tab) { String s = tabString(tab); - s = s + "while (" + condition.toStringExpression() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ + s = s + "while (" + condition.toStringExpression() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ if (action == null) s = s + " {} ;"; //$NON-NLS-1$ else if (action instanceof Block) @@ -254,9 +269,7 @@ public class WhileStatement extends Statement { return s; } - public void traverse( - ASTVisitor visitor, - BlockScope blockScope) { + public void traverse(ASTVisitor visitor, BlockScope blockScope) { if (visitor.visit(this, blockScope)) { condition.traverse(visitor, blockScope);