135135
136136// TODO: superclass inheritance for JAXB XmlAccessorType
137137
138+ //BH 2020.03.20 -- 3.2.9-v1c more efficient static call from 3.2.9-v1a
138139//BH 2020.02.26 -- 3.2.9-v1b allows (byte) = (byte) to not use |0
139140//BH 2020.02.20 -- 3.2.9-v1a order of 1st two parameters in new_ should be reversed
140141//BH 2020.02.18 -- 3.2.8-v2 fixes no-argument call to varargs constructor
@@ -344,7 +345,7 @@ public class Java2ScriptVisitor extends ASTVisitor {
344345// private static Map<String, Map<String, List<String[]>>> syntheticClassMethodNameMap = new HashMap<String, Map<String, List<String[]>>>();
345346// private static Map<String, Map<String, Object>> genericClassTypes = new HashMap<String, Map<String, Object>>();
346347
347- private static Map <String , String > htStrLitCache = new Hashtable <>();
348+ private static Map <String , String > htStringLiteralCache = new Hashtable <>();
348349
349350 /**
350351 * includes @j2sDebug blocks; from j2s.compiler.mode=debug in .j2s
@@ -368,7 +369,7 @@ public static void setAnnotating(String ignoredAnnotations) {
368369 }
369370
370371 static void startCleanBuild () {
371- htStrLitCache = new Hashtable <>();
372+ htStringLiteralCache = new Hashtable <>();
372373 }
373374
374375 /**
@@ -466,6 +467,7 @@ private Java2ScriptVisitor setInnerGlobals(Java2ScriptVisitor parent, ASTNode no
466467 package_htIncludeNames = parent .package_htIncludeNames ;
467468 package_includeCount = parent .package_includeCount ;
468469 package_includes = parent .package_includes ;
470+ package_haveStaticArgsReversal = parent .package_haveStaticArgsReversal ;
469471 package_mapBlockJavadoc = parent .package_mapBlockJavadoc ;
470472
471473 // final and effectively final references
@@ -633,6 +635,15 @@ int getPrimitiveDefaultType(Code code) {
633635
634636 private ArrayList <String > applets , apps ;
635637
638+ private boolean isUserApplet ;
639+
640+ private int class_localType = NOT_LOCAL ;
641+
642+ /**
643+ * flag to indicate that we need the $I$(i,n,m) definition.
644+ */
645+ private boolean [] package_haveStaticArgsReversal = new boolean [] {false };
646+
636647 private void addApplication () {
637648 if (apps == null )
638649 apps = new ArrayList <String >();
@@ -663,10 +674,6 @@ public ArrayList<String> getAppList(boolean isApplets) {
663674 return (isApplets ? applets : apps );
664675 }
665676
666- private boolean isUserApplet ;
667-
668- private int class_localType = NOT_LOCAL ;
669-
670677 public boolean visit (CompilationUnit node ) {
671678 resetPrivateVars ();
672679 return true ;
@@ -846,22 +853,22 @@ private void addConstructor(ITypeBinding javaClass,
846853 IMethodBinding constructorMethodDeclaration = (constructorMethodBinding == null ? null
847854 : constructorMethodBinding .getMethodDeclaration ());
848855 addMethodParameterList (arguments , constructorMethodDeclaration , prefix , postfix , METHOD_CONSTRUCTOR );
849- checkStaticParams (pt , pt1 , true );
856+ checkStaticParams2 (pt , pt1 , true );
850857 }
851858 buffer .append (")" );
852859 }
853860
854861 /**
855- * 3.2.9.v1
862+ * 3.2.9.v1a
856863 *
857864 * Static method invocations must process parameters before initializing the method's class
858865 * if any parameter either calls a method or defines a static variable. We do this by changing
859866 *
860- * $I(3).xxxx(x,y,z)
867+ * $I$ (3).xxxx(x,y,z)
861868 *
862869 * to
863870 *
864- * (function(a,b){b.apply(null,a)})([x,y,z],$I(3).xxxx)
871+ * (function(a,b){b.apply(null,a)})([x,y,z],$I$ (3).xxxx)
865872 *
866873 * In addition, for constructors, Clazz.new_ needs to have the parameters as the first
867874 * parameter and the constructor method as the second parameter:
@@ -875,10 +882,10 @@ private void addConstructor(ITypeBinding javaClass,
875882 */
876883 private void checkStaticParams (int pt , int pt1 , boolean isConstructor ) {
877884 String args ;
878- // must switch from Clazz.new_($I(3).xxxx,[x,y,z] to Clazz.new([x,y,z],$I(3).xxxx
879- // ............................^pt.......^pt1
880- // must switch from $I(3).xxxx(x,y,z to (function(a,f){return f.apply(null,a)})([x,y,z],$I(3).xxxx
881- // .................^pt.......^pt1
885+ // must switch from Clazz.new_($I$ (3).xxxx,[x,y,z] to Clazz.new([x,y,z],$I$ (3).xxxx
886+ // ............................^pt........ ^pt1
887+ // must switch from $I$ (3).xxxx(x,y,z to (function(a,f){return f.apply(null,a)})([x,y,z],$I$ (3).xxxx
888+ // .................^pt........ ^pt1
882889 if (pt1 == pt
883890 || buffer .charAt (pt ) != '$'
884891 || (args = buffer .substring (pt1 + 1 )).indexOf ("(" ) < 0 && args .indexOf ("=" ) < 0 )
@@ -891,6 +898,53 @@ private void checkStaticParams(int pt, int pt1, boolean isConstructor) {
891898 buffer .append (args ).append ("," ).append (f );
892899 }
893900
901+
902+ /**
903+ * 3.2.9.v1c
904+ *
905+ * Static method invocations must process parameters before initializing the method's class
906+ * if any parameter either calls a method or defines a static variable. We do this by changing
907+ *
908+ * $I$(3).xxxx(x,y,z)
909+ *
910+ * to
911+ *
912+ * $I$(3,"xxxx",[x,y,z])
913+ *
914+ * In addition, for constructors, Clazz.new_ needs to have the parameters as the first
915+ * parameter and the constructor method as the second parameter:
916+ *
917+ * Clazz.new_([args],constr)
918+ *
919+ * The method invocation has not been closed at this point.
920+ *
921+ * @param pt start of method name
922+ * @param pt1 end of method name
923+ */
924+ private void checkStaticParams2 (int pt , int pt1 , boolean isConstructor ) {
925+ String args ;
926+ // must switch from Clazz.new_($I$(3).xxxx,[x,y,z] to Clazz.new([x,y,z],$I$(3).xxxx
927+ // ............................^pt........^pt1
928+ // must switch from $I$(3).xxxx(x,y,z to $I$(3,"xxxx",[x,y,z])
929+ // .................fffffffffff
930+ // .................^pt..^fpt..^pt1
931+ if (pt1 == pt
932+ || buffer .charAt (pt ) != '$'
933+ || (args = buffer .substring (pt1 + 1 )).indexOf ("(" ) < 0 && args .indexOf ("=" ) < 0 )
934+ return ;
935+ String f = buffer .substring (pt , pt1 );
936+ buffer .setLength (pt );
937+ if (isConstructor ) {
938+ buffer .append (args ).append ("," ).append (f );
939+ } else {
940+ package_haveStaticArgsReversal [0 ] = true ;
941+ int fpt = f .indexOf (")" );
942+ buffer .append (f .substring (0 , fpt ))
943+ .append (",\" " ).append (f .substring (fpt +2 )).append ("\" ,[" )
944+ .append (args ).append ("]" );
945+ }
946+ }
947+
894948 /**
895949 * Start a new Clazz.new_(cl,[args],innerClass) call for class creation or inner classes
896950 * and adds the construtor reference.
@@ -1592,7 +1646,7 @@ private boolean addMethodInvocation(SimpleName javaQualifier, List<?> arguments,
15921646 buffer .append ("(" );
15931647 addMethodParameterList (arguments , mBinding , null , null , isIndexOf ? METHOD_INDEXOF : METHOD_NOTSPECIAL );
15941648 if (isStatic && lambdaArity < 0 && term == ")" ) {
1595- checkStaticParams (pt , pt1 , false );
1649+ checkStaticParams2 (pt , pt1 , false );
15961650 }
15971651 buffer .append (term );
15981652 return true ;
@@ -2789,7 +2843,7 @@ private void addInnerTypeInstance(ASTNode node, ITypeBinding binding, ITypeBindi
27892843 METHOD_CONSTRUCTOR );
27902844 }
27912845 buffer .append ("]" );
2792- checkStaticParams (pt , pt1 , true );
2846+ checkStaticParams2 (pt , pt1 , true );
27932847
27942848 // an anonymous class will be calling a constructor in another
27952849 // class, so we need to indicate its actual call explicitly with a third parameter
@@ -3848,9 +3902,9 @@ public boolean visit(StringLiteral node) {
38483902 buffer .append (s );
38493903 } else {
38503904 // \1 doesn't work for JavaScript strict mode
3851- String v = htStrLitCache .get (s );
3905+ String v = htStringLiteralCache .get (s );
38523906 if (v == null ) {
3853- htStrLitCache .put (s , v = !po0 .matcher (s ).find () ? s : replaceOctal (s ));
3907+ htStringLiteralCache .put (s , v = !po0 .matcher (s ).find () ? s : replaceOctal (s ));
38543908 }
38553909 buffer .append (v );
38563910 }
@@ -5055,7 +5109,7 @@ String getFinalJ2SClassNameQualifier(Name methodQualifier, ITypeBinding declarin
50555109 *
50565110 * For Clazz.newClass we want an array if the superclass is an inner class so
50575111 * that the outer class is guaranteed to be loaded first. The same goes for
5058- * $ I$[] dynamic class loading and interfaces, (but interfaces are handled
5112+ * I$[] dynamic class loading and interfaces, (but interfaces are handled
50595113 * differently).
50605114 *
50615115 * @param packageName Java package name or "_"
@@ -6104,9 +6158,20 @@ public List<String> getElementList() {
61046158 header = header
61056159 .replace (",I$=[]" ,
61066160 privateVarString + (package_includes .length () == 0 ? ""
6107- : package_includes .append ("]]," + "$I$=function(i,n){return"
6108- + "(i=(I$[i]||(I$[i]=Clazz.load(I$[0][i])))),"
6109- + "!n&&i.$load$&&Clazz.load(i,2)," + "i}" )));
6161+ : package_includes .append ("]]," + "$I$=function(i,n,m){return("
6162+ + (package_haveStaticArgsReversal [0 ] ? "m?(i=function(f,a){return f.apply(null,a)}($I$(i)[n],m)):" : "" )
6163+ + "((i=(I$[i]||(I$[i]=Clazz.load(I$[0][i]))))"
6164+ + ",!n&&i.$load$&&Clazz.load(i,2)))"
6165+ + ",i};"
6166+ //
6167+ //
6168+ //
6169+ // "$I$=function(i,n){return"
6170+ // + "(i=(I$[i]||(I$[i]=Clazz.load(I$[0][i])))),"
6171+ // + "!n&&i.$load$&&Clazz.load(i,2)," + "i}"
6172+ //
6173+ //
6174+ )));
61106175 for (int i = 1 ; i < parts .length ; i ++) {
61116176 js = parts [i ];
61126177 int pt = js .indexOf ("\n " );
0 commit comments