Class PossiblyRedundantMethodCalls

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

@CustomUserValue public class PossiblyRedundantMethodCalls extends edu.umd.cs.findbugs.BytecodeScanningDetector
looks for calls of the same method on the same object when that object hasn't changed. This often is redundant, and the second call can be removed, or combined.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    (package private) static class 
    contains information about a field access
    (package private) static class 
    contains information about a method call
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private BitSet
     
    private final edu.umd.cs.findbugs.BugReporter
     
    private static final Set<FQMethod>
     
     
    private static int
     
    private static int
     
     
    private static int
     
    private static int
     
    private static int
     
    private static int
     
    static final String
     
    static final String
     
    static final String
     
    static final String
     
    static final String
     
    static final String
     
    static final String
     
    static final String
     
    private static Set<String>
     
    private static Set<String>
    a collection of names that are to be checked against a currently parsed method, to see if that method is risky to be called redundant.
    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
    PossiblyRedundantMethodCalls(edu.umd.cs.findbugs.BugReporter bugReporter)
    constructs a PRMC detector given the reporter to report bugs on
  • Method Summary

    Modifier and Type
    Method
    Description
    private void
     
    private static int
    getBugPriority(String methodName, MethodInfo mi)
    returns the bug priority based on metrics about the method
    private int
    getLineNumber(int pc)
    returns the source line number for the pc, or just the pc if the line number table doesn't exist
    private static boolean
    isRiskyName(String className, String methodName)
    returns true if the class or method name contains a pattern that is considered likely to be this modifying
    void
    sawOpcode(int seen)
    implements the visitor to look for repetitive calls to the same method on the same object using the same constant parameters.
    void
    visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
    implements the visitor to create and clear the stack, method call maps, and branch targets
    void
    visitCode(org.apache.bcel.classfile.Code obj)
    implements the visitor to reset the stack, and method call maps for new method Note: that when collecting branch targets, it's unfortunately not good enough to just collect the handler pcs, as javac plays fast and loose, and will sometimes jam code below the end pc and before the first handler pc, which gets executed.

    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

    • PRMC_RISKY_FIELD_USER_KEY

      public static final String PRMC_RISKY_FIELD_USER_KEY
      See Also:
    • PRMC_RISKY_CLASS_USER_KEY

      public static final String PRMC_RISKY_CLASS_USER_KEY
      See Also:
    • PRMC_HIGH_BYTECOUNT

      public static final String PRMC_HIGH_BYTECOUNT
      See Also:
    • PRMC_HIGH_METHODCALLS

      public static final String PRMC_HIGH_METHODCALLS
      See Also:
    • PRMC_NORMAL_BYTECOUNT

      public static final String PRMC_NORMAL_BYTECOUNT
      See Also:
    • PRMC_NORMAL_METHODCALLS

      public static final String PRMC_NORMAL_METHODCALLS
      See Also:
    • PRMC_LOW_BYTECOUNT

      public static final String PRMC_LOW_BYTECOUNT
      See Also:
    • PRMC_LOW_METHODCALLS

      public static final String PRMC_LOW_METHODCALLS
      See Also:
    • riskyMethodNameContents

      private static Set<String> riskyMethodNameContents
      a collection of names that are to be checked against a currently parsed method, to see if that method is risky to be called redundant. The contents are either
      • a simple name that can be found as part of the methodName, like "destroy" which would match destroy(), or destroyAll()
      • a fully qualified method name that exactly matches a method, like "java/lang/String.valueOf"
    • highByteCountLimit

      private static int highByteCountLimit
    • highMethodCallLimit

      private static int highMethodCallLimit
    • normalByteCountLimit

      private static int normalByteCountLimit
    • normalMethodCallLimit

      private static int normalMethodCallLimit
    • lowByteCountLimit

      private static int lowByteCountLimit
    • lowMethodCallLimit

      private static int lowMethodCallLimit
    • riskyClassNames

      private static Set<String> riskyClassNames
    • commonMethods

      private static final Set<FQMethod> commonMethods
    • bugReporter

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

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

    • fieldMethodCalls

    • staticMethodCalls

    • branchTargets

      private BitSet branchTargets
  • Constructor Details

    • PossiblyRedundantMethodCalls

      public PossiblyRedundantMethodCalls(edu.umd.cs.findbugs.BugReporter bugReporter)
      constructs a PRMC 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 clear the stack, method call maps, and branch targets
      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 visited class
    • visitCode

      public void visitCode(org.apache.bcel.classfile.Code obj)
      implements the visitor to reset the stack, and method call maps for new method Note: that when collecting branch targets, it's unfortunately not good enough to just collect the handler pcs, as javac plays fast and loose, and will sometimes jam code below the end pc and before the first handler pc, which gets executed. So we need to clear our maps if we go past the end pc as well.
      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 repetitive calls to the same method on the same object using the same constant parameters. These methods must return a value.
      Overrides:
      sawOpcode in class edu.umd.cs.findbugs.visitclass.DismantleBytecode
      Parameters:
      seen - the opcode of the currently parsed instruction
    • clearFieldMethods

      private void clearFieldMethods(String fieldSource)
    • getBugPriority

      private static int getBugPriority(String methodName, MethodInfo mi)
      returns the bug priority based on metrics about the method
      Parameters:
      methodName - TODO
      mi - metrics about the method
      Returns:
      the bug priority
    • isRiskyName

      private static boolean isRiskyName(String className, String methodName)
      returns true if the class or method name contains a pattern that is considered likely to be this modifying
      Parameters:
      className - the class name to check
      methodName - the method name to check
      Returns:
      whether the method sounds like it modifies this
    • getLineNumber

      private int getLineNumber(int pc)
      returns the source line number for the pc, or just the pc if the line number table doesn't exist
      Parameters:
      pc - current pc
      Returns:
      the line number