122122import org .eclipse .jdt .core .dom .WhileStatement ;
123123import org .eclipse .jdt .core .dom .WildcardType ;
124124
125+ // BH 6/23/2018 -- synchronized(a = new Object()) {...} ---> if(!(a = new Object()) {throw new NullPointerException()}else{...}
126+ // BH 6/21/2018 -- CharSequence.subSequence() should be defined both subSequence$I$I and subSequence
127+ // BH 6/20/2018 -- fixes for (int var : new int[] {3,4,5}) becoming for var var
128+ // BH 6/19/2018 -- adds .j2s j2s.class.replacements=org.apache.log4j.->jalview.javascript.log4j.;
125129// BH 5/15/2018 -- fix for a[pt++] |= 3 incrementing pt twice and disregarding a[][] (see test/Test_Or.java)
126130// BH 3/27/2018 -- fix for anonymous inner classes of inner classes not having this.this$0
127131// BH 1/5/2018 -- @j2sKeep removed; refactored into one class
@@ -337,8 +341,8 @@ public void endVisit(Block node) {
337341 // look for trailing j2sNative block just before the end of a block
338342 getJ2sJavadoc (node , false );
339343 buffer .append ("}" );
340- clearVariables (getVariableList ( 'f' ) );
341- clearVariables (getVariableList ( 'n' ) );
344+ clearVariables ('f' );
345+ clearVariables ('n' );
342346 blockLevel --;
343347 super .endVisit (node );
344348 }
@@ -494,8 +498,10 @@ public boolean visit(EmptyStatement node) {
494498
495499 public boolean visit (EnhancedForStatement node ) {
496500 SimpleName name = node .getParameter ().getName ();
497- String varName = name .getIdentifier ();
498- writeReplaceV ("for (var V, $V = " , "V" , varName );
501+ String varName = getQualifiedSimpleName (name );
502+ buffer .append ("for (var " );
503+ acceptVariableFinal (name , 1 );
504+ writeReplaceV (", $V = " , "V" , varName );
499505 Expression exp = node .getExpression ();
500506 ITypeBinding typeBinding = exp .resolveTypeBinding ();
501507 if (typeBinding .isArray ()) {
@@ -671,8 +677,6 @@ public boolean visit(MethodDeclaration node) {
671677 buffer .append ("alert('native method must be replaced! " + key + "');\r \n " );
672678 log ("native: " + key );
673679 }
674- // didn't we just find out that there was nothing to do?
675- // addNativeJavadoc(node.getJavadoc(), null);
676680 buffer .append ("}\r \n " );
677681 // clearVariables(getVariableList('n'));
678682 // blockLevel--;
@@ -688,16 +692,33 @@ public boolean visit(MethodDeclaration node) {
688692 public void endVisit (MethodDeclaration node ) {
689693 if (NativeDoc .checkj2sIgnore (node ))
690694 return ;
695+ removeVariableFinals (node );
696+ super .endVisit (node );
697+ }
698+
699+ private void acceptVariableFinal (SimpleName name , int offset ) {
700+ IBinding binding = name .resolveBinding ();
701+ if (binding != null ) {
702+ String identifier = name .getIdentifier ();
703+ int level = blockLevel + offset ;
704+ VariableAdapter .FinalVariable f = new VariableAdapter .FinalVariable (level , identifier ,
705+ methodDeclareNameStack .size () == 0 ? null : methodDeclareNameStack .peek ());
706+ addVariable (f , identifier , binding );
707+ //buffer.append("/*blockLevel " + blockLevel + " level " + level + "*/");
708+ }
709+ name .accept (this );
710+ }
711+
712+ private void removeVariableFinals (MethodDeclaration node ) {
691713 IMethodBinding mBinding = node .resolveBinding ();
692714 if (mBinding != null )
693715 methodDeclareNameStack .pop ();
716+ @ SuppressWarnings ("unchecked" )
717+ List <SingleVariableDeclaration > parameters = node .parameters ();
718+ String methodSig = (mBinding == null ? null : mBinding .getKey ());
694719 List <VariableAdapter .FinalVariable > finalVars = getVariableList ('f' );
695720 List <VariableAdapter .FinalVariable > visitedVars = getVariableList ('v' );
696721 List <VariableAdapter .FinalVariable > normalVars = getVariableList ('n' );
697- @ SuppressWarnings ("unchecked" )
698- List <SingleVariableDeclaration > parameters = node .parameters ();
699- IMethodBinding resolveBinding = node .resolveBinding ();
700- String methodSig = (resolveBinding == null ? null : resolveBinding .getKey ());
701722 for (int i = parameters .size () - 1 ; i >= 0 ; i --) {
702723 SingleVariableDeclaration varDecl = parameters .get (i );
703724 SimpleName name = varDecl .getName ();
@@ -707,13 +728,26 @@ public void endVisit(MethodDeclaration node) {
707728 VariableAdapter .FinalVariable f = new VariableAdapter .FinalVariable (blockLevel + 1 , identifier , methodSig );
708729 f .toVariableName = identifier ;
709730 normalVars .remove (f );
731+ //buffer.append("/*remNorm " + f.variableName + "/to/" + f.toVariableName + "*/");
710732 if (Modifier .isFinal (binding .getModifiers ())) {
711733 finalVars .remove (f );
734+ //buffer.append("/*remFinal " + f.variableName + "/to/" + f.toVariableName + "*/");
712735 }
713736 visitedVars .remove (f );
737+ //buffer.append("/*remVis " + f.variableName + "/to/" + f.toVariableName + "*/");
738+ }
739+ }
740+ }
741+
742+ private void clearVariables (char nf ) {
743+ List <VariableAdapter .FinalVariable > vars = getVariableList (nf );
744+ for (int i = vars .size (); --i >= 0 ;) {
745+ VariableAdapter .FinalVariable var = vars .get (i );
746+ if (var .blockLevel >= blockLevel ) {
747+ vars .remove (i );
748+ //buffer.append("/*remVar " + nf + " " + var.toVariableName + " */");
714749 }
715750 }
716- super .endVisit (node );
717751 }
718752
719753 public boolean visit (MethodInvocation node ) {
@@ -816,21 +850,12 @@ public void endVisit(ReturnStatement node) {
816850 super .endVisit (node );
817851 }
818852
853+ /**
854+ * method parameters or catch variables
855+ */
819856 public boolean visit (SingleVariableDeclaration node ) {
820857 SimpleName name = node .getName ();
821- IBinding binding = name .resolveBinding ();
822- if (binding != null ) {
823- String identifier = name .getIdentifier ();
824- VariableAdapter .FinalVariable f = null ;
825- if (methodDeclareNameStack .size () == 0 ) {
826- f = new VariableAdapter .FinalVariable (blockLevel + 1 , identifier , null );
827- } else {
828- String methodSig = methodDeclareNameStack .peek ();
829- f = new VariableAdapter .FinalVariable (blockLevel + 1 , identifier , methodSig );
830- }
831- addVariable (f , identifier , binding );
832- }
833- name .accept (this );
858+ acceptVariableFinal (name , 1 );
834859 return false ;
835860 }
836861
@@ -885,7 +910,11 @@ public boolean visit(SwitchCase node) {
885910 }
886911
887912 public boolean visit (SynchronizedStatement node ) {
888- // not implemented in JS, as there is only one thread
913+ // we wrap this with a simple if() statement,
914+ // checking that it is not null
915+ buffer .append ("if(!(" );
916+ node .getExpression ().accept (this );
917+ buffer .append ("){throw new NullPointerException()}else" );
889918 node .getBody ().accept (this );
890919 return false ;
891920 }
@@ -1450,7 +1479,9 @@ private boolean addClassOrInterface(ASTNode node, ITypeBinding binding, List<?>
14501479 buffer .append (trailingBuffer .getAssertString ());
14511480 addDefaultConstructor ();
14521481 buffer .append ("var $vals=[];\r \n " );
1453- buffer .append ("Clazz.newMeth(C$, 'values', function() { return $vals }, 1);\r \n " );
1482+ // implicit Enum methods added as trailer
1483+ buffer .append ("Clazz.newMeth(C$, 'values', function() { return $vals }, 1);\r \n " );
1484+ buffer .append ("Clazz.newMeth(C$, '$valueOf$S', function(name) { for (var val in $vals){ if ($vals[val].$name == name) return $vals[val]} return null }, 1);\r \n " );
14541485 } else {
14551486 buffer .append (trailingBuffer ); // also writes the assert string
14561487 if (isAnonymous ) {
@@ -1740,15 +1771,6 @@ private void addSuperConstructor(SuperConstructorInvocation node, IMethodBinding
17401771 addCallInit ();
17411772 }
17421773
1743- private void clearVariables (List <VariableAdapter .FinalVariable > vars ) {
1744- for (int i = vars .size (); --i >= 0 ;) {
1745- VariableAdapter .FinalVariable var = vars .get (i );
1746- if (var .blockLevel >= blockLevel ) {
1747- vars .remove (i );
1748- }
1749- }
1750- }
1751-
17521774 private String getAnonymousName (ITypeBinding binding ) {
17531775 String binaryName = null , bindingKey ;
17541776 if ((binding .isAnonymous () || binding .isLocal ()) && (binaryName = binding .getBinaryName ()) == null
@@ -2823,12 +2845,13 @@ private String simpleNameInVarBinding(SimpleName node, char ch, IVariableBinding
28232845 if (currentBlockForVisit != -1 ) {
28242846 List <VariableAdapter .FinalVariable > finalVars = getVariableList ('f' );
28252847 List <VariableAdapter .FinalVariable > visitedVars = getVariableList ('v' );
2826- int size = finalVars . size ();
2827- for (int i = 0 ; i < size ; i ++) {
2848+ String vname = varBinding . getName ();
2849+ for (int i = 0 , size = finalVars . size () ; i < size ; i ++) {
28282850 VariableAdapter .FinalVariable vv = finalVars .get (size - i - 1 );
2829- if (vv .variableName . equals ( varBinding . getName ()) && vv . blockLevel <= currentBlockForVisit ) {
2851+ if (vv .blockLevel <= currentBlockForVisit && vv . variableName . equals ( vname ) ) {
28302852 if (!visitedVars .contains (vv )) {
28312853 visitedVars .add (vv );
2854+ //buffer.append("/* current " + currentBlockForVisit + " vlevel " + vv.blockLevel + " " + vv.variableName + "*/");
28322855 }
28332856 fieldVar = vv .toVariableName ;
28342857 }
@@ -2951,11 +2974,7 @@ public boolean visit(VariableDeclarationFragment node) {
29512974 IBinding binding = name .resolveBinding ();
29522975 if (binding == null )
29532976 return false ;
2954- String identifier = name .getIdentifier ();
2955- VariableAdapter .FinalVariable f = new VariableAdapter .FinalVariable (blockLevel , identifier ,
2956- methodDeclareNameStack .size () == 0 ? null : (String ) methodDeclareNameStack .peek ());
2957- addVariable (f , identifier , binding );
2958- name .accept (this );
2977+ acceptVariableFinal (name , 0 );
29592978 Expression right = node .getInitializer ();
29602979 ITypeBinding rightBinding = (right == null ? null : right .resolveTypeBinding ());
29612980 if (rightBinding == null )
@@ -3605,8 +3624,11 @@ private void addVariable(VariableAdapter.FinalVariable f, String identifier, IBi
36053624 List <VariableAdapter .FinalVariable > normalVars = getVariableList ('n' );
36063625 f .toVariableName = identifier ;
36073626 normalVars .add (f );
3608- if (Modifier .isFinal (binding .getModifiers ()))
3627+ //buffer.append("/*addVar n " + identifier + " */");
3628+ if (Modifier .isFinal (binding .getModifiers ())) {
36093629 finalVars .add (f );
3630+ //buffer.append("/*addVar f " + identifier + " */");
3631+ }
36103632 }
36113633
36123634 /**
@@ -4106,6 +4128,10 @@ private String getMethodNameOrArrayForDeclaration(MethodDeclaration node, IMetho
41064128 boolean isConstructor , boolean addUnqualified ) {
41074129 SimpleName nodeName = node .getName ();
41084130 String methodName = (isConstructor ? "c$" : NameMapper .getJ2SName (nodeName ));
4131+ if (methodName .equals ("subSequence$I$I" )) {
4132+ // for StringBuffer and StringBuilder to be like String
4133+ return "['subSequence','subSequence$I$I']" ;
4134+ }
41094135 String qname = getJ2SQualifiedName (methodName , null , mBinding , null , false );
41104136 ITypeBinding methodClass = mBinding .getDeclaringClass ();
41114137 List <String > names = null ;
@@ -4359,9 +4385,10 @@ private static String j2sGetParamCode(ITypeBinding binding, boolean addAAA, bool
43594385 name = "S" ;
43604386 break ;
43614387 default :
4362- if (prefix != null )
4388+ if (prefix == null )
4389+ name = checkClassReplacement (name );
4390+ else
43634391 name = (asGenericObject ? "O" : prefix + name ); // "O";//
4364-
43654392 name = name .replace ("java.lang." , "" ).replace ('.' , '_' );
43664393 break ;
43674394 }
@@ -4653,6 +4680,54 @@ public void setDebugging(boolean isDebugging) {
46534680 }
46544681
46554682
4683+
4684+ private static Map <String , String > htClassReplacements ;
4685+ private static List <String > lstPackageReplacements ;
4686+
4687+ public static void setClassReplacements (String keyValues ) {
4688+ // j2s.class.replacements=org.apache.log4j.*:jalview.jslogger.;
4689+ htClassReplacements = null ;
4690+ if (keyValues == null )
4691+ return ;
4692+ htClassReplacements = new Hashtable <String , String >();
4693+ lstPackageReplacements = new ArrayList <String >();
4694+ String [] pairs = keyValues .split (";" );
4695+ for (int i = pairs .length ; --i >= 0 ;) {
4696+ pairs [i ] = pairs [i ].trim ();
4697+ if (pairs [i ].length () == 0 )
4698+ continue ;
4699+ String [] kv = pairs [i ].split ("->" );
4700+ htClassReplacements .put (kv [0 ], kv [1 ]);
4701+ if (kv [0 ].endsWith ("." ))
4702+ lstPackageReplacements .add (kv [0 ]);
4703+ System .err .println ("class replacement " + kv [0 ] + " --> " + kv [1 ]);
4704+ }
4705+ }
4706+
4707+
4708+ private static String checkClassReplacement (String className ) {
4709+ if (htClassReplacements != null ) {
4710+ String rep = htClassReplacements .get (className );
4711+ if (rep == null && lstPackageReplacements != null ) {
4712+ for (int i = lstPackageReplacements .size (); --i >= 0 ;) {
4713+ rep = lstPackageReplacements .get (i );
4714+ if (className .startsWith (rep )) {
4715+ rep = htClassReplacements .get (rep ) + className .substring (rep .length ());
4716+ break ;
4717+ }
4718+ if (i == 0 )
4719+ rep = null ;
4720+ }
4721+
4722+ }
4723+ if (rep != null ) {
4724+ System .out .println (className + " -> " + rep );
4725+ return rep ;
4726+ }
4727+ }
4728+ return className ;
4729+ }
4730+
46564731 /**
46574732 * tracks file byte pointers for @j2sNative, @j2sIgnore
46584733 */
@@ -4714,7 +4789,7 @@ private String getNestedClazzLoads(String className, boolean doCache) {
47144789 // loop through packages and outer Class
47154790 while (i < parts .length && (i == 1 || !Character .isUpperCase (parts [i - 1 ].charAt (0 ))))
47164791 s += "." + parts [i ++];
4717- s = "'" + s + "'" ;
4792+ s = "'" + checkClassReplacement ( s ) + "'" ;
47184793 // int nlast = parts.length;
47194794 if (i < parts .length ) {
47204795 s = "[" + s ;
0 commit comments