/*******************************************************************************
 * 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.jdt.internal.compiler.ast;

import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.codegen.*;
import org.eclipse.jdt.internal.compiler.env.IGenericType;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.*;
import org.eclipse.jdt.internal.compiler.problem.*;

public class Clinit extends AbstractMethodDeclaration {
	
	private FieldBinding assertionSyntheticFieldBinding = null;
	private FieldBinding classLiteralSyntheticField = null;

	public Clinit(CompilationResult compilationResult) {
		super(compilationResult);
		modifiers = 0;
		selector = TypeConstants.CLINIT;
	}

	public void analyseCode(
		ClassScope classScope,
		InitializationFlowContext staticInitializerFlowContext,
		FlowInfo flowInfo) {

		if (ignoreFurtherInvestigation)
			return;
		try {
			ExceptionHandlingFlowContext clinitContext =
				new ExceptionHandlingFlowContext(
					staticInitializerFlowContext.parent,
					this,
					NoExceptions,
					scope,
					FlowInfo.DEAD_END);

			// check for missing returning path
			this.needFreeReturn = flowInfo.isReachable();

			// check missing blank final field initializations
			flowInfo = flowInfo.mergedWith(staticInitializerFlowContext.initsOnReturn);
			FieldBinding[] fields = scope.enclosingSourceType().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,
						scope.referenceType().declarationOf(field.original()));
					// can complain against the field decl, since only one <clinit>
				}
			}
			// check static initializers thrown exceptions
			staticInitializerFlowContext.checkInitializerExceptions(
				scope,
				clinitContext,
				flowInfo);
		} catch (AbortMethod e) {
			this.ignoreFurtherInvestigation = true;
		}
	}

	/**
	 * Bytecode generation for a <clinit> method
	 *
	 * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
	 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
	 */
	public void generateCode(ClassScope classScope, ClassFile classFile) {

		int clinitOffset = 0;
		if (ignoreFurtherInvestigation) {
			// should never have to add any <clinit> problem method
			return;
		}
		try {
			clinitOffset = classFile.contentsOffset;
			this.generateCode(classScope, classFile, clinitOffset);
		} catch (AbortMethod e) {
			// should never occur
			// the clinit referenceContext is the type declaration
			// All clinit problems will be reported against the type: AbortType instead of AbortMethod
			// reset the contentsOffset to the value before generating the clinit code
			// decrement the number of method info as well.
			// This is done in the addProblemMethod and addProblemConstructor for other
			// cases.
			if (e.compilationResult == CodeStream.RESTART_IN_WIDE_MODE) {
				// a branch target required a goto_w, restart code gen in wide mode.
				try {
					classFile.contentsOffset = clinitOffset;
					classFile.methodCount--;
					classFile.codeStream.wideMode = true; // request wide mode 
					this.generateCode(classScope, classFile, clinitOffset);
					// restart method generation
				} catch (AbortMethod e2) {
					classFile.contentsOffset = clinitOffset;
					classFile.methodCount--;
				}
			} else {
				// produce a problem method accounting for this fatal error
				classFile.contentsOffset = clinitOffset;
				classFile.methodCount--;
			}
		}
	}

	/**
	 * Bytecode generation for a <clinit> method
	 *
	 * @param classScope org.eclipse.jdt.internal.compiler.lookup.ClassScope
	 * @param classFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
	 */
	private void generateCode(
		ClassScope classScope,
		ClassFile classFile,
		int clinitOffset) {

		ConstantPool constantPool = classFile.constantPool;
		int constantPoolOffset = constantPool.currentOffset;
		int constantPoolIndex = constantPool.currentIndex;
		classFile.generateMethodInfoHeaderForClinit();
		int codeAttributeOffset = classFile.contentsOffset;
		classFile.generateCodeAttributeHeader();
		CodeStream codeStream = classFile.codeStream;
		this.resolve(classScope);

		codeStream.reset(this, classFile);
		TypeDeclaration declaringType = classScope.referenceContext;

		// initialize local positions - including initializer scope.
		MethodScope staticInitializerScope = declaringType.staticInitializerScope;
		staticInitializerScope.computeLocalVariablePositions(0, codeStream);

		// 1.4 feature
		// This has to be done before any other initialization
		if (this.assertionSyntheticFieldBinding != null) {
			// generate code related to the activation of assertion for this class
			codeStream.generateClassLiteralAccessForType(
					classScope.enclosingSourceType(),
				classLiteralSyntheticField);
			codeStream.invokeJavaLangClassDesiredAssertionStatus();
			Label falseLabel = new Label(codeStream);
			codeStream.ifne(falseLabel);
			codeStream.iconst_1();
			Label jumpLabel = new Label(codeStream);
			codeStream.goto_(jumpLabel);
			falseLabel.place();
			codeStream.iconst_0();
			jumpLabel.place();
			codeStream.putstatic(this.assertionSyntheticFieldBinding);
		}
		// generate static fields/initializers/enum constants
		final FieldDeclaration[] fieldDeclarations = declaringType.fields;
		if (declaringType.kind() == IGenericType.ENUM_DECL) {
			int enumCount = 0;
			int notEnumConstants = 0;
			if (fieldDeclarations != null) {
				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
					FieldDeclaration fieldDecl = fieldDeclarations[i];
					if (fieldDecl.isStatic()) {
						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
							fieldDecl.generateCode(staticInitializerScope, codeStream);
							enumCount++;
						} else {
							notEnumConstants++;
						}
					}
				}
			}
			// enum need to initialize $VALUES synthetic cache of enum constants
			if (enumCount > 0) {
				if (fieldDeclarations != null) {
					// $VALUES := new <EnumType>[<enumCount>]
					codeStream.generateInlinedValue(enumCount);
					codeStream.anewarray(declaringType.binding);
					for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
						FieldDeclaration fieldDecl = fieldDeclarations[i];
						// $VALUES[i] = <enum-constant-i>
						if (fieldDecl.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
							codeStream.dup();
							codeStream.generateInlinedValue(fieldDecl.binding.id);
							codeStream.getstatic(fieldDecl.binding);
							codeStream.aastore();
						}
					}
					codeStream.putstatic(declaringType.enumValuesSyntheticfield);
				}
			}
			if (notEnumConstants != 0) {
				// if fields that are not enum constants need to be generated (static initializer/static field)
				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
					FieldDeclaration fieldDecl = fieldDeclarations[i];
					if (fieldDecl.isStatic() && fieldDecl.getKind() != AbstractVariableDeclaration.ENUM_CONSTANT) {
						fieldDecl.generateCode(staticInitializerScope, codeStream);
					}
				}
			}
		} else {
			if (fieldDeclarations != null) {
				for (int i = 0, max = fieldDeclarations.length; i < max; i++) {
					FieldDeclaration fieldDecl = fieldDeclarations[i];
					if (fieldDecl.isStatic()) {
						fieldDecl.generateCode(staticInitializerScope, codeStream);
					}
				}
			}
		}
		
		if (codeStream.position == 0) {
			// do not need to output a Clinit if no bytecodes
			// so we reset the offset inside the byte array contents.
			classFile.contentsOffset = clinitOffset;
			// like we don't addd a method we need to undo the increment on the method count
			classFile.methodCount--;
			// reset the constant pool to its state before the clinit
			constantPool.resetForClinit(constantPoolIndex, constantPoolOffset);
		} else {
			if (this.needFreeReturn) {
				int oldPosition = codeStream.position;
				codeStream.return_();
				codeStream.updateLocalVariablesAttribute(oldPosition);
			}
			// Record the end of the clinit: point to the declaration of the class
			codeStream.recordPositionsFrom(0, declaringType.sourceStart);
			classFile.completeCodeAttributeForClinit(codeAttributeOffset);
		}
	}

	public boolean isClinit() {

		return true;
	}

	public boolean isInitializationMethod() {

		return true;
	}

	public boolean isStatic() {

		return true;
	}

	public void parseStatements(Parser parser, CompilationUnitDeclaration unit) {
		//the clinit is filled by hand .... 
	}

	public StringBuffer print(int tab, StringBuffer output) {

		printIndent(tab, output).append("<clinit>()"); //$NON-NLS-1$
		printBody(tab + 1, output);
		return output;
	}

	public void resolve(ClassScope classScope) {

		this.scope = new MethodScope(classScope, classScope.referenceContext, true);
	}

	public void traverse(
		ASTVisitor visitor,
		ClassScope classScope) {

		visitor.visit(this, classScope);
		visitor.endVisit(this, classScope);
	}

	public void setAssertionSupport(FieldBinding assertionSyntheticFieldBinding, boolean needClassLiteralField) {

		this.assertionSyntheticFieldBinding = assertionSyntheticFieldBinding;

		// we need to add the field right now, because the field infos are generated before the methods
		SourceTypeBinding sourceType =
			this.scope.outerMostMethodScope().enclosingSourceType();
		if (needClassLiteralField) {
			this.classLiteralSyntheticField =
				sourceType.addSyntheticFieldForClassLiteral(sourceType, scope);
		}
	}

}
