1.1 --- a/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Sun Dec 02 14:01:17 2012 +0100
1.2 +++ b/vm/src/main/java/org/apidesign/vm4brwsr/ByteCodeToJavaScript.java Tue Dec 04 11:21:10 2012 +0100
1.3 @@ -82,6 +82,10 @@
1.4 return null;
1.5 }
1.6 }
1.7 + String[] proto = findAnnotation(arrData, jc,
1.8 + "org.apidesign.bck2brwsr.core.JavaScriptPrototype",
1.9 + "container", "prototype"
1.10 + );
1.11 StringArray toInitilize = new StringArray();
1.12 final String className = className(jc);
1.13 out.append("\n\n").append(assignClass(className));
1.14 @@ -92,28 +96,41 @@
1.15 out.append("\n CLS.").append(v.getName()).append(initField(v));
1.16 }
1.17 }
1.18 - // ClassName sc = jc.getSuperClass();
1.19 - String sc = jc.getSuperClassName(); // with _
1.20 - if (sc != null) {
1.21 + if (proto == null) {
1.22 + String sc = jc.getSuperClassName(); // with _
1.23 out.append("\n var pp = ").
1.24 append(sc.replace('/', '_')).append("(true);");
1.25 out.append("\n var p = CLS.prototype = pp;");
1.26 + out.append("\n var c = p;");
1.27 out.append("\n var sprcls = pp.constructor.$class;");
1.28 } else {
1.29 - out.append("\n var p = CLS.prototype;");
1.30 + out.append("\n var p = CLS.prototype = ").append(proto[1]).append(";");
1.31 + out.append("\n var c = ").append(proto[0]).append(";");
1.32 out.append("\n var sprcls = null;");
1.33 }
1.34 for (MethodData m : jc.getMethods()) {
1.35 + byte[] onlyArr = m.findAnnotationData(true);
1.36 + String[] only = findAnnotation(onlyArr, jc,
1.37 + "org.apidesign.bck2brwsr.core.JavaScriptOnly",
1.38 + "name", "value"
1.39 + );
1.40 + if (only != null) {
1.41 + if (only[0] != null && only[1] != null) {
1.42 + out.append("\n p.").append(only[0]).append(" = ")
1.43 + .append(only[1]).append(";");
1.44 + }
1.45 + continue;
1.46 + }
1.47 if (m.isStatic()) {
1.48 - generateStaticMethod("\n p.", m, toInitilize);
1.49 + generateStaticMethod("\n c.", m, toInitilize);
1.50 } else {
1.51 - generateInstanceMethod("\n p.", m);
1.52 + generateInstanceMethod("\n c.", m);
1.53 }
1.54 }
1.55 - out.append("\n p.constructor = CLS;");
1.56 - out.append("\n p.$instOf_").append(className).append(" = true;");
1.57 + out.append("\n c.constructor = CLS;");
1.58 + out.append("\n c.$instOf_").append(className).append(" = true;");
1.59 for (String superInterface : jc.getSuperInterfaces()) {
1.60 - out.append("\n p.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
1.61 + out.append("\n c.$instOf_").append(superInterface.replace('/', '_')).append(" = true;");
1.62 }
1.63 out.append("\n CLS.$class = java_lang_Class(true);");
1.64 out.append("\n CLS.$class.jvmName = '").append(jc.getClassName()).append("';");
1.65 @@ -131,6 +148,18 @@
1.66 out.append("\n return new CLS();");
1.67 out.append("\n }");
1.68 for (FieldData v : jc.getFields()) {
1.69 + byte[] onlyArr = v.findAnnotationData(true);
1.70 + String[] only = findAnnotation(onlyArr, jc,
1.71 + "org.apidesign.bck2brwsr.core.JavaScriptOnly",
1.72 + "name", "value"
1.73 + );
1.74 + if (only != null) {
1.75 + if (only[0] != null && only[1] != null) {
1.76 + out.append("\n p.").append(only[0]).append(" = ")
1.77 + .append(only[1]).append(";");
1.78 + }
1.79 + continue;
1.80 + }
1.81 if (!v.isStatic()) {
1.82 out.append("\n this.fld_").
1.83 append(v.getName()).append(initField(v));
1.84 @@ -153,7 +182,7 @@
1.85 StringBuilder argsCnt = new StringBuilder();
1.86 final String mn = findMethodName(m, argsCnt);
1.87 out.append(prefix).append(mn).append(" = function");
1.88 - if (mn.equals("classV")) {
1.89 + if (mn.equals("class__V")) {
1.90 toInitilize.add(className(jc) + "(false)." + mn);
1.91 }
1.92 out.append('(');
1.93 @@ -782,6 +811,7 @@
1.94 int i = 0;
1.95 Boolean count = null;
1.96 boolean array = false;
1.97 + sig.append("__");
1.98 int firstPos = sig.length();
1.99 while (i < descriptor.length()) {
1.100 char ch = descriptor.charAt(i++);
1.101 @@ -792,9 +822,6 @@
1.102 case ')':
1.103 count = false;
1.104 continue;
1.105 - case 'A':
1.106 - array = true;
1.107 - break;
1.108 case 'B':
1.109 case 'C':
1.110 case 'D':
1.111 @@ -805,7 +832,7 @@
1.112 case 'Z':
1.113 if (count) {
1.114 if (array) {
1.115 - sig.append('A');
1.116 + sig.append("_3");
1.117 }
1.118 sig.append(ch);
1.119 if (ch == 'J' || ch == 'D') {
1.120 @@ -817,7 +844,7 @@
1.121 hasReturnType[0] = true;
1.122 sig.insert(firstPos, ch);
1.123 if (array) {
1.124 - sig.insert(firstPos, 'A');
1.125 + sig.insert(firstPos, "_3");
1.126 }
1.127 }
1.128 array = false;
1.129 @@ -829,33 +856,47 @@
1.130 continue;
1.131 case 'L':
1.132 int next = descriptor.indexOf(';', i);
1.133 + String realSig = mangleSig(descriptor, i - 1, next + 1);
1.134 if (count) {
1.135 if (array) {
1.136 - sig.append('A');
1.137 + sig.append("_3");
1.138 }
1.139 - sig.append(ch);
1.140 - sig.append(descriptor.substring(i, next).replace('/', '_'));
1.141 + sig.append(realSig);
1.142 cnt.append('0');
1.143 } else {
1.144 - sig.insert(firstPos, descriptor.substring(i, next).replace('/', '_'));
1.145 - sig.insert(firstPos, ch);
1.146 + sig.insert(firstPos, realSig);
1.147 if (array) {
1.148 - sig.insert(firstPos, 'A');
1.149 + sig.insert(firstPos, "_3");
1.150 }
1.151 hasReturnType[0] = true;
1.152 }
1.153 i = next + 1;
1.154 continue;
1.155 case '[':
1.156 - //arrays++;
1.157 + array = true;
1.158 continue;
1.159 default:
1.160 - break; // invalid character
1.161 + throw new IllegalStateException("Invalid char: " + ch);
1.162 }
1.163 }
1.164 }
1.165 +
1.166 + private static String mangleSig(String txt, int first, int last) {
1.167 + StringBuilder sb = new StringBuilder();
1.168 + for (int i = first; i < last; i++) {
1.169 + final char ch = txt.charAt(i);
1.170 + switch (ch) {
1.171 + case '/': sb.append('_'); break;
1.172 + case '_': sb.append("_1"); break;
1.173 + case ';': sb.append("_2"); break;
1.174 + case '[': sb.append("_3"); break;
1.175 + default: sb.append(ch); break;
1.176 + }
1.177 + }
1.178 + return sb.toString();
1.179 + }
1.180
1.181 - private String findMethodName(MethodData m, StringBuilder cnt) {
1.182 + private static String findMethodName(MethodData m, StringBuilder cnt) {
1.183 StringBuilder name = new StringBuilder();
1.184 if ("<init>".equals(m.getName())) { // NOI18N
1.185 name.append("cons"); // NOI18N
1.186 @@ -866,11 +907,11 @@
1.187 }
1.188
1.189 boolean hasReturn[] = { false };
1.190 - countArgs(findDescriptor(m.getInternalSig()), hasReturn, name, cnt);
1.191 + countArgs(m.getInternalSig(), hasReturn, name, cnt);
1.192 return name.toString();
1.193 }
1.194
1.195 - private String findMethodName(String[] mi, StringBuilder cnt, boolean[] hasReturn) {
1.196 + static String findMethodName(String[] mi, StringBuilder cnt, boolean[] hasReturn) {
1.197 StringBuilder name = new StringBuilder();
1.198 String descr = mi[2];//mi.getDescriptor();
1.199 String nm= mi[1];
1.200 @@ -879,7 +920,7 @@
1.201 } else {
1.202 name.append(nm);
1.203 }
1.204 - countArgs(findDescriptor(descr), hasReturn, name, cnt);
1.205 + countArgs(descr, hasReturn, name, cnt);
1.206 return name.toString();
1.207 }
1.208
1.209 @@ -983,10 +1024,6 @@
1.210 return s;
1.211 }
1.212
1.213 - private String findDescriptor(String d) {
1.214 - return d.replace('[', 'A');
1.215 - }
1.216 -
1.217 private boolean javaScriptBody(String prefix, MethodData m, boolean isStatic) throws IOException {
1.218 byte[] arr = m.findAnnotationData(true);
1.219 if (arr == null) {