renamed Script to JSU
[org.ibex.js.git] / src / org / ibex / js / JSReflection.java
index 69fb9b3..9c23830 100644 (file)
@@ -1,39 +1,46 @@
-// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL] 
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
 package org.ibex.js; 
 
-import org.ibex.util.*; 
-import java.io.*;
-import java.util.*;
 import java.lang.reflect.*;
 
 /** Automatic JS-ification via Reflection (not for use in the core) */
-public class JSReflection extends JS {
+public class JSReflection extends JS.Immutable {
+    private static final JS.Method METHOD = new JS.Method();
 
-    public static Object wrap(Object o) throws JSExn {
+    public static JS wrap(Object o) throws JSExn {
         if (o == null) return null;
-        if (o instanceof String) return o;
-        if (o instanceof Boolean) return o;
-        if (o instanceof Number) return o;
-        if (o instanceof JS) return o;
+        if (o instanceof String) return JSU.S((String)o);
+        if (o instanceof Boolean) return JSU.B(((Boolean)o).booleanValue());
+        if (o instanceof Number) return JSU.N((Number)o);
+        if (o instanceof JS) return (JS)o;
         if (o instanceof Object[]) {
             // FIXME: get element type here
         }
         throw new JSExn("Reflection object tried to return a " + o.getClass().getName());
     }
 
-    public static class Array extends JS {
+    public static class Array extends JS.Immutable {
         final Object[] arr;
         public Array(Object[] arr) { this.arr = arr; }
-        public Enumeration keys() throws JSExn { return new CounterEnumeration(arr.length); }
-        public Object get(Object key) throws JSExn { return wrap(arr[toInt(key)]); }
-        public void put(Object key, Object val) throws JSExn { throw new JSExn("can't write to org.ibex.js.Reflection.Array's"); }
+        // FEATURE: Add a JSCounterEnumeration
+        public Enumeration keys() throws JSExn {
+            return new Enumeration(null) {
+                private int n = 0;
+                public boolean _hasNext() { return n < arr.length; }
+                public JS _next() { return JSU.N(n++); }
+            };
+        }
+        public JS get(JS key) throws JSExn { return wrap(arr[JSU.toInt(key)]); }
     }
 
     // FIXME public static class Hash { }
     // FIXME public Enumeration keys() throws JSExn {  }
 
-    public Object get(Object key) throws JSExn {
-        String k = toString(key);
+    public JS get(JS key) throws JSExn {
+        String k = JSU.toString(key);
         try {
             Field f = this.getClass().getField(k);
             return wrap(f.get(this));
@@ -42,39 +49,33 @@ public class JSReflection extends JS {
         } catch (SecurityException nfe) { }
 
         try {
-            Method[] methods = this.getClass().getMethods();
+            java.lang.reflect.Method[] methods = this.getClass().getMethods();
             for(int i=0; i<methods.length; i++) if (methods[i].getName().equals(k)) return METHOD;
         } catch (SecurityException nfe) { }
         return null;
     }
 
-    public void put(Object key, Object val) throws JSExn {
+    public void put(JS key, JS val) throws JSExn {
         throw new JSExn("put() not supported yet");
     }
 
-    public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
-        String k = toString(method);
+    public JS call(JS method, JS[] args) throws JSExn {
+        String k = JSU.toString(method);
         try {
-            Method[] methods = this.getClass().getMethods();
+            java.lang.reflect.Method[] methods = this.getClass().getMethods();
             for(int j=0; j<methods.length; j++) {
-                if (methods[j].getName().equals(k) && methods[j].getParameterTypes().length == nargs) {
-                    Object[] args = new Object[nargs];
-                    for(int i = 0; i<args.length; i++) {
-                        if (i==0) args[i] = a0;
-                        else if (i==1) args[i] = a1;
-                        else if (i==2) args[i] = a2;
-                        else args[i] = rest[i-3];
-                    }
-                    return wrap(methods[j].invoke(this, args));
+                if (methods[j].getName().equals(k) &&
+                    methods[j].getParameterTypes().length == args.length) {
+                    return wrap(methods[j].invoke(this, (Object[])args));
                 }
             }
         } catch (IllegalAccessException nfe) {
         } catch (InvocationTargetException it) {
             Throwable ite = it.getTargetException();
             if (ite instanceof JSExn) throw ((JSExn)ite);
-            JS.warn(ite);
+            JSU.warn(ite);
             throw new JSExn("unhandled reflected exception: " + ite.toString());
         } catch (SecurityException nfe) { }
         throw new JSExn("called a reflection method with the wrong number of arguments");
-    }    
+    }
 }