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));