return subtypes2.isSubtype(type, obligationType);
}
private void reportPath(final BugInstance bugInstance, final Obligation obligation, final State state) {
Path path = state.getPath();
// This PathVisitor will traverse the Path and add appropriate
// SourceLineAnnotations to the BugInstance.
PathVisitor visitor = new PathVisitor() {
boolean sawFirstCreation;
SourceLineAnnotation lastSourceLine;// = creationSourceLine;
BasicBlock curBlock;
@Override
public void visitBasicBlock(BasicBlock basicBlock) {
curBlock = basicBlock;
// See if the initial instance of the leaked resource
// is in the entry fact due to a @WillClose annotation.
if (curBlock == cfg.getEntry()) {
// Get the entry fact - it should have precisely one
// state
StateSet entryFact = dataflow.getResultFact(curBlock);
Iterator<State> i = entryFact.stateIterator();
if (i.hasNext()) {
State entryState = i.next();
if (entryState.getObligationSet().getCount(obligation.getId()) > 0) {
lastSourceLine = SourceLineAnnotation.forFirstLineOfMethod(methodDescriptor);
lastSourceLine
.setDescription(SourceLineAnnotation.ROLE_OBLIGATION_CREATED_BY_WILLCLOSE_PARAMETER);
bugInstance.add(lastSourceLine);
sawFirstCreation = true;
if (REPORT_PATH_DEBUG) {
System.out.println(" " + obligation + " created by @WillClose parameter at "
+ lastSourceLine);
}
}
}
}
}
@Override
public void visitInstructionHandle(InstructionHandle handle) {
boolean isCreation = (dataflow.getAnalysis().getActionCache().addsObligation(curBlock, handle, obligation));
if (!sawFirstCreation && !isCreation) {
return;
}
SourceLineAnnotation sourceLine = SourceLineAnnotation.fromVisitedInstruction(methodDescriptor, new Location(
handle, curBlock));
sourceLine.setDescription(isCreation ? SourceLineAnnotation.ROLE_OBLIGATION_CREATED
: SourceLineAnnotation.ROLE_PATH_CONTINUES);
boolean isInteresting = (sourceLine.getStartLine() > 0)
&& (lastSourceLine == null || isCreation || sourceLine.getStartLine() != lastSourceLine.getStartLine());
if (REPORT_PATH_DEBUG) {
System.out.println(" " + handle.getPosition() + " --> " + sourceLine + (isInteresting ? " **" : ""));
}
if (isInteresting) {
bugInstance.add(sourceLine);
lastSourceLine = sourceLine;
if (isCreation) {
sawFirstCreation = true;
}
}
}
@Override
public void visitEdge(Edge edge) {
if (REPORT_PATH_DEBUG) {
System.out.println("Edge of type " + Edge.edgeTypeToString(edge.getType()) + " to "
+ edge.getTarget().getLabel());
if (edge.getTarget().getFirstInstruction() != null) {
System.out.println(" First instruction in target: " + edge.getTarget().getFirstInstruction());
}
if (edge.getTarget().isExceptionThrower()) {
System.out.println(" exception thrower for " + edge.getTarget().getExceptionThrower());
}
if (edge.isExceptionEdge()) {
System.out.println(" exceptions thrown: " + typeDataflow.getEdgeExceptionSet(edge));
}
}
}
};
// Visit the Path
path.acceptVisitor(cfg, visitor);
}