Package ai.cfg

Source Code of ai.cfg.MethodControlFlowGraph

package ai.cfg;

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.Set;

import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ConstructorInvocation;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.SuperConstructorInvocation;

import ai.cfg.edges.CFGMultiTargetEdge;
import ai.cfg.edges.ConditionalEdge;
import ai.cfg.edges.ConstructorInvocationEdge;
import ai.cfg.edges.EmptyEdge;
import ai.cfg.edges.ExpressionStatementEdge;
import ai.cfg.edges.FinallyOrCatchEdge;
import ai.cfg.edges.InputEdge;
import ai.cfg.edges.NewVariableEdge;
import ai.cfg.edges.SuperConstructorInvocationEdge;
import ai.cfg.edges.SwitchEdge;
import ai.common.Pair;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

public class MethodControlFlowGraph {// nodes, edges
  private final InterestingCodeFragment codeFragment;
  private final CFGVertice start;
  private final CFGVertice end;

  private final Set<CFGVertice> vertices = new HashSet<CFGVertice>();
  private final Set<CFGMultiTargetEdge> edges = new HashSet<CFGMultiTargetEdge>();
  private final InputEdge inputEdge;
 
  /**
   * vertice -> set of nodes after directly after the vertice
   */
  private final Multimap<CFGVertice, ASTNode> beforeVertice = HashMultimap.create();

  /**
   * vertice -> set of nodes after directly before the vertice
   */
  private final Multimap<CFGVertice, ASTNode> afterVertice = HashMultimap.create();
 
  private final Map<ASTNode, CFGVertice> afterNode = new HashMap<ASTNode, CFGVertice>();
  private final Map<ASTNode, CFGVertice> beforeNode = new HashMap<ASTNode, CFGVertice>();
 
  private final Map<CFGVertice, ASTNode> loopVertices = new HashMap<CFGVertice, ASTNode>();

  public MethodControlFlowGraph(InterestingCodeFragment codeFragment) {
    this.codeFragment = codeFragment;
    this.start = new CFGVertice(codeFragment.getNode());
    this.end = new CFGVertice(null);
    this.inputEdge = new InputEdge(this.start, codeFragment);
    edges.add(inputEdge);
    this.vertices.add(start);
    this.vertices.add(end);

    this.start.addDescription("IN");
    this.end.addDescription("OUT");
  }

  public InterestingCodeFragment getCodeFragment() {
    return codeFragment;
  }

  public CFGMultiTargetEdge getInput() {
    return this.inputEdge;
  }

  CFGVertice getStartVertice() {
    return start;
  }

  public CFGVertice getEndVertice() {
    return end;
  }

  private void assertGraphVertice(CFGVertice vertice) {
    if (!vertices.contains(vertice))
      throw new CFGException("Not a graph vertice: '%s'", vertice);
  }

  public void createVariableDeclarationEdge(CFGVertice previousVertice, CFGVertice nextVertice,
      SimpleName name, Expression initializerOrNull, boolean asAssignment) {
    assertGraphVertice(previousVertice);
    assertGraphVertice(nextVertice);
    CFGMultiTargetEdge edge = new NewVariableEdge(previousVertice, nextVertice, name, initializerOrNull, asAssignment);
    previousVertice.addEdge(edge);
  }
 
  public void createConditionalEdge(CFGVertice previousVertice, CFGVertice positiveTarget,
      CFGVertice negativeTarget, Expression conditionOrNull) {
    assertGraphVertice(previousVertice);
    assertGraphVertice(positiveTarget);
    assertGraphVertice(negativeTarget);
    CFGMultiTargetEdge edge = new ConditionalEdge(previousVertice, positiveTarget, negativeTarget, conditionOrNull);
    previousVertice.addEdge(edge);
    edges.add(edge);
  }

  public void createExceptionEdge(CFGVertice previousVertice, CFGVertice nextVertice,
      SingleVariableDeclaration exceptionOrNull) {
    assertGraphVertice(previousVertice);
    assertGraphVertice(nextVertice);
    CFGMultiTargetEdge edge = new FinallyOrCatchEdge(previousVertice, nextVertice, exceptionOrNull);
    previousVertice.addEdge(edge);
    edges.add(edge);
  }

  public CFGVertice addNewVertice(ASTNode node) {
    CFGVertice result = new CFGVertice(node);
    vertices.add(result);
    return result;
  }

  public CFGVertice addNewVertice(ASTNode node, String description) {
    CFGVertice result = new CFGVertice(node);
    result.addDescription(description);
    vertices.add(result);
    return result;
  }

  public void createExpressionStatementEdge(CFGVertice previousVertice, CFGVertice nextVertice, Expression expression) {
    assertGraphVertice(previousVertice);
    assertGraphVertice(nextVertice);
    CFGMultiTargetEdge edge = new ExpressionStatementEdge(previousVertice, nextVertice, expression);
    previousVertice.addEdge(edge);
    edges.add(edge);
  }

  public void createEmptyEdge(CFGVertice previousVertice, CFGVertice nextVertice) {
    createEmptyEdge(previousVertice, nextVertice, new LinkedList<SimpleName>());
  }
 
  public void createEmptyEdge(CFGVertice previousVertice, CFGVertice nextVertice,
      List<SimpleName> variablesToRemove) {
    assertGraphVertice(previousVertice);
    assertGraphVertice(nextVertice);
    CFGMultiTargetEdge edge = new EmptyEdge(previousVertice, nextVertice, variablesToRemove);
    previousVertice.addEdge(edge);
    edges.add(edge);
  }

  public int size() {
    return vertices.size();
  }

  public void createConstructorInvocationEdge(CFGVertice previousVertice, CFGVertice nextVertice,
      ConstructorInvocation node) {
    assertGraphVertice(previousVertice);
    assertGraphVertice(nextVertice);
    CFGMultiTargetEdge edge = new ConstructorInvocationEdge(previousVertice, nextVertice, node);
    previousVertice.addEdge(edge);
    edges.add(edge);
  }

  public void createSuperConstructorInvocationEdge(CFGVertice previousVertice, CFGVertice nextVertice,
      SuperConstructorInvocation node) {
    assertGraphVertice(previousVertice);
    assertGraphVertice(nextVertice);
    CFGMultiTargetEdge edge = new SuperConstructorInvocationEdge(previousVertice, nextVertice, node);
    previousVertice.addEdge(edge);
    edges.add(edge);
  }
 
  public void createSwitchEdge(CFGVertice previousVertice, CFGVertice defaultVertice, Expression expression,
      List<Pair<CFGVertice, Expression>> cases) {
    assertGraphVertice(previousVertice);
    assertGraphVertice(defaultVertice);
    for(Pair<CFGVertice, Expression> aCase: cases)
      assertGraphVertice(aCase.left);
    CFGMultiTargetEdge edge = new SwitchEdge(previousVertice, expression, defaultVertice, cases);
    previousVertice.addEdge(edge);
    edges.add(edge);
  }
 
  public void addMapping(ASTNode node, CFGVertice before, CFGVertice after) {
    afterVertice.put(before, node);
    beforeVertice.put(after, node);
   
    CFGVertice x = afterNode.get(node);
    if (x != null && x != after)
      throw new RuntimeException("Duplicate after node vertice");
    afterNode.put(node, after);
   
    x = beforeNode.get(node);
    if (x != null && x != before)
      throw new RuntimeException("Duplicate after before vertice");
    beforeNode.put(node, before);
  }
 
  public void addLoopInvariangMapping(ASTNode node, CFGVertice loopVertice){
    loopVertices.put(loopVertice, node);
  }
 
  public Pair<Pair<Map<ASTNode, CFGVertice>, Multimap<CFGVertice, ASTNode>>, Pair<Map<ASTNode, CFGVertice>, Multimap<CFGVertice, ASTNode>>> getMappings(){
    return Pair.create(Pair.create(beforeNode, beforeVertice), Pair.create(afterNode, afterVertice));
  }
 
  public Pair<Multimap<CFGVertice, ASTNode>, Multimap<CFGVertice, ASTNode>> getVerticeMappings(){
    return Pair.create(beforeVertice, afterVertice);
  }
 
  public Map<CFGVertice, ASTNode> getLoopVerticesMapping(){
    return loopVertices;
  }
 
  public Collection<CFGVertice> getVertices() {
    return vertices;
  }
}
TOP

Related Classes of ai.cfg.MethodControlFlowGraph

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.