package org.eclipse.jdt.internal.compiler.flow;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.problem.*;

/**
 * Record initialization status during definite assignment analysis
 *
 * No caching of pre-allocated instances.
 */
public class UnconditionalFlowInfo extends FlowInfo {
	public long definiteInits;
	long potentialInits;
	public long extraDefiniteInits[];
	long extraPotentialInits[];
	public boolean isFakeReachable;
	public int maxFieldCount;
	
	// Constants
	public static final int BitCacheSize = 64; // 64 bits in a long.
UnconditionalFlowInfo() {
}
public UnconditionalFlowInfo addInitializationsFrom(UnconditionalFlowInfo otherInits) {

	// unions of both sets of initialization - used for try/finally
	if (this == DeadEnd)
		return this;
	if (otherInits == DeadEnd)
		return this;
		
	// union of definitely assigned variables, 
	definiteInits |= otherInits.definiteInits;
	// union of potentially set ones
	potentialInits |= otherInits.potentialInits;

	// treating extra storage
	if (extraDefiniteInits != null) {
		if (otherInits.extraDefiniteInits != null) {
			// both sides have extra storage
			int i = 0, length, otherLength;
			if ((length = extraDefiniteInits.length) < (otherLength = otherInits.extraDefiniteInits.length)) {
				// current storage is shorter -> grow current (could maybe reuse otherInits extra storage?)
				System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength]), 0, length);
				System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, length);
				while (i < length) {
					extraDefiniteInits[i] |= otherInits.extraDefiniteInits[i];
					extraPotentialInits[i] |= otherInits.extraPotentialInits[i++];
				}
				while (i < otherLength) {
					extraPotentialInits[i] = otherInits.extraPotentialInits[i++];
				}
			} else {
				// current storage is longer
				while (i < otherLength) {
					extraDefiniteInits[i] |= otherInits.extraDefiniteInits[i];
					extraPotentialInits[i] |= otherInits.extraPotentialInits[i++];
				}
				while (i < length)
					extraDefiniteInits[i++] = 0;
			}
		} else {
			// no extra storage on otherInits
		}
	} else
		if (otherInits.extraDefiniteInits != null) {
			// no storage here, but other has extra storage.
			int otherLength;
			System.arraycopy(otherInits.extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length]), 0, otherLength);			
			System.arraycopy(otherInits.extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, otherLength);
		}
	return this;
}
public UnconditionalFlowInfo addPotentialInitializationsFrom(UnconditionalFlowInfo otherInits) {

	// unions of both sets of initialization - used for try/finally
	if (this == DeadEnd){
		return this;
	}
	if (otherInits == DeadEnd){
		return this;
	}
	// union of potentially set ones
	potentialInits |= otherInits.potentialInits;

	// treating extra storage
	if (extraDefiniteInits != null) {
		if (otherInits.extraDefiniteInits != null) {
			// both sides have extra storage
			int i = 0, length, otherLength;
			if ((length = extraDefiniteInits.length) < (otherLength = otherInits.extraDefiniteInits.length)) {
				// current storage is shorter -> grow current (could maybe reuse otherInits extra storage?)
				System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength]), 0, length);
				System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, length);
				while (i < length) {
					extraPotentialInits[i] |= otherInits.extraPotentialInits[i++];
				}
				while (i < otherLength) {
					extraPotentialInits[i] = otherInits.extraPotentialInits[i++];
				}
			} else {
				// current storage is longer
				while (i < otherLength) {
					extraPotentialInits[i] |= otherInits.extraPotentialInits[i++];
				}
			}
		}
	} else
		if (otherInits.extraDefiniteInits != null) {
			// no storage here, but other has extra storage.
			int otherLength;
			extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length];			
			System.arraycopy(otherInits.extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, otherLength);
		}
	return this;
}
public boolean complainIfUnreachable(Statement statement, BlockScope scope) {
	// Report an error if necessary

	boolean isDeadEnd;
	if ((isDeadEnd = (this == DeadEnd)) || isFakeReachable) {
		statement.bits &= ~Statement.IsReachableMASK;
		/* EXTRA REFERENCE RECORDING
		statement.recordUnreachableReferences(scope.referenceType()); // scopes cannot have an enclosingMethod slot since there are class scopes
		*/
		if (isDeadEnd)
			scope.problemReporter().unreachableCode(statement);
		return isDeadEnd;
	}
	return false;
}
/**
 * Answers a copy of the current instance
 */
public FlowInfo copy() {
	// do not clone the DeadEnd
	if (this == DeadEnd)
		return this;

	// look for an unused preallocated object
	UnconditionalFlowInfo copy = new UnconditionalFlowInfo();

	// copy slots
	copy.definiteInits = definiteInits;
	copy.potentialInits = potentialInits;
	copy.isFakeReachable = isFakeReachable;
	copy.maxFieldCount = maxFieldCount;
	
	if (extraDefiniteInits != null) {
		int length;
		System.arraycopy(extraDefiniteInits, 0, (copy.extraDefiniteInits = new long[ (length = extraDefiniteInits.length)]), 0, length);
		System.arraycopy(extraPotentialInits, 0, (copy.extraPotentialInits = new long[length]), 0, length);
	};
	return copy;
}
public FlowInfo initsWhenFalse() {
	return this;
}
public FlowInfo initsWhenTrue() {
	return this;
}
/**
 * Check status of definite assignment at a given position.
 * It deals with the dual representation of the InitializationInfo2:
 * bits for the first 64 entries, then an array of booleans.
 */
final private boolean isDefinitelyAssigned(int position) {
	// Dependant of CodeStream.isDefinitelyAssigned(..)
	// id is zero-based
	if (position < BitCacheSize) {
		return (definiteInits & (1L << position)) != 0; // use bits
	}
	// use extra vector
	if (extraDefiniteInits == null)
		return false; // if vector not yet allocated, then not initialized
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= extraDefiniteInits.length)
		return false; // if not enough room in vector, then not initialized 
	return ((extraDefiniteInits[vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
}
/**
 * Check status of definite assignment for a field.
 */
final public boolean isDefinitelyAssigned(FieldBinding field) {
	// Dependant of CodeStream.isDefinitelyAssigned(..)
	// We do not want to complain in unreachable code
	if ((this == DeadEnd) || (this.isFakeReachable))
		return true;
	return isDefinitelyAssigned(field.id); 
}
/**
 * Check status of definite assignment for a local.
 */
final public boolean isDefinitelyAssigned(LocalVariableBinding local) {
	// Dependant of CodeStream.isDefinitelyAssigned(..)
	// We do not want to complain in unreachable code
	if ((this == DeadEnd) || (this.isFakeReachable))
		return true;
	if (local.isArgument) {
		return true;
	}
	return isDefinitelyAssigned(local.id + maxFieldCount);
}
public boolean isFakeReachable() {
	return isFakeReachable;
}
/**
 * Check status of potential assignment at a given position.
 * It deals with the dual representation of the InitializationInfo3:
 * bits for the first 64 entries, then an array of booleans.
 */
final private boolean isPotentiallyAssigned(int position) {
	// id is zero-based
	if (position < BitCacheSize) {
		// use bits
		return (potentialInits & (1L << position)) != 0;
	}
	// use extra vector
	if (extraPotentialInits == null)
		return false; // if vector not yet allocated, then not initialized
	int vectorIndex;
	if ((vectorIndex = (position / BitCacheSize) - 1) >= extraPotentialInits.length)
		return false; // if not enough room in vector, then not initialized 
	return ((extraPotentialInits[vectorIndex]) & (1L << (position % BitCacheSize))) != 0;
}
/**
 * Check status of definite assignment for a field.
 */
final public boolean isPotentiallyAssigned(FieldBinding field) {
	// We do not want to complain in unreachable code
	if (this == DeadEnd)
		return false;
	return isPotentiallyAssigned(field.id); 
}
/**
 * Check status of potential assignment for a local.
 */
final public boolean isPotentiallyAssigned(LocalVariableBinding local) {
	// We do not want to complain in unreachable code
	if ((this == DeadEnd) || (this.isFakeReachable))
		return false;
	if (local.isArgument) {
		return true;
	}
	return isPotentiallyAssigned(local.id + maxFieldCount);
}
/**
 * Record a definite assignment at a given position.
 * It deals with the dual representation of the InitializationInfo2:
 * bits for the first 64 entries, then an array of booleans.
 */
final private void markAsDefinitelyAssigned(int position) {
	if (this != DeadEnd) {

		// position is zero-based
		if (position < BitCacheSize) {
			// use bits
			long mask;
			definiteInits |= (mask = 1L << position);
			potentialInits |= mask;
		} else {
			// use extra vector
			int vectorIndex = (position / BitCacheSize) - 1;
			if (extraDefiniteInits == null) {
				int length;
				extraDefiniteInits = new long[length = vectorIndex + 1];
				extraPotentialInits = new long[length];
			} else {
				int oldLength; // might need to grow the arrays
				if (vectorIndex >= (oldLength = extraDefiniteInits.length)) {
					System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[vectorIndex + 1]), 0, oldLength);
					System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[vectorIndex + 1]), 0, oldLength);
				}
			}
			long mask;
			extraDefiniteInits[vectorIndex] |= (mask = 1L << (position % BitCacheSize));
			extraPotentialInits[vectorIndex] |= mask;
		}
	}
}
/**
 * Record a field got definitely assigned.
 */
public void markAsDefinitelyAssigned(FieldBinding field) {
	if (this != DeadEnd)
		markAsDefinitelyAssigned(field.id);
}
/**
 * Record a local got definitely assigned.
 */
public void markAsDefinitelyAssigned(LocalVariableBinding local) {
	if (this != DeadEnd)
		markAsDefinitelyAssigned(local.id + maxFieldCount);
}
/**
 * Clear initialization information at a given position.
 * It deals with the dual representation of the InitializationInfo2:
 * bits for the first 64 entries, then an array of booleans.
 */
final private void markAsDefinitelyNotAssigned(int position) {
	if (this != DeadEnd) {

		// position is zero-based
		if (position < BitCacheSize) {
			// use bits
			long mask;
			definiteInits &= ~(mask = 1L << position);
			potentialInits &= ~mask;
		} else {
			// use extra vector
			int vectorIndex = (position / BitCacheSize) - 1;
			if (extraDefiniteInits == null) {
				return; // nothing to do, it was not yet set 
			} else {
				int oldLength; // might need to grow the arrays
				if (vectorIndex >= (oldLength = extraDefiniteInits.length)) {
					return; // nothing to do, it was not yet set 
				}
			}
			long mask;
			extraDefiniteInits[vectorIndex] &= ~(mask = 1L << (position % BitCacheSize));
			extraPotentialInits[vectorIndex] &= ~mask;
		}
	}
}
/**
 * Clear the initialization info for a field
 */
public void markAsDefinitelyNotAssigned(FieldBinding field) {
	if (this != DeadEnd)
		markAsDefinitelyNotAssigned(field.id);
}
/**
 * Clear the initialization info for a local variable
 */

public void markAsDefinitelyNotAssigned(LocalVariableBinding local) {
	if (this != DeadEnd)
		markAsDefinitelyNotAssigned(local.id + maxFieldCount);
}
public FlowInfo markAsFakeReachable(boolean isFakeReachable) {
	this.isFakeReachable = isFakeReachable;
	return this;
}
public UnconditionalFlowInfo mergedWith(UnconditionalFlowInfo otherInits) {
	// updates the receiver with:
	// - intersection of definitely assigned variables, 
	// - union of potentially set ones

	if (this == DeadEnd)
		return otherInits;
	if (otherInits == DeadEnd)
		return this;

	// if one branch is not fake reachable, then the merged one is reachable
	if (!otherInits.isFakeReachable())
		markAsFakeReachable(false);

	// intersection of definitely assigned variables, 
	definiteInits &= otherInits.definiteInits;
	// union of potentially set ones
	potentialInits |= otherInits.potentialInits;

	// treating extra storage
	if (extraDefiniteInits != null) {
		if (otherInits.extraDefiniteInits != null) {
			// both sides have extra storage
			int i = 0, length, otherLength;
			if ((length = extraDefiniteInits.length) < (otherLength = otherInits.extraDefiniteInits.length)) {
				// current storage is shorter -> grow current (could maybe reuse otherInits extra storage?)
				System.arraycopy(extraDefiniteInits, 0, (extraDefiniteInits = new long[otherLength]), 0, length);
				System.arraycopy(extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, length);
				while (i < length) {
					extraDefiniteInits[i] &= otherInits.extraDefiniteInits[i];
					extraPotentialInits[i] |= otherInits.extraPotentialInits[i++];
				}
				while (i < otherLength) {
					extraPotentialInits[i] = otherInits.extraPotentialInits[i++];
				}
			} else {
				// current storage is longer
				while (i < otherLength) {
					extraDefiniteInits[i] &= otherInits.extraDefiniteInits[i];
					extraPotentialInits[i] |= otherInits.extraPotentialInits[i++];
				}
				while (i < length)
					extraDefiniteInits[i++] = 0;
			}
		} else {
			// no extra storage on otherInits
			int i = 0, length = extraDefiniteInits.length;
			while (i < length)
				extraDefiniteInits[i++] = 0;
		}
	} else
		if (otherInits.extraDefiniteInits != null) {
			// no storage here, but other has extra storage.
			int otherLength;
			extraDefiniteInits = new long[otherLength = otherInits.extraDefiniteInits.length];
			System.arraycopy(otherInits.extraPotentialInits, 0, (extraPotentialInits = new long[otherLength]), 0, otherLength);
		}
	return this;
}
/*
 * Answer the total number of fields in enclosing types of a given type
 */
static int numberOfEnclosingFields(ReferenceBinding type){
	int count = 0;
	type = type.enclosingType();
	while(type != null) {
		count += type.fieldCount();
		type = type.enclosingType();
	}
	return count;
}
public String toString(){
	if (this == DeadEnd){
		return "FlowInfo.DeadEnd"/*nonNLS*/;
	}
	return "FlowInfo<def: "/*nonNLS*/+ definiteInits +", pot: "/*nonNLS*/ + potentialInits + ">"/*nonNLS*/;
}
public UnconditionalFlowInfo unconditionalInits() {
	// also see conditional inits, where it requests them to merge
	return this;
}
}
