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 }