Skip to content

Commit 79cfe3b

Browse files
hansonrhansonr
authored andcommitted
New transpiler adds optimization for no-finals lambda
lambda expressions val -> val.getEnd() lambda methods System.out::println will use a singleton class instance (unlike Java) if no final references are involved.
1 parent 44a20cd commit 79cfe3b

File tree

9 files changed

+38
-6
lines changed

9 files changed

+38
-6
lines changed
-32 Bytes
Binary file not shown.
235 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20190829124003
1+
20190907142751
-32 Bytes
Binary file not shown.
235 Bytes
Binary file not shown.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
20190829124003
1+
20190907142751

sources/net.sf.j2s.core/src/net/sf/j2s/core/Java2ScriptVisitor.java

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@
134134
import org.eclipse.jdt.core.dom.WhileStatement;
135135
import org.eclipse.jdt.core.dom.WildcardType;
136136

137+
// BH 2019.09.07 adds optimization for lambda methods that do not have finals
137138
// BH 2019.08.29 fix for boxing of binary representation 0b01... (Google Closure Compiler bug)
138139
// BH 2019.05.13 fix for Math.getExponent, ulp, nextDown, nextUp, nextAfter needing qualification
139140
// BH 2019.05.13 fix for Function reference in new Foo()::test(...)
@@ -163,6 +164,12 @@ public class Java2ScriptVisitor extends ASTVisitor {
163164
*/
164165
private static final boolean ALLOW_NEW_LAMBDA = false;
165166

167+
/**
168+
* If there are no finals for a lambda method, then we can reuse the object.
169+
* This can be huge for preventing repetitive object creation
170+
*/
171+
private static final boolean ALLOW_LAMBDA_OBJECT_REUSE = true;
172+
166173
private static final int NOT_LAMBDA = 0;
167174
private static final int LAMBDA_METHOD = 1;
168175
private static final int LAMBDA_CREATION = 3;
@@ -657,8 +664,10 @@ private String getClassJavaNameForType(Type type) {
657664
* anonymous class names
658665
* @param isLambda
659666
* @param isClassTrulyLocal
667+
*
668+
* @return anonymous name only if there are no finals
660669
*/
661-
private void processLocalInstance(ASTNode node, ASTNode anonymousClassDeclaration, ITypeBinding binding,
670+
private String processLocalInstance(ASTNode node, ASTNode anonymousClassDeclaration, ITypeBinding binding,
662671
ITypeBinding innerClass, String javaInnerClassName, int lambdaType, boolean isClassTrulyLocal) {
663672

664673
// In the case of local classes, the declaration is dissociated from the
@@ -701,6 +710,7 @@ private void processLocalInstance(ASTNode node, ASTNode anonymousClassDeclaratio
701710
anonymousSuperclassName, anonName);
702711
if (lambdaType != LAMBDA_METHOD && !isClassTrulyLocal)
703712
buffer.append(")"); // end of line (..., ...)
713+
return finals == null ? anonName : null;
704714
}
705715

706716
/**
@@ -6808,15 +6818,19 @@ private boolean addLambdaMethodReference(MethodReference node, Expression exp) {
68086818
*/
68096819
private boolean addLambda$class$Method(MethodReference node, ITypeBinding binding, Expression exp,
68106820
ITypeBinding declaringClass, boolean checkFinals) {
6821+
6822+
68116823
allowClazzNewLambda = (ALLOW_NEW_LAMBDA && getLastCharInBuffer() != '=');
68126824
int pt = buffer.length();
68136825
buffer.append("(function($class$){");
6814-
processLocalInstance(node, null, binding, null, null, LAMBDA_METHOD, false);
6826+
String anonName = processLocalInstance(node, null, binding, null, null, LAMBDA_METHOD, false);
68156827
buffer.append("})(");
68166828
appendFinalMethodQualifier(exp, declaringClass, null, FINAL_ESCAPECACHE | FINAL_LAMBDA);
68176829
buffer.append(")");
68186830
if (checkFinals && allowClazzNewLambda)
68196831
buffer.setLength(pt);
6832+
if (anonName != null && ALLOW_LAMBDA_OBJECT_REUSE)
6833+
addLambdaReuse(pt, anonName);
68206834
return !allowClazzNewLambda;
68216835

68226836
}
@@ -6871,12 +6885,28 @@ public boolean visit(LambdaExpression node) {
68716885
private boolean addLambda$class$Expr(LambdaExpression node, ITypeBinding binding, boolean checkFinals) {
68726886
allowClazzNewLambda = (ALLOW_NEW_LAMBDA && getLastCharInBuffer() != '=');
68736887
int pt = buffer.length();
6874-
processLocalInstance(node, null, binding, null, null, LAMBDA_EXPRESSION, false);
6888+
String anonName = processLocalInstance(node, null, binding, null, null, LAMBDA_EXPRESSION, false);
68756889
if (checkFinals && allowClazzNewLambda)
68766890
buffer.setLength(pt);
6891+
if (anonName != null && ALLOW_LAMBDA_OBJECT_REUSE)
6892+
addLambdaReuse(pt, anonName);
68776893
return !allowClazzNewLambda;
68786894
}
68796895

6896+
/**
6897+
* allow reuse of Lambda method and expression objects when they involve no finals
6898+
*
6899+
* @param pt
6900+
* @param anonName
6901+
*/
6902+
private void addLambdaReuse(int pt, String anonName) {
6903+
String tmp = buffer.substring(pt);
6904+
buffer.setLength(pt);
6905+
anonName = getFinalJ2SClassName(anonName, FINAL_P);
6906+
buffer.append("(" + anonName + "$||(" + anonName + "$=(")
6907+
.append(tmp).append(")))");
6908+
}
6909+
68806910
private char getLambdaType(ITypeBinding binding) {
68816911
String name = removeBracketsAndFixNullPackageName(getJavaClassNameQualified(binding));
68826912
if (!name.startsWith("java.util.function.") || name.indexOf("To") >= 0)
-32 Bytes
Binary file not shown.

sources/net.sf.j2s.java.core/srcjs/swingjs2.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14041,7 +14041,9 @@ Clazz.forName = function(name, initialize, loader, isQuiet) {
1404114041
isQuiet = true;
1404214042
var className = loader.baseClass.getName$(); // set in java.lang.Class.getClassLoader$()
1404314043
var i = className.lastIndexOf(".");
14044-
var name1 = className.substring(0, i + 1) + name;
14044+
var name1 = className.substring(0, i + 1);
14045+
if (name.indexOf(name1) != 0)
14046+
name1 += name;
1404514047
cl = Clazz._4Name(name1, null, null, false, initialize, true);
1404614048
} catch (e) {}
1404714049
}

0 commit comments

Comments
 (0)