comparison src/luan/lib/JavaLib.java @ 40:e3624b7cd603

implement stack trace git-svn-id: https://luan-java.googlecode.com/svn/trunk@41 21e917c8-12df-6dd8-5cb6-c86387c605b9
author fschmidt@gmail.com <fschmidt@gmail.com@21e917c8-12df-6dd8-5cb6-c86387c605b9>
date Fri, 21 Dec 2012 10:45:54 +0000
parents 8a57ebfdfd78
children 57054fa43189
comparison
equal deleted inserted replaced
39:e5bcb1eeafc1 40:e3624b7cd603
16 import luan.LuaTable; 16 import luan.LuaTable;
17 import luan.MetatableGetter; 17 import luan.MetatableGetter;
18 import luan.LuaException; 18 import luan.LuaException;
19 import luan.LuaFunction; 19 import luan.LuaFunction;
20 import luan.LuaJavaFunction; 20 import luan.LuaJavaFunction;
21 import luan.LuaElement;
21 22
22 23
23 public final class JavaLib { 24 public final class JavaLib {
24 25
25 public static void register(LuaState lua) { 26 public static void register(LuaState lua) {
27 LuaTable module = new LuaTable(); 28 LuaTable module = new LuaTable();
28 LuaTable global = lua.global(); 29 LuaTable global = lua.global();
29 global.put("java",module); 30 global.put("java",module);
30 try { 31 try {
31 global.put( "import", new LuaJavaFunction(JavaLib.class.getMethod("importClass",LuaState.class,String.class),null) ); 32 global.put( "import", new LuaJavaFunction(JavaLib.class.getMethod("importClass",LuaState.class,String.class),null) );
32 module.put( "class", new LuaJavaFunction(JavaLib.class.getMethod("getClass",String.class),null) ); 33 module.put( "class", new LuaJavaFunction(JavaLib.class.getMethod("getClass",LuaState.class,String.class),null) );
33 } catch(NoSuchMethodException e) { 34 } catch(NoSuchMethodException e) {
34 throw new RuntimeException(e); 35 throw new RuntimeException(e);
35 } 36 }
36 add( global, "ipairs", Object.class );
37 add( global, "pairs", Object.class );
38 } 37 }
39 38
40 private static final LuaTable mt = new LuaTable(); 39 private static final LuaTable mt = new LuaTable();
41 static { 40 static {
42 add( mt, "__index", Object.class, Object.class ); 41 add( mt, "__index", LuaState.class, Object.class, Object.class );
43 } 42 }
44 43
45 private static void add(LuaTable t,String method,Class<?>... parameterTypes) { 44 private static void add(LuaTable t,String method,Class<?>... parameterTypes) {
46 try { 45 try {
47 t.put( method, new LuaJavaFunction(JavaLib.class.getMethod(method,parameterTypes),null) ); 46 t.put( method, new LuaJavaFunction(JavaLib.class.getMethod(method,parameterTypes),null) );
56 return null; 55 return null;
57 return mt; 56 return mt;
58 } 57 }
59 }; 58 };
60 59
61 public static Object __index(Object obj,Object key) throws LuaException { 60 public static Object __index(LuaState lua,Object obj,Object key) throws LuaException {
62 if( obj instanceof Static ) { 61 if( obj instanceof Static ) {
63 if( key instanceof String ) { 62 if( key instanceof String ) {
64 String name = (String)key; 63 String name = (String)key;
65 Static st = (Static)obj; 64 Static st = (Static)obj;
66 Class cls = st.cls; 65 Class cls = st.cls;
84 if( !members.isEmpty() ) { 83 if( !members.isEmpty() ) {
85 return member(null,members); 84 return member(null,members);
86 } 85 }
87 } 86 }
88 } 87 }
89 throw new LuaException("invalid index for java class: "+key); 88 throw new LuaException(lua,LuaElement.JAVA,"invalid index for java class: "+key);
90 } 89 }
91 Class cls = obj.getClass(); 90 Class cls = obj.getClass();
92 if( cls.isArray() ) { 91 if( cls.isArray() ) {
93 if( "length".equals(key) ) { 92 if( "length".equals(key) ) {
94 return Array.getLength(obj); 93 return Array.getLength(obj);
99 int i = (int)d; 98 int i = (int)d;
100 if( d==i ) { 99 if( d==i ) {
101 return Array.get(obj,i); 100 return Array.get(obj,i);
102 } 101 }
103 } 102 }
104 throw new LuaException("invalid index for java array: "+key); 103 throw new LuaException(lua,LuaElement.JAVA,"invalid index for java array: "+key);
105 } 104 }
106 if( key instanceof String ) { 105 if( key instanceof String ) {
107 String name = (String)key; 106 String name = (String)key;
108 if( "instanceof".equals(name) ) { 107 if( "instanceof".equals(name) ) {
109 return new LuaJavaFunction(instanceOf,new InstanceOf(obj)); 108 return new LuaJavaFunction(instanceOf,new InstanceOf(obj));
112 if( !members.isEmpty() ) { 111 if( !members.isEmpty() ) {
113 return member(obj,members); 112 return member(obj,members);
114 } 113 }
115 } 114 }
116 } 115 }
117 throw new LuaException("invalid index for java object: "+key); 116 throw new LuaException(lua,LuaElement.JAVA,"invalid index for java object: "+key);
118 } 117 }
119 118
120 private static Object member(Object obj,List<Member> members) throws LuaException { 119 private static Object member(Object obj,List<Member> members) throws LuaException {
121 try { 120 try {
122 if( members.size()==1 ) { 121 if( members.size()==1 ) {
190 Static(Class cls) { 189 Static(Class cls) {
191 this.cls = cls; 190 this.cls = cls;
192 } 191 }
193 } 192 }
194 193
195 public static Static getClass(String name) throws LuaException { 194 public static Static getClass(LuaState lua,String name) throws LuaException {
196 try { 195 try {
197 return new Static( Class.forName(name) ); 196 return new Static( Class.forName(name) );
198 } catch(ClassNotFoundException e) { 197 } catch(ClassNotFoundException e) {
199 throw new LuaException(e); 198 throw new LuaException(lua,LuaElement.JAVA,e);
200 } 199 }
201 } 200 }
202 201
203 public static void importClass(LuaState lua,String name) throws LuaException { 202 public static void importClass(LuaState lua,String name) throws LuaException {
204 lua.global().put( name.substring(name.lastIndexOf('.')+1), getClass(name) ); 203 lua.global().put( name.substring(name.lastIndexOf('.')+1), getClass(lua,name) );
205 } 204 }
206 205
207 static class AmbiguousJavaFunction extends LuaFunction { 206 static class AmbiguousJavaFunction extends LuaFunction {
208 private final Map<Integer,List<LuaJavaFunction>> fnMap = new HashMap<Integer,List<LuaJavaFunction>>(); 207 private final Map<Integer,List<LuaJavaFunction>> fnMap = new HashMap<Integer,List<LuaJavaFunction>>();
209 208
217 } 216 }
218 list.add(fn); 217 list.add(fn);
219 } 218 }
220 } 219 }
221 220
222 @Override public Object[] call(LuaState lua,Object... args) throws LuaException { 221 @Override public Object[] call(LuaState lua,Object[] args) throws LuaException {
223 for( LuaJavaFunction fn : fnMap.get(args.length) ) { 222 for( LuaJavaFunction fn : fnMap.get(args.length) ) {
224 try { 223 try {
225 return fn.call(lua,args); 224 return fn.call(lua,args);
226 } catch(IllegalArgumentException e) {} 225 } catch(IllegalArgumentException e) {}
227 } 226 }
228 throw new LuaException("no method matched args"); 227 throw new LuaException(lua,LuaElement.JAVA,"no method matched args");
229 } 228 }
230 } 229 }
231
232
233 public static LuaFunction pairs(Object t) throws LuaException {
234 if( t instanceof LuaTable )
235 return BasicLib.pairs((LuaTable)t);
236 if( t instanceof Map ) {
237 @SuppressWarnings("unchecked")
238 Map<Object,Object> m = (Map<Object,Object>)t;
239 return BasicLib.pairs(m.entrySet().iterator());
240 }
241 throw new LuaException( "bad argument #1 to 'pairs' (table or Map expected)" );
242 }
243
244 private static class Iter {
245 private final Iterator iter;
246 private double i = 0.0;
247
248 Iter(Iterable t) {
249 this.iter = t.iterator();
250 }
251
252 public Object[] next() {
253 if( !iter.hasNext() )
254 return LuaFunction.EMPTY_RTN ;
255 return new Object[]{ new LuaNumber(i++), iter.next() };
256 }
257 }
258 private static final Method nextIter;
259 static {
260 try {
261 nextIter = Iter.class.getMethod("next");
262 nextIter.setAccessible(true);
263 } catch(NoSuchMethodException e) {
264 throw new RuntimeException(e);
265 }
266 }
267
268 public static LuaFunction ipairs(Object t) throws LuaException {
269 if( t instanceof LuaTable )
270 return BasicLib.ipairs((LuaTable)t);
271 if( t instanceof Iterable ) {
272 Iter ai = new Iter((Iterable)t);
273 return new LuaJavaFunction(nextIter,ai);
274 }
275 throw new LuaException( "bad argument #1 to 'ipairs' (table or Iterable expected)" );
276 }
277
278 230
279 private static class InstanceOf { 231 private static class InstanceOf {
280 private final Object obj; 232 private final Object obj;
281 233
282 InstanceOf(Object obj) { 234 InstanceOf(Object obj) {