001    /*
002     * InvokeMethodAdapter.java created on 14.09.2006
003     *
004     * To change this generated comment go to 
005     * Window>Preferences>Java>Code Generation>Code and Comments
006     */
007    package org.codehaus.groovy.classgen;
008    
009    import org.objectweb.asm.MethodVisitor;
010    
011    public class MethodCallerMultiAdapter {
012        private MethodCaller[] methods;
013        boolean skipSpreadSafeAndSafe;
014        
015        public final static int maxArgs = 0;
016        
017        public static MethodCallerMultiAdapter newStatic(Class theClass, String baseName, boolean createNArgs, boolean skipSpreadSafeAndSafe) {
018            MethodCallerMultiAdapter mcma = new MethodCallerMultiAdapter();
019            mcma.skipSpreadSafeAndSafe = skipSpreadSafeAndSafe;
020            if (createNArgs) {
021                int numberOfBaseMethods = mcma.numberOfBaseMethods();
022                mcma.methods = new MethodCaller[(maxArgs+2)*numberOfBaseMethods];
023                for (int i=0; i<=maxArgs; i++) {
024                    mcma.methods[i*numberOfBaseMethods] = MethodCaller.newStatic(theClass,baseName+i);
025                    if (skipSpreadSafeAndSafe) continue;
026                    mcma.methods[i*numberOfBaseMethods+1] = MethodCaller.newStatic(theClass,baseName+i+"Safe");
027                    mcma.methods[i*numberOfBaseMethods+2] = MethodCaller.newStatic(theClass,baseName+i+"SpreadSafe");
028                }
029                mcma.methods[(maxArgs+1)*numberOfBaseMethods] = MethodCaller.newStatic(theClass,baseName+"N");
030                if (!skipSpreadSafeAndSafe) {
031                    mcma.methods[(maxArgs+1)*numberOfBaseMethods+1] = MethodCaller.newStatic(theClass,baseName+"N"+"Safe");
032                    mcma.methods[(maxArgs+1)*numberOfBaseMethods+2] = MethodCaller.newStatic(theClass,baseName+"N"+"SpreadSafe");
033                }
034                
035            } else if (!skipSpreadSafeAndSafe) {
036                mcma.methods = new MethodCaller[]{
037                        MethodCaller.newStatic(theClass,baseName),
038                        MethodCaller.newStatic(theClass,baseName+"Safe"),
039                        MethodCaller.newStatic(theClass,baseName+"SpreadSafe")
040                };
041            } else {
042                mcma.methods = new MethodCaller[]{
043                        MethodCaller.newStatic(theClass,baseName)
044                };
045            }
046            return mcma;
047        }
048        
049        /**
050         * 
051         * @param methodVisitor
052         * @param numberOfArguments a value >0 describing how many arguments are additionally used for the method call
053         * @param safe
054         * @param spreadSafe
055         */
056        public void call(MethodVisitor methodVisitor, int numberOfArguments, boolean safe, boolean spreadSafe) {
057            int offset = 0;
058            if (safe && !skipSpreadSafeAndSafe) offset = 1;
059            if (spreadSafe && !skipSpreadSafeAndSafe) offset = 2;
060            if (numberOfArguments>maxArgs || numberOfArguments<0){
061                offset += (maxArgs+1)*numberOfBaseMethods();
062            } else {
063                offset += numberOfArguments*numberOfBaseMethods();
064            }
065            methods[offset].call(methodVisitor);
066        }
067        
068        private int numberOfBaseMethods(){
069            if (skipSpreadSafeAndSafe) return 1;
070            return 3;
071        }
072    }