org.whole.lang.bytecode.util.BytecodeStoreProducerBuilder.java Source code

Java tutorial

Introduction

Here is the source code for org.whole.lang.bytecode.util.BytecodeStoreProducerBuilder.java

Source

/**
 * Copyright 2004-2014 Riccardo Solmi. All rights reserved.
 * This file is part of the Whole Platform.
 *
 * The Whole Platform is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The Whole Platform is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with the Whole Platform. If not, see <http://www.gnu.org/licenses/>.
 */
package org.whole.lang.bytecode.util;

import java.util.Date;

import org.objectweb.asm.*;
import org.whole.lang.builders.BuilderConstants;
import org.whole.lang.builders.IBuilder;
import org.whole.lang.builders.IBuilderOperation;
import org.whole.lang.contexts.IBuilderContext;
import org.whole.lang.contexts.IEntityContext;
import org.whole.lang.model.EnumValue;
import org.whole.lang.reflect.EntityDescriptor;
import org.whole.lang.reflect.FeatureDescriptor;
import org.whole.lang.reflect.ILanguageKit;
import org.whole.lang.templates.AbstractTemplateFactory;
import org.whole.lang.templates.ITemplate;

/**
 * @author Riccardo Solmi
 */
public class BytecodeStoreProducerBuilder implements IBuilder, Opcodes {
    //   private List<ClassWriter> cwList = new ArrayList<ClassWriter>();
    private ClassWriter cw;
    private MethodVisitor mv;
    private String builderInterfaceInternalName;
    private int varNum = 2;

    public byte[] getResult() {
        return cw.toByteArray();
    }

    public static void visitIntInsn(MethodVisitor mv, int value) {
        switch (value) {
        case -1:
            mv.visitInsn(ICONST_M1);
            break;
        case 0:
            mv.visitInsn(ICONST_0);
            break;
        case 1:
            mv.visitInsn(ICONST_1);
            break;
        case 2:
            mv.visitInsn(ICONST_2);
            break;
        case 3:
            mv.visitInsn(ICONST_3);
            break;
        case 4:
            mv.visitInsn(ICONST_4);
            break;
        case 5:
            mv.visitInsn(ICONST_5);
            break;
        default:
            if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE)
                mv.visitIntInsn(BIPUSH, value);
            else
                mv.visitIntInsn(SIPUSH, value);
        }
    }

    public static String getInternalName(String type) {
        return Type.getType(type).getInternalName();
    }

    public static String getMethodDescriptor(final Class<?> res, final Class<?> arg0) {
        final StringBuffer buf = new StringBuffer();
        buf.append('(');

        buf.append(Type.getDescriptor(arg0));

        buf.append(')');
        buf.append(Type.getDescriptor(res));
        return buf.toString();
    }

    public void buildStartCompilationUnit(String packageName, String className) {
        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);

        String classInternalName = Type
                .getType(packageName.length() > 0 ? packageName + '.' + className : className).getInternalName();
        String superInternalName = Type.getInternalName(AbstractTemplateFactory.class);

        cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, classInternalName, null, superInternalName, null);
        cw.visitSource(className + ".java", null);

        mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, superInternalName, "<init>", "()V");
        mv.visitInsn(RETURN);
        mv.visitEnd();

        mv = cw.visitMethod(ACC_PUBLIC, "apply", getMethodDescriptor(Void.TYPE, IBuilderOperation.class), null,
                null);
        mv.visitCode();
    }

    public void buildEndCompilationUnit() {
        mv.visitInsn(RETURN);
        mv.visitEnd();
    }

    public void ensureBuilder(ILanguageKit languageKit) {
        //TODO
    }

    protected void buildGetBuilder(ILanguageKit languageKit, String builderType) {
        builderInterfaceInternalName = getInternalName(builderType);

        mv.visitVarInsn(ALOAD, 1);
        mv.visitLdcInsn(languageKit.getClass().getName());
        mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(IBuilderOperation.class), "wGetBuilder",
                getMethodDescriptor(IBuilder.class, String.class));
        mv.visitTypeInsn(CHECKCAST, builderInterfaceInternalName);
        mv.visitVarInsn(ASTORE, varNum);
    }

    public void wEntity_(EntityDescriptor<?> entityDesc) {
        ensureBuilder(entityDesc.getLanguageKit());
        mv.visitVarInsn(ALOAD, varNum);
        mv.visitMethodInsn(INVOKEINTERFACE, builderInterfaceInternalName,
                BuilderConstants.startBuildName(entityDesc), "()V");
    }

    public void wEntity_(EntityDescriptor<?> entityDesc, int initialCapacity) {
        ensureBuilder(entityDesc.getLanguageKit());
        mv.visitVarInsn(ALOAD, varNum);

        visitIntInsn(mv, initialCapacity);

        mv.visitMethodInsn(INVOKEINTERFACE, builderInterfaceInternalName,
                BuilderConstants.startBuildName(entityDesc), "(I)V");
    }

    public void _wEntity(EntityDescriptor<?> entityDesc) {
        ensureBuilder(entityDesc.getLanguageKit());
        mv.visitVarInsn(ALOAD, varNum);
        mv.visitMethodInsn(INVOKEINTERFACE, builderInterfaceInternalName, BuilderConstants.endBuildName(entityDesc),
                "()V");
    }

    public void wEntity(EntityDescriptor<?> entityDesc) {
        ensureBuilder(entityDesc.getLanguageKit());
        mv.visitVarInsn(ALOAD, varNum);
        mv.visitMethodInsn(INVOKEINTERFACE, builderInterfaceInternalName, BuilderConstants.buildName(entityDesc),
                "()V");
    }

    public void wEntity(EntityDescriptor<?> entityDesc, boolean value) {
        ensureBuilder(entityDesc.getLanguageKit());
        mv.visitVarInsn(ALOAD, varNum);
        mv.visitInsn(value ? ICONST_1 : ICONST_0);
        mv.visitMethodInsn(INVOKEINTERFACE, builderInterfaceInternalName, BuilderConstants.buildName(entityDesc),
                "(Z)V");
    }

    public void wEntity(EntityDescriptor<?> entityDesc, byte value) {
        ensureBuilder(entityDesc.getLanguageKit());

        wEntity(entityDesc, value);

    }

    public void wEntity(EntityDescriptor<?> entityDesc, char value) {
        ensureBuilder(entityDesc.getLanguageKit());

    }

    public void wEntity(EntityDescriptor<?> entityDesc, double value) {
        ensureBuilder(entityDesc.getLanguageKit());

    }

    public void wEntity(EntityDescriptor<?> entityDesc, float value) {
        ensureBuilder(entityDesc.getLanguageKit());

    }

    public void wEntity(EntityDescriptor<?> entityDesc, int value) {
        ensureBuilder(entityDesc.getLanguageKit());
        mv.visitVarInsn(ALOAD, varNum);
        visitIntInsn(mv, value);
        mv.visitMethodInsn(INVOKEINTERFACE, builderInterfaceInternalName, BuilderConstants.buildName(entityDesc),
                "(I)V");
    }

    public void wEntity(EntityDescriptor<?> entityDesc, long value) {
        ensureBuilder(entityDesc.getLanguageKit());

    }

    public void wEntity(EntityDescriptor<?> entityDesc, short value) {
        ensureBuilder(entityDesc.getLanguageKit());

    }

    public void wEntity(EntityDescriptor<?> entityDesc, String value) {
        ensureBuilder(entityDesc.getLanguageKit());
        mv.visitVarInsn(ALOAD, varNum);
        mv.visitLdcInsn(value);
        mv.visitMethodInsn(INVOKEINTERFACE, builderInterfaceInternalName, BuilderConstants.buildName(entityDesc),
                "(Ljava/lang/String;)V");
    }

    public void wEntity(EntityDescriptor<?> entityDesc, Date value) {
        ensureBuilder(entityDesc.getLanguageKit());

    }

    public void wEntity(EntityDescriptor<?> entityDesc, EnumValue value) {
        ensureBuilder(entityDesc.getLanguageKit());

    }

    public void wEntity(EntityDescriptor<?> entityDesc, Object value) {

    }

    public void wSetBuilderContext(IBuilderContext context) {
    }

    public void wSetEntityContext(IEntityContext context) {
    }

    public void wDefault() {
        // TODO
        throw new UnsupportedOperationException();
    }

    public void wEntity() {
        // TODO
        throw new UnsupportedOperationException();
    }

    public void wEntity_() {
        // TODO
        throw new UnsupportedOperationException();
    }

    public void _wEntity() {
        // TODO
        throw new UnsupportedOperationException();
    }

    public void wFeature(int index) {
        // TODO
        throw new UnsupportedOperationException();
    }

    public void wFeature(FeatureDescriptor feature) {
        // TODO
        throw new UnsupportedOperationException();
    }

    public void wFeature(ITemplate template) {
        // TODO
        throw new UnsupportedOperationException();
    }
}