package dk.brics.jspointers.flowgraph.analysis; import java.util.Collections; import java.util.Set; import dk.brics.tajs.flowgraph.Function; import dk.brics.tajs.flowgraph.Node; import dk.brics.tajs.flowgraph.nodes.BinaryOperatorNode; import dk.brics.tajs.optimizer2.Decorator; import dk.brics.tajs.optimizer2.FixpointSolver; public class TypeAnalysis implements ReadVarsInterface { private ReadVarsVisitor readvars = new ReadVarsVisitor(); private FixpointSolver<Set<Integer>> solver; /** * Returns the set of variables that might be strings or * objects at the given node. Non-live variables may be * excluded. * @param node a node from the same function passed to the constructor * @return unmodifiable set */ public Set<Integer> getVariables(Node node) { return solver.getJoinPoint(node); } public TypeAnalysis(Decorator fgd, Function func, Liveness liveness) { // ForwardAnalysis<Set<Integer>> fa = new ForwardAnalysis<Set<Integer>>(fgd, func); // map = fa.solve(new TypeAnalysisTransfer(liveness)); // solver = new FixpointSolver<Set<Integer>>(new TypeAnalysisFlow(fgd, liveness), func); solver = new FixpointSolver<Set<Integer>>(new TypeAnalysisFlow(fgd, liveness), func); solver.solve(); } /** * Returns the relevant variables read by the given node. * <p/> * This function takes into account that binary plus statements * do not use their arguments if both arguments are known to * be non-string non-object values. * Apart from that, it defaults to the same semantics as {@link ReadVarsVisitor}. */ public int[] getReadVars(Node node) { if (node instanceof BinaryOperatorNode) { BinaryOperatorNode bin = (BinaryOperatorNode)node; switch (bin.getOperator()) { case ADD: Set<Integer> vars = getVariables(node); if (!vars.contains(bin.getArg1Var()) && !vars.contains(bin.getArg2Var())) { return new int[0]; } break; } } return readvars.getReadVars(node); } }