| package org.checkerframework.dataflow.livevariable; |
| |
| import java.util.List; |
| import org.checkerframework.checker.nullness.qual.Nullable; |
| import org.checkerframework.dataflow.analysis.BackwardTransferFunction; |
| import org.checkerframework.dataflow.analysis.RegularTransferResult; |
| 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.MethodInvocationNode; |
| import org.checkerframework.dataflow.cfg.node.Node; |
| import org.checkerframework.dataflow.cfg.node.ObjectCreationNode; |
| import org.checkerframework.dataflow.cfg.node.ReturnNode; |
| import org.checkerframework.dataflow.cfg.node.StringConcatenateAssignmentNode; |
| |
| /** A live variable transfer function. */ |
| public class LiveVarTransfer |
| extends AbstractNodeVisitor< |
| TransferResult<LiveVarValue, LiveVarStore>, TransferInput<LiveVarValue, LiveVarStore>> |
| implements BackwardTransferFunction<LiveVarValue, LiveVarStore> { |
| |
| @Override |
| public LiveVarStore initialNormalExitStore( |
| UnderlyingAST underlyingAST, @Nullable List<ReturnNode> returnNodes) { |
| return new LiveVarStore(); |
| } |
| |
| @Override |
| public LiveVarStore initialExceptionalExitStore(UnderlyingAST underlyingAST) { |
| return new LiveVarStore(); |
| } |
| |
| @Override |
| public RegularTransferResult<LiveVarValue, LiveVarStore> visitNode( |
| Node n, TransferInput<LiveVarValue, LiveVarStore> p) { |
| return new RegularTransferResult<>(null, p.getRegularStore()); |
| } |
| |
| @Override |
| public RegularTransferResult<LiveVarValue, LiveVarStore> visitAssignment( |
| AssignmentNode n, TransferInput<LiveVarValue, LiveVarStore> p) { |
| RegularTransferResult<LiveVarValue, LiveVarStore> transferResult = |
| (RegularTransferResult<LiveVarValue, LiveVarStore>) super.visitAssignment(n, p); |
| processLiveVarInAssignment(n.getTarget(), n.getExpression(), transferResult.getRegularStore()); |
| return transferResult; |
| } |
| |
| @Override |
| public RegularTransferResult<LiveVarValue, LiveVarStore> visitStringConcatenateAssignment( |
| StringConcatenateAssignmentNode n, TransferInput<LiveVarValue, LiveVarStore> p) { |
| RegularTransferResult<LiveVarValue, LiveVarStore> transferResult = |
| (RegularTransferResult<LiveVarValue, LiveVarStore>) |
| super.visitStringConcatenateAssignment(n, p); |
| processLiveVarInAssignment( |
| n.getLeftOperand(), n.getRightOperand(), transferResult.getRegularStore()); |
| return transferResult; |
| } |
| |
| @Override |
| public RegularTransferResult<LiveVarValue, LiveVarStore> visitMethodInvocation( |
| MethodInvocationNode n, TransferInput<LiveVarValue, LiveVarStore> p) { |
| RegularTransferResult<LiveVarValue, LiveVarStore> transferResult = |
| (RegularTransferResult<LiveVarValue, LiveVarStore>) super.visitMethodInvocation(n, p); |
| LiveVarStore store = transferResult.getRegularStore(); |
| for (Node arg : n.getArguments()) { |
| store.addUseInExpression(arg); |
| } |
| return transferResult; |
| } |
| |
| @Override |
| public RegularTransferResult<LiveVarValue, LiveVarStore> visitObjectCreation( |
| ObjectCreationNode n, TransferInput<LiveVarValue, LiveVarStore> p) { |
| RegularTransferResult<LiveVarValue, LiveVarStore> transferResult = |
| (RegularTransferResult<LiveVarValue, LiveVarStore>) super.visitObjectCreation(n, p); |
| LiveVarStore store = transferResult.getRegularStore(); |
| for (Node arg : n.getArguments()) { |
| store.addUseInExpression(arg); |
| } |
| return transferResult; |
| } |
| |
| /** |
| * Update the information of live variables from an assignment statement. |
| * |
| * @param variable the variable that should be killed |
| * @param expression the expression in which the variables should be added |
| * @param store the live variable store |
| */ |
| private void processLiveVarInAssignment(Node variable, Node expression, LiveVarStore store) { |
| store.killLiveVar(new LiveVarValue(variable)); |
| store.addUseInExpression(expression); |
| } |
| } |