Mercurial Hosting > luan
comparison 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 |
comparison
equal
deleted
inserted
replaced
3:7a2cdbc5767f | 4:24fd6381caca |
---|---|
1 package luan; | 1 package luan; |
2 | 2 |
3 import java.lang.reflect.Array; | |
3 import java.lang.reflect.Method; | 4 import java.lang.reflect.Method; |
4 import java.lang.reflect.InvocationTargetException; | 5 import java.lang.reflect.InvocationTargetException; |
5 | 6 |
6 | 7 |
7 public final class LuaJavaFunction extends LuaFunction { | 8 public final class LuaJavaFunction extends LuaFunction { |
8 private final Method method; | 9 private final Method method; |
9 private final Object obj; | 10 private final Object obj; |
10 private final RtnConverter rtnConverter; | 11 private final RtnConverter rtnConverter; |
11 private final ArgConverter[] argConverters; | 12 private final ArgConverter[] argConverters; |
13 private final Class<?> varArgCls; | |
12 | 14 |
13 public LuaJavaFunction(Method method,Object obj) { | 15 public LuaJavaFunction(Method method,Object obj) { |
14 this.method = method; | 16 this.method = method; |
15 this.obj = obj; | 17 this.obj = obj; |
16 rtnConverter = getRtnConverter(method); | 18 this.rtnConverter = getRtnConverter(method); |
17 argConverters = getArgConverters(method); | 19 this.argConverters = getArgConverters(method); |
20 if( method.isVarArgs() ) { | |
21 Class<?>[] paramTypes = method.getParameterTypes(); | |
22 this.varArgCls = paramTypes[paramTypes.length-1].getComponentType(); | |
23 } else { | |
24 this.varArgCls = null; | |
25 } | |
18 } | 26 } |
19 | 27 |
20 @Override public Object[] call(Object... args) { | 28 @Override public Object[] call(Object... args) { |
21 args = fixArgs(args); | 29 args = fixArgs(args); |
22 Object rtn; | 30 Object rtn; |
29 } | 37 } |
30 return rtnConverter.convert(rtn); | 38 return rtnConverter.convert(rtn); |
31 } | 39 } |
32 | 40 |
33 private Object[] fixArgs(Object[] args) { | 41 private Object[] fixArgs(Object[] args) { |
34 if( args.length != argConverters.length ) { | 42 if( varArgCls==null ) { |
35 Object[] t = new Object[argConverters.length]; | 43 if( args.length != argConverters.length ) { |
36 System.arraycopy(args,0,t,0,Math.min(args.length,t.length)); | 44 Object[] t = new Object[argConverters.length]; |
37 args = t; | 45 System.arraycopy(args,0,t,0,Math.min(args.length,t.length)); |
38 } | 46 args = t; |
39 for( int i=0; i<args.length; i++ ) { | 47 } |
40 args[i] = argConverters[i].convert(args[i]); | 48 for( int i=0; i<args.length; i++ ) { |
41 } | 49 args[i] = argConverters[i].convert(args[i]); |
42 return args; | 50 } |
51 return args; | |
52 } else { // varargs | |
53 Object[] rtn = new Object[argConverters.length]; | |
54 int n = argConverters.length - 1; | |
55 if( args.length < argConverters.length ) { | |
56 System.arraycopy(args,0,rtn,0,args.length); | |
57 rtn[rtn.length-1] = Array.newInstance(varArgCls,0); | |
58 } else { | |
59 System.arraycopy(args,0,rtn,0,n); | |
60 Object[] varArgs = (Object[])Array.newInstance(varArgCls,args.length-n); | |
61 ArgConverter ac = argConverters[n]; | |
62 for( int i=0; i<varArgs.length; i++ ) { | |
63 varArgs[i] = ac.convert(args[n+i]); | |
64 } | |
65 rtn[rtn.length-1] = varArgs; | |
66 } | |
67 for( int i=0; i<n; i++ ) { | |
68 rtn[i] = argConverters[i].convert(rtn[i]); | |
69 } | |
70 return rtn; | |
71 } | |
43 } | 72 } |
44 | 73 |
45 | 74 |
46 private interface RtnConverter { | 75 private interface RtnConverter { |
47 public Object[] convert(Object obj); | 76 public Object[] convert(Object obj); |
182 return obj; | 211 return obj; |
183 } | 212 } |
184 }; | 213 }; |
185 | 214 |
186 private static ArgConverter[] getArgConverters(Method m) { | 215 private static ArgConverter[] getArgConverters(Method m) { |
216 final boolean isVarArgs = m.isVarArgs(); | |
187 Class<?>[] paramTypes = m.getParameterTypes(); | 217 Class<?>[] paramTypes = m.getParameterTypes(); |
188 ArgConverter[] a = new ArgConverter[paramTypes.length]; | 218 ArgConverter[] a = new ArgConverter[paramTypes.length]; |
189 for( int i=0; i<a.length; i++ ) { | 219 for( int i=0; i<a.length; i++ ) { |
190 a[i] = getArgConverter(paramTypes[i]); | 220 Class<?> paramType = paramTypes[i]; |
221 if( isVarArgs && i == a.length-1 ) | |
222 paramType = paramType.getComponentType(); | |
223 a[i] = getArgConverter(paramType); | |
191 } | 224 } |
192 return a; | 225 return a; |
193 } | 226 } |
194 | 227 |
195 private static ArgConverter getArgConverter(Class<?> cls) { | 228 private static ArgConverter getArgConverter(Class<?> cls) { |