Rewritten Parser/Scanner to package net.sourceforge.phpdt.internal.compiler.parser
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / flow / FlowContext.java
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
deleted file mode 100644 (file)
index e92b862..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
- * All rights reserved. This program and the accompanying materials 
- * are made available under the terms of the Common Public License v0.5 
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v05.html
- * 
- * Contributors:
- *     IBM Corporation - initial API and implementation
- ******************************************************************************/
-package net.sourceforge.phpdt.internal.compiler.flow;
-
-import net.sourceforge.phpdt.internal.compiler.ast.AbstractMethodDeclaration;
-import net.sourceforge.phpdt.internal.compiler.ast.AstNode;
-import net.sourceforge.phpdt.internal.compiler.ast.Reference;
-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.phpdt.internal.compiler.util.CharOperation;
-
-/**
- * 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 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) {
-
-               // 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
-               int raisedCount; // total number of exceptions raised
-               if ((raisedExceptions == null)
-                       || ((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);
-               FlowContext traversedContext = this;
-               while (traversedContext != null) {
-                       AstNode sub;
-                       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 most enclosing 
-                       // try statement to the outer ones.
-                       if (traversedContext instanceof ExceptionHandlingFlowContext) {
-                               ExceptionHandlingFlowContext exceptionContext =
-                                       (ExceptionHandlingFlowContext) traversedContext;
-                               ReferenceBinding[] caughtExceptions;
-                               if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) {
-                                       int caughtCount = caughtExceptions.length;
-                                       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,
-                                                                                       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
-                                                               }
-                                                       }
-                                               }
-                                       }
-                                       // 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.
-                                               }
-                                       }
-                               }
-                               // method treatment for unchecked exceptions
-                               if (exceptionContext.isMethodContext) {
-                                       for (int i = 0; i < raisedCount; i++) {
-                                               TypeBinding raisedException;
-                                               if ((raisedException = raisedExceptions[i]) != null) {
-                                                       if (scope
-                                                               .areTypesCompatible(raisedException, scope.getJavaLangRuntimeException())
-                                                               || scope.areTypesCompatible(raisedException, scope.getJavaLangError())) {
-                                                               remainingCount--;
-                                                               raisedExceptions[i] = null;
-                                                       }
-                                               }
-                                       }
-                                       // 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()){
-                                                               
-                                                       for (int i = 0; i < raisedCount; i++) {
-                                                               TypeBinding raisedException;
-                                                               if ((raisedException = raisedExceptions[i]) != null) {
-                                                                       exceptionContext.mergeUnhandledException(raisedException);
-                                                               }
-                                                       }
-                                                       return; // no need to complain, will fix up constructor exceptions                                              
-                                               }
-                                       }
-                                       break; // not handled anywhere, thus jump to error handling
-                               }
-                       }
-                       if (remainingCount == 0)
-                               return;
-                       traversedContext = traversedContext.parent;
-               }
-               // if reaches this point, then there are some remaining unhandled exception types.      
-               for (int i = 0; i < raisedCount; i++) {
-                       TypeBinding exception;
-                       if ((exception = raisedExceptions[i]) != null) {
-                               scope.problemReporter().unhandledException(exception, location);
-                       }
-               }
-       }
-
-       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)
-               FlowContext traversedContext = this;
-               while (traversedContext != null) {
-                       AstNode sub;
-                       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 most enclosing 
-                       // try statement to the outer ones.
-                       if (traversedContext instanceof ExceptionHandlingFlowContext) {
-                               ExceptionHandlingFlowContext exceptionContext =
-                                       (ExceptionHandlingFlowContext) traversedContext;
-                               ReferenceBinding[] caughtExceptions;
-                               if ((caughtExceptions = exceptionContext.handledExceptions) != NoExceptions) {
-                                       boolean definitelyCaught = false;
-                                       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
-                                               }
-                                       }
-                                       if (definitelyCaught)
-                                               return;
-                               }
-                               // method treatment for unchecked exceptions
-                               if (exceptionContext.isMethodContext) {
-                                       if (scope
-                                               .areTypesCompatible(raisedException, scope.getJavaLangRuntimeException())
-                                               || scope.areTypesCompatible(raisedException, scope.getJavaLangError()))
-                                               return;
-                                               
-                                       // 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                                              
-                                               }
-                                       }
-                                       break; // not handled anywhere, thus jump to error handling
-                               }
-                       }
-                       traversedContext = traversedContext.parent;
-               }
-               // if reaches this point, then there are some remaining unhandled exception types.
-               scope.problemReporter().unhandledException(raisedException, location);
-       }
-
-       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;
-       }
-
-       /*
-        * lookup through continue labels
-        */
-       public FlowContext getTargetContextForContinueLabel(char[] labelName) {
-               FlowContext current = this,
-                       lastContinuable = null,
-                       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)) {
-                               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()) {
-                               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 String individualToString() {
-               return "Flow context"; //$NON-NLS-1$
-       }
-
-       public FlowInfo initsOnBreak() {
-               return FlowInfo.DeadEnd;
-       }
-
-       public boolean isBreakable() {
-               return false;
-       }
-
-       public boolean isContinuable() {
-               return false;
-       }
-
-       public boolean isNonReturningContext() {
-               return false;
-       }
-
-       public boolean isSubRoutine() {
-               return false;
-       }
-
-       public char[] labelName() {
-               return null;
-       }
-
-       public void recordBreakFrom(FlowInfo flowInfo) {
-       }
-
-       public void recordContinueFrom(FlowInfo flowInfo) {
-       }
-
-       boolean recordFinalAssignment(
-               VariableBinding variable,
-               Reference finalReference) {
-               return true; // keep going
-       }
-
-       public void recordReturnFrom(UnconditionalFlowInfo flowInfo) {
-       }
-
-       public void recordSettingFinal(
-               VariableBinding variable,
-               Reference finalReference) {
-               // for initialization inside looping statement that effectively loops
-               FlowContext context = this;
-               while (context != null) {
-                       if (!context.recordFinalAssignment(variable, finalReference)) {
-                               break; // no need to keep going
-                       }
-                       context = context.parent;
-               }
-       }
-
-       void removeFinalAssignmentIfAny(Reference reference) {
-       }
-
-       public AstNode subRoutine() {
-               return null;
-       }
-
-       public String toString() {
-               StringBuffer buffer = new StringBuffer();
-               FlowContext current = this;
-               int parentsCount = 0;
-               while ((current = current.parent) != null) {
-                       parentsCount++;
-               }
-               FlowContext[] parents = new FlowContext[parentsCount + 1];
-               current = this;
-               int index = parentsCount;
-               while (index >= 0) {
-                       parents[index--] = current;
-                       current = current.parent;
-               }
-               for (int i = 0; i < parentsCount; i++) {
-                       for (int j = 0; j < i; j++)
-                               buffer.append('\t');
-                       buffer.append(parents[i].individualToString()).append('\n');
-               }
-               buffer.append('*');
-               for (int j = 0; j < parentsCount + 1; j++)
-                       buffer.append('\t');
-               buffer.append(individualToString()).append('\n');
-               return buffer.toString();
-       }
-}
\ No newline at end of file