Package com.mebigfatguy.fbcontrib.detect
Class BuryingLogic
java.lang.Object
edu.umd.cs.findbugs.visitclass.BetterVisitor
edu.umd.cs.findbugs.visitclass.PreorderVisitor
edu.umd.cs.findbugs.visitclass.AnnotationVisitor
edu.umd.cs.findbugs.visitclass.DismantleBytecode
edu.umd.cs.findbugs.BytecodeScanningDetector
com.mebigfatguy.fbcontrib.detect.BuryingLogic
- All Implemented Interfaces:
edu.umd.cs.findbugs.Detector,edu.umd.cs.findbugs.Priorities,org.apache.bcel.classfile.Visitor
public class BuryingLogic
extends edu.umd.cs.findbugs.BytecodeScanningDetector
looks for relatively large if blocks of code, where you unconditionally
return from them, and then follow that with an unconditional return of a
small block. This places the bulk of the logic to the right indentation-wise,
making it more difficult to read than needed. It would be better to invert
the logic of the if block, and immediately return, allowing the bulk of the
logic to be move to the left, for easier reading.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static classrepresents the byte offset code range of code that is executed inside an if block(package private) static classrepresents all the if blocks in a method -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate BuryingLogic.IfBlockif an previous if block has been closed off with a return, hold onto it.private edu.umd.cs.findbugs.BugReporterprivate static final Stringprivate static final Stringprivate BitSetprivate BitSetprivate BitSetprivate BuryingLogic.IfBlocksprivate booleanif we've processed an if block, we want to avoid else ifs, so don't start looking for a new if branch, until some instruction that can't be part of a conditional is foundprivate static final doubleprivate doubleprivate static final doubleprivate doubleprivate static final BitSetprivate edu.umd.cs.findbugs.OpcodeStackFields inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
codeBytes, lineNumberTable, M_BR, M_CP, M_INT, M_PAD, M_R, M_UINTFields inherited from interface edu.umd.cs.findbugs.Priorities
EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY -
Constructor Summary
ConstructorsConstructorDescriptionBuryingLogic(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a BL detector given the reporter to report bugs on -
Method Summary
Modifier and TypeMethodDescriptionprivate booleangotoAcrossPC(int pc) returns whether the last downward branching jump seen crosses over the current locationprivate booleanisResetOp(int seen) determines if this opcode couldn't be part of a conditional expression or at least is very unlikely to be so.voidsawOpcode(int seen) the difficult problem is to figure out when you are at the bottom of an if/else chain when all the above if/else blocks leave via returns.voidvisitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext) implements the visitor to reset the opcode stack, and initialize if tracking collectionsvoidvisitCode(org.apache.bcel.classfile.Code obj) Methods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector
getClassContext, report, shouldVisitCodeMethods inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode
afterOpcode, areOppositeBranches, atCatchBlock, beforeOpcode, getBranchFallThrough, getBranchOffset, getBranchTarget, getClassConstantOperand, getClassDescriptorOperand, getCodeByte, getConstantRefOperand, getDefaultSwitchOffset, getDottedClassConstantOperand, getFieldDescriptorOperand, getIntConstant, getLongConstant, getMaxPC, getMethodDescriptorOperand, getNameConstantOperand, getNextCodeByte, getNextOpcode, getNextPC, getOpcode, getPC, getPrevOpcode, getRefConstantOperand, getRefFieldIsStatic, getRegisterOperand, getSigConstantOperand, getStringConstantOperand, getSwitchLabels, getSwitchOffsets, getXClassOperand, getXFieldOperand, getXMethodOperand, isBranch, isMethodCall, isRegisterLoad, isRegisterStore, isRegisterStore, isReturn, isShift, isSwitch, isWideOpcode, printOpCode, sawBranchTo, sawClass, sawDouble, sawField, sawFloat, sawIMethod, sawInt, sawLong, sawMethod, sawRegister, sawString, visitMethods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor
getAnnotationParameterAsEnum, getAnnotationParameterAsString, getAnnotationParameterAsStringArray, visitAnnotation, visitAnnotation, visitParameterAnnotation, visitParameterAnnotation, visitSyntheticParameterAnnotationMethods inherited from class edu.umd.cs.findbugs.visitclass.PreorderVisitor
amVisitingMainMethod, asUnsignedByte, doVisitMethod, getClassDescriptor, getClassName, getCode, getConstantPool, getDottedClassName, getDottedFieldSig, getDottedMethodSig, getDottedSuperclassName, getField, getFieldDescriptor, getFieldIsStatic, getFieldName, getFieldSig, getFullyQualifiedFieldName, getFullyQualifiedMethodName, getMethod, getMethodDescriptor, getMethodName, getMethodSig, getMethodVisitOrder, getNumberArguments, getNumberMethodArguments, getPackageName, getSizeOfSurroundingTryBlock, getSizeOfSurroundingTryBlock, getSourceFile, getStringFromIndex, getSuperclassName, getSurroundingCaughtExceptions, getSurroundingCaughtExceptions, getSurroundingCaughtExceptionTypes, getSurroundingTryBlock, getSurroundingTryBlock, getThisClass, getXClass, getXField, getXMethod, hasInterestingClass, hasInterestingMethod, isVisitMethodsInCallOrder, setupVisitorForClass, setVisitMethodsInCallOrder, shouldVisit, toString, visitAfter, visitAfter, visitAnnotationDefault, visitAnnotationEntry, visitBootstrapMethods, visitConstantInvokeDynamic, visitConstantMethodHandle, visitConstantMethodType, visitConstantModule, visitConstantPackage, visitConstantPool, visitEnclosingMethod, visitingField, visitingMethod, visitInnerClasses, visitJavaClass, visitLineNumberTable, visitLocalVariableTable, visitMethodParameters, visitParameterAnnotationEntry, visitStackMap, visitStackMapEntryMethods inherited from class edu.umd.cs.findbugs.visitclass.BetterVisitor
clone, report, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visit, visitCodeException, visitConstantClass, visitConstantDouble, visitConstantFieldref, visitConstantFloat, visitConstantInteger, visitConstantInterfaceMethodref, visitConstantLong, visitConstantMethodref, visitConstantNameAndType, visitConstantString, visitConstantUtf8, visitConstantValue, visitDeprecated, visitExceptionTable, visitField, visitInnerClass, visitLineNumber, visitLocalVariable, visitLocalVariableTypeTable, visitMethod, visitSignature, visitSourceFile, visitSynthetic, visitUnknownMethods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitMethods inherited from interface org.apache.bcel.classfile.Visitor
visitConstantDynamic, visitMethodParameter, visitModule, visitModuleExports, visitModuleMainClass, visitModuleOpens, visitModulePackages, visitModuleProvides, visitModuleRequires, visitNestHost, visitNestMembers, visitRecord, visitRecordComponent, visitStackMapType
-
Field Details
-
BURY_LOGIC_LOW_RATIO_PROPERTY
- See Also:
-
BURY_LOGIC_NORMAL_RATIO_PROPERTY
- See Also:
-
LOW_BUG_RATIO_LIMIT
private static final double LOW_BUG_RATIO_LIMIT- See Also:
-
NORMAL_BUG_RATIO_LIMIT
private static final double NORMAL_BUG_RATIO_LIMIT- See Also:
-
resetOps
-
bugReporter
private edu.umd.cs.findbugs.BugReporter bugReporter -
stack
private edu.umd.cs.findbugs.OpcodeStack stack -
ifBlocks
-
activeUnconditional
if an previous if block has been closed off with a return, hold onto it. -
casePositions
-
lowBugRatioLimit
private double lowBugRatioLimit -
normalBugRatioLimit
private double normalBugRatioLimit -
catchPCs
-
gotoBranchPCs
-
lookingForResetOp
private boolean lookingForResetOpif we've processed an if block, we want to avoid else ifs, so don't start looking for a new if branch, until some instruction that can't be part of a conditional is found
-
-
Constructor Details
-
BuryingLogic
public BuryingLogic(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a BL detector given the reporter to report bugs on- Parameters:
bugReporter- the sync of bug reports
-
-
Method Details
-
visitClassContext
public void visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext) implements the visitor to reset the opcode stack, and initialize if tracking collections- Specified by:
visitClassContextin interfaceedu.umd.cs.findbugs.Detector- Overrides:
visitClassContextin classedu.umd.cs.findbugs.BytecodeScanningDetector- Parameters:
classContext- the currently parsed java class
-
visitCode
public void visitCode(org.apache.bcel.classfile.Code obj) - Specified by:
visitCodein interfaceorg.apache.bcel.classfile.Visitor- Overrides:
visitCodein classedu.umd.cs.findbugs.visitclass.PreorderVisitor
-
sawOpcode
public void sawOpcode(int seen) the difficult problem is to figure out when you are at the bottom of an if/else chain when all the above if/else blocks leave via returns. then there is only one branch target to the statement after the last else, which is indistinquishable from a simple if/else.- Overrides:
sawOpcodein classedu.umd.cs.findbugs.visitclass.DismantleBytecode
-
gotoAcrossPC
private boolean gotoAcrossPC(int pc) returns whether the last downward branching jump seen crosses over the current location- Parameters:
pc- the current location- Returns:
- if the last if statement branched over here
-
isResetOp
private boolean isResetOp(int seen) determines if this opcode couldn't be part of a conditional expression or at least is very unlikely to be so.- Parameters:
seen- the currently parse opcode- Returns:
- if this operation resets the looking for conditionals
-