/*******************************************************************************
 * Copyright (c) 2000, 2017 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 319201 - [null] no warning when unboxing SingleNameReference causes NPE
 *								bug 345305 - [compiler][null] Compiler misidentifies a case of "variable can only be null"
 *								bug 403147 - [compiler][null] FUP of bug 400761: consolidate interaction between unboxing, NPE, and deferred checking
 *								Bug 417758 - [1.8][null] Null safety compromise during array creation.
 *								Bug 427163 - [1.8][null] bogus error "Contradictory null specification" on varags
 *     Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
 *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
 *                          Bug 409247 - [1.8][compiler] Verify error with code allocating multidimensional array
 *******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.compiler.ast;

import java.util.List;

import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.aspectj.org.eclipse.jdt.internal.compiler.impl.*;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference.AnnotationCollector;
import org.aspectj.org.eclipse.jdt.internal.compiler.codegen.*;
import org.aspectj.org.eclipse.jdt.internal.compiler.flow.*;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.*;

@SuppressWarnings({"rawtypes"})
public class ArrayAllocationExpression extends Expression {

	public TypeReference type;

	//dimensions.length gives the number of dimensions, but the
	// last ones may be nulled as in new int[4][5][][]
	public Expression[] dimensions;
	public Annotation [][] annotationsOnDimensions; // jsr308 style annotations.
	public ArrayInitializer initializer;

	@Override
	public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
		for (int i = 0, max = this.dimensions.length; i < max; i++) {
			Expression dim;
			if ((dim = this.dimensions[i]) != null) {
				flowInfo = dim.analyseCode(currentScope, flowContext, flowInfo);
				dim.checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
			}
		}
		// account for potential OutOfMemoryError:
		flowContext.recordAbruptExit();
		if (this.initializer != null) {
			return this.initializer.analyseCode(currentScope, flowContext, flowInfo);
		}
		return flowInfo;
	}

	/**
	 * Code generation for a array allocation expression
	 */
	@Override
	public void generateCode(BlockScope currentScope, 	CodeStream codeStream, boolean valueRequired) {

		int pc = codeStream.position;

		if (this.initializer != null) {
			this.initializer.generateCode(this.type, this, currentScope, codeStream, valueRequired);
			return;
		}

		int explicitDimCount = 0;
		for (int i = 0, max = this.dimensions.length; i < max; i++) {
			Expression dimExpression;
			if ((dimExpression = this.dimensions[i]) == null) break; // implicit dim, no further explict after this point
			dimExpression.generateCode(currentScope, codeStream, true);
			explicitDimCount++;
		}

		// array allocation
		if (explicitDimCount == 1) {
			// Mono-dimensional array
			codeStream.newArray(this.type, this, (ArrayBinding)this.resolvedType);
		} else {
			// Multi-dimensional array
			codeStream.multianewarray(this.type, this.resolvedType, explicitDimCount, this);
		}
		if (valueRequired) {
			codeStream.generateImplicitConversion(this.implicitConversion);
		} else {
			codeStream.pop();
		}
		codeStream.recordPositionsFrom(pc, this.sourceStart);
	}


	@Override
	public StringBuffer printExpression(int indent, StringBuffer output) {
		output.append("new "); //$NON-NLS-1$
		this.type.print(0, output);
		for (int i = 0; i < this.dimensions.length; i++) {
			if (this.annotationsOnDimensions != null && this.annotationsOnDimensions[i] != null) {
				output.append(' ');
				printAnnotations(this.annotationsOnDimensions[i], output);
				output.append(' ');
			}
			if (this.dimensions[i] == null)
				output.append("[]"); //$NON-NLS-1$
			else {
				output.append('[');
				this.dimensions[i].printExpression(0, output);
				output.append(']');
			}
		}
		if (this.initializer != null) this.initializer.printExpression(0, output);
		return output;
	}

	@Override
	public TypeBinding resolveType(BlockScope scope) {
		// Build an array type reference using the current dimensions
		// The parser does not check for the fact that dimension may be null
		// only at the -end- like new int [4][][]. The parser allows new int[][4][]
		// so this must be checked here......(this comes from a reduction to LL1 grammar)

		TypeBinding referenceType = this.type.resolveType(scope, true /* check bounds*/);

		// will check for null after dimensions are checked
		this.constant = Constant.NotAConstant;
		if (referenceType == TypeBinding.VOID) {
			scope.problemReporter().cannotAllocateVoidArray(this);
			referenceType = null;
		}

		// check the validity of the dimension syntax (and test for all null dimensions)
		int explicitDimIndex = -1;
		loop: for (int i = this.dimensions.length; --i >= 0;) {
			if (this.dimensions[i] != null) {
				if (explicitDimIndex < 0) explicitDimIndex = i;
			} else if (explicitDimIndex > 0) {
				// should not have an empty dimension before an non-empty one
				scope.problemReporter().incorrectLocationForNonEmptyDimension(this, explicitDimIndex);
				break loop;
			}
		}

		// explicitDimIndex < 0 says if all dimensions are nulled
		// when an initializer is given, no dimension must be specified
		if (this.initializer == null) {
			if (explicitDimIndex < 0) {
				scope.problemReporter().mustDefineDimensionsOrInitializer(this);
			}
			// allow new List<?>[5] - only check for generic array when no initializer, since also checked inside initializer resolution
			if (referenceType != null && !referenceType.isReifiable()) {
			    scope.problemReporter().illegalGenericArray(referenceType, this);
			}
		} else if (explicitDimIndex >= 0) {
			scope.problemReporter().cannotDefineDimensionsAndInitializer(this);
		}

		// dimensions resolution
		for (int i = 0; i <= explicitDimIndex; i++) {
			Expression dimExpression;
			if ((dimExpression = this.dimensions[i]) != null) {
				TypeBinding dimensionType = dimExpression.resolveTypeExpecting(scope, TypeBinding.INT);
				if (dimensionType != null) {
					this.dimensions[i].computeConversion(scope, TypeBinding.INT, dimensionType);
				}
			}
		}

		// building the array binding
		if (referenceType != null) {
			if (this.dimensions.length > 255) {
				scope.problemReporter().tooManyDimensions(this);
			}
			if (this.type.annotations != null
					&& (referenceType.tagBits & TagBits.AnnotationNullMASK) == TagBits.AnnotationNullMASK)
			{
				scope.problemReporter().contradictoryNullAnnotations(this.type.annotations[this.type.annotations.length-1]);
			}
			this.resolvedType = scope.createArrayType(referenceType, this.dimensions.length);

			if (this.annotationsOnDimensions != null) {
				this.resolvedType = resolveAnnotations(scope, this.annotationsOnDimensions, this.resolvedType);
				long[] nullTagBitsPerDimension = ((ArrayBinding)this.resolvedType).nullTagBitsPerDimension;
				if (nullTagBitsPerDimension != null) {
					for (int i = 0; i < this.annotationsOnDimensions.length; i++) {
						if ((nullTagBitsPerDimension[i] & TagBits.AnnotationNullMASK) == TagBits.AnnotationNullMASK) {
							scope.problemReporter().contradictoryNullAnnotations(this.annotationsOnDimensions[i]);
							nullTagBitsPerDimension[i] = 0;
						}
					}
				}
			}

			// check the initializer
			if (this.initializer != null) {
				this.resolvedType = ArrayTypeReference.maybeMarkArrayContentsNonNull(scope, this.resolvedType, this.sourceStart, this.dimensions.length, null);
				if ((this.initializer.resolveTypeExpecting(scope, this.resolvedType)) != null)
					this.initializer.binding = (ArrayBinding)this.resolvedType;
			}
			if ((referenceType.tagBits & TagBits.HasMissingType) != 0) {
				return null;
			}
		}
		return this.resolvedType;
	}

	@Override
	public void traverse(ASTVisitor visitor, BlockScope scope) {
		if (visitor.visit(this, scope)) {
			int dimensionsLength = this.dimensions.length;
			this.type.traverse(visitor, scope);
			for (int i = 0; i < dimensionsLength; i++) {
				Annotation [] annotations = this.annotationsOnDimensions == null ? null : this.annotationsOnDimensions[i];
				int annotationsLength = annotations == null ? 0 : annotations.length;
				for (int j = 0; j < annotationsLength; j++) {
					annotations[j].traverse(visitor, scope);
				}
				if (this.dimensions[i] != null)
					this.dimensions[i].traverse(visitor, scope);
			}
			if (this.initializer != null)
				this.initializer.traverse(visitor, scope);
		}
		visitor.endVisit(this, scope);
	}

	public void getAllAnnotationContexts(int targetType, int info, List allTypeAnnotationContexts) {
		AnnotationCollector collector = new AnnotationCollector(this, targetType, info, allTypeAnnotationContexts);
		this.type.traverse(collector, (BlockScope) null);
		if (this.annotationsOnDimensions != null)  {
			int dimensionsLength = this.dimensions.length;
			for (int i = 0; i < dimensionsLength; i++) {
				Annotation [] annotations = this.annotationsOnDimensions[i];
				int annotationsLength = annotations == null ? 0 : annotations.length;
				for (int j = 0; j < annotationsLength; j++) {
					annotations[j].traverse(collector, (BlockScope) null);
				}
			}
		}
	}

	public Annotation[][] getAnnotationsOnDimensions() {
		return this.annotationsOnDimensions;
	}
}
