/*******************************************************************************
 * Copyright (c) 2000, 2013 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
 *        Andy Clement - Contributions for
 *                          Bug 383624 - [1.8][compiler] Revive code generation support for type annotations (from Olivier's work)
 *******************************************************************************/
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.codegen.TypeAnnotationCodeStream;
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;
	//TODO: Might have to update even for CLDC_1_1
	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.produceAttributes |= ClassFileConstants.ATTR_STACK_MAP_TABLE;
		if (this.targetJDK >= ClassFileConstants.JDK1_8) {
			this.produceAttributes |= ClassFileConstants.ATTR_TYPE_ANNOTATION;
			this.codeStream = new TypeAnnotationCodeStream(this);
		} else {
			this.codeStream = new StackMapFrameCodeStream(this);
		}
	} 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;
	boolean abstractMethodsOnly = false;
	if (methodDecls != null) {
		if (typeBinding.isInterface()) {
			if (typeBinding.scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8)
				abstractMethodsOnly = true;
			// We generate a clinit which contains all the problems, since we may not be able to generate problem methods (< 1.8) and problem constructors (all levels).
			classFile.addProblemClinit(problemsCopy);
		}
		for (int i = 0, length = methodDecls.length; i < length; i++) {
			AbstractMethodDeclaration methodDecl = methodDecls[i];
			MethodBinding method = methodDecl.binding;
			if (method == null) continue;
			if (abstractMethodsOnly) {
				method.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract;
			}		
			if (method.isConstructor()) {
				if (typeBinding.isInterface()) continue;
				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);
}
}
