Mercurial Hosting > luan
diff src/luan/modules/JavaLuan.java @ 1335:e0cf0d108a77
major cleanup
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 14 Feb 2019 03:10:45 -0700 |
parents | 25746915a241 |
children | 8d95711f6615 |
line wrap: on
line diff
--- a/src/luan/modules/JavaLuan.java Tue Feb 12 22:53:57 2019 -0700 +++ b/src/luan/modules/JavaLuan.java Thu Feb 14 03:10:45 2019 -0700 @@ -22,6 +22,7 @@ import luan.LuanException; import luan.LuanFunction; import luan.LuanJavaFunction; +import luan.LuanCloner; public final class JavaLuan { @@ -31,13 +32,17 @@ luan.peek().javaOk = true; } - public static final LuanFunction javaFn; - static { - try { - javaFn = new LuanJavaFunction(JavaLuan.class.getMethod("java",Luan.class),null); - } catch(NoSuchMethodException e) { - throw new RuntimeException(e); + public static LuanFunction javaFn(Luan luan) { + LuanFunction fn = (LuanFunction)luan.registry().get("JavaLuan.java"); + if( fn == null ) { + try { + fn = new LuanJavaFunction(luan,JavaLuan.class.getMethod("java",Luan.class),null); + } catch(NoSuchMethodException e) { + throw new RuntimeException(e); + } + luan.registry().put("JavaLuan.java",fn); } + return fn; } private static void checkJava(Luan luan) throws LuanException { @@ -59,11 +64,11 @@ Constructor[] constructors = cls.getConstructors(); if( constructors.length > 0 ) { if( constructors.length==1 ) { - return new LuanJavaFunction(constructors[0],null); + return new LuanJavaFunction(luan,constructors[0],null); } else { List<LuanJavaFunction> fns = new ArrayList<LuanJavaFunction>(); for( Constructor constructor : constructors ) { - fns.add(new LuanJavaFunction(constructor,null)); + fns.add(new LuanJavaFunction(luan,constructor,null)); } return new AmbiguousJavaFunction(fns); } @@ -73,11 +78,11 @@ return new LuanJavaFunction(assertClass,new AssertClass(cls)); */ } else if( "luan_proxy".equals(name) ) { - return new LuanJavaFunction(luan_proxyMethod,st); + return new LuanJavaFunction(luan,luan_proxyMethod,st); } else { List<Member> members = getStaticMembers(cls,name); if( !members.isEmpty() ) { - return member(null,members); + return member(luan,null,members); } } } @@ -95,11 +100,11 @@ } else if( key instanceof String ) { String name = (String)key; if( "instanceof".equals(name) ) { - return new LuanJavaFunction(instanceOf,new InstanceOf(obj)); + return new LuanJavaFunction(luan,instanceOf,new InstanceOf(obj)); } else { List<Member> members = getMembers(cls,name); if( !members.isEmpty() ) { - return member(obj,members); + return member(luan,obj,members); } } } @@ -108,7 +113,7 @@ throw new LuanException( "invalid index '"+key+"' for java "+cls ); } - private static Object member(Object obj,List<Member> members) throws LuanException { + private static Object member(Luan luan,Object obj,List<Member> members) throws LuanException { try { if( members.size()==1 ) { Member member = members.get(0); @@ -120,13 +125,13 @@ return rtn instanceof Object[] ? Arrays.asList((Object[])rtn) : rtn; } else { Method method = (Method)member; - return new LuanJavaFunction(method,obj); + return new LuanJavaFunction(luan,method,obj); } } else { List<LuanJavaFunction> fns = new ArrayList<LuanJavaFunction>(); for( Member member : members ) { Method method = (Method)member; - fns.add(new LuanJavaFunction(method,obj)); + fns.add(new LuanJavaFunction(luan,method,obj)); } return new AmbiguousJavaFunction(fns); } @@ -309,7 +314,7 @@ return cls.isSynthetic(); } - public Object luan_proxy(final Luan luan,final LuanTable t) throws LuanException { + public Object luan_proxy(final LuanTable t) throws LuanException { return Proxy.newProxyInstance( cls.getClassLoader(), new Class[]{cls}, @@ -324,7 +329,7 @@ if( fnObj == null ) throw new NullPointerException("luan_proxy couldn't find method '"+name+"'"); LuanFunction fn = Luan.checkFunction(fnObj); - return Luan.first(fn.call(luan,args)); + return Luan.first(fn.call(args)); } } ); @@ -333,7 +338,7 @@ private static final Method luan_proxyMethod; static { try { - luan_proxyMethod = Static.class.getMethod("luan_proxy",Luan.class,LuanTable.class); + luan_proxyMethod = Static.class.getMethod("luan_proxy",LuanTable.class); luan_proxyMethod.setAccessible(true); } catch(NoSuchMethodException e) { throw new RuntimeException(e); @@ -361,11 +366,12 @@ } }; - private static class AmbiguousJavaFunction extends LuanFunction { - private final Map<Integer,List<LuanJavaFunction>> fnMap = new HashMap<Integer,List<LuanJavaFunction>>(); + private static final class AmbiguousJavaFunction extends LuanFunction { + private Map<Integer,List<LuanJavaFunction>> fnMap = new HashMap<Integer,List<LuanJavaFunction>>(); private List<LuanJavaFunction> varArgs = new ArrayList<LuanJavaFunction>(); AmbiguousJavaFunction(List<LuanJavaFunction> fns) { + super(true); for( LuanJavaFunction fn : fns ) { if( fn.isVarArgs() ) { varArgs.add(fn); @@ -382,18 +388,24 @@ Collections.sort(varArgs,varArgsSorter); } - @Override public Object call(Luan luan,Object[] args) throws LuanException { + @Override protected void completeClone(LuanFunction dc,LuanCloner cloner) { + AmbiguousJavaFunction clone = (AmbiguousJavaFunction)dc; + clone.fnMap = (Map)cloner.clone(fnMap); + clone.varArgs = (List)cloner.clone(varArgs); + } + + @Override public Object call(Object[] args) throws LuanException { List<LuanJavaFunction> list = fnMap.get(args.length); if( list != null ) { for( LuanJavaFunction fn : list ) { try { - return fn.rawCall(luan,args); + return fn.rawCall(args); } catch(IllegalArgumentException e) {} } } for( LuanJavaFunction fn : varArgs ) { try { - return fn.rawCall(luan,args); + return fn.rawCall(args); } catch(IllegalArgumentException e) {} } throw new LuanException("no method matched args: "+Arrays.asList(args));