package org.checkerframework.dataflow.constantpropagation; import java.util.List; import org.checkerframework.dataflow.analysis.ConditionalTransferResult; import org.checkerframework.dataflow.analysis.RegularTransferResult; import org.checkerframework.dataflow.analysis.TransferFunction; import org.checkerframework.dataflow.analysis.TransferInput; import org.checkerframework.dataflow.analysis.TransferResult; import org.checkerframework.dataflow.cfg.UnderlyingAST; import org.checkerframework.dataflow.cfg.node.AbstractNodeVisitor; import org.checkerframework.dataflow.cfg.node.AssignmentNode; import org.checkerframework.dataflow.cfg.node.EqualToNode; import org.checkerframework.dataflow.cfg.node.IntegerLiteralNode; import org.checkerframework.dataflow.cfg.node.LocalVariableNode; import org.checkerframework.dataflow.cfg.node.Node; import com.sun.tools.javac.tree.JCTree.JCIdent; public class ConstantPropagationTransfer extends AbstractNodeVisitor<TransferResult<Constant, ConstantPropagationStore>, TransferInput<Constant, ConstantPropagationStore>> implements TransferFunction<Constant, ConstantPropagationStore> { @Override public ConstantPropagationStore initialStore(UnderlyingAST underlyingAST, List<LocalVariableNode> parameters) { ConstantPropagationStore store = new ConstantPropagationStore(); return store; } @Override public TransferResult<Constant, ConstantPropagationStore> visitLocalVariable( LocalVariableNode node, TransferInput<Constant, ConstantPropagationStore> before) { ConstantPropagationStore store = before.getRegularStore(); Constant value = store.getInformation(node); return new RegularTransferResult<>(value, store); } @Override public TransferResult<Constant, ConstantPropagationStore> visitNode(Node n, TransferInput<Constant, ConstantPropagationStore> p) { return new RegularTransferResult<>(null, p.getRegularStore()); } @Override public TransferResult<Constant, ConstantPropagationStore> visitAssignment( AssignmentNode n, TransferInput<Constant, ConstantPropagationStore> pi) { ConstantPropagationStore p = pi.getRegularStore(); Node target = n.getTarget(); Constant info = null; if (target instanceof LocalVariableNode) { LocalVariableNode t = (LocalVariableNode) target; info = p.getInformation(n.getExpression()); p.setInformation(t, info); } return new RegularTransferResult<>(info, p); } @Override public TransferResult<Constant, ConstantPropagationStore> visitIntegerLiteral( IntegerLiteralNode n, TransferInput<Constant, ConstantPropagationStore> pi) { ConstantPropagationStore p = pi.getRegularStore(); Constant c = new Constant(n.getValue()); p.setInformation(n, c); return new RegularTransferResult<>(c, p); } @Override public TransferResult<Constant, ConstantPropagationStore> visitEqualTo( EqualToNode n, TransferInput<Constant, ConstantPropagationStore> pi) { ConstantPropagationStore p = pi.getRegularStore(); ConstantPropagationStore old = p.copy(); Node left = n.getLeftOperand(); Node right = n.getRightOperand(); process(p, left, right); process(p, right, left); return new ConditionalTransferResult<>(null, p, old); } protected void process(ConstantPropagationStore p, Node a, Node b) { Constant val = p.getInformation(a); if (b instanceof LocalVariableNode && val.isConstant()) { p.setInformation(b, val); } } }