Skip to content

Commit 8710578

Browse files
committed
Fixing bug that #castObjectAs method is generated for many unnecessary
method invocations. Add two options for j2s compiler: j2s.compiler.method.overloading=enable/disable, enable by default j2s.compiler.interface.casting=enable/disable, disable by default If method overloading is enabled(by default), #castObjectAs will be generated If interface casting is disabled(by default), method(IA) and method(IB) invocation won't be generated with castObjectAs, as it is unnecessary for most cases
1 parent 93ac00e commit 8710578

File tree

2 files changed

+59
-7
lines changed

2 files changed

+59
-7
lines changed

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

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,26 @@ public class ASTScriptVisitor extends ASTJ2SDocVisitor {
9292

9393
protected AbstractTypeDeclaration rootTypeNode;
9494

95+
protected boolean methodOverloadingSupported = true;
96+
97+
protected boolean interfaceCastingSupported = false;
98+
99+
public boolean isMethodOverloadingSupported() {
100+
return methodOverloadingSupported;
101+
}
102+
103+
public void setSupportsMethodOverloading(boolean recognizeMethodOverloading) {
104+
methodOverloadingSupported = recognizeMethodOverloading;
105+
}
106+
107+
public boolean isInterfaceCastingSupported() {
108+
return interfaceCastingSupported;
109+
}
110+
111+
public void setSupportsInterfaceCasting(boolean recognizeInterfaceCasting) {
112+
interfaceCastingSupported = recognizeInterfaceCasting;
113+
}
114+
95115
public boolean isMethodRegistered(String methodName) {
96116
return ((ASTMethodVisitor) getAdaptable(ASTMethodVisitor.class)).isMethodRegistered(methodName);
97117
}
@@ -748,6 +768,7 @@ String[] getParameterSimilarities(ITypeBinding[] params1, ITypeBinding[] params2
748768
} else if (t1.isArray()) {
749769
if (!t2.isArray()) return null;
750770
/*
771+
* TODO:
751772
* Current Java2Script does not distinguish different array types.
752773
*
753774
ITypeBinding cType1 = t1.getComponentType();
@@ -758,9 +779,27 @@ String[] getParameterSimilarities(ITypeBinding[] params1, ITypeBinding[] params2
758779
}
759780
// */
760781
} else {
761-
if (t1 != t2 && !t2.isCastCompatible(t1)) return null;
762782
if (t1 != t2) {
763-
result[i] = t1.getQualifiedName();
783+
// In most cases, different interfaces means different method signatures, no needs of casting
784+
if (!interfaceCastingSupported && t1.isInterface() && t2.isInterface() && !t1.isSubTypeCompatible(t2)) {
785+
return null;
786+
}
787+
if (!t2.isCastCompatible(t1)) {
788+
return null;
789+
} else {
790+
/*
791+
* B(Object) and B(Event)
792+
* C extends B with
793+
* C(Event) {
794+
* super(event)
795+
* }
796+
* There should be no needs of casting for super constructor invocation
797+
*/
798+
if (!t1.isInterface() && !t2.isInterface() && "java.lang.Object".equals(t2.getQualifiedName())) {
799+
return null;
800+
}
801+
result[i] = t1.getQualifiedName();
802+
}
764803
}
765804
}
766805
}
@@ -869,6 +908,10 @@ protected void visitMethodParameterList(ITypeBinding nodeTypeBinding, List argum
869908
}
870909
ITypeBinding[] parameterTypes = methodDeclaration.getParameterTypes();
871910
String methodName = methodDeclaration.getName();
911+
boolean ignoringCasting = !methodOverloadingSupported;
912+
if (declaringClass.getBinaryName().equals("java.io.PrintStream") && methodName.startsWith("print")) {
913+
ignoringCasting = true;
914+
}
872915
int argSize = arguments.size();
873916
for (int i = 0; i < parameterTypes.length; i++) {
874917
boolean isVarArgs = false;
@@ -890,12 +933,12 @@ protected void visitMethodParameterList(ITypeBinding nodeTypeBinding, List argum
890933
buffer.append(prefix);
891934
alreadyPrefixed = true;
892935
}
893-
if (!isVarArgs && ambitiousResult != null && ambitiousResult[i] != null) {
894-
buffer.append("Clazz.castObjectAs(");
895-
}
896936
String parameterTypeName = null;
897937
if (parameterTypes != null) {
898-
parameterTypeName = parameterTypes[i].getName();
938+
parameterTypeName = parameterTypes[i].getQualifiedName();
939+
}
940+
if (!isVarArgs && !ignoringCasting && ambitiousResult != null && ambitiousResult[i] != null) {
941+
buffer.append("Clazz.castObjectAs(");
899942
}
900943
if (isVarArgs) {
901944
buffer.append("[");
@@ -910,7 +953,7 @@ protected void visitMethodParameterList(ITypeBinding nodeTypeBinding, List argum
910953
} else {
911954
ASTNode element = (ASTNode) arguments.get(i);
912955
visitArgumentItem(element, clazzName, methodName, parameterTypeName, i);
913-
if (ambitiousResult != null && ambitiousResult[i] != null) {
956+
if (!ignoringCasting && ambitiousResult != null && ambitiousResult[i] != null) {
914957
String typeName = ambitiousResult[i];
915958
if (typeName.length() == 0) {
916959
ITypeBinding paramType = parameterTypes[i];
@@ -3632,6 +3675,11 @@ public boolean visit(TypeDeclaration node) {
36323675
visitor = new ASTScriptVisitor(); // Default visitor
36333676
}
36343677
visitor.rootTypeNode = node;
3678+
visitor.methodOverloadingSupported = this.methodOverloadingSupported;
3679+
visitor.interfaceCastingSupported = this.interfaceCastingSupported;
3680+
visitor.supportsObjectStaticFields = this.supportsObjectStaticFields;
3681+
visitor.setDebugging(this.isDebugging());
3682+
((ASTVariableVisitor) visitor.getAdaptable(ASTVariableVisitor.class)).setToCompileVariableName(((ASTVariableVisitor) this.getAdaptable(ASTVariableVisitor.class)).isToCompileVariableName());
36353683
String className = typeVisitor.getClassName();
36363684
String visitorClassName = null;
36373685
if (node.getParent() instanceof TypeDeclarationStatement) {

sources/net.sf.j2s.core/src/net/sf/j2s/core/compiler/Java2ScriptCompiler.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ public void run() {
218218
visitor = new SWTScriptVisitor();
219219
}
220220
}
221+
boolean ignoreMethodOverloading = !("enable".equals(props.getProperty("j2s.compiler.method.overloading")));
222+
visitor.setSupportsMethodOverloading(!ignoreMethodOverloading);
223+
boolean supportsInterfaceCasting = "enable".equals(props.getProperty("j2s.compiler.interface.casting")); // if not set explicitly, it is not supported
224+
visitor.setSupportsInterfaceCasting(supportsInterfaceCasting);
221225
boolean objectStaticFields = "enable".equals(props.getProperty("j2s.compiler.static.quirks"));
222226
visitor.setSupportsObjectStaticFields(objectStaticFields);
223227
boolean isDebugging = "debug".equals(props.getProperty("j2s.compiler.mode"));

0 commit comments

Comments
 (0)