Package ai.cfg

Source Code of ai.cfg.Utils$VerticeNameGenerator

package ai.cfg;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;

import org.apache.log4j.Logger;
import org.eclipse.jdt.core.dom.IMethodBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;

import ai.cfg.edges.CFGMultiTargetEdge.CFGSingleEdge;
import ai.common.DefaultHashMap;

public class Utils {
  private final static Logger log = Logger.getLogger(Utils.class.getName());

//  private static int methodIdxGen = 0;
//  private static Map<MethodDeclaration, String> generatedNames = new HashMap<MethodDeclaration, String>();
//
//  public static String getUniqueName(InterestingCodeFragment codeFragment) {
//    MethodDeclaration node   
//    IMethodBinding binding = node.resolveBinding();
//    if (binding == null) {
//      log.error("Binding not resolved, probably project path is invalid: " + node);
//      if (generatedNames.containsKey(node))
//        return generatedNames.get(node);
//      String name = "Dummy_method_location_" + methodIdxGen++ + ":" + node.getName();
//      generatedNames.put(node, name);
//      return name;
//    }
//    return binding.getDeclaringClass().getBinaryName() + ":" + node.getName();
//  }

  private static class VerticeNameGenerator {
    private final Map<CFGVertice, String> names = new HashMap<CFGVertice, String>();
    private final Set<String> usedNames = new HashSet<String>();
    private final String prefix;
    private int counter = 0;

    public VerticeNameGenerator(String prefix) {
      this.prefix = prefix;
    }

    public String getName(CFGVertice vertice) {
      if (vertice.getDescription() != null)
        return vertice.getDescription();
      if (!names.containsKey(vertice)) {
        String name = prefix + counter++;
        if (usedNames.contains(name))
          throw new RuntimeException("Error in vertice name generation");
        names.put(vertice, name);
        usedNames.add(name);
      }
      return names.get(vertice);
    }

    public void setName(CFGVertice vertice, String name) {
      if (usedNames.contains(name))
        throw new RuntimeException("Name already in use");
      if (names.containsKey(vertice))
        throw new RuntimeException("Vertice already has a name");
      names.put(vertice, name);
    }
  }

  public static Collection<CFGVertice> walkGraph(MethodControlFlowGraph graph, ControlFlowGraphVisitor visitor) {
    Queue<CFGSingleEdge> queue = new LinkedList<CFGSingleEdge>();
    queue.addAll(Arrays.asList(graph.getInput().singleEdges));
    Set<CFGVertice> visited = new HashSet<CFGVertice>();
    while (!queue.isEmpty()) {
      CFGSingleEdge edge = queue.poll();
      boolean visitTarget = visitor.visitEdge(edge);
      if (!visitTarget)
        continue;
      CFGVertice vertice = edge.target;
      if (visited.contains(vertice))
        continue;
      visited.add(vertice);
      boolean visitOutgoingEdges = visitor.visitVertice(vertice);
      if (!visitOutgoingEdges)
        continue;
      queue.addAll(vertice.getOutgoingEdges());
    }
    return visited;
  }

  public static void printCFG(MethodControlFlowGraph graph) {
    final VerticeNameGenerator namesGen = new VerticeNameGenerator("Vertice_");
    final StringBuffer buffer = new StringBuffer("Edges:\n");
    namesGen.setName(graph.getStartVertice(), "IN");
    namesGen.setName(graph.getEndVertice(), "OUT");
    // initialise
    ControlFlowGraphVisitor visitor = new ControlFlowGraphVisitor() {
      @Override
      public boolean visitVertice(CFGVertice vertice) {
        return true;
      }

      @Override
      public boolean visitEdge(CFGSingleEdge edge) {
        if (edge.source != null)
          buffer.append("[["+namesGen.getName(edge.source)+"]]");
        buffer.append(" -> ");
        buffer.append("[["+namesGen.getName(edge.target)+ "]]");
        buffer.append(": ");
        buffer.append(edge.toString());
        buffer.append("\n");
        return true;
      }
    };
    System.out.print("Vertices:");
    for (CFGVertice vertice : walkGraph(graph, visitor)) {
      System.out.print(" ");
      System.out.print("[["+namesGen.getName(vertice)+"]]\n");
    }
    System.out.println();
    System.out.println(buffer.toString());
  }

  public static Map<CFGVertice, List<CFGSingleEdge>> computeInputEdges(MethodControlFlowGraph graph) {
    final Map<CFGVertice, List<CFGSingleEdge>> inputs = new HashMap<CFGVertice, List<CFGSingleEdge>>();
    walkGraph(graph, new ControlFlowGraphVisitor() {
      @Override
      public boolean visitVertice(CFGVertice vertice) {
        return true;
      }

      @Override
      public boolean visitEdge(CFGSingleEdge edge) {
        CFGVertice target = edge.target;
        if (!inputs.containsKey(target)) {
          inputs.put(target, new LinkedList<CFGSingleEdge>());
        }
        inputs.get(target).add(edge);
        return true;
      }
    });
    return inputs;
  }

  private static void helper(CFGSingleEdge inputEdge, Set<CFGVertice> verticesAlreadyOnPath, Set<CFGVertice> visited,
      DefaultHashMap<CFGVertice, Collection<CFGSingleEdge>> result) {
    CFGVertice vertice = inputEdge.target;
    if (verticesAlreadyOnPath.contains(vertice)) // loop
      result.setDefault(vertice, new LinkedList<CFGSingleEdge>()).add(inputEdge);
    if (visited.contains(vertice))
      return;
    verticesAlreadyOnPath.add(vertice);
    visited.add(vertice);
    for(CFGSingleEdge edge: vertice.getOutgoingEdges())
      helper(edge, verticesAlreadyOnPath, visited, result);
    verticesAlreadyOnPath.remove(vertice);
  }

  public static Map<CFGVertice, Collection<CFGSingleEdge>> findLoopVertices(MethodControlFlowGraph graph) {
    DefaultHashMap<CFGVertice, Collection<CFGSingleEdge>> result = new DefaultHashMap<CFGVertice, Collection<CFGSingleEdge>>();
    helper(graph.getInput().singleEdges[0], new HashSet<CFGVertice>(), new HashSet<CFGVertice>(), result);
    return result;
  }
}
TOP

Related Classes of ai.cfg.Utils$VerticeNameGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.