diff src/luan/LuaJavaFunction.java @ 4:24fd6381caca

add to interp git-svn-id: https://luan-java.googlecode.com/svn/trunk@5 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Sun, 18 Nov 2012 04:18:15 +0000
parents 4da26b11d12a
children 9cea1aea5eef
line wrap: on
line diff
--- a/src/luan/LuaJavaFunction.java	Fri Nov 16 05:23:12 2012 +0000
+++ b/src/luan/LuaJavaFunction.java	Sun Nov 18 04:18:15 2012 +0000
@@ -1,5 +1,6 @@
 package luan;
 
+import java.lang.reflect.Array;
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
 
@@ -9,12 +10,19 @@
 	private final Object obj;
 	private final RtnConverter rtnConverter;
 	private final ArgConverter[] argConverters;
+	private final Class<?> varArgCls;
 
 	public LuaJavaFunction(Method method,Object obj) {
 		this.method = method;
 		this.obj = obj;
-		rtnConverter = getRtnConverter(method);
-		argConverters = getArgConverters(method);
+		this.rtnConverter = getRtnConverter(method);
+		this.argConverters = getArgConverters(method);
+		if( method.isVarArgs() ) {
+			Class<?>[] paramTypes = method.getParameterTypes();
+			this.varArgCls = paramTypes[paramTypes.length-1].getComponentType();
+		} else {
+			this.varArgCls = null;
+		}
 	}
 
 	@Override public Object[] call(Object... args) {
@@ -31,15 +39,36 @@
 	}
 
 	private Object[] fixArgs(Object[] args) {
-		if( args.length != argConverters.length ) {
-			Object[] t = new Object[argConverters.length];
-			System.arraycopy(args,0,t,0,Math.min(args.length,t.length));
-			args = t;
+		if( varArgCls==null ) {
+			if( args.length != argConverters.length ) {
+				Object[] t = new Object[argConverters.length];
+				System.arraycopy(args,0,t,0,Math.min(args.length,t.length));
+				args = t;
+			}
+			for( int i=0; i<args.length; i++ ) {
+				args[i] = argConverters[i].convert(args[i]);
+			}
+			return args;
+		} else {  // varargs
+			Object[] rtn = new Object[argConverters.length];
+			int n = argConverters.length - 1;
+			if( args.length < argConverters.length ) {
+				System.arraycopy(args,0,rtn,0,args.length);
+				rtn[rtn.length-1] = Array.newInstance(varArgCls,0);
+			} else {
+				System.arraycopy(args,0,rtn,0,n);
+				Object[] varArgs = (Object[])Array.newInstance(varArgCls,args.length-n);
+				ArgConverter ac = argConverters[n];
+				for( int i=0; i<varArgs.length; i++ ) {
+					varArgs[i] = ac.convert(args[n+i]);
+				}
+				rtn[rtn.length-1] = varArgs;
+			}
+			for( int i=0; i<n; i++ ) {
+				rtn[i] = argConverters[i].convert(rtn[i]);
+			}
+			return rtn;
 		}
-		for( int i=0; i<args.length; i++ ) {
-			args[i] = argConverters[i].convert(args[i]);
-		}
-		return args;
 	}
 
 
@@ -184,10 +213,14 @@
 	};
 
 	private static ArgConverter[] getArgConverters(Method m) {
+		final boolean isVarArgs = m.isVarArgs();
 		Class<?>[] paramTypes = m.getParameterTypes();
 		ArgConverter[] a = new ArgConverter[paramTypes.length];
 		for( int i=0; i<a.length; i++ ) {
-			a[i] = getArgConverter(paramTypes[i]);
+			Class<?> paramType = paramTypes[i];
+			if( isVarArgs && i == a.length-1 )
+				paramType = paramType.getComponentType();
+			a[i] = getArgConverter(paramType);
 		}
 		return a;
 	}