X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowContext.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowContext.java index 5cefb30..90a1f67 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowContext.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/flow/FlowContext.java @@ -10,113 +10,114 @@ *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.flow; -import net.sourceforge.phpdt.core.compiler.CharOperation; -import net.sourceforge.phpdt.internal.compiler.codegen.Label; +//import net.sourceforge.phpdt.core.compiler.CharOperation; +import net.sourceforge.phpdt.internal.compiler.ast.ASTNode; +import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration; +import net.sourceforge.phpdt.internal.compiler.ast.Reference; +import net.sourceforge.phpdt.internal.compiler.ast.TryStatement; +//import net.sourceforge.phpdt.internal.compiler.codegen.Label; import net.sourceforge.phpdt.internal.compiler.lookup.BlockScope; import net.sourceforge.phpdt.internal.compiler.lookup.ReferenceBinding; import net.sourceforge.phpdt.internal.compiler.lookup.Scope; import net.sourceforge.phpdt.internal.compiler.lookup.TypeBinding; import net.sourceforge.phpdt.internal.compiler.lookup.TypeConstants; import net.sourceforge.phpdt.internal.compiler.lookup.VariableBinding; -import net.sourceforge.phpeclipse.internal.compiler.ast.ASTNode; -import net.sourceforge.phpeclipse.internal.compiler.ast.AbstractMethodDeclaration; -import net.sourceforge.phpeclipse.internal.compiler.ast.Reference; -import net.sourceforge.phpeclipse.internal.compiler.ast.TryStatement; /** - * Reflects the context of code analysis, keeping track of enclosing - * try statements, exception handlers, etc... + * Reflects the context of code analysis, keeping track of enclosing try + * statements, exception handlers, etc... */ public class FlowContext implements TypeConstants { - + public ASTNode associatedNode; + public FlowContext parent; - public final static FlowContext NotContinuableContext = new FlowContext(null, null); - + public final static FlowContext NotContinuableContext = new FlowContext( + null, null); + public FlowContext(FlowContext parent, ASTNode associatedNode) { this.parent = parent; this.associatedNode = associatedNode; } - - public Label breakLabel() { - return null; - } - - public void checkExceptionHandlers( - TypeBinding[] raisedExceptions, - ASTNode location, - FlowInfo flowInfo, - BlockScope scope) { +// public Label breakLabel() { +// +// return null; +// } + + public void checkExceptionHandlers(TypeBinding[] raisedExceptions, + ASTNode location, FlowInfo flowInfo, BlockScope scope) { // check that all the argument exception types are handled - // JDK Compatible implementation - when an exception type is thrown, - // all related catch blocks are marked as reachable... instead of those only - // until the point where it is safely handled (Smarter - see comment at the end) - int remainingCount; // counting the number of remaining unhandled exceptions + // JDK Compatible implementation - when an exception type is thrown, + // all related catch blocks are marked as reachable... instead of those + // only + // until the point where it is safely handled (Smarter - see comment at + // the end) + int remainingCount; // counting the number of remaining unhandled + // exceptions int raisedCount; // total number of exceptions raised if ((raisedExceptions == null) - || ((raisedCount = raisedExceptions.length) == 0)) + || ((raisedCount = raisedExceptions.length) == 0)) return; remainingCount = raisedCount; // duplicate the array of raised exceptions since it will be updated // (null replaces any handled exception) - System.arraycopy( - raisedExceptions, - 0, - (raisedExceptions = new TypeBinding[raisedCount]), - 0, - raisedCount); + System.arraycopy(raisedExceptions, 0, + (raisedExceptions = new TypeBinding[raisedCount]), 0, + raisedCount); FlowContext traversedContext = this; while (traversedContext != null) { ASTNode sub; - if (((sub = traversedContext.subRoutine()) != null) && sub.cannotReturn()) { - // traversing a non-returning subroutine means that all unhandled + if (((sub = traversedContext.subRoutine()) != null) + && sub.cannotReturn()) { + // traversing a non-returning subroutine means that all + // unhandled // exceptions will actually never get sent... return; } - // filter exceptions that are locally caught from the innermost enclosing + // filter exceptions that are locally caught from the innermost + // enclosing // try statement to the outermost ones. if (traversedContext instanceof ExceptionHandlingFlowContext) { - ExceptionHandlingFlowContext exceptionContext = - (ExceptionHandlingFlowContext) traversedContext; + ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) traversedContext; ReferenceBinding[] caughtExceptions; if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) { int caughtCount = caughtExceptions.length; - boolean[] locallyCaught = new boolean[raisedCount]; // at most + boolean[] locallyCaught = new boolean[raisedCount]; // at + // most for (int caughtIndex = 0; caughtIndex < caughtCount; caughtIndex++) { ReferenceBinding caughtException = caughtExceptions[caughtIndex]; for (int raisedIndex = 0; raisedIndex < raisedCount; raisedIndex++) { TypeBinding raisedException; if ((raisedException = raisedExceptions[raisedIndex]) != null) { - switch (Scope.compareTypes(raisedException, caughtException)) { - case EqualOrMoreSpecific : - exceptionContext.recordHandlingException( - caughtException, - flowInfo.unconditionalInits(), - raisedException, - location, + switch (Scope.compareTypes(raisedException, + caughtException)) { + case EqualOrMoreSpecific: + exceptionContext.recordHandlingException( + caughtException, flowInfo + .unconditionalInits(), + raisedException, location, locallyCaught[raisedIndex]); - // was already definitely caught ? - if (!locallyCaught[raisedIndex]) { - locallyCaught[raisedIndex] = true; - // remember that this exception has been definitely caught - remainingCount--; - } - break; - case MoreGeneric : - exceptionContext.recordHandlingException( - caughtException, - flowInfo.unconditionalInits(), - raisedException, - location, - false); - // was not caught already per construction + // was already definitely caught ? + if (!locallyCaught[raisedIndex]) { + locallyCaught[raisedIndex] = true; + // remember that this exception has been + // definitely caught + remainingCount--; + } + break; + case MoreGeneric: + exceptionContext.recordHandlingException( + caughtException, flowInfo + .unconditionalInits(), + raisedException, location, false); + // was not caught already per construction } } } @@ -124,7 +125,8 @@ public class FlowContext implements TypeConstants { // remove locally caught exceptions from the remaining ones for (int i = 0; i < raisedCount; i++) { if (locallyCaught[i]) { - raisedExceptions[i] = null; // removed from the remaining ones. + raisedExceptions[i] = null; // removed from the + // remaining ones. } } } @@ -133,26 +135,33 @@ public class FlowContext implements TypeConstants { for (int i = 0; i < raisedCount; i++) { TypeBinding raisedException; if ((raisedException = raisedExceptions[i]) != null) { - if (raisedException.isCompatibleWith(scope.getJavaLangRuntimeException()) - || raisedException.isCompatibleWith(scope.getJavaLangError())) { + if (raisedException.isCompatibleWith(scope + .getJavaLangRuntimeException()) + || raisedException.isCompatibleWith(scope + .getJavaLangError())) { remainingCount--; raisedExceptions[i] = null; } } } - // anonymous constructors are allowed to throw any exceptions (their thrown exceptions + // anonymous constructors are allowed to throw any + // exceptions (their thrown exceptions // clause will be fixed up later as per JLS 8.6). - if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration){ - AbstractMethodDeclaration method = (AbstractMethodDeclaration)exceptionContext.associatedNode; - if (method.isConstructor() && method.binding.declaringClass.isAnonymousType()){ - + if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration) { + AbstractMethodDeclaration method = (AbstractMethodDeclaration) exceptionContext.associatedNode; + if (method.isConstructor() + && method.binding.declaringClass + .isAnonymousType()) { + for (int i = 0; i < raisedCount; i++) { TypeBinding raisedException; if ((raisedException = raisedExceptions[i]) != null) { - exceptionContext.mergeUnhandledException(raisedException); + exceptionContext + .mergeUnhandledException(raisedException); } } - return; // no need to complain, will fix up constructor exceptions + return; // no need to complain, will fix up + // constructor exceptions } } break; // not handled anywhere, thus jump to error handling @@ -160,77 +169,80 @@ public class FlowContext implements TypeConstants { } if (remainingCount == 0) return; - + traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); - if (traversedContext.associatedNode instanceof TryStatement){ - flowInfo = flowInfo.copy().addInitializationsFrom(((TryStatement) traversedContext.associatedNode).subRoutineInits); + if (traversedContext.associatedNode instanceof TryStatement) { + flowInfo = flowInfo + .copy() + .addInitializationsFrom( + ((TryStatement) traversedContext.associatedNode).subRoutineInits); } traversedContext = traversedContext.parent; } - // if reaches this point, then there are some remaining unhandled exception types. + // if reaches this point, then there are some remaining unhandled + // exception types. nextReport: for (int i = 0; i < raisedCount; i++) { TypeBinding exception; if ((exception = raisedExceptions[i]) != null) { - // only one complaint if same exception declared to be thrown more than once + // only one complaint if same exception declared to be thrown + // more than once for (int j = 0; j < i; j++) { - if (raisedExceptions[j] == exception) continue nextReport; // already reported + if (raisedExceptions[j] == exception) + continue nextReport; // already reported } scope.problemReporter().unhandledException(exception, location); } } } - public void checkExceptionHandlers( - TypeBinding raisedException, - ASTNode location, - FlowInfo flowInfo, - BlockScope scope) { + public void checkExceptionHandlers(TypeBinding raisedException, + ASTNode location, FlowInfo flowInfo, BlockScope scope) { // LIGHT-VERSION OF THE EQUIVALENT WITH AN ARRAY OF EXCEPTIONS // check that all the argument exception types are handled - // JDK Compatible implementation - when an exception type is thrown, - // all related catch blocks are marked as reachable... instead of those only - // until the point where it is safely handled (Smarter - see comment at the end) + // JDK Compatible implementation - when an exception type is thrown, + // all related catch blocks are marked as reachable... instead of those + // only + // until the point where it is safely handled (Smarter - see comment at + // the end) FlowContext traversedContext = this; while (traversedContext != null) { ASTNode sub; - if (((sub = traversedContext.subRoutine()) != null) && sub.cannotReturn()) { - // traversing a non-returning subroutine means that all unhandled + if (((sub = traversedContext.subRoutine()) != null) + && sub.cannotReturn()) { + // traversing a non-returning subroutine means that all + // unhandled // exceptions will actually never get sent... return; } - - // filter exceptions that are locally caught from the innermost enclosing + + // filter exceptions that are locally caught from the innermost + // enclosing // try statement to the outermost ones. if (traversedContext instanceof ExceptionHandlingFlowContext) { - ExceptionHandlingFlowContext exceptionContext = - (ExceptionHandlingFlowContext) traversedContext; + ExceptionHandlingFlowContext exceptionContext = (ExceptionHandlingFlowContext) traversedContext; ReferenceBinding[] caughtExceptions; if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) { boolean definitelyCaught = false; - for (int caughtIndex = 0, caughtCount = caughtExceptions.length; - caughtIndex < caughtCount; - caughtIndex++) { + for (int caughtIndex = 0, caughtCount = caughtExceptions.length; caughtIndex < caughtCount; caughtIndex++) { ReferenceBinding caughtException = caughtExceptions[caughtIndex]; - switch (Scope.compareTypes(raisedException, caughtException)) { - case EqualOrMoreSpecific : - exceptionContext.recordHandlingException( - caughtException, - flowInfo.unconditionalInits(), - raisedException, - location, - definitelyCaught); - // was it already definitely caught ? - definitelyCaught = true; - break; - case MoreGeneric : - exceptionContext.recordHandlingException( - caughtException, - flowInfo.unconditionalInits(), - raisedException, - location, - false); - // was not caught already per construction + switch (Scope.compareTypes(raisedException, + caughtException)) { + case EqualOrMoreSpecific: + exceptionContext + .recordHandlingException(caughtException, + flowInfo.unconditionalInits(), + raisedException, location, + definitelyCaught); + // was it already definitely caught ? + definitelyCaught = true; + break; + case MoreGeneric: + exceptionContext.recordHandlingException( + caughtException, flowInfo + .unconditionalInits(), + raisedException, location, false); + // was not caught already per construction } } if (definitelyCaught) @@ -238,18 +250,25 @@ public class FlowContext implements TypeConstants { } // method treatment for unchecked exceptions if (exceptionContext.isMethodContext) { - if (raisedException.isCompatibleWith(scope.getJavaLangRuntimeException()) - || raisedException.isCompatibleWith(scope.getJavaLangError())) + if (raisedException.isCompatibleWith(scope + .getJavaLangRuntimeException()) + || raisedException.isCompatibleWith(scope + .getJavaLangError())) return; - - // anonymous constructors are allowed to throw any exceptions (their thrown exceptions + + // anonymous constructors are allowed to throw any + // exceptions (their thrown exceptions // clause will be fixed up later as per JLS 8.6). - if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration){ - AbstractMethodDeclaration method = (AbstractMethodDeclaration)exceptionContext.associatedNode; - if (method.isConstructor() && method.binding.declaringClass.isAnonymousType()){ - - exceptionContext.mergeUnhandledException(raisedException); - return; // no need to complain, will fix up constructor exceptions + if (exceptionContext.associatedNode instanceof AbstractMethodDeclaration) { + AbstractMethodDeclaration method = (AbstractMethodDeclaration) exceptionContext.associatedNode; + if (method.isConstructor() + && method.binding.declaringClass + .isAnonymousType()) { + + exceptionContext + .mergeUnhandledException(raisedException); + return; // no need to complain, will fix up + // constructor exceptions } } break; // not handled anywhere, thus jump to error handling @@ -257,181 +276,185 @@ public class FlowContext implements TypeConstants { } traversedContext.recordReturnFrom(flowInfo.unconditionalInits()); - if (traversedContext.associatedNode instanceof TryStatement){ - flowInfo = flowInfo.copy().addInitializationsFrom(((TryStatement) traversedContext.associatedNode).subRoutineInits); + if (traversedContext.associatedNode instanceof TryStatement) { + flowInfo = flowInfo + .copy() + .addInitializationsFrom( + ((TryStatement) traversedContext.associatedNode).subRoutineInits); } traversedContext = traversedContext.parent; } - // if reaches this point, then there are some remaining unhandled exception types. + // if reaches this point, then there are some remaining unhandled + // exception types. scope.problemReporter().unhandledException(raisedException, location); } - public Label continueLabel() { - - return null; - } +// public Label continueLabel() { +// +// return null; +// } /* * lookup through break labels */ - public FlowContext getTargetContextForBreakLabel(char[] labelName) { - - FlowContext current = this, lastNonReturningSubRoutine = null; - while (current != null) { - if (current.isNonReturningContext()) { - lastNonReturningSubRoutine = current; - } - char[] currentLabelName; - if (((currentLabelName = current.labelName()) != null) - && CharOperation.equals(currentLabelName, labelName)) { - if (lastNonReturningSubRoutine == null) { - return current; - } else { - return lastNonReturningSubRoutine; - } - } - current = current.parent; - } - // not found - return null; - } +// public FlowContext getTargetContextForBreakLabel(char[] labelName) { +// +// FlowContext current = this, lastNonReturningSubRoutine = null; +// while (current != null) { +// if (current.isNonReturningContext()) { +// lastNonReturningSubRoutine = current; +// } +// char[] currentLabelName; +// if (((currentLabelName = current.labelName()) != null) +// && CharOperation.equals(currentLabelName, labelName)) { +// if (lastNonReturningSubRoutine == null) { +// return current; +// } else { +// return lastNonReturningSubRoutine; +// } +// } +// current = current.parent; +// } +// // not found +// return null; +// } /* * lookup through continue labels */ - public FlowContext getTargetContextForContinueLabel(char[] labelName) { - - FlowContext current = this; - FlowContext lastContinuable = null; - FlowContext lastNonReturningSubRoutine = null; - - while (current != null) { - if (current.isNonReturningContext()) { - lastNonReturningSubRoutine = current; - } else { - if (current.isContinuable()) { - lastContinuable = current; - } - } - - char[] currentLabelName; - if ((currentLabelName = current.labelName()) != null && CharOperation.equals(currentLabelName, labelName)) { - - // matching label found - if ((lastContinuable != null) - && (current.associatedNode.concreteStatement() == lastContinuable.associatedNode)) { - - if (lastNonReturningSubRoutine == null) { - return lastContinuable; - } else { - return lastNonReturningSubRoutine; - } - } else { - // label is found, but not a continuable location - return NotContinuableContext; - } - } - current = current.parent; - } - // not found - return null; - } +// public FlowContext getTargetContextForContinueLabel(char[] labelName) { +// +// FlowContext current = this; +// FlowContext lastContinuable = null; +// FlowContext lastNonReturningSubRoutine = null; +// +// while (current != null) { +// if (current.isNonReturningContext()) { +// lastNonReturningSubRoutine = current; +// } else { +// if (current.isContinuable()) { +// lastContinuable = current; +// } +// } +// +// char[] currentLabelName; +// if ((currentLabelName = current.labelName()) != null +// && CharOperation.equals(currentLabelName, labelName)) { +// +// // matching label found +// if ((lastContinuable != null) +// && (current.associatedNode.concreteStatement() == lastContinuable.associatedNode)) { +// +// if (lastNonReturningSubRoutine == null) { +// return lastContinuable; +// } else { +// return lastNonReturningSubRoutine; +// } +// } else { +// // label is found, but not a continuable location +// return NotContinuableContext; +// } +// } +// current = current.parent; +// } +// // not found +// return null; +// } /* * lookup a default break through breakable locations */ - public FlowContext getTargetContextForDefaultBreak() { - - FlowContext current = this, lastNonReturningSubRoutine = null; - while (current != null) { - if (current.isNonReturningContext()) { - lastNonReturningSubRoutine = current; - } - if (current.isBreakable() && current.labelName() == null) { - if (lastNonReturningSubRoutine == null) { - return current; - } else { - return lastNonReturningSubRoutine; - } - } - current = current.parent; - } - // not found - return null; - } +// public FlowContext getTargetContextForDefaultBreak() { +// +// FlowContext current = this, lastNonReturningSubRoutine = null; +// while (current != null) { +// if (current.isNonReturningContext()) { +// lastNonReturningSubRoutine = current; +// } +// if (current.isBreakable() && current.labelName() == null) { +// if (lastNonReturningSubRoutine == null) { +// return current; +// } else { +// return lastNonReturningSubRoutine; +// } +// } +// current = current.parent; +// } +// // not found +// return null; +// } /* * lookup a default continue amongst continuable locations */ - public FlowContext getTargetContextForDefaultContinue() { - - FlowContext current = this, lastNonReturningSubRoutine = null; - while (current != null) { - if (current.isNonReturningContext()) { - lastNonReturningSubRoutine = current; - } - if (current.isContinuable()) { - if (lastNonReturningSubRoutine == null) { - return current; - } else { - return lastNonReturningSubRoutine; - } - } - current = current.parent; - } - // not found - return null; - } +// public FlowContext getTargetContextForDefaultContinue() { +// +// FlowContext current = this, lastNonReturningSubRoutine = null; +// while (current != null) { +// if (current.isNonReturningContext()) { +// lastNonReturningSubRoutine = current; +// } +// if (current.isContinuable()) { +// if (lastNonReturningSubRoutine == null) { +// return current; +// } else { +// return lastNonReturningSubRoutine; +// } +// } +// current = current.parent; +// } +// // not found +// return null; +// } public String individualToString() { return "Flow context"; //$NON-NLS-1$ } - public FlowInfo initsOnBreak() { - - return FlowInfo.DEAD_END; - } - - public UnconditionalFlowInfo initsOnReturn() { - - return FlowInfo.DEAD_END; - } - - public boolean isBreakable() { +// public FlowInfo initsOnBreak() { +// +// return FlowInfo.DEAD_END; +// } - return false; - } - - public boolean isContinuable() { - - return false; - } +// public UnconditionalFlowInfo initsOnReturn() { +// +// return FlowInfo.DEAD_END; +// } - public boolean isNonReturningContext() { +// public boolean isBreakable() { +// +// return false; +// } - return false; - } +// public boolean isContinuable() { +// +// return false; +// } - public boolean isSubRoutine() { +// public boolean isNonReturningContext() { +// +// return false; +// } - return false; - } +// public boolean isSubRoutine() { +// +// return false; +// } public char[] labelName() { return null; } - public void recordBreakFrom(FlowInfo flowInfo) { - } +// public void recordBreakFrom(FlowInfo flowInfo) { +// } - public void recordContinueFrom(FlowInfo flowInfo) { - } +// public void recordContinueFrom(FlowInfo flowInfo) { +// } - boolean recordFinalAssignment( - VariableBinding variable, - Reference finalReference) { + boolean recordFinalAssignment(VariableBinding variable, + Reference finalReference) { return true; // keep going } @@ -439,9 +462,8 @@ public class FlowContext implements TypeConstants { public void recordReturnFrom(FlowInfo flowInfo) { } - public void recordSettingFinal( - VariableBinding variable, - Reference finalReference) { + public void recordSettingFinal(VariableBinding variable, + Reference finalReference) { // for initialization inside looping statement that effectively loops FlowContext context = this;