Class BloatedAssignmentScope

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.BloatedAssignmentScope
All Implemented Interfaces:
edu.umd.cs.findbugs.Detector, edu.umd.cs.findbugs.Priorities, org.apache.bcel.classfile.Visitor

@CustomUserValue public class BloatedAssignmentScope extends edu.umd.cs.findbugs.BytecodeScanningDetector
looks for variable assignments at a scope larger than its use. In this case, the assignment can be pushed down into the smaller scope to reduce the performance impact of that assignment.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    private class 
    holds the description of a scope { } block, be it a for, if, while block
    (package private) static class 
    represents the source of an assignment to a variable, which could be a method call or a field
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    (package private) edu.umd.cs.findbugs.BugReporter
     
    private BitSet
     
    private static final Set<String>
     
    private static final Set<Pattern>
     
    private static final Set<FQMethod>
     
    private static final Set<String>
     
    private boolean
     
    (package private) BitSet
     
    private List<Integer>
     
     
    private boolean
     
    private boolean
     
    private edu.umd.cs.findbugs.OpcodeStack
     
    private BitSet
     
    private BitSet
     

    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
    BloatedAssignmentScope(edu.umd.cs.findbugs.BugReporter bugReporter)
    constructs a BAS detector given the reporter to report bugs on
  • Method Summary

    Modifier and Type
    Method
    Description
    private int
    returns the catch handler for a given try block
    looks for the ScopeBlock has the same parent as this given one, but precedes it in the list.
    returns the scope block in which this register was assigned, by traversing the scope block tree
    returns an existing scope block that has the same target as the one looked for
    finds the scope block that is the active synchronized block
    private Comparable<?>
    returns either a register number of a field reference of the object that a method is being called on, or null, if it can't be determined.
    boolean
     
    boolean
     
    private void
    sawBranch(int seen, int pc)
    creates a scope block to describe this branch location.
     
    private void
    sawIINC(int pc)
    processes a register IINC by updating the appropriate scope block to mark this register as being stored in the block
    processes a instance method call to see if that call is modifies state or is otherwise'risky', if so mark the variable(s) associated with the caller as not reportable
    private void
    sawLoad(int seen, int pc)
    processes a register store by updating the appropriate scope block to mark this register as being read in the block
    private void
    processes a monitor enter call to create a scope block
    private void
    processes a monitor exit to set the end of the already created scope block
    void
    sawOpcode(int seen)
    implements the visitor to look for variables assigned below the scope in which they are used.
    private void
    sawPutField(int pc)
     
    processes a static call or initializer by checking to see if the call is risky, and returning a OpcodeStack item user value saying so.
    private void
    sawStore(int seen, int pc)
    processes a register store by updating the appropriate scope block to mark this register as being stored in the block
    private void
    sawSwitch(int pc)
    creates a new scope block for each case statement
    void
    visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
    implements the visitor to create and the clear the register to location map
    void
    visitCode(org.apache.bcel.classfile.Code obj)
    implements the visitor to reset the register to location map

    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

    • dangerousAssignmentClassSources

      private static final Set<String> dangerousAssignmentClassSources
    • dangerousAssignmentMethodSources

      private static final Set<FQMethod> dangerousAssignmentMethodSources
    • dangerousAssignmentMethodPatterns

      private static final Set<Pattern> dangerousAssignmentMethodPatterns
    • dangerousStoreClassSigs

      private static final Set<String> dangerousStoreClassSigs
    • bugReporter

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

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

      BitSet ignoreRegs
    • rootScopeBlock

      private BloatedAssignmentScope.ScopeBlock rootScopeBlock
    • tryBlocks

      private BitSet tryBlocks
    • catchHandlers

      private BitSet catchHandlers
    • switchTargets

      private BitSet switchTargets
    • monitorSyncPCs

      private List<Integer> monitorSyncPCs
    • dontReport

      private boolean dontReport
    • sawDup

      private boolean sawDup
    • sawNull

      private boolean sawNull
  • Constructor Details

    • BloatedAssignmentScope

      public BloatedAssignmentScope(edu.umd.cs.findbugs.BugReporter bugReporter)
      constructs a BAS 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 create and the clear the register to location map
      Specified by:
      visitClassContext in interface edu.umd.cs.findbugs.Detector
      Overrides:
      visitClassContext in class edu.umd.cs.findbugs.BytecodeScanningDetector
      Parameters:
      classContext - the context object of the currently parsed class
    • visitCode

      public void visitCode(org.apache.bcel.classfile.Code obj)
      implements the visitor to reset the register to location map
      Specified by:
      visitCode in interface org.apache.bcel.classfile.Visitor
      Overrides:
      visitCode in class edu.umd.cs.findbugs.visitclass.PreorderVisitor
      Parameters:
      obj - the context object of the currently parsed code block
    • sawOpcode

      public void sawOpcode(int seen)
      implements the visitor to look for variables assigned below the scope in which they are used.
      Overrides:
      sawOpcode in class edu.umd.cs.findbugs.visitclass.DismantleBytecode
      Parameters:
      seen - the opcode of the currently parsed instruction
    • sawStore

      private void sawStore(int seen, int pc)
      processes a register store by updating the appropriate scope block to mark this register as being stored in the block
      Parameters:
      seen - the currently parsed opcode
      pc - the current program counter
    • sawIINC

      private void sawIINC(int pc)
      processes a register IINC by updating the appropriate scope block to mark this register as being stored in the block
      Parameters:
      pc - the current program counter
    • sawLoad

      private void sawLoad(int seen, int pc)
      processes a register store by updating the appropriate scope block to mark this register as being read in the block
      Parameters:
      seen - the currently parsed opcode
      pc - the current program counter
    • sawBranch

      private void sawBranch(int seen, int pc)
      creates a scope block to describe this branch location.
      Parameters:
      seen - the currently parsed opcode
      pc - the current program counter
    • sawSwitch

      private void sawSwitch(int pc)
      creates a new scope block for each case statement
      Parameters:
      pc - the current program counter
    • sawInstanceCall

      @Nullable private BloatedAssignmentScope.UserObject sawInstanceCall(int pc)
      processes a instance method call to see if that call is modifies state or is otherwise'risky', if so mark the variable(s) associated with the caller as not reportable
      Parameters:
      pc - the current program counter
      Returns:
      a user object to place on the return value's OpcodeStack item
    • sawStaticCall

      @Nullable private BloatedAssignmentScope.UserObject sawStaticCall()
      processes a static call or initializer by checking to see if the call is risky, and returning a OpcodeStack item user value saying so.
      Returns:
      the user object to place on the OpcodeStack
    • sawGetField

      @Nullable private BloatedAssignmentScope.UserObject sawGetField()
    • sawPutField

      private void sawPutField(int pc)
    • sawMonitorEnter

      private void sawMonitorEnter(int pc)
      processes a monitor enter call to create a scope block
      Parameters:
      pc - the current program counter
    • sawMonitorExit

      private void sawMonitorExit(int pc)
      processes a monitor exit to set the end of the already created scope block
      Parameters:
      pc - the current program counter
    • getCallingObject

      @Nullable private Comparable<?> getCallingObject()
      returns either a register number of a field reference of the object that a method is being called on, or null, if it can't be determined.
      Returns:
      either an Integer for a register, or a String for the field name, or null
    • findScopeBlock

      @Nullable private BloatedAssignmentScope.ScopeBlock findScopeBlock(BloatedAssignmentScope.ScopeBlock sb, int pc)
      returns the scope block in which this register was assigned, by traversing the scope block tree
      Parameters:
      sb - the scope block to start searching in
      pc - the current program counter
      Returns:
      the scope block or null if not found
    • findScopeBlockWithTarget

      private BloatedAssignmentScope.ScopeBlock findScopeBlockWithTarget(BloatedAssignmentScope.ScopeBlock sb, int start, int target)
      returns an existing scope block that has the same target as the one looked for
      Parameters:
      sb - the scope block to start with
      start - the current pc
      target - the target to look for
      Returns:
      the scope block found or null
    • findPreviousSiblingScopeBlock

      @Nullable private BloatedAssignmentScope.ScopeBlock findPreviousSiblingScopeBlock(BloatedAssignmentScope.ScopeBlock sb)
      looks for the ScopeBlock has the same parent as this given one, but precedes it in the list.
      Parameters:
      sb - the scope block to look for the previous scope block
      Returns:
      the previous sibling scope block, or null if doesn't exist
    • findSynchronizedScopeBlock

      private BloatedAssignmentScope.ScopeBlock findSynchronizedScopeBlock(BloatedAssignmentScope.ScopeBlock sb, int monitorEnterPC)
      finds the scope block that is the active synchronized block
      Parameters:
      sb - the parent scope block to start with
      monitorEnterPC - the pc where the current synchronized block starts
      Returns:
      the scope block
    • findCatchHandlerFor

      private int findCatchHandlerFor(int pc)
      returns the catch handler for a given try block
      Parameters:
      pc - the current instruction
      Returns:
      the pc of the handler for this pc if it's the start of a try block, or -1
    • isRiskyMethodCall

      public boolean isRiskyMethodCall()
    • isRiskyStoreClass

      public boolean isRiskyStoreClass(int reg)