/*******************************************************************************
 * 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 Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.flow;

import java.util.ArrayList;

import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.codegen.ObjectCache;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;

/**
 * Reflects the context of code analysis, keeping track of enclosing
 *	try statements, exception handlers, etc...
 */
public class ExceptionHandlingFlowContext extends FlowContext {
	
	public ReferenceBinding[] handledExceptions;
	
	public final static int BitCacheSize = 32; // 32 bits per int
	int[] isReached;
	int[] isNeeded;
	UnconditionalFlowInfo[] initsOnExceptions;
	ObjectCache indexes = new ObjectCache();
	boolean isMethodContext;

	public UnconditionalFlowInfo initsOnReturn;

	// for dealing with anonymous constructor thrown exceptions
	public ArrayList extendedExceptions;
	
	public ExceptionHandlingFlowContext(
		FlowContext parent,
		ASTNode associatedNode,
		ReferenceBinding[] handledExceptions,
		BlockScope scope,
		UnconditionalFlowInfo flowInfo) {

		super(parent, associatedNode);
		isMethodContext = scope == scope.methodScope();
		this.handledExceptions = handledExceptions;
		int count = handledExceptions.length, cacheSize = (count / BitCacheSize) + 1;
		this.isReached = new int[cacheSize]; // none is reached by default
		this.isNeeded = new int[cacheSize]; // none is needed by default
		this.initsOnExceptions = new UnconditionalFlowInfo[count];
		for (int i = 0; i < count; i++) {
			this.indexes.put(handledExceptions[i], i); // key type  -> value index
			int cacheIndex = i / BitCacheSize, bitMask = 1 << (i % BitCacheSize);
			if (handledExceptions[i].isUncheckedException(true)) {
				isReached[cacheIndex] |= bitMask;
				this.initsOnExceptions[i] = flowInfo.copy().unconditionalInits();
			} else {
				this.initsOnExceptions[i] = FlowInfo.DEAD_END;
			}
		}
		System.arraycopy(this.isReached, 0, this.isNeeded, 0, cacheSize);
		this.initsOnReturn = FlowInfo.DEAD_END;	
	}

	public void complainIfUnusedExceptionHandlers(AbstractMethodDeclaration method) {
		MethodScope scope = method.scope;
		// can optionally skip overriding methods
		if ((method.binding.modifiers & (ExtraCompilerModifiers.AccOverriding | ExtraCompilerModifiers.AccImplementing)) != 0
		        && !scope.compilerOptions().reportUnusedDeclaredThrownExceptionWhenOverriding) {
		    return;
		}
		    
		// report errors for unreachable exception handlers
		for (int i = 0, count = handledExceptions.length; i < count; i++) {
			int index = indexes.get(handledExceptions[i]);
			int cacheIndex = index / BitCacheSize;
			int bitMask = 1 << (index % BitCacheSize);
			if ((isReached[cacheIndex] & bitMask) == 0) {
				scope.problemReporter().unusedDeclaredThrownException(
					handledExceptions[index],
					method,
					method.thrownExceptions[index]);
			}
		}
	}
	
	public void complainIfUnusedExceptionHandlers(
		BlockScope scope,
		TryStatement tryStatement) {
		// report errors for unreachable exception handlers
		for (int i = 0, count = handledExceptions.length; i < count; i++) {
			int index = indexes.get(handledExceptions[i]);
			int cacheIndex = index / BitCacheSize;
			int bitMask = 1 << (index % BitCacheSize);
			if ((isReached[cacheIndex] & bitMask) == 0) {
				scope.problemReporter().unreachableCatchBlock(
					handledExceptions[index],
					tryStatement.catchArguments[index].type);
			} else {
				if ((isNeeded[cacheIndex] & bitMask) == 0) {
					scope.problemReporter().hiddenCatchBlock(
						handledExceptions[index],
						tryStatement.catchArguments[index].type);
				}
			}
		}
	}

	public String individualToString() {
		
		StringBuffer buffer = new StringBuffer("Exception flow context"); //$NON-NLS-1$
		int length = handledExceptions.length;
		for (int i = 0; i < length; i++) {
			int cacheIndex = i / BitCacheSize;
			int bitMask = 1 << (i % BitCacheSize);
			buffer.append('[').append(handledExceptions[i].readableName());
			if ((isReached[cacheIndex] & bitMask) != 0) {
				if ((isNeeded[cacheIndex] & bitMask) == 0) {
					buffer.append("-masked"); //$NON-NLS-1$
				} else {
					buffer.append("-reached"); //$NON-NLS-1$
				}
			} else {
				buffer.append("-not reached"); //$NON-NLS-1$
			}
			buffer.append('-').append(initsOnExceptions[i].toString()).append(']');
		}
		buffer.append("[initsOnReturn -").append(initsOnReturn.toString()).append(']'); //$NON-NLS-1$
		return buffer.toString();
	}

	public UnconditionalFlowInfo initsOnException(ReferenceBinding exceptionType) {
		
		int index;
		if ((index = indexes.get(exceptionType)) < 0) {
			return FlowInfo.DEAD_END;
		}
		return initsOnExceptions[index];
	}

	public UnconditionalFlowInfo initsOnReturn(){
		return this.initsOnReturn;
	}
	
	public void recordHandlingException(
		ReferenceBinding exceptionType,
		UnconditionalFlowInfo flowInfo,
		TypeBinding raisedException,
		ASTNode invocationSite,
		boolean wasAlreadyDefinitelyCaught) {
			
		int index = indexes.get(exceptionType);
		// if already flagged as being reached (unchecked exception handler)
		int cacheIndex = index / BitCacheSize;
		int bitMask = 1 << (index % BitCacheSize);
		if (!wasAlreadyDefinitelyCaught) {
			this.isNeeded[cacheIndex] |= bitMask;
		}
		this.isReached[cacheIndex] |= bitMask;
		
		initsOnExceptions[index] =
			initsOnExceptions[index] == FlowInfo.DEAD_END
				? flowInfo.copy().unconditionalInits()
				: initsOnExceptions[index].mergedWith(flowInfo.copy().unconditionalInits());
	}
	
	public void recordReturnFrom(FlowInfo flowInfo) {

		if (!flowInfo.isReachable()) return; 
		if (initsOnReturn == FlowInfo.DEAD_END) {
			initsOnReturn = flowInfo.copy().unconditionalInits();
		} else {
			initsOnReturn = initsOnReturn.mergedWith(flowInfo.copy().unconditionalInits());
		}
	}
	
	/*
	 * Compute a merged list of unhandled exception types (keeping only the most generic ones).
	 * This is necessary to add synthetic thrown exceptions for anonymous type constructors (JLS 8.6).
	 */
	public void mergeUnhandledException(TypeBinding newException){
		
		if (this.extendedExceptions == null){
			this.extendedExceptions = new ArrayList(5);
			for (int i = 0; i < this.handledExceptions.length; i++){
				this.extendedExceptions.add(this.handledExceptions[i]);
			}
		}
		
		boolean isRedundant = false;
		
		for(int i = this.extendedExceptions.size()-1; i >= 0; i--){
			switch(Scope.compareTypes(newException, (TypeBinding)this.extendedExceptions.get(i))){
				case MoreGeneric :
					this.extendedExceptions.remove(i);
					break;
				case EqualOrMoreSpecific :
					isRedundant = true;
					break;
				case NotRelated :
					break;
			}
		}
		if (!isRedundant){
			this.extendedExceptions.add(newException);
		}
	}
}
