/*******************************************************************************
 * 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.ast;

import java.util.ArrayList;

import org.eclipse.wst.jsdt.core.compiler.*;
import org.eclipse.wst.jsdt.internal.compiler.*;
import org.eclipse.wst.jsdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.wst.jsdt.internal.compiler.codegen.*;
import org.eclipse.wst.jsdt.internal.compiler.flow.*;
import org.eclipse.wst.jsdt.internal.compiler.lookup.*;
import org.eclipse.wst.jsdt.internal.compiler.parser.*;
import org.eclipse.wst.jsdt.internal.compiler.problem.*;

public class ConstructorDeclaration extends AbstractMethodDeclaration {

	public ExplicitConstructorCall constructorCall;
	public final static char[] ConstantPoolName = "<init>".toCharArray(); //$NON-NLS-1$
	public boolean isDefaultConstructor = false;
	public TypeParameter[] typeParameters;

	public ConstructorDeclaration(CompilationResult compilationResult){
		super(compilationResult);
	}
	
	public void analyseCode(
		ClassScope classScope,
		InitializationFlowContext initializerFlowContext,
		FlowInfo flowInfo) {

		if (ignoreFurtherInvestigation)
			return;

		if (this.binding != null && this.binding.isPrivate() && !this.binding.isPrivateUsed()) {
			if (!classScope.referenceCompilationUnit().compilationResult.hasSyntaxError()) {
				scope.problemReporter().unusedPrivateConstructor(this);
			}
		}
			
		// check constructor recursion, once all constructor got resolved
		if (isRecursive(null /*lazy initialized visited list*/)) {				
			this.scope.problemReporter().recursiveConstructorInvocation(this.constructorCall);
		}
			
		try {
			ExceptionHandlingFlowContext constructorContext =
				new ExceptionHandlingFlowContext(
					initializerFlowContext.parent,
					this,
					binding.thrownExceptions,
					scope,
					FlowInfo.DEAD_END);
			initializerFlowContext.checkInitializerExceptions(
				scope,
				constructorContext,
				flowInfo);

			// anonymous constructor can gain extra thrown exceptions from unhandled ones
			if (binding.declaringClass.isAnonymousType()) {
				ArrayList computedExceptions = constructorContext.extendedExceptions;
				if (computedExceptions != null){
					int size;
					if ((size = computedExceptions.size()) > 0){
						ReferenceBinding[] actuallyThrownExceptions;
						computedExceptions.toArray(actuallyThrownExceptions = new ReferenceBinding[size]);
						binding.thrownExceptions = actuallyThrownExceptions;
					}
				}
			}
			
			// propagate to constructor call
			if (constructorCall != null) {
				// if calling 'this(...)', then flag all non-static fields as definitely
				// set since they are supposed to be set inside other local constructor
				if (constructorCall.accessMode == ExplicitConstructorCall.This) {
					FieldBinding[] fields = binding.declaringClass.fields();
					for (int i = 0, count = fields.length; i < count; i++) {
						FieldBinding field;
						if (!(field = fields[i]).isStatic()) {
							flowInfo.markAsDefinitelyAssigned(field);
						}
					}
				}
				flowInfo = constructorCall.analyseCode(scope, constructorContext, flowInfo);
			}
			// propagate to statements
			if (statements != null) {
				boolean didAlreadyComplain = false;
				for (int i = 0, count = statements.length; i < count; i++) {
					Statement stat = statements[i];
					if (!stat.complainIfUnreachable(flowInfo, scope, didAlreadyComplain)) {
						flowInfo = stat.analyseCode(scope, constructorContext, flowInfo);
					} else {
						didAlreadyComplain = true;
					}
				}
			}
			// check for missing returning path
			this.needFreeReturn = flowInfo.isReachable();

			// check missing blank final field initializations
			if ((constructorCall != null)
				&& (constructorCall.accessMode != ExplicitConstructorCall.This)) {
				flowInfo = flowInfo.mergedWith(constructorContext.initsOnReturn);
				FieldBinding[] fields = binding.declaringClass.fields();
				for (int i = 0, count = fields.length; i < count; i++) {
					FieldBinding field;
					if ((!(field = fields[i]).isStatic())
						&& field.isFinal()
						&& (!flowInfo.isDefinitelyAssigned(fields[i]))) {
						scope.problemReporter().uninitializedBlankFinalField(
							field,
							isDefaultConstructor ? (ASTNode) scope.referenceType() : this);
					}
				}
			}
			// check unreachable catch blocks
			constructorContext.complainIfUnusedExceptionHandlers(this);
		} catch (AbortMethod e) {
			this.ignoreFurtherInvestigation = true;
		}
	}

	/**
	 * Bytecode generation for a constructor
	 *
	 * @param classScope org.eclipse.wst.jsdt.internal.compiler.lookup.ClassScope
	 * @param classFile org.eclipse.wst.jsdt.internal.compiler.codegen.ClassFile
	 */
	public void generateCode(ClassScope classScope, ClassFile classFile) {
		
		int problemResetPC = 0;
		if (ignoreFurtherInvestigation) {
			if (this.binding == null)
				return; // Handle methods with invalid signature or duplicates
			int problemsLength;
			IProblem[] problems =
				scope.referenceCompilationUnit().compilationResult.getProblems();
			IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
			System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
			classFile.addProblemConstructor(this, binding, problemsCopy);
			return;
		}
		try {
			problemResetPC = classFile.contentsOffset;
			this.internalGenerateCode(classScope, classFile);
		} catch (AbortMethod e) {
			if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
				// a branch target required a goto_w, restart code gen in wide mode.
				try {
					classFile.contentsOffset = problemResetPC;
					classFile.methodCount--;
					classFile.codeStream.wideMode = true; // request wide mode 
					this.internalGenerateCode(classScope, classFile); // restart method generation
				} catch (AbortMethod e2) {
					int problemsLength;
					IProblem[] problems =
						scope.referenceCompilationUnit().compilationResult.getAllProblems();
					IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
					System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
					classFile.addProblemConstructor(this, binding, problemsCopy, problemResetPC);
				}
			} else {
				int problemsLength;
				IProblem[] problems =
					scope.referenceCompilationUnit().compilationResult.getAllProblems();
				IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
				System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
				classFile.addProblemConstructor(this, binding, problemsCopy, problemResetPC);
			}
		}
	}

	public void generateSyntheticFieldInitializationsIfNecessary(
		MethodScope methodScope,
		CodeStream codeStream,
		ReferenceBinding declaringClass) {
			
		if (!declaringClass.isNestedType()) return;
		
		NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;

		SyntheticArgumentBinding[] syntheticArgs = nestedType.syntheticEnclosingInstances();
		for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) {
			SyntheticArgumentBinding syntheticArg;
			if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
				codeStream.aload_0();
				codeStream.load(syntheticArg);
				codeStream.putfield(syntheticArg.matchingField);
			}
		}
		syntheticArgs = nestedType.syntheticOuterLocalVariables();
		for (int i = 0, max = syntheticArgs == null ? 0 : syntheticArgs.length; i < max; i++) {
			SyntheticArgumentBinding syntheticArg;
			if ((syntheticArg = syntheticArgs[i]).matchingField != null) {
				codeStream.aload_0();
				codeStream.load(syntheticArg);
				codeStream.putfield(syntheticArg.matchingField);
			}
		}
	}

	private void internalGenerateCode(ClassScope classScope, ClassFile classFile) {
		
		classFile.generateMethodInfoHeader(binding);
		int methodAttributeOffset = classFile.contentsOffset;
		int attributeNumber = classFile.generateMethodInfoAttribute(binding);
		if ((!binding.isNative()) && (!binding.isAbstract())) {
			
			TypeDeclaration declaringType = classScope.referenceContext;
			int codeAttributeOffset = classFile.contentsOffset;
			classFile.generateCodeAttributeHeader();
			CodeStream codeStream = classFile.codeStream;
			codeStream.reset(this, classFile);

			// initialize local positions - including initializer scope.
			ReferenceBinding declaringClass = binding.declaringClass;

			int argSlotSize = 1; // this==aload0
			
			if (declaringClass.isNestedType()){
				NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass;
				this.scope.extraSyntheticArguments = nestedType.syntheticOuterLocalVariables();
				scope.computeLocalVariablePositions(// consider synthetic arguments if any
					nestedType.enclosingInstancesSlotSize + 1,
					codeStream);
				argSlotSize += nestedType.enclosingInstancesSlotSize;
				argSlotSize += nestedType.outerLocalVariablesSlotSize;
			} else {
				scope.computeLocalVariablePositions(1,  codeStream);
			}
				
			if (arguments != null) {
				for (int i = 0, max = arguments.length; i < max; i++) {
					// arguments initialization for local variable debug attributes
					LocalVariableBinding argBinding;
					codeStream.addVisibleLocalVariable(argBinding = arguments[i].binding);
					argBinding.recordInitializationStartPC(0);
					TypeBinding argType;
					if ((argType = argBinding.type) == LongBinding || (argType == DoubleBinding)) {
						argSlotSize += 2;
					} else {
						argSlotSize++;
					}
				}
			}
			
			MethodScope initializerScope = declaringType.initializerScope;
			initializerScope.computeLocalVariablePositions(argSlotSize, codeStream); // offset by the argument size (since not linked to method scope)

			boolean needFieldInitializations = constructorCall == null || constructorCall.accessMode != ExplicitConstructorCall.This;

			// post 1.4 source level, synthetic initializations occur prior to explicit constructor call
			boolean preInitSyntheticFields = scope.environment().options.targetJDK >= ClassFileConstants.JDK1_4;

			if (needFieldInitializations && preInitSyntheticFields){
				generateSyntheticFieldInitializationsIfNecessary(scope, codeStream, declaringClass);
			}			
			// generate constructor call
			if (constructorCall != null) {
				constructorCall.generateCode(scope, codeStream);
			}
			// generate field initialization - only if not invoking another constructor call of the same class
			if (needFieldInitializations) {
				if (!preInitSyntheticFields){
					generateSyntheticFieldInitializationsIfNecessary(scope, codeStream, declaringClass);
				}
				// generate user field initialization
				if (declaringType.fields != null) {
					for (int i = 0, max = declaringType.fields.length; i < max; i++) {
						FieldDeclaration fieldDecl;
						if (!(fieldDecl = declaringType.fields[i]).isStatic()) {
							fieldDecl.generateCode(initializerScope, codeStream);
						}
					}
				}
			}
			// generate statements
			if (statements != null) {
				for (int i = 0, max = statements.length; i < max; i++) {
					statements[i].generateCode(scope, codeStream);
				}
			}
			if (this.needFreeReturn) {
				codeStream.return_();
			}
			// local variable attributes
			codeStream.exitUserScope(scope);
			codeStream.recordPositionsFrom(0, this.bodyEnd);
			classFile.completeCodeAttribute(codeAttributeOffset);
			attributeNumber++;
		}
		classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);

		// if a problem got reported during code gen, then trigger problem method creation
		if (ignoreFurtherInvestigation) {
			throw new AbortMethod(scope.referenceCompilationUnit().compilationResult, null);
		}
	}

	public boolean isConstructor() {

		return true;
	}

	public boolean isDefaultConstructor() {

		return this.isDefaultConstructor;
	}

	public boolean isInitializationMethod() {

		return true;
	}

	/*
	 * Returns true if the constructor is directly involved in a cycle.
	 * Given most constructors aren't, we only allocate the visited list
	 * lazily.
	 */
	public boolean isRecursive(ArrayList visited) {

		if (this.binding == null
				|| this.constructorCall == null
				|| this.constructorCall.binding == null
				|| this.constructorCall.isSuperAccess()
				|| !this.constructorCall.binding.isValidBinding()) {
			return false;
		}
		
		ConstructorDeclaration targetConstructor = 
			((ConstructorDeclaration)this.scope.referenceType().declarationOf(constructorCall.binding.original()));
		if (this == targetConstructor) return true; // direct case

		if (visited == null) { // lazy allocation
			visited = new ArrayList(1);
		} else {
			int index = visited.indexOf(this);
			if (index >= 0) return index == 0; // only blame if directly part of the cycle
		}
		visited.add(this);

		return targetConstructor.isRecursive(visited);
	}
	
	public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {

		//fill up the constructor body with its statements
		if (ignoreFurtherInvestigation)
			return;
		if (isDefaultConstructor){
			constructorCall = SuperReference.implicitSuperConstructorCall();
			constructorCall.sourceStart = sourceStart;
			constructorCall.sourceEnd = sourceEnd; 
			return;
		}
		parser.parse(this, unit);

	}

	public StringBuffer printBody(int indent, StringBuffer output) {

		output.append(" {"); //$NON-NLS-1$
		if (constructorCall != null) {
			output.append('\n');
			constructorCall.printStatement(indent, output); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (statements != null) {
			for (int i = 0; i < statements.length; i++) {
				output.append('\n');
				statements[i].printStatement(indent, output); //$NON-NLS-1$
			}
		}
		output.append('\n');
		printIndent(indent == 0 ? 0 : indent - 1, output).append('}');
		return output;
	}
	
	public void resolveJavadoc() {
		
		if (this.binding == null || this.javadoc != null) {
			super.resolveJavadoc();
		} else if (!isDefaultConstructor) {
			this.scope.problemReporter().javadocMissing(this.sourceStart, this.sourceEnd, this.binding.modifiers);
		}
	}

	/*
	 * Type checking for constructor, just another method, except for special check
	 * for recursive constructor invocations.
	 */
	public void resolveStatements() {

		if (!CharOperation.equals(scope.enclosingSourceType().sourceName, selector)){
			scope.problemReporter().missingReturnType(this);
		}

		// if null ==> an error has occurs at parsing time ....
		if (this.constructorCall != null) {
			// e.g. using super() in java.lang.Object
			if (this.binding != null
				&& this.binding.declaringClass.id == T_Object
				&& this.constructorCall.accessMode != ExplicitConstructorCall.This) {
					if (this.constructorCall.accessMode == ExplicitConstructorCall.Super) {
						scope.problemReporter().cannotUseSuperInJavaLangObject(this.constructorCall);
					}
					this.constructorCall = null;
			} else {
				this.constructorCall.resolve(this.scope);
			}
		}
		if ((modifiers & AccSemicolonBody) != 0) {
			scope.problemReporter().methodNeedBody(this);		
		}
		super.resolveStatements();
	}

	public void traverse(
		ASTVisitor visitor,
		ClassScope classScope) {

		
		if (visitor.visit(this, classScope)) {
			if (this.annotations != null) {
				int annotationsLength = this.annotations.length;
				for (int i = 0; i < annotationsLength; i++)
					this.annotations[i].traverse(visitor, scope);
			}
			if (this.typeParameters != null) {
				int typeParametersLength = this.typeParameters.length;
				for (int i = 0; i < typeParametersLength; i++) {
					this.typeParameters[i].traverse(visitor, scope);
				}
			}			
			if (arguments != null) {
				int argumentLength = arguments.length;
				for (int i = 0; i < argumentLength; i++)
					arguments[i].traverse(visitor, scope);
			}
			if (thrownExceptions != null) {
				int thrownExceptionsLength = thrownExceptions.length;
				for (int i = 0; i < thrownExceptionsLength; i++)
					thrownExceptions[i].traverse(visitor, scope);
			}
			if (constructorCall != null)
				constructorCall.traverse(visitor, scope);
			if (statements != null) {
				int statementsLength = statements.length;
				for (int i = 0; i < statementsLength; i++)
					statements[i].traverse(visitor, scope);
			}
		}
		visitor.endVisit(this, classScope);
	}
	public TypeParameter[] typeParameters() {
	    return this.typeParameters;
	}		
}
