package org.checkerframework.checker.index; import java.util.Set; import javax.lang.model.element.AnnotationMirror; import org.checkerframework.dataflow.analysis.ConditionalTransferResult; import org.checkerframework.dataflow.analysis.TransferResult; import org.checkerframework.dataflow.cfg.node.BinaryOperationNode; import org.checkerframework.dataflow.cfg.node.Node; import org.checkerframework.framework.flow.CFAnalysis; import org.checkerframework.framework.flow.CFStore; import org.checkerframework.framework.flow.CFValue; import org.checkerframework.framework.type.QualifierHierarchy; import org.checkerframework.javacutil.ErrorReporter; /** * This struct contains all of the information that the refinement functions need. It's called by * each node function (i.e. greater than node, less than node, etc.) and then the results are passed * to the refinement function in whatever order is appropriate for that node. Its constructor * contains all of its logic. */ public class IndexRefinementInfo { public Node left, right; /** * Annotation for left and right expressions. Might be null if dataflow doesn't have a value for * the expression. * */ public AnnotationMirror leftAnno, rightAnno; public CFStore thenStore, elseStore; public ConditionalTransferResult<CFValue, CFStore> newResult; public IndexRefinementInfo( TransferResult<CFValue, CFStore> result, CFAnalysis analysis, Node r, Node l) { right = r; left = l; if (analysis.getValue(right) == null || analysis.getValue(left) == null) { leftAnno = null; rightAnno = null; newResult = new ConditionalTransferResult<>(result.getResultValue(), thenStore, elseStore); } else { QualifierHierarchy hierarchy = analysis.getTypeFactory().getQualifierHierarchy(); rightAnno = getAnno(analysis.getValue(right).getAnnotations(), hierarchy); leftAnno = getAnno(analysis.getValue(left).getAnnotations(), hierarchy); thenStore = result.getThenStore(); elseStore = result.getElseStore(); newResult = new ConditionalTransferResult<>(result.getResultValue(), thenStore, elseStore); } } public IndexRefinementInfo( TransferResult<CFValue, CFStore> result, CFAnalysis analysis, BinaryOperationNode node) { this(result, analysis, node.getRightOperand(), node.getLeftOperand()); } private static AnnotationMirror getAnno( Set<AnnotationMirror> set, QualifierHierarchy hierarchy) { if (set.size() == 1) { return set.iterator().next(); } if (set.size() == 0) { return null; } Set<? extends AnnotationMirror> tops = hierarchy.getTopAnnotations(); if (tops.size() != 1) { ErrorReporter.errorAbort( IndexRefinementInfo.class + ": Found multiple tops, but expected one. \nFound: %s", tops.toString()); return null; // dead code } return hierarchy.findAnnotationInSameHierarchy(set, tops.iterator().next()); } }