1 // Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL]
7 * Misc static methods used internally by the JS engine
10 // Package Helper Methods //////////////////////////////////////////////////////////////
12 private static Object wrapInt(int i) { return new Integer(i); }
13 static Object callMethodOnPrimitive(Object o, Object method, JS.Array args) {
14 int alength = args.length();
16 if(o instanceof Number) {
17 if(method.equals("toFixed")) throw new JS.Exn("toFixed() not implemented");
18 if(method.equals("toExponential")) throw new JS.Exn("toExponential() not implemented");
19 if(method.equals("toPrecision")) throw new JS.Exn("toPrecision() not implemented");
20 if(method.equals("toString")) {
21 int radix = alength >= 1 ? JS.toInt(args.elementAt(0)) : 10;
22 return Long.toString(((Number)o).longValue(),radix);
24 } else if(o instanceof Boolean) {
25 // No methods for Booleans
28 int slength = s.length();
29 if(method.equals("substring")) {
30 int a = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
31 int b = alength >= 2 ? JS.toInt(args.elementAt(1)) : slength;
32 if(a > slength) a = slength;
33 if(b > slength) b = slength;
36 if(a > b) { int tmp = a; a = b; b = tmp; }
37 return s.substring(a,b);
39 if(method.equals("charAt")) {
40 int p = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
41 if(p < 0 || p >= slength) return "";
42 return s.substring(p,p+1);
44 if(method.equals("charCodeAt")) {
45 int p = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
46 if(p < 0 || p >= slength) return new Double(Double.NaN);
47 return wrapInt(s.charAt(p));
49 if(method.equals("concat")) {
50 StringBuffer sb = new StringBuffer(slength*2).append(s);
51 for(int i=0;i<alength;i++) sb.append(args.elementAt(i));
54 if(method.equals("indexOf")) {
55 String search = alength >= 1 ? args.elementAt(0).toString() : "null";
56 int start = alength >= 2 ? JS.toInt(args.elementAt(1)) : 0;
57 // Java's indexOf handles an out of bounds start index, it'll return -1
58 return wrapInt(s.indexOf(search,start));
60 if(method.equals("lastIndexOf")) {
61 String search = alength >= 1 ? args.elementAt(0).toString() : "null";
62 int start = alength >= 2 ? JS.toInt(args.elementAt(1)) : 0;
63 // Java's indexOf handles an out of bounds start index, it'll return -1
64 return wrapInt(s.lastIndexOf(search,start));
66 if(method.equals("match")) {
67 return Regexp.stringMatch(s,args);
69 if(method.equals("replace")) {
70 return Regexp.stringReplace(s,args);
72 if(method.equals("search")) {
73 return Regexp.stringSearch(s,args);
75 if(method.equals("slice")) {
76 int a = alength >= 1 ? JS.toInt(args.elementAt(0)) : 0;
77 int b = alength >= 2 ? JS.toInt(args.elementAt(1)) : slength;
78 if(a < 0) a = slength + a;
79 if(b < 0) b = slength + b;
82 if(a > slength) a = slength;
83 if(b > slength) b = slength;
85 return s.substring(a,b);
87 if(method.equals("split")){
88 return Regexp.stringSplit(s,args);
90 if(method.equals("toLowerCase")) return s.toLowerCase();
91 if(method.equals("toUpperCase")) return s.toUpperCase();
92 if(method.equals("toString")) return s;
93 throw new JS.Exn("Attempted to call non-existent method: " + method);
96 static Object getFromPrimitive(Object o, Object key) {
97 boolean returnCallable = false;
98 if(o instanceof Boolean) {
99 // no properties for Booleans
100 } else if(o instanceof Number) {
101 if(key.equals("toPrecision") || key.equals("toExponential") || key.equals("toFixed"))
102 returnCallable = true;
104 if(!returnCallable) {
105 // the string stuff applies to everything
106 String s = o.toString();
108 if(key.equals("length")) return wrapInt(s.length());
110 // this is sort of ugly, but this list should never change
111 // These should provide a complete (enough) implementation of the ECMA-262 String object
112 if(key.equals("substring") || key.equals("charAt") || key.equals("charCodeAt") || key.equals("concat") ||
113 key.equals("indexOf") || key.equals("lastIndexOf") || key.equals("match") || key.equals("replace") ||
114 key.equals("seatch") || key.equals("slice") || key.equals("split") || key.equals("toLowerCase") ||
115 key.equals("toUpperCase") || key.equals("toString")
117 returnCallable = true;
120 final Object target = o;
121 final String method = key.toString();
122 return new JS.Callable() {
123 public Object call(JS.Array args) { return callMethodOnPrimitive(target,method,args); }
129 static class CallableStub extends JS.Callable {
130 private Object method;
132 public CallableStub(JS.Obj obj, Object method) { this.obj = obj; this.method = method; }
133 public Object call(JS.Array args) { return obj.callMethod(method,args,false); }