/*******************************************************************************

 * Copyright (c) 2006 IONA Technologies PLC

 * 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:

 *     IONA Technologies PLC - initial API and implementation

 *******************************************************************************/
package org.eclipse.stp.sc.xmlvalidator.classbuilder;

import java.io.IOException;

import org.eclipse.stp.sc.xmlvalidator.classbuilder.inst.JFieldInst;
import org.eclipse.stp.sc.xmlvalidator.classbuilder.inst.JLSInst;
import org.eclipse.stp.sc.xmlvalidator.classbuilder.inst.JMethodInst;

/**
 * @author jma
 * visite the class to generate sorted constant pool
 */
class JConstantPoolVisitor implements JVisitor {


	JConstantPool pool = null;
	

	public JConstantPoolVisitor() {
	}

	public void setConstantPool(JConstantPool value) {
	    pool = value;
	}
	
	public void visitClass(JClass cls) throws Exception {

		buildClass(cls);
	}

	/**
	 * write the method to java byte code format.
	 * 
	 * @param method,
	 *            the method to visit
	 * @param bos,
	 *            output stream to write
	 * @return
	 */
	public void visitMethod(JMethod method) throws Exception {

		pool.stringUTFConstant(method.getName());
		pool.stringUTFConstant(ByteCodeUtils.getMethodDescriptor(method));
		 
		int exceptionCount = method.getExceptions().size();
		if (exceptionCount > 0) {
		    pool.stringUTFConstant("Exceptions");
		}
		int codeCount = method.getCode().size();
		if (codeCount > 0) {
		    pool.stringUTFConstant("Code");
		}

	}
	

	public void visitField(JField field) throws Exception {
		pool.stringUTFConstant(field.getName());
	    pool.stringUTFConstant(ByteCodeUtils.getFieldDescriptor(field));
	}

	
	public void buildClass(JClass cls) throws Exception {
		pool.classConstant(cls.getName());
		pool.classConstant(cls.getSuperClass());
	}

	

    public void visitConstantPool(JConstantPool pool) throws IOException {
	}
    
    public void visitCodeStep(JCodeStep code) throws Exception {
    	if (code.paramList == null ) {
    		return;
    	}
    	switch (code.opCode.value()) {
    	case JLSInst.LDC:
    		pool.stringConstant((String)code.paramList.get(0));
    		break;
    	case JMethodInst.INVOKEVIRTUAL:
    	case JMethodInst.INVOKESPECIAL:
    		String clsName = (String)code.paramList.get(0);
    		JMethod method = (JMethod)code.paramList.get(1);
    		pool.methodConstant(clsName, method);
    		break;
    	case JFieldInst.GETSTATIC:
    		clsName = (String)code.paramList.get(0);
    		JField field = (JField)code.paramList.get(1);
    		pool.fieldConstant(clsName, field);
    		break;
    	}
    }
    
    /**
     * sort the constant pool accorind to javac result order as following:
     * @throws Exception
     */
    public void sort() throws Exception{
    	
    }

}
