Commits

Tim Vernum  committed 69ff06a

Split variable declarations if required

  • Participants
  • Parent commits 7de6c9e

Comments (0)

Files changed (3)

File convert/source/java/main/org/adjective/syntactic/convert/j7to8/Convert7To8Visitor.java

 import org.adjective.syntactic.parser.BaseNode;
 import org.adjective.syntactic.parser.DefaultVisitor;
 import org.adjective.syntactic.parser.ast.*;
-import org.adjective.syntactic.parser.util.ExpressionNode;
-import org.adjective.syntactic.parser.util.HasModifiers;
-import org.adjective.syntactic.parser.util.JavaType;
-import org.adjective.syntactic.parser.util.ModifierSet;
+import org.adjective.syntactic.parser.util.*;
+import org.adjective.syntactic.util.Pair;
 
 import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
 import java.util.Stack;
 
 public class Convert7To8Visitor extends DefaultVisitor<Object, Object>
 {
     private final Stack<String> className;
     private final VariableStack vars;
+    private final List<Pair<VariableDeclarationNode, String>> toMarkFinal;
 
     public Convert7To8Visitor()
     {
         className = new Stack<String>();
         vars = new VariableStack();
+        toMarkFinal = new ArrayList<Pair<VariableDeclarationNode, String>>();
+    }
+
+    @Override
+    public Object visit(final ASTCompilationUnit node, final Object data)
+    {
+        final Object val = super.visit(node, data);
+        for (Pair<VariableDeclarationNode, String> pair : toMarkFinal)
+        {
+            markFinal(pair.tail, pair.head);
+        }
+        return val;
+    }
+
+    private void markFinal(final String name, final VariableDeclarationNode node)
+    {
+        if (node.isMultiVariable())
+        {
+            Map<String, VariableDeclarationNode> split = node.split();
+            ASTBlock block = ((BaseNode) node).findAncestor(ASTBlock.class);
+            split.get(name).getModifiers().set(ModifierSet.Modifier.FINAL);
+            List<StatementNode> statements = new ArrayList<StatementNode>();
+            for (VariableDeclarationNode decl : split.values())
+            {
+                assert decl instanceof ASTLocalVariableDeclaration;
+                statements.add(new ASTVariableDeclarationStatement((ASTLocalVariableDeclaration) decl));
+            }
+            block.replace(node.jjtGetParent(), statements);
+        }
+        else
+        {
+            node.getModifiers().set(ModifierSet.Modifier.FINAL);
+        }
     }
 
     @Override
                     if (prefix.is(ASTQualifiedIdentifier.class))
                     {
                         String id = prefix.as(ASTQualifiedIdentifier.class).getName();
-                        final HasModifiers modifiers = vars.get(id);
-                        if (modifiers != null)
-                        {
-                            modifiers.getModifiers().set(ModifierSet.Modifier.FINAL);
-                        }
+                        markFinal(id);
                     }
                 }
                 if (prefix.is(ASTThis.class))
         }, null);
     }
 
+    private void markFinal(final String var)
+    {
+        final VariableDeclarationNode node = vars.get(var);
+        if (node == null)
+        {
+            return;
+        }
+        toMarkFinal.add(new Pair<VariableDeclarationNode, String>(node, var));
+    }
+
     private <T> Iterable<T> merge(final T first, final Iterable<T> rest)
     {
         final ArrayList<T> list = new ArrayList<T>();

File convert/source/java/main/org/adjective/syntactic/convert/j7to8/VariableStack.java

  */
 package org.adjective.syntactic.convert.j7to8;
 
-import org.adjective.syntactic.parser.util.HasModifiers;
+import org.adjective.syntactic.parser.util.VariableDeclarationNode;
 
 import java.util.HashMap;
 import java.util.Map;
 
 public class VariableStack
 {
-    private Stack<Map<String, HasModifiers>> _stack;
+    private Stack<Map<String, VariableDeclarationNode>> _stack;
 
     public VariableStack()
     {
-        _stack = new Stack<Map<String, HasModifiers>>();
+        _stack = new Stack<Map<String, VariableDeclarationNode>>();
     }
 
     public void pushScope()
     {
-        _stack.push(new HashMap<String, HasModifiers>());
+        _stack.push(new HashMap<String, VariableDeclarationNode>());
     }
 
     public void popScope()
         _stack.pop();
     }
 
-    public void store(String name, HasModifiers var)
+    public void store(String name, VariableDeclarationNode var)
     {
-        final Map<String, HasModifiers> map = _stack.peek();
+        System.err.println("Store: " + name + " [ " + var + "]");
+        final Map<String, VariableDeclarationNode> map = _stack.peek();
         if (map.containsKey(name))
         {
-            throw new IllegalArgumentException("Variable '" +
-                                                       name +
-                                                       "' already exists in current scope");
+            throw new IllegalArgumentException("Variable '" + name + "' already exists in current scope");
         }
         map.put(name, var);
     }
 
-    public HasModifiers get(String name)
+    public VariableDeclarationNode get(String name)
     {
         for (int i = _stack.size() - 1; i >= 0; i--)
         {
-            final HasModifiers var = _stack.get(i).get(name);
+            final VariableDeclarationNode var = _stack.get(i).get(name);
             if (var != null)
             {
                 return var;

File convert/source/java/samples/sample/LambdaEffectiveFinal.java

 
 public class LambdaEffectiveFinal
 {
-
     public Runnable getRunnable(int i)
     {
-        int j = -i;
+        int j = -i, k=9;
         Runnable r = () -> {
             System.out.println(i + " : " + j);
         };
+        k++;
         return r;
     }
-
 }