package natlab.toolkits.analysis.core;

import natlab.toolkits.analysis.HashSetFlowSet;
import analysis.AbstractSimpleStructuralForwardAnalysis;
import ast.ASTNode;
import ast.AssignStmt;
import ast.Function;
import ast.GlobalStmt;
import ast.Name;
import ast.Script;
import ast.Stmt;

public class DefinitelyAssignedAnalysis extends
    AbstractSimpleStructuralForwardAnalysis<HashSetFlowSet<String>> {

  public DefinitelyAssignedAnalysis(ASTNode tree) {
    super(tree);
  }

  @Override
  public void caseScript(Script node) {
    currentInSet = newInitialFlow();
    currentOutSet = currentInSet.copy();
    node.getStmts().analyze(this);
    outFlowSets.put(node, currentOutSet);
  }

  @Override
  public void caseFunction(Function node) {
    currentInSet = newInitialFlow();
    currentOutSet = currentInSet.copy();

    for (Name n : node.getInputParams()) {
      currentInSet.add(n.getID());
    }

    node.getStmts().analyze(this);
    outFlowSets.put( node, currentOutSet);

    node.getNestedFunctions().analyze(this);
  }

  @Override
  public void caseAssignStmt(AssignStmt node) {
    inFlowSets.put(node, currentInSet);
    currentOutSet = currentInSet.copy();
    currentOutSet.addAll(node.getLValues());
    outFlowSets.put(node, currentOutSet);
  }
  
  @Override
  public void caseGlobalStmt(GlobalStmt node) {
    inFlowSets.put(node, currentInSet);
    currentOutSet = currentInSet.copy();
    for (Name name : node.getNames()) {
      currentOutSet.add(name.getID());
    }
    outFlowSets.put(node, currentOutSet);
  }

  @Override
  public void caseStmt(Stmt node){
    inFlowSets.put(node, currentInSet);
    currentOutSet = currentInSet;
    outFlowSets.put(node, currentOutSet);
  }

  @Override
  public void copy(HashSetFlowSet<String> source, HashSetFlowSet<String> dest) {
    source.copy(dest);
  }

  @Override
  public void merge(HashSetFlowSet<String> in1, HashSetFlowSet<String> in2,
      HashSetFlowSet<String> out) {
    in1.intersection(in2,out);
  }

  @Override
  public HashSetFlowSet<String> newInitialFlow() {
    return new HashSetFlowSet<String>();
  }
  
  public boolean isDefinitelyAssignedAtInputOf(Stmt node, String name) {
    return inFlowSets.get(node).contains(name);
  }
}

@@ -44,49 +44,24 @@
 ort 
-natlab.toolkits.analysis.HashSetFlow
+java.util.
 Set;%0A
+%0A
 impo
@@ -254,16 +254,56 @@
 .Stmt;%0A%0A
+import com.google.common.collect.Sets;%0A%0A
 public c
@@ -386,27 +386,16 @@
 nalysis%3C
-HashSetFlow
 Set%3CStri
@@ -577,32 +577,48 @@
 currentOutSet = 
+Sets.newHashSet(
 currentInSet.cop
@@ -609,30 +609,24 @@
 currentInSet
-.copy(
 );%0A    node.
@@ -803,32 +803,48 @@
 currentOutSet = 
+Sets.newHashSet(
 currentInSet.cop
@@ -839,22 +839,16 @@
 entInSet
-.copy(
 );%0A%0A    
@@ -1169,32 +1169,48 @@
 currentOutSet = 
+Sets.newHashSet(
 currentInSet.cop
@@ -1201,30 +1201,24 @@
 currentInSet
-.copy(
 );%0A    curre
@@ -1414,32 +1414,48 @@
 currentOutSet = 
+Sets.newHashSet(
 currentInSet.cop
@@ -1450,22 +1450,16 @@
 entInSet
-.copy(
 );%0A    f
@@ -1784,27 +1784,16 @@
 id copy(
-HashSetFlow
 Set%3CStri
@@ -1804,27 +1804,16 @@
 source, 
-HashSetFlow
 Set%3CStri
@@ -1832,24 +1832,90 @@
     
+if (
 source
-.copy(dest
+ == dest) %7B%0A      return;%0A    %7D%0A    dest.clear();%0A    dest.addAll(source
 );%0A 
@@ -1950,27 +1950,16 @@
 d merge(
-HashSetFlow
 Set%3CStri
@@ -1971,100 +1971,268 @@
 n1, 
-HashSetFlowSet%3CString%3E in2,%0A      HashSetFlowSet%3CString%3E out) %7B%0A    in1.intersection(in2,out
+Set%3CString%3E in2, Set%3CString%3E out) %7B%0A    if (in1 == in2 && in2 == out) %7B%0A      return;%0A    %7D%0A    if (in1 == out) %7B%0A      out.retainAll(in2);%0A    %7D else if (in2 == out) %7B%0A      out.retainAll(in1);%0A    %7D%0A    out.clear();%0A    out.addAll(in1);%0A    out.retainAll(in2
 );%0A 
@@ -2256,27 +2256,16 @@
  public 
-HashSetFlow
 Set%3CStri
@@ -2302,34 +2302,23 @@
 urn 
+Sets.
 new
- 
 HashSet
-FlowSet%3CString%3E
 ();%0A

Use Set instead of HashSetFlowSet in defasn.