Skip to content

Commit 36e425a

Browse files
committed
1. Fixed bug that super calls in anonymous classes are not compiled
correctly 2. Improved anonymous class compiling, make it more JavaScript friendly 3. Pack rt.z.js for runtime core 4. Generate simpler HTML page
1 parent 41b67a8 commit 36e425a

File tree

11 files changed

+670
-150
lines changed

11 files changed

+670
-150
lines changed

sources/net.sf.j2s.core/src/net/sf/j2s/core/astvisitors/ASTScriptVisitor.java

Lines changed: 145 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ public boolean visit(AnonymousClassDeclaration node) {
189189
//
190190
String fullClassName = anonClassName;
191191
// String fullClassName = null;
192-
String packageName = ((ASTPackageVisitor) getAdaptable(ASTPackageVisitor.class)).getPackageName();
193192
// if (packageName != null && packageName.length() != 0) {
194193
// fullClassName = packageName + '.' + anonymousName;
195194
// } else {
@@ -202,9 +201,9 @@ public boolean visit(AnonymousClassDeclaration node) {
202201
// fullClassName = anonymousName;
203202
// }
204203

205-
buffer.append("(Clazz.isClassDefined (\"");
206-
buffer.append(fullClassName);
207-
buffer.append("\") ? 0 : ");
204+
// buffer.append("(Clazz.isClassDefined (\"");
205+
// buffer.append(fullClassName);
206+
// buffer.append("\") ? 0 : ");
208207

209208
StringBuffer tmpBuffer = buffer;
210209
buffer = methodBuffer;
@@ -213,6 +212,7 @@ public boolean visit(AnonymousClassDeclaration node) {
213212
buffer.append("cla$$.$");
214213
buffer.append(shortClassName);
215214
buffer.append("$ = function () {\r\n");
215+
buffer.append("if (Clazz.isClassDefined (\"").append(fullClassName).append("\")) ").append("return ").append(fullClassName).append(";\r\n");
216216

217217
buffer.append("Clazz.pu$h ();\r\n");
218218
buffer.append("cla$$ = ");
@@ -401,31 +401,46 @@ public boolean visit(AnonymousClassDeclaration node) {
401401
}
402402
}
403403

404+
buffer.append("var rc = cla$$;\r\n");
404405
buffer.append("cla$$ = Clazz.p0p ();\r\n");
405406

406407
typeVisitor.setClassName(oldClassName);
407408

408409
buffer.append(laterBuffer);
409410
laterBuffer = oldLaterBuffer;
410411

412+
buffer.append("return rc;\r\n");
411413
buffer.append("};\r\n");
412414

413415
String methods = methodBuffer.toString();
414416
methodBuffer = buffer;
415417
methodBuffer.append(methods);
416418
buffer = tmpBuffer;
417419

418-
buffer.append(packageName);
419-
buffer.append(".");
420-
idx = className.indexOf('$');
421-
if (idx != -1) {
422-
buffer.append(className.substring(0, idx));
423-
} else {
424-
buffer.append(className);
420+
ITypeBinding declareClass = binding;
421+
boolean prefixed = false;
422+
while (declareClass != null) {
423+
if (!declareClass.isAnonymous()) {
424+
buffer.append(declareClass.getQualifiedName());
425+
prefixed = true;
426+
break;
427+
}
428+
declareClass = declareClass.getDeclaringClass();
429+
}
430+
if (!prefixed) {
431+
String packageName = ((ASTPackageVisitor) getAdaptable(ASTPackageVisitor.class)).getPackageName();
432+
buffer.append(packageName);
433+
buffer.append(".");
434+
idx = className.indexOf('$');
435+
if (idx != -1) {
436+
buffer.append(className.substring(0, idx));
437+
} else {
438+
buffer.append(className);
439+
}
425440
}
426441
buffer.append(".$");
427442
buffer.append(shortClassName);
428-
buffer.append("$ ())");
443+
buffer.append("$ ()");
429444
/*
430445
* Anonymouse class won't have static members and methods and initializers
431446
*/
@@ -625,7 +640,9 @@ public boolean visit(ClassInstanceCreation node) {
625640
// StringBuffer tmpBuffer = buffer;
626641
// buffer = methodBuffer;
627642

628-
buffer.append("(");
643+
// buffer.append("(");
644+
buffer.append("Clazz.innerTypeInstance (");
645+
// buffer.append(anonClassName);
629646
// buffer.append(baseClassName);
630647
// buffer.append(".$");
631648
// buffer.append(shortClassName);
@@ -651,10 +668,8 @@ public boolean visit(ClassInstanceCreation node) {
651668
methodDeclareStack.push(binding.getKey());
652669
anonDeclare.accept(this);
653670
methodDeclareStack.pop();
654-
buffer.append(", ");
671+
// buffer.append(", ");
655672

656-
buffer.append("Clazz.innerTypeInstance (");
657-
buffer.append(anonClassName);
658673
buffer.append(", this, ");
659674
String scope = null;
660675
if (methodDeclareStack.size() != 0) {
@@ -689,7 +704,7 @@ public boolean visit(ClassInstanceCreation node) {
689704
currentBlockForVisit = lastCurrentBlock;
690705
//buffer.append("};\r\n");
691706
buffer.append(")"); // Clazz.innerTypeInstance
692-
buffer.append(")"); // end of line (..., ...)
707+
// buffer.append(")"); // end of line (..., ...)
693708

694709
// methodBuffer = buffer;
695710
// buffer = tmpBuffer;
@@ -2406,10 +2421,14 @@ private void appendFieldName(ASTNode parent, ITypeBinding declaringClass) {
24062421
String name = declaringClass.getQualifiedName();
24072422
boolean isThis = false;
24082423
int superLevel = 0;
2424+
ITypeBinding originalType = null;
24092425
while (parent != null) {
24102426
if (parent instanceof AbstractTypeDeclaration) {
24112427
AbstractTypeDeclaration type = (AbstractTypeDeclaration) parent;
24122428
ITypeBinding typeBinding = type.resolveBinding();
2429+
if (typeBinding != null && originalType == null) {
2430+
originalType = typeBinding;
2431+
}
24132432
superLevel++;
24142433
if (Bindings.isSuperType(declaringClass, typeBinding)) {
24152434
if (superLevel == 1) {
@@ -2423,6 +2442,9 @@ private void appendFieldName(ASTNode parent, ITypeBinding declaringClass) {
24232442
} else if (parent instanceof AnonymousClassDeclaration) {
24242443
AnonymousClassDeclaration type = (AnonymousClassDeclaration) parent;
24252444
ITypeBinding typeBinding = type.resolveBinding();
2445+
if (typeBinding != null && originalType == null) {
2446+
originalType = typeBinding;
2447+
}
24262448
superLevel++;
24272449
if (Bindings.isSuperType(declaringClass, typeBinding)) {
24282450
if (superLevel == 1) {
@@ -2465,7 +2487,23 @@ private void appendFieldName(ASTNode parent, ITypeBinding declaringClass) {
24652487
}
24662488
if (!isThis) {
24672489
buffer.append("this.callbacks[\"");
2468-
buffer.append(shortenQualifiedName(name));
2490+
//buffer.append(shortenQualifiedName(name));
2491+
StringBuilder dollarBuilder = new StringBuilder();
2492+
if (originalType != null) {
2493+
ITypeBinding thisDeclaringClass = originalType.getDeclaringClass();
2494+
while (thisDeclaringClass != null) {
2495+
dollarBuilder.append("$");
2496+
thisDeclaringClass = thisDeclaringClass.getDeclaringClass();
2497+
}
2498+
}
2499+
declaringClass = declaringClass.getDeclaringClass();
2500+
while (declaringClass != null) {
2501+
if (dollarBuilder.length() > 0) {
2502+
dollarBuilder.deleteCharAt(0);
2503+
}
2504+
declaringClass = declaringClass.getDeclaringClass();
2505+
}
2506+
buffer.append(dollarBuilder);
24692507
buffer.append("\"].");
24702508
}
24712509
}
@@ -2583,8 +2621,57 @@ public boolean visit(SuperFieldAccess node) {
25832621
}
25842622

25852623
public boolean visit(SuperMethodInvocation node) {
2586-
buffer.append("Clazz.superCall (this, ");
2587-
buffer.append(assureQualifiedName(shortenQualifiedName(getFullClassName())));
2624+
boolean extraSuper = false;
2625+
Name qualifier = node.getQualifier();
2626+
if (qualifier != null) {
2627+
String fullyQualifiedName = null;
2628+
ITypeBinding typeBinding = qualifier.resolveTypeBinding();
2629+
if (typeBinding != null) {
2630+
fullyQualifiedName = typeBinding.getQualifiedName();
2631+
}
2632+
if (fullyQualifiedName != null && !fullyQualifiedName.equals(getFullClassName())) {
2633+
ITypeBinding originalType = null;
2634+
ASTNode parent = node.getParent();
2635+
while (parent != null) {
2636+
if (parent instanceof AbstractTypeDeclaration) {
2637+
AbstractTypeDeclaration type = (AbstractTypeDeclaration) parent;
2638+
ITypeBinding parentTypeBinding = type.resolveBinding();
2639+
if (parentTypeBinding != null && originalType == null) {
2640+
originalType = parentTypeBinding;
2641+
}
2642+
} else if (parent instanceof AnonymousClassDeclaration) {
2643+
AnonymousClassDeclaration type = (AnonymousClassDeclaration) parent;
2644+
ITypeBinding parentTypeBinding = type.resolveBinding();
2645+
if (parentTypeBinding != null && originalType == null) {
2646+
originalType = parentTypeBinding;
2647+
}
2648+
}
2649+
parent = parent.getParent();
2650+
}
2651+
StringBuilder dollarBuilder = new StringBuilder();
2652+
if (originalType != null) {
2653+
ITypeBinding thisDeclaringClass = originalType.getDeclaringClass();
2654+
while (thisDeclaringClass != null) {
2655+
dollarBuilder.append("$");
2656+
thisDeclaringClass = thisDeclaringClass.getDeclaringClass();
2657+
}
2658+
}
2659+
ITypeBinding declaringClass = typeBinding.getDeclaringClass();
2660+
while (declaringClass != null) {
2661+
if (dollarBuilder.length() > 0) {
2662+
dollarBuilder.deleteCharAt(0);
2663+
}
2664+
declaringClass = declaringClass.getDeclaringClass();
2665+
}
2666+
buffer.append("Clazz.superCall (this.callbacks[\"").append(dollarBuilder).append("\"], ");
2667+
buffer.append(assureQualifiedName(shortenQualifiedName(fullyQualifiedName)));
2668+
extraSuper = true;
2669+
}
2670+
}
2671+
if (!extraSuper) {
2672+
buffer.append("Clazz.superCall (this, ");
2673+
buffer.append(assureQualifiedName(shortenQualifiedName(getFullClassName())));
2674+
}
25882675
buffer.append(", \"");
25892676
String name = getJ2SName(node.getName());
25902677
buffer.append(name);
@@ -2614,7 +2701,44 @@ public boolean visit(ThisExpression node) {
26142701
* or anonymous classes.
26152702
*/
26162703
buffer.append("this.callbacks[\"");
2617-
qualifier.accept(this);
2704+
//qualifier.accept(this);
2705+
ITypeBinding originalType = null;
2706+
ASTNode parent = node.getParent();
2707+
while (parent != null) {
2708+
if (parent instanceof AbstractTypeDeclaration) {
2709+
AbstractTypeDeclaration type = (AbstractTypeDeclaration) parent;
2710+
ITypeBinding parentTypeBinding = type.resolveBinding();
2711+
if (parentTypeBinding != null && originalType == null) {
2712+
originalType = parentTypeBinding;
2713+
}
2714+
} else if (parent instanceof AnonymousClassDeclaration) {
2715+
AnonymousClassDeclaration type = (AnonymousClassDeclaration) parent;
2716+
ITypeBinding parentTypeBinding = type.resolveBinding();
2717+
if (parentTypeBinding != null && originalType == null) {
2718+
originalType = parentTypeBinding;
2719+
}
2720+
}
2721+
parent = parent.getParent();
2722+
}
2723+
StringBuilder dollarBuilder = new StringBuilder();
2724+
if (originalType != null) {
2725+
ITypeBinding thisDeclaringClass = originalType.getDeclaringClass();
2726+
while (thisDeclaringClass != null) {
2727+
dollarBuilder.append("$");
2728+
thisDeclaringClass = thisDeclaringClass.getDeclaringClass();
2729+
}
2730+
}
2731+
ITypeBinding typeBinding = qualifier.resolveTypeBinding();
2732+
if (typeBinding != null) { // always true
2733+
ITypeBinding declaringClass = typeBinding.getDeclaringClass();
2734+
while (declaringClass != null) {
2735+
if (dollarBuilder.length() > 0) {
2736+
dollarBuilder.deleteCharAt(0);
2737+
}
2738+
declaringClass = declaringClass.getDeclaringClass();
2739+
}
2740+
}
2741+
buffer.append(dollarBuilder);
26182742
buffer.append("\"]");
26192743
}
26202744
} else {

sources/net.sf.j2s.core/src/net/sf/j2s/core/astvisitors/ASTVariableVisitor.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,17 @@ protected String listFinalVariables(List list, String seperator, String scope) {
143143
return "null";
144144
}
145145
StringBuffer buf = new StringBuffer();
146-
buf.append("Clazz.cloneFinals (");
146+
buf.append("{");
147147
for (Iterator iter = list.iterator(); iter.hasNext();) {
148148
ASTFinalVariable fv = (ASTFinalVariable) iter.next();
149149
String name = fv.variableName;
150150
if (fv.toVariableName != null) {
151151
name = fv.toVariableName;
152152
}
153-
buf.append("\"");
153+
//buf.append("\"");
154154
buf.append(name);
155-
buf.append("\", ");
155+
//buf.append("\": ");
156+
buf.append(": ");
156157
String methodScope = fv.methodScope;
157158
if (methodScope == null && scope == null) {
158159
buf.append(name);
@@ -167,7 +168,7 @@ protected String listFinalVariables(List list, String seperator, String scope) {
167168
buf.append(seperator);
168169
}
169170
}
170-
buf.append(")");
171+
buf.append("}");
171172
return buf.toString();
172173
}
173174

sources/net.sf.j2s.java.core/src/java/lang/AbstractStringBuilder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ public String substring(int start) {
534534
return "";
535535

536536
shared = true;
537-
return new String(start, count - start, value);
537+
return new String(value, start, count - start);
538538
}
539539
throw new StringIndexOutOfBoundsException(start);
540540
}
@@ -578,7 +578,7 @@ public String toString() {
578578
if (count >= 256 && count <= (value.length >> 1))
579579
return new String(value, 0, count);
580580
shared = true;
581-
return new String(0, count, value);
581+
return new String(value, 0, count);
582582
}
583583

584584
/**

sources/net.sf.j2s.java.core/src/java/lang/Class.js

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,13 @@ JavaObject.prototype.equals = function (obj) {
5858
return this == obj;
5959
};
6060

61+
Clazz.internalHashCode = 1;
62+
6163
JavaObject.prototype.hashCode = function () {
62-
try {
63-
return this.toString ().hashCode ();
64-
} catch (e) {
65-
var str = ":";
66-
for (var s in this) {
67-
str += s + ":"
68-
}
69-
return str.hashCode ();
64+
if (!this.internalHashCode) {
65+
this.internalHashCode = Clazz.internalHashCode++;
7066
}
67+
return this.internalHashCode;
7168
};
7269

7370
JavaObject.prototype.getClass = function () {
@@ -143,6 +140,10 @@ Clazz.getClassName = function (clazzHost) {
143140
return clazz.__CLASS_NAME__;
144141
}
145142
/*-# clazzStr -> Sc #-*/
143+
if (clazz.toString === Clazz.innerFunctions.toString) {
144+
// Avoid running into recursion of #toString calling #getClassName
145+
return "Object";
146+
}
146147
var clazzStr = clazz.toString ();
147148
var idx0 = clazzStr.indexOf ("function");
148149
if (idx0 == -1) {

0 commit comments

Comments
 (0)