All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boomerang.results.AbstractBoomerangResults Maven / Gradle / Ivy

There is a newer version: 3.2.2
Show newest version
package boomerang.results;

import boomerang.ForwardQuery;
import boomerang.scene.ControlFlowGraph.Edge;
import boomerang.scene.Statement;
import boomerang.scene.Val;
import boomerang.solver.AbstractBoomerangSolver;
import boomerang.solver.ForwardBoomerangSolver;
import boomerang.util.DefaultValueMap;
import com.google.common.collect.Table;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sync.pds.solver.nodes.GeneratedState;
import sync.pds.solver.nodes.INode;
import sync.pds.solver.nodes.Node;
import sync.pds.solver.nodes.SingleNode;
import wpds.impl.PAutomaton;
import wpds.impl.Transition;
import wpds.impl.Weight;
import wpds.impl.WeightedPAutomaton;
import wpds.interfaces.WPAStateListener;

public class AbstractBoomerangResults {
  protected final DefaultValueMap> queryToSolvers;
  protected final Logger LOGGER = LoggerFactory.getLogger(AbstractBoomerangResults.class);

  public AbstractBoomerangResults(
      DefaultValueMap> solverMap) {
    this.queryToSolvers = solverMap;
  }

  protected Context constructContextGraph(ForwardQuery forwardQuery, Node targetFact) {
    Context context = new Context(targetFact, forwardQuery);
    AbstractBoomerangSolver forwardSolver = queryToSolvers.get(forwardQuery);
    computeUnmatchedOpeningContext(context, forwardSolver, targetFact);
    computeUnmatchedClosingContext(context, forwardSolver);
    return context;
  }

  public void computeUnmatchedClosingContext(
      Context context, AbstractBoomerangSolver forwardSolver) {
    for (Transition> t : forwardSolver.getCallAutomaton().getTransitions()) {
      if (t.getTarget().fact().isUnbalanced()) {
        INode v = t.getTarget();
        forwardSolver
            .getCallAutomaton()
            .registerListener(new ClosingCallStackExtracter<>(v, v, context, forwardSolver));
      }
    }
  }

  public void computeUnmatchedOpeningContext(
      Context context, AbstractBoomerangSolver forwardSolver, Node node) {
    SingleNode initialState = new SingleNode<>(node.fact());
    forwardSolver
        .getCallAutomaton()
        .registerListener(
            new OpeningCallStackExtracter<>(initialState, initialState, context, forwardSolver));
  }

  public Table asStatementValWeightTable(ForwardQuery query) {
    return queryToSolvers.getOrCreate(query).asStatementValWeightTable();
  }

  private static class OpeningCallStackExtracter
      extends WPAStateListener, W> {

    private AbstractBoomerangSolver solver;
    private INode source;
    private Context context;

    public OpeningCallStackExtracter(
        INode state, INode source, Context context, AbstractBoomerangSolver solver) {
      super(state);
      this.source = source;
      this.context = context;
      this.solver = solver;
    }

    @Override
    public void onOutTransitionAdded(
        Transition> t,
        W w,
        WeightedPAutomaton, W> weightedPAutomaton) {
      if (weightedPAutomaton.getInitialStates().contains(t.getTarget())) {
        return;
      }

      // TODO Doesn't work anymore!
      if (t.getLabel().getMethod() != null) {
        if (t.getStart() instanceof GeneratedState) {
          context
              .getOpeningContext()
              .addTransition(new Transition<>(source, t.getLabel(), t.getTarget()));
        } else {
          weightedPAutomaton.registerListener(
              new OpeningCallStackExtracter<>(t.getTarget(), source, context, solver));
          return;
        }
      }
      weightedPAutomaton.registerListener(
          new OpeningCallStackExtracter<>(t.getTarget(), t.getTarget(), context, solver));
    }

    @Override
    public void onInTransitionAdded(
        Transition> t,
        W w,
        WeightedPAutomaton, W> weightedPAutomaton) {}

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = super.hashCode();
      result = prime * result + ((context == null) ? 0 : context.hashCode());
      result = prime * result + ((solver == null) ? 0 : solver.hashCode());
      result = prime * result + ((source == null) ? 0 : source.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) return true;
      if (!super.equals(obj)) return false;
      if (getClass() != obj.getClass()) return false;
      OpeningCallStackExtracter other = (OpeningCallStackExtracter) obj;
      if (context == null) {
        if (other.context != null) return false;
      } else if (!context.equals(other.context)) return false;
      if (solver == null) {
        if (other.solver != null) return false;
      } else if (!solver.equals(other.solver)) return false;
      if (source == null) {
        if (other.source != null) return false;
      } else if (!source.equals(other.source)) return false;
      return true;
    }
  }

  private static class ClosingCallStackExtracter
      extends WPAStateListener, W> {

    private AbstractBoomerangSolver solver;
    private INode source;
    private Context context;

    public ClosingCallStackExtracter(
        INode state, INode source, Context context, AbstractBoomerangSolver solver) {
      super(state);
      this.source = source;
      this.context = context;
      this.solver = solver;
    }

    @Override
    public void onOutTransitionAdded(
        Transition> t,
        W w,
        WeightedPAutomaton, W> weightedPAutomaton) {}

    @Override
    public void onInTransitionAdded(
        Transition> t,
        W w,
        WeightedPAutomaton, W> weightedPAutomaton) {
      if (weightedPAutomaton.isUnbalancedState(t.getStart())) {
        if (!t.getStart().fact().isStatic()) {
          context.getClosingContext().addTransition(t);
        }
      }
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = super.hashCode();
      result = prime * result + ((context == null) ? 0 : context.hashCode());
      result = prime * result + ((solver == null) ? 0 : solver.hashCode());
      result = prime * result + ((source == null) ? 0 : source.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) return true;
      if (!super.equals(obj)) return false;
      if (getClass() != obj.getClass()) return false;
      ClosingCallStackExtracter other = (ClosingCallStackExtracter) obj;
      if (context == null) {
        if (other.context != null) return false;
      } else if (!context.equals(other.context)) return false;
      if (solver == null) {
        if (other.solver != null) return false;
      } else if (!solver.equals(other.solver)) return false;
      if (source == null) {
        if (other.source != null) return false;
      } else if (!source.equals(other.source)) return false;
      return true;
    }
  }

  public static class Context {
    final Node node;
    private final PAutomaton> openingContext;
    private final PAutomaton> closingContext;

    public Context(Node node, ForwardQuery forwardQuery) {
      this.node = node;
      this.openingContext =
          new PAutomaton>() {

            @Override
            public INode createState(INode d, Edge loc) {
              throw new RuntimeException("Not implemented");
            }

            @Override
            public boolean isGeneratedState(INode d) {
              throw new RuntimeException("Not implemented");
            }

            @Override
            public Edge epsilon() {
              return new Edge(Statement.epsilon(), Statement.epsilon());
            }
          };
      this.closingContext =
          new PAutomaton>() {

            @Override
            public INode createState(INode d, Edge loc) {
              throw new RuntimeException("Not implemented");
            }

            @Override
            public boolean isGeneratedState(INode d) {
              throw new RuntimeException("Not implemented");
            }

            @Override
            public Edge epsilon() {
              return new Edge(Statement.epsilon(), Statement.epsilon());
            }
          };
    }

    @Override
    public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((closingContext == null) ? 0 : closingContext.hashCode());
      result = prime * result + ((node == null) ? 0 : node.hashCode());
      result = prime * result + ((openingContext == null) ? 0 : openingContext.hashCode());
      return result;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) return true;
      if (obj == null) return false;
      if (getClass() != obj.getClass()) return false;
      Context other = (Context) obj;
      if (node == null) {
        if (other.node != null) return false;
      } else if (!node.equals(other.node)) return false;
      return true;
    }

    public PAutomaton> getOpeningContext() {
      return openingContext;
    }

    public PAutomaton> getClosingContext() {
      return closingContext;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy