package net.folab.fo.bytecode;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class MethodGenerator implements Opcodes {

    private final ClassGenerator cg;

    private AccessModifier accessModifier = AccessModifier.PUBLIC;

    private JavaType returnType = JavaType.VOID;

    private String name;

    private JavaType[] parameterTypes = new JavaType[0];

    protected MethodGenerator(ClassGenerator cg) {
        this.cg = cg;
    }

    public void generate(ClassWriter cw) {
        String desc = "(";
        for (JavaType pt : parameterTypes) {
            desc += pt.getDescName();
        }
        desc += ")";
        desc += returnType.getDescName();

        MethodVisitor mv = cw.visitMethod(//
                accessModifier.modifier, // access
                name, // name
                desc, // desc
                null, // signature
                null // exceptions
                );

        mv.visitCode();

        if (returnType.equals(JavaType.VOID)) {
            mv.visitInsn(RETURN);
        } else if (returnType.equals(JavaType.BOOLEAN)) {
            mv.visitInsn(ICONST_0);
            mv.visitInsn(IRETURN);
        } else if (returnType.equals(JavaType.BYTE)) {
            mv.visitInsn(ICONST_0);
            mv.visitInsn(IRETURN);
        } else if (returnType.equals(JavaType.CHAR)) {
            mv.visitInsn(ICONST_0);
            mv.visitInsn(IRETURN);
        } else if (returnType.equals(JavaType.SHORT)) {
            mv.visitInsn(ICONST_0);
            mv.visitInsn(IRETURN);
        } else if (returnType.equals(JavaType.INT)) {
            mv.visitInsn(ICONST_0);
            mv.visitInsn(IRETURN);
        } else if (returnType.equals(JavaType.LONG)) {
            mv.visitInsn(LCONST_0);
            mv.visitInsn(LRETURN);
        } else if (returnType.equals(JavaType.FLOAT)) {
            mv.visitInsn(FCONST_0);
            mv.visitInsn(FRETURN);
        } else if (returnType.equals(JavaType.DOUBLE)) {
            mv.visitInsn(DCONST_0);
            mv.visitInsn(DRETURN);
        } else {
            mv.visitInsn(ACONST_NULL);
            mv.visitInsn(ARETURN);
        }

        mv.visitMaxs(1, 1);
        mv.visitEnd();

    }

    public AccessModifier getAccessModifier() {
        return accessModifier;
    }

    public void setAccessModifier(AccessModifier accessModifier) {
        this.accessModifier = accessModifier;
    }

    public JavaType getReturnType() {
        return returnType;
    }

    public void setReturnType(JavaType returnType) {
        this.returnType = returnType;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public JavaType[] getParameterTypes() {
        return parameterTypes;
    }

    public void setParameterTypes(JavaType[] parameterTypes) {
        this.parameterTypes = parameterTypes;
    }

}

@@ -732,24 +732,72 @@
 escName();%0A%0A
+        int modifier = accessModifier.modifier;%0A
         Meth
@@ -845,31 +845,16 @@
         
-accessModifier.
 modifier
@@ -1053,95 +1053,166 @@
    i
-f (returnType.equals(JavaType.VOID)) %7B%0A            mv.visitInsn(RETURN);%0A 
+nt maxStack = 0;%0A        int maxLocals = 0;%0A%0A        if ((modifier & ACC_STATIC) != ACC_STATIC)%0A            maxLocals++; // local variable for %60this%60%0A%0A
        
-%7D else
  if 
@@ -1243,15 +1243,12 @@
 ype.
-BOOLEAN
+VOID
 )) %7B
@@ -1277,45 +1277,8 @@
 nsn(
-ICONST_0);%0A            mv.visitInsn(I
 RETU
@@ -1333,15 +1333,15 @@
 pe.B
-YTE)) %7B
+OOLEAN)
 %0A   
@@ -1353,86 +1353,67 @@
     
-mv.visitInsn(ICONST_0);%0A            mv.visitInsn(IRETURN);%0A        %7D else if (
+    %7C%7C returnType.equals(JavaType.BYTE)%0A                %7C%7C 
 retu
@@ -1440,19 +1440,16 @@
 pe.CHAR)
-) %7B
 %0A       
@@ -1457,86 +1457,15 @@
     
-mv.visitInsn(ICONST_0);%0A            mv.visitInsn(IRETURN);%0A        %7D else if (
+    %7C%7C 
 retu
@@ -1493,19 +1493,16 @@
 e.SHORT)
-) %7B
 %0A       
@@ -1510,86 +1510,15 @@
     
-mv.visitInsn(ICONST_0);%0A            mv.visitInsn(IRETURN);%0A        %7D else if (
+    %7C%7C 
 retu
@@ -1544,24 +1544,48 @@
 ype.INT)) %7B%0A
+            maxStack++;%0A
             
@@ -1694,24 +1694,72 @@
 pe.LONG)) %7B%0A
+            maxStack++;%0A            maxStack++;%0A
             
@@ -1869,24 +1869,48 @@
 e.FLOAT)) %7B%0A
+            maxStack++;%0A
             
@@ -2021,24 +2021,72 @@
 .DOUBLE)) %7B%0A
+            maxStack++;%0A            maxStack++;%0A
             
@@ -2161,16 +2161,40 @@
  else %7B%0A
+            maxStack++;%0A
         
@@ -2295,12 +2295,27 @@
 axs(
-1, 1
+maxStack, maxLocals
 );%0A 

Add maxStack/maxLocal calculation logic