/*******************************************************************************
 * Copyright (c) 2000, 2014 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
 *     Stephan Herrmann - Contributions for
 *								bug 186342 - [compiler][null] Using annotations for null checking
 *								bug 365519 - editorial cleanup after bug 186342 and bug 365387
 *								bug 368546 - [compiler][resource] Avoid remaining false positives found when compiling the Eclipse SDK
 *								bug 365859 - [compiler][null] distinguish warnings based on flow analysis vs. null annotations
 *								bug 385626 - @NonNull fails across loop boundaries
 *								bug 388996 - [compiler][resource] Incorrect 'potential resource leak'
 *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
 *								Bug 453483 - [compiler][null][loop] Improve null analysis for loops
 *								Bug 455723 - Nonnull argument not correctly inferred in loop
 *     Jesper S Moller - Contributions for
 *								bug 404657 - [1.8][compiler] Analysis for effectively final variables fails to consider loops
 *******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.compiler.flow;

import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Reference;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.VariableBinding;

/**
 * Reflects the context of code analysis, keeping track of enclosing
 *	try statements, exception handlers, etc...
 */
public class FinallyFlowContext extends TryFlowContext {

	Reference[] finalAssignments;
	VariableBinding[] finalVariables;
	int assignCount;

	// the following three arrays are in sync regarding their indices:
	LocalVariableBinding[] nullLocals; // slots can be null for checkType == IN_UNBOXING
	ASTNode[] nullReferences;	// Expressions for null checking, Statements for resource analysis
								// cast to Expression is safe if corresponding nullCheckType != EXIT_RESOURCE
	int[] nullCheckTypes;
	int nullCount;
	// see also the related field FlowContext#expectedTypes

	// back reference to the flow context of the corresponding try statement
	public FlowContext tryContext;

	public FinallyFlowContext(FlowContext parent, ASTNode associatedNode, ExceptionHandlingFlowContext tryContext) {
		super(parent, associatedNode);
		this.tryContext = tryContext;
	}

/**
 * Given some contextual initialization info (derived from a try block or a catch block), this
 * code will check that the subroutine context does not also initialize a final variable potentially set
 * redundantly.
 */
public void complainOnDeferredChecks(FlowInfo flowInfo, BlockScope scope) {

	// check redundant final assignments
	for (int i = 0; i < this.assignCount; i++) {
		VariableBinding variable = this.finalVariables[i];
		if (variable == null) continue;

		boolean complained = false; // remember if have complained on this final assignment
		if (variable instanceof FieldBinding) {
			// final field
			if (flowInfo.isPotentiallyAssigned((FieldBinding)variable)) {
				complained = true;
				scope.problemReporter().duplicateInitializationOfBlankFinalField((FieldBinding)variable, this.finalAssignments[i]);
			}
		} else {
			// final local variable
			if (flowInfo.isPotentiallyAssigned((LocalVariableBinding)variable)) {
				variable.tagBits &= ~TagBits.IsEffectivelyFinal;
				if (variable.isFinal()) {
					complained = true;
					scope.problemReporter().duplicateInitializationOfFinalLocal(
						(LocalVariableBinding) variable,
						this.finalAssignments[i]);
				}
			}
		}
		// any reference reported at this level is removed from the parent context
		// where it could also be reported again
		if (complained) {
			FlowContext currentContext = this.getLocalParent();
			while (currentContext != null) {
				//if (currentContext.isSubRoutine()) {
				currentContext.removeFinalAssignmentIfAny(this.finalAssignments[i]);
				//}
				currentContext = currentContext.getLocalParent();
			}
		}
	}

	// check inconsistent null checks
	if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative
		for (int i = 0; i < this.nullCount; i++) {
			ASTNode location = this.nullReferences[i];
			switch (this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) {
				case ASSIGN_TO_NONNULL:
					int nullStatus = flowInfo.nullStatus(this.nullLocals[i]);
					if (nullStatus != FlowInfo.NON_NULL) {
						this.parent.recordNullityMismatch(scope, (Expression) location,
								this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], flowInfo, nullStatus, null);
					}
					break;
				case IN_UNBOXING:
					checkUnboxing(scope, (Expression) location, flowInfo);
					break;
				default:
					this.parent.recordUsingNullReference(scope, this.nullLocals[i],
							this.nullReferences[i],	this.nullCheckTypes[i], flowInfo);
			}

		}
	}
	else { // no enclosing loop, be as precise as possible right now
		for (int i = 0; i < this.nullCount; i++) {
			ASTNode location = this.nullReferences[i];
			// final local variable
			LocalVariableBinding local = this.nullLocals[i];
			switch (this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) {
				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
				case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
					if (flowInfo.isDefinitelyNonNull(local)) {
						if ((this.nullCheckTypes[i] & ~HIDE_NULL_COMPARISON_WARNING_MASK) == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
							if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
								scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
							}
						} else {
							scope.problemReporter().localVariableNonNullComparedToNull(local, location);
						}
						continue;
					}
					//$FALL-THROUGH$
				case CAN_ONLY_NULL | IN_COMPARISON_NULL:
				case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
				case CAN_ONLY_NULL | IN_ASSIGNMENT:
				case CAN_ONLY_NULL | IN_INSTANCEOF:
					Expression expression = (Expression) location;
					if (flowInfo.isDefinitelyNull(local)) {
						switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
							case FlowContext.IN_COMPARISON_NULL:
								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
									scope.problemReporter().localVariableNullReference(local, expression);
									continue;
								}
								if ((this.nullCheckTypes[i] & HIDE_NULL_COMPARISON_WARNING) == 0) {
									scope.problemReporter().localVariableRedundantCheckOnNull(local, expression);
								}
								continue;
							case FlowContext.IN_COMPARISON_NON_NULL:
								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
									scope.problemReporter().localVariableNullReference(local, expression);
									continue;
								}
								scope.problemReporter().localVariableNullComparedToNonNull(local, expression);
								continue;
							case FlowContext.IN_ASSIGNMENT:
								scope.problemReporter().localVariableRedundantNullAssignment(local, expression);
								continue;
							case FlowContext.IN_INSTANCEOF:
								scope.problemReporter().localVariableNullInstanceof(local, expression);
								continue;
						}
					} else if (flowInfo.isPotentiallyNull(local)) {
						switch(this.nullCheckTypes[i] & CONTEXT_MASK) {
							case FlowContext.IN_COMPARISON_NULL:
								this.nullReferences[i] = null;
								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
									scope.problemReporter().localVariablePotentialNullReference(local, expression);
									continue;
								}
								break;
							case FlowContext.IN_COMPARISON_NON_NULL:
								this.nullReferences[i] = null;
								if (((this.nullCheckTypes[i] & CHECK_MASK & ~HIDE_NULL_COMPARISON_WARNING_MASK) == CAN_ONLY_NULL) && (expression.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
									scope.problemReporter().localVariablePotentialNullReference(local, expression);
									continue;
								}
								break;
						}
					}
					break;
				case MAY_NULL:
					if (flowInfo.isDefinitelyNull(local)) {
						scope.problemReporter().localVariableNullReference(local, location);
						continue;
					}
					if (flowInfo.isPotentiallyNull(local)) {
						scope.problemReporter().localVariablePotentialNullReference(local, location);
					}
					break;
				case ASSIGN_TO_NONNULL:
					int nullStatus = flowInfo.nullStatus(local);
					if (nullStatus != FlowInfo.NON_NULL) {
						char[][] annotationName = scope.environment().getNonNullAnnotationName();
						scope.problemReporter().nullityMismatch((Expression) location, this.providedExpectedTypes[i][0], this.providedExpectedTypes[i][1], nullStatus, annotationName);
					}
					break;
				case IN_UNBOXING:
					checkUnboxing(scope, (Expression) location, flowInfo);	
					break;
				default:
					// should not happen
			}
		}
	}
}

	@Override
	public String individualToString() {

		StringBuffer buffer = new StringBuffer("Finally flow context"); //$NON-NLS-1$
		buffer.append("[finalAssignments count - ").append(this.assignCount).append(']'); //$NON-NLS-1$
		buffer.append("[nullReferences count - ").append(this.nullCount).append(']'); //$NON-NLS-1$
		return buffer.toString();
	}

	@Override
	public boolean isSubRoutine() {
		return true;
	}

	@Override
	protected boolean recordFinalAssignment(
		VariableBinding binding,
		Reference finalAssignment) {
		if (this.assignCount == 0) {
			this.finalAssignments = new Reference[5];
			this.finalVariables = new VariableBinding[5];
		} else {
			if (this.assignCount == this.finalAssignments.length)
				System.arraycopy(
					this.finalAssignments,
					0,
					(this.finalAssignments = new Reference[this.assignCount * 2]),
					0,
					this.assignCount);
			System.arraycopy(
				this.finalVariables,
				0,
				(this.finalVariables = new VariableBinding[this.assignCount * 2]),
				0,
				this.assignCount);
		}
		this.finalAssignments[this.assignCount] = finalAssignment;
		this.finalVariables[this.assignCount++] = binding;
		return true;
	}

	@Override
	public void recordUsingNullReference(Scope scope, LocalVariableBinding local,
			ASTNode location, int checkType, FlowInfo flowInfo) {
		if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0 && !flowInfo.isDefinitelyUnknown(local))	{
			// if reference is being recorded inside an assert, we will not raise redundant null check warnings
			checkType |= (this.tagBits & FlowContext.HIDE_NULL_COMPARISON_WARNING);
			int checkTypeWithoutHideNullWarning = checkType & ~FlowContext.HIDE_NULL_COMPARISON_WARNING_MASK;
			if ((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0) { // within an enclosing loop, be conservative
				switch (checkTypeWithoutHideNullWarning) {
					case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
					case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
					case CAN_ONLY_NULL | IN_COMPARISON_NULL:
					case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
					case CAN_ONLY_NULL | IN_ASSIGNMENT:
					case CAN_ONLY_NULL | IN_INSTANCEOF:
						Expression reference = (Expression) location;
						if (flowInfo.cannotBeNull(local)) {
							if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
								if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
									scope.problemReporter().localVariableRedundantCheckOnNonNull(local, reference);
								}
								flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
							} else if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL)) {
								scope.problemReporter().localVariableNonNullComparedToNull(local, reference);
								flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
							}
							return;
						}
						if (flowInfo.canOnlyBeNull(local)) {
							switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
								case FlowContext.IN_COMPARISON_NULL:
									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
										scope.problemReporter().localVariableNullReference(local, reference);
										return;
									}
									if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
										scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
									}
									flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
									return;
								case FlowContext.IN_COMPARISON_NON_NULL:
									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
										scope.problemReporter().localVariableNullReference(local, reference);
										return;
									}
									scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
									flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
									return;
								case FlowContext.IN_ASSIGNMENT:
									scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
									return;
								case FlowContext.IN_INSTANCEOF:
									scope.problemReporter().localVariableNullInstanceof(local, reference);
									return;
							}
						} else if (flowInfo.isPotentiallyNull(local)) {
							switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
								case FlowContext.IN_COMPARISON_NULL:
									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
										scope.problemReporter().localVariablePotentialNullReference(local, reference);
										return;
									}
									break;
								case FlowContext.IN_COMPARISON_NON_NULL:
									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
										scope.problemReporter().localVariablePotentialNullReference(local, reference);
										return;
									}
									break;
							}
						}
						break;
					case MAY_NULL :
						if (flowInfo.cannotBeNull(local)) {
							return;
						}
						if (flowInfo.canOnlyBeNull(local)) {
							scope.problemReporter().localVariableNullReference(local, location);
							return;
						}
						break;
					default:
						// never happens
				}
			}
			else { // no enclosing loop, be as precise as possible right now
				switch (checkTypeWithoutHideNullWarning) {
					case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NULL:
					case CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL:
						if (flowInfo.isDefinitelyNonNull(local)) {
							if (checkTypeWithoutHideNullWarning == (CAN_ONLY_NULL_NON_NULL | IN_COMPARISON_NON_NULL)) {
								if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
									scope.problemReporter().localVariableRedundantCheckOnNonNull(local, location);
								}
								flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
							} else {
								scope.problemReporter().localVariableNonNullComparedToNull(local, location);
								flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
							}
							return;
						}
						//$FALL-THROUGH$
					case CAN_ONLY_NULL | IN_COMPARISON_NULL:
					case CAN_ONLY_NULL | IN_COMPARISON_NON_NULL:
					case CAN_ONLY_NULL | IN_ASSIGNMENT:
					case CAN_ONLY_NULL | IN_INSTANCEOF:
						Expression reference = (Expression) location;
						if (flowInfo.isDefinitelyNull(local)) {
							switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
								case FlowContext.IN_COMPARISON_NULL:
									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
										scope.problemReporter().localVariableNullReference(local, reference);
										return;
									}
									if ((checkType & HIDE_NULL_COMPARISON_WARNING) == 0) {
										scope.problemReporter().localVariableRedundantCheckOnNull(local, reference);
									}
									flowInfo.initsWhenFalse().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
									return;
								case FlowContext.IN_COMPARISON_NON_NULL:
									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
										scope.problemReporter().localVariableNullReference(local, reference);
										return;
									}
									scope.problemReporter().localVariableNullComparedToNonNull(local, reference);
									flowInfo.initsWhenTrue().setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
									return;
								case FlowContext.IN_ASSIGNMENT:
									scope.problemReporter().localVariableRedundantNullAssignment(local, reference);
									return;
								case FlowContext.IN_INSTANCEOF:
									scope.problemReporter().localVariableNullInstanceof(local, reference);
									return;
							}
						} else if (flowInfo.isPotentiallyNull(local)) {
							switch(checkTypeWithoutHideNullWarning & CONTEXT_MASK) {
								case FlowContext.IN_COMPARISON_NULL:
									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
										scope.problemReporter().localVariablePotentialNullReference(local, reference);
										return;
									}
									break;
								case FlowContext.IN_COMPARISON_NON_NULL:
									if (((checkTypeWithoutHideNullWarning & CHECK_MASK) == CAN_ONLY_NULL) && (reference.implicitConversion & TypeIds.UNBOXING) != 0) { // check for auto-unboxing first and report appropriate warning
										scope.problemReporter().localVariablePotentialNullReference(local, reference);
										return;
									}
									break;
							}
						}
						break;
					case MAY_NULL :
						if (flowInfo.isDefinitelyNull(local)) {
							scope.problemReporter().localVariableNullReference(local, location);
							return;
						}
						if (flowInfo.isPotentiallyNull(local)) {
							scope.problemReporter().localVariablePotentialNullReference(local, location);
							return;
						}
						if (flowInfo.isDefinitelyNonNull(local)) {
							return; // shortcut: cannot be null
						}
						break;
					default:
						// never happens
				}
			}
			recordNullReference(local, location, checkType, flowInfo);
			// prepare to re-check with try/catch flow info
		}
	}

	@Override
	void removeFinalAssignmentIfAny(Reference reference) {
		for (int i = 0; i < this.assignCount; i++) {
			if (this.finalAssignments[i] == reference) {
				this.finalAssignments[i] = null;
				this.finalVariables[i] = null;
				return;
			}
		}
	}

@Override
protected void recordNullReference(LocalVariableBinding local,
	ASTNode expression, int checkType, FlowInfo nullInfo) {
	if (this.nullCount == 0) {
		this.nullLocals = new LocalVariableBinding[5];
		this.nullReferences = new ASTNode[5];
		this.nullCheckTypes = new int[5];
	}
	else if (this.nullCount == this.nullLocals.length) {
		int newLength = this.nullCount * 2;
		System.arraycopy(this.nullLocals, 0,
			this.nullLocals = new LocalVariableBinding[newLength], 0,
			this.nullCount);
		System.arraycopy(this.nullReferences, 0,
			this.nullReferences = new ASTNode[newLength], 0,
			this.nullCount);
		System.arraycopy(this.nullCheckTypes, 0,
			this.nullCheckTypes = new int[newLength], 0,
			this.nullCount);
	}
	this.nullLocals[this.nullCount] = local;
	this.nullReferences[this.nullCount] = expression;
	this.nullCheckTypes[this.nullCount++] = checkType;
}
@Override
public void recordUnboxing(Scope scope, Expression expression, int nullStatus, FlowInfo flowInfo) {
	if (nullStatus == FlowInfo.NULL)
		super.recordUnboxing(scope, expression, nullStatus, flowInfo);
	else // defer checking:
		recordNullReference(null, expression, IN_UNBOXING, flowInfo);
}
@Override
protected boolean internalRecordNullityMismatch(Expression expression, TypeBinding providedType, FlowInfo flowInfo, int nullStatus, TypeBinding expectedType, int checkType) {
	// cf. decision structure inside FinallyFlowContext.recordUsingNullReference(..)
	if (nullStatus == FlowInfo.UNKNOWN ||
			((this.tagBits & FlowContext.DEFER_NULL_DIAGNOSTIC) != 0 && nullStatus != FlowInfo.NULL)) {
		recordProvidedExpectedTypes(providedType, expectedType, this.nullCount);
		recordNullReference(expression.localVariableBinding(), expression, checkType, flowInfo);
		return true;
	}
	return false;
}
}
