/*******************************************************************************
 * Copyright (c) 2000, 2010 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
 *******************************************************************************/
package org.eclipse.jdt.internal.eval;

import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
import org.eclipse.jdt.internal.compiler.codegen.StackMapFrameCodeStream;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
import org.eclipse.jdt.internal.compiler.util.Util;

public class CodeSnippetClassFile extends ClassFile {
/**
 * CodeSnippetClassFile constructor comment.
 * @param aType org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
 * @param enclosingClassFile org.eclipse.jdt.internal.compiler.ClassFile
 * @param creatingProblemType boolean
 */
public CodeSnippetClassFile(
	org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding aType,
	org.eclipse.jdt.internal.compiler.ClassFile enclosingClassFile,
	boolean creatingProblemType) {
	/**
	 * INTERNAL USE-ONLY
	 * This methods creates a new instance of the receiver.
	 *
	 * @param aType org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding
	 * @param enclosingClassFile org.eclipse.jdt.internal.compiler.codegen.ClassFile
	 * @param creatingProblemType <CODE>boolean</CODE>
	 */
	this.referenceBinding = aType;
	initByteArrays();
	// generate the magic numbers inside the header
	this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 24);
	this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 16);
	this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 8);
	this.header[this.headerOffset++] = (byte) (0xCAFEBABEL >> 0);

	long targetVersion = this.targetJDK = this.referenceBinding.scope.compilerOptions().targetJDK;
	this.header[this.headerOffset++] = (byte) (targetVersion >> 8); // minor high
	this.header[this.headerOffset++] = (byte) (targetVersion >> 0); // minor low
	this.header[this.headerOffset++] = (byte) (targetVersion >> 24); // major high
	this.header[this.headerOffset++] = (byte) (targetVersion >> 16); // major low

	this.constantPoolOffset = this.headerOffset;
	this.headerOffset += 2;
	this.constantPool = new ConstantPool(this);
	int accessFlags = aType.getAccessFlags();

	if (!aType.isInterface()) { // class or enum
		accessFlags |= ClassFileConstants.AccSuper;
	}
	if (aType.isNestedType()) {
		if (aType.isStatic()) {
			// clear Acc_Static
			accessFlags &= ~ClassFileConstants.AccStatic;
		}
		if (aType.isPrivate()) {
			// clear Acc_Private and Acc_Public
			accessFlags &= ~(ClassFileConstants.AccPrivate | ClassFileConstants.AccPublic);
		}
		if (aType.isProtected()) {
			// clear Acc_Protected and set Acc_Public
			accessFlags &= ~ClassFileConstants.AccProtected;
			accessFlags |= ClassFileConstants.AccPublic;
		}
	}
	// clear Acc_Strictfp
	accessFlags &= ~ClassFileConstants.AccStrictfp;

	this.enclosingClassFile = enclosingClassFile;
	// now we continue to generate the bytes inside the contents array
	this.contents[this.contentsOffset++] = (byte) (accessFlags >> 8);
	this.contents[this.contentsOffset++] = (byte) accessFlags;
	int classNameIndex = this.constantPool.literalIndexForType(aType);
	this.contents[this.contentsOffset++] = (byte) (classNameIndex >> 8);
	this.contents[this.contentsOffset++] = (byte) classNameIndex;
	int superclassNameIndex;
	if (aType.isInterface()) {
		superclassNameIndex = this.constantPool.literalIndexForType(ConstantPool.JavaLangObjectConstantPoolName);
	} else {
		superclassNameIndex =
			(aType.superclass == null ? 0 : this.constantPool.literalIndexForType(aType.superclass));
	}
	this.contents[this.contentsOffset++] = (byte) (superclassNameIndex >> 8);
	this.contents[this.contentsOffset++] = (byte) superclassNameIndex;
	ReferenceBinding[] superInterfacesBinding = aType.superInterfaces();
	int interfacesCount = superInterfacesBinding.length;
	this.contents[this.contentsOffset++] = (byte) (interfacesCount >> 8);
	this.contents[this.contentsOffset++] = (byte) interfacesCount;
	for (int i = 0; i < interfacesCount; i++) {
		int interfaceIndex = this.constantPool.literalIndexForType(superInterfacesBinding[i]);
		this.contents[this.contentsOffset++] = (byte) (interfaceIndex >> 8);
		this.contents[this.contentsOffset++] = (byte) interfaceIndex;
	}
	this.produceAttributes = this.referenceBinding.scope.compilerOptions().produceDebugAttributes;
	this.creatingProblemType = creatingProblemType;
	if (this.targetJDK >= ClassFileConstants.JDK1_6) {
		this.codeStream = new StackMapFrameCodeStream(this);
		this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
	} else if (this.targetJDK == ClassFileConstants.CLDC_1_1) {
		this.targetJDK = ClassFileConstants.JDK1_1; // put back 45.3
		this.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP;
		this.codeStream = new StackMapFrameCodeStream(this);
	} else {
		this.codeStream = new CodeStream(this);
	}
	// retrieve the enclosing one guaranteed to be the one matching the propagated flow info
	// 1FF9ZBU: LFCOM:ALL - Local variable attributes busted (Sanity check)
	this.codeStream.maxFieldCount = aType.scope.outerMostClassScope().referenceType().maxFieldCount;
}
/**
 * INTERNAL USE-ONLY
 * Request the creation of a ClassFile compatible representation of a problematic type
 *
 * @param typeDeclaration org.eclipse.jdt.internal.compiler.ast.TypeDeclaration
 * @param unitResult org.eclipse.jdt.internal.compiler.CompilationUnitResult
 */
public static void createProblemType(TypeDeclaration typeDeclaration, CompilationResult unitResult) {
	SourceTypeBinding typeBinding = typeDeclaration.binding;
	ClassFile classFile = new CodeSnippetClassFile(typeBinding, null, true);

	// inner attributes
	if (typeBinding.hasMemberTypes()) {
		// see bug 180109
		ReferenceBinding[] members = typeBinding.memberTypes;
		for (int i = 0, l = members.length; i < l; i++)
			classFile.recordInnerClasses(members[i]);
	}
	// TODO (olivier) handle cases where a field cannot be generated (name too long)
	// TODO (olivier) handle too many methods
	// inner attributes
	if (typeBinding.isNestedType()) {
		classFile.recordInnerClasses(typeBinding);
	}
	TypeVariableBinding[] typeVariables = typeBinding.typeVariables();
	for (int i = 0, max = typeVariables.length; i < max; i++) {
		TypeVariableBinding typeVariableBinding = typeVariables[i];
		if ((typeVariableBinding.tagBits & TagBits.ContainsNestedTypeReferences) != 0) {
			Util.recordNestedType(classFile, typeVariableBinding);
		}
	}

	// add its fields
	FieldBinding[] fields = typeBinding.fields();
	if ((fields != null) && (fields != Binding.NO_FIELDS)) {
		classFile.addFieldInfos();
	} else {
		// we have to set the number of fields to be equals to 0
		classFile.contents[classFile.contentsOffset++] = 0;
		classFile.contents[classFile.contentsOffset++] = 0;
	}
	// leave some space for the methodCount
	classFile.setForMethodInfos();
	// add its user defined methods
	int problemsLength;
	CategorizedProblem[] problems = unitResult.getErrors();
	if (problems == null) {
		problems = new CategorizedProblem[0];
	}
	CategorizedProblem[] problemsCopy = new CategorizedProblem[problemsLength = problems.length];
	System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
	AbstractMethodDeclaration[] methodDecls = typeDeclaration.methods;
	if (methodDecls != null) {
		if (typeBinding.isInterface()) {
			// we cannot create problem methods for an interface. So we have to generate a clinit
			// which should contain all the problem
			classFile.addProblemClinit(problemsCopy);
			for (int i = 0, length = methodDecls.length; i < length; i++) {
				AbstractMethodDeclaration methodDecl = methodDecls[i];
				MethodBinding method = methodDecl.binding;
				if (method == null || method.isConstructor()) continue;
				method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
				classFile.addAbstractMethod(methodDecl, method);
			}
		} else {
			for (int i = 0, length = methodDecls.length; i < length; i++) {
				AbstractMethodDeclaration methodDecl = methodDecls[i];
				MethodBinding method = methodDecl.binding;
				if (method == null) continue;
				if (method.isConstructor()) {
					classFile.addProblemConstructor(methodDecl, method, problemsCopy);
				} else if (method.isAbstract()) {
					classFile.addAbstractMethod(methodDecl, method);
				} else {
					classFile.addProblemMethod(methodDecl, method, problemsCopy);
				}
			}
		}
		// add abstract methods
		classFile.addDefaultAbstractMethods();
	}
	// propagate generation of (problem) member types
	if (typeDeclaration.memberTypes != null) {
		for (int i = 0, max = typeDeclaration.memberTypes.length; i < max; i++) {
			TypeDeclaration memberType = typeDeclaration.memberTypes[i];
			if (memberType.binding != null) {
				ClassFile.createProblemType(memberType, unitResult);
			}
		}
	}
	classFile.addAttributes();
	unitResult.record(typeBinding.constantPoolName(), classFile);
}
}
