Mercurial Hosting > luan
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) { |
