/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * 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-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.jsdt.internal.compiler.flow;

import org.eclipse.wst.jsdt.core.compiler.CharOperation;
import org.eclipse.wst.jsdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.ASTNode;
import org.eclipse.wst.jsdt.internal.compiler.ast.Reference;
import org.eclipse.wst.jsdt.internal.compiler.ast.SubRoutineStatement;
import org.eclipse.wst.jsdt.internal.compiler.ast.TryStatement;
import org.eclipse.wst.jsdt.internal.compiler.codegen.Label;
import org.eclipse.wst.jsdt.internal.compiler.lookup.BlockScope;
import org.eclipse.wst.jsdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.wst.jsdt.internal.compiler.lookup.Scope;
import org.eclipse.wst.jsdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.wst.jsdt.internal.compiler.lookup.TypeConstants;
import org.eclipse.wst.jsdt.internal.compiler.lookup.VariableBinding;

/**
 * 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) {
			SubRoutineStatement sub;
			if (((sub = traversedContext.subRoutine()) != null) && sub.isSubRoutineEscaping()) {
				// 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 
			// try statement to the outermost 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) {
							    int state = caughtException == null 
							    	? EqualOrMoreSpecific /* any exception */
							        : Scope.compareTypes(raisedException, caughtException);
								switch (state) {
									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 (raisedException.isCompatibleWith(scope.getJavaLangRuntimeException())
								|| raisedException.isCompatibleWith(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.recordReturnFrom(flowInfo.unconditionalInits());
			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.	
		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
				for (int j = 0; j < i; j++) {
					if (raisedExceptions[j] == exception) continue nextReport; // already reported 
				}
				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) {
			SubRoutineStatement sub;
			if (((sub = traversedContext.subRoutine()) != null) && sub.isSubRoutineEscaping()) {
				// 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 
			// try statement to the outermost 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];
					    int state = caughtException == null 
					    	? EqualOrMoreSpecific /* any exception */
					        : Scope.compareTypes(raisedException, caughtException);						
						switch (state) {
							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 (raisedException.isCompatibleWith(scope.getJavaLangRuntimeException())
						|| raisedException.isCompatibleWith(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.recordReturnFrom(flowInfo.unconditionalInits());
			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.
		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;
				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;
					return lastNonReturningSubRoutine;
				} 
				// 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;
				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;
				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() {

		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) {
		// default implementation: do nothing
	}

	public void recordContinueFrom(FlowInfo flowInfo) {
		// default implementation: do nothing
	}

	boolean recordFinalAssignment(
		VariableBinding variable,
		Reference finalReference) {

		return true; // keep going
	}

	public void recordReturnFrom(FlowInfo flowInfo) {
		// default implementation: do nothing
	}

	public void recordSettingFinal(
		VariableBinding variable,
		Reference finalReference,
		FlowInfo flowInfo) {

		if (!flowInfo.isReachable()) return;

		// 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) {
		// default implementation: do nothing
	}

	public SubRoutineStatement 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();
	}
}
