All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.maxifier.mxcache.util.MxConstructorGenerator Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2014 Maxifier Ltd. All Rights Reserved.
 */
package com.maxifier.mxcache.util;

import com.maxifier.mxcache.asm.MethodVisitor;
import com.maxifier.mxcache.asm.Type;
import com.maxifier.mxcache.asm.commons.Method;

import static com.maxifier.mxcache.asm.Opcodes.*;
import static com.maxifier.mxcache.util.CodegenHelper.*;

/**
 * @author Alexander Kochurov ([email protected])
 */
public class MxConstructorGenerator extends MxGeneratorAdapter {
    private final Type superType;

    private boolean codeVisited;
    private boolean superCalled;
    private int startLocal;

    public MxConstructorGenerator(MethodVisitor mv, int access, Method method, Type thisClass, Type superType) {
        super(mv, access, method, thisClass);
        this.superType = superType;
    }

    @Override
    public void visitCode() {
        codeVisited = true;
        super.visitCode();
    }

    @Override
    public void visitMethodInsn(int opcode, String owner, String name, String desc) {
        if (opcode == INVOKESPECIAL && owner.equals(superType.getInternalName()) && name.equals(CONSTRUCTOR_NAME)) {
            checkSuperCalled();
        }
        super.visitMethodInsn(opcode, owner, name, desc);
    }

    private void checkSuperCalled() {
        if (superCalled) {
            throw new IllegalArgumentException("Super already called");
        }
        superCalled = true;
    }

    public void callSuper() {
        checkCodeVisited();
        loadThis();
        invokeConstructor(superType, NO_ARG_CONSTRUCTOR);
    }

    public void callSuper(Type... argumentTypes) {
        checkCodeVisited();
        loadThis();
        for (int i = argumentTypes.length; i != 0; i--) {
            loadArg(startLocal++);
        }
        invokeConstructor(superType, new Method(CONSTRUCTOR_NAME, Type.VOID_TYPE, argumentTypes));
    }

    private void checkCodeVisited() {
        if (!codeVisited) {
            visitCode();
        }
    }

    public void initFields(MxField... fields) {
        checkCodeVisited();
        for (MxField field : fields) {
            loadThis();
            loadArg(startLocal++);
            put(field);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy