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 Classes
    Modifier and Type
    Class
    Description
    (package private) static class 
    represents the byte offset code range of code that is executed inside an if block
    (package private) static class 
    represents all the if blocks in a method
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    if an previous if block has been closed off with a return, hold onto it.
    private edu.umd.cs.findbugs.BugReporter
     
    private static final String
     
    private static final String
     
    private BitSet
     
    private BitSet
     
    private BitSet
     
     
    private boolean
    if 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
    private static final double
     
    private double
     
    private static final double
     
    private double
     
    private static final BitSet
     
    private edu.umd.cs.findbugs.OpcodeStack
     

    Fields inherited from class edu.umd.cs.findbugs.visitclass.DismantleBytecode

    codeBytes, lineNumberTable, M_BR, M_CP, M_INT, M_PAD, M_R, M_UINT

    Fields inherited from interface edu.umd.cs.findbugs.Priorities

    EXP_PRIORITY, HIGH_PRIORITY, IGNORE_PRIORITY, LOW_PRIORITY, NORMAL_PRIORITY
  • Constructor Summary

    Constructors
    Constructor
    Description
    BuryingLogic(edu.umd.cs.findbugs.BugReporter bugReporter)
    constructs a BL detector given the reporter to report bugs on
  • Method Summary

    Modifier and Type
    Method
    Description
    private boolean
    gotoAcrossPC(int pc)
    returns whether the last downward branching jump seen crosses over the current location
    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.
    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.
    void
    visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
    implements the visitor to reset the opcode stack, and initialize if tracking collections
    void
    visitCode(org.apache.bcel.classfile.Code obj)
     

    Methods inherited from class edu.umd.cs.findbugs.BytecodeScanningDetector

    getClassContext, report, shouldVisitCode

    Methods 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, visit

    Methods inherited from class edu.umd.cs.findbugs.visitclass.AnnotationVisitor

    getAnnotationParameterAsEnum, getAnnotationParameterAsString, getAnnotationParameterAsStringArray, visitAnnotation, visitAnnotation, visitParameterAnnotation, visitParameterAnnotation, visitSyntheticParameterAnnotation

    Methods 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, visitStackMapEntry

    Methods 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, visitUnknown

    Methods inherited from class java.lang.Object

    equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait

    Methods 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

      private static final String BURY_LOGIC_LOW_RATIO_PROPERTY
      See Also:
    • BURY_LOGIC_NORMAL_RATIO_PROPERTY

      private static final String 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

      private static final BitSet resetOps
    • bugReporter

      private edu.umd.cs.findbugs.BugReporter bugReporter
    • stack

      private edu.umd.cs.findbugs.OpcodeStack stack
    • ifBlocks

      private BuryingLogic.IfBlocks ifBlocks
    • activeUnconditional

      private BuryingLogic.IfBlock activeUnconditional
      if an previous if block has been closed off with a return, hold onto it.
    • casePositions

      private BitSet casePositions
    • lowBugRatioLimit

      private double lowBugRatioLimit
    • normalBugRatioLimit

      private double normalBugRatioLimit
    • catchPCs

      private BitSet catchPCs
    • gotoBranchPCs

      private BitSet gotoBranchPCs
    • lookingForResetOp

      private boolean lookingForResetOp
      if 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:
      visitClassContext in interface edu.umd.cs.findbugs.Detector
      Overrides:
      visitClassContext in class edu.umd.cs.findbugs.BytecodeScanningDetector
      Parameters:
      classContext - the currently parsed java class
    • visitCode

      public void visitCode(org.apache.bcel.classfile.Code obj)
      Specified by:
      visitCode in interface org.apache.bcel.classfile.Visitor
      Overrides:
      visitCode in class edu.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:
      sawOpcode in class edu.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