public SourceLineAnnotation getCurrentSwitchStatement(BytecodeScanningDetector detector) { if (switchOffsetStack.isEmpty()) { throw new IllegalStateException("No current switch statement"); } SwitchDetails details = switchOffsetStack.get(switchOffsetStack.size()-1); return SourceLineAnnotation.fromVisitedInstructionRange( detector.getClassContext(), detector, details.switchPC, details.switchPC + details.maxOffset-1); } public static class SwitchDetails {
/** * Factory method for creating a source line annotation describing the * source line number for the instruction being visited by given visitor. * * @param visitor * a BetterVisitor which is visiting the method * @param pc * the bytecode offset of the instruction in the method * @return the SourceLineAnnotation, or null if we do not have line number * information for the instruction */ public static SourceLineAnnotation fromVisitedInstruction(BytecodeScanningDetector visitor, int pc) { return fromVisitedInstructionRange(visitor.getClassContext(), visitor, pc, pc); }
/** * Factory method for creating a source line annotation describing the * source line number for the instruction being visited by given visitor. * * @param visitor * a DismantleBytecode visitor which is visiting the method * @return the SourceLineAnnotation, or null if we do not have line number * information for the instruction */ public static SourceLineAnnotation fromVisitedInstruction(BytecodeScanningDetector visitor) { return fromVisitedInstruction(visitor.getClassContext(), visitor, visitor.getPC()); }
/** * Add a source line annotation describing the source line numbers for a * range of instructions in the method being visited by the given visitor. * Note that if the method does not have line number information, then no * source line annotation will be added. * * @param visitor * a BetterVisitor which is visiting the method * @param startPC * the bytecode offset of the start instruction in the range * @param endPC * the bytecode offset of the end instruction in the range * @return this object */ @Nonnull public BugInstance addSourceLineRange(BytecodeScanningDetector visitor, int startPC, int endPC) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstructionRange(visitor.getClassContext(), visitor, startPC, endPC); requireNonNull(sourceLineAnnotation); add(sourceLineAnnotation); return this; }
/** * Add a source line annotation for instruction whose PC is given in the * method that the given visitor is currently visiting. Note that if the * method does not have line number information, then no source line * annotation will be added. * * @param visitor * a BytecodeScanningDetector that is currently visiting the * method * @param pc * bytecode offset of the instruction * @return this object */ @Nonnull public BugInstance addSourceLine(BytecodeScanningDetector visitor, int pc) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(visitor.getClassContext(), visitor, pc); if (sourceLineAnnotation != null) { add(sourceLineAnnotation); } return this; }
public SourceLineAnnotation getCurrentSwitchStatement(BytecodeScanningDetector detector) { if (switchOffsetStack.isEmpty()) { throw new IllegalStateException("No current switch statement"); } SwitchDetails details = switchOffsetStack.get(switchOffsetStack.size()-1); return SourceLineAnnotation.fromVisitedInstructionRange( detector.getClassContext(), detector, details.switchPC, details.switchPC + details.maxOffset-1); } public static class SwitchDetails {
/** * Factory method for creating a source line annotation describing the * source line number for the instruction being visited by given visitor. * * @param visitor * a BetterVisitor which is visiting the method * @param pc * the bytecode offset of the instruction in the method * @return the SourceLineAnnotation, or null if we do not have line number * information for the instruction */ public static SourceLineAnnotation fromVisitedInstruction(BytecodeScanningDetector visitor, int pc) { return fromVisitedInstructionRange(visitor.getClassContext(), visitor, pc, pc); }
/** * Factory method for creating a source line annotation describing the * source line number for the instruction being visited by given visitor. * * @param visitor * a DismantleBytecode visitor which is visiting the method * @return the SourceLineAnnotation, or null if we do not have line number * information for the instruction */ public static SourceLineAnnotation fromVisitedInstruction(BytecodeScanningDetector visitor) { return fromVisitedInstruction(visitor.getClassContext(), visitor, visitor.getPC()); }
/** * Add a source line annotation describing the source line numbers for a * range of instructions in the method being visited by the given visitor. * Note that if the method does not have line number information, then no * source line annotation will be added. * * @param visitor * a BetterVisitor which is visiting the method * @param startPC * the bytecode offset of the start instruction in the range * @param endPC * the bytecode offset of the end instruction in the range * @return this object */ @Nonnull public BugInstance addSourceLineRange(BytecodeScanningDetector visitor, int startPC, int endPC) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstructionRange(visitor.getClassContext(), visitor, startPC, endPC); requireNonNull(sourceLineAnnotation); add(sourceLineAnnotation); return this; }
/** * Add a source line annotation for instruction whose PC is given in the * method that the given visitor is currently visiting. Note that if the * method does not have line number information, then no source line * annotation will be added. * * @param visitor * a BytecodeScanningDetector that is currently visiting the * method * @param pc * bytecode offset of the instruction * @return this object */ @Nonnull public BugInstance addSourceLine(BytecodeScanningDetector visitor, int pc) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.fromVisitedInstruction(visitor.getClassContext(), visitor, pc); if (sourceLineAnnotation != null) { add(sourceLineAnnotation); } return this; }