Class OverlyConcreteParameter

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

public class OverlyConcreteParameter extends edu.umd.cs.findbugs.BytecodeScanningDetector
looks for parameters that are defined by classes, but only use methods defined by an implemented interface or super class. Relying on concrete classes in public signatures causes cohesion, and makes low impact changes more difficult.
  • Nested Class Summary

    Nested Classes
    Modifier and Type
    Class
    Description
    (package private) static class 
    an inner helper class that holds basic information about a method
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private final edu.umd.cs.findbugs.BugReporter
     
    private org.apache.bcel.classfile.JavaClass
     
    private org.apache.bcel.classfile.JavaClass[]
     
    private static final Set<String>
     
    private static final Set<String>
     
    private static final Set<String>
     
    private boolean
     
    private boolean
     
    private org.apache.bcel.classfile.JavaClass
     
    private static final Set<String>
     
    private Map<Integer,Map<org.apache.bcel.classfile.JavaClass,List<OverlyConcreteParameter.MethodInfo>>>
     
    private int
     
    private edu.umd.cs.findbugs.OpcodeStack
     
    private edu.umd.cs.findbugs.OpcodeStack.Item
     
    private edu.umd.cs.findbugs.OpcodeStack.Item
     
    private int
     
    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
    OverlyConcreteParameter(edu.umd.cs.findbugs.BugReporter bugReporter)
    constructs a OCP detector given the reporter to report bugs on
  • Method Summary

    Modifier and Type
    Method
    Description
    private boolean
    builds a map of method information for each method of each interface that each parameter implements of this method
    private static String
    getCardinality(int num)
    returns a string defining what parameter in the signature a certain one is, for the bug report
    private static Map<org.apache.bcel.classfile.JavaClass,List<OverlyConcreteParameter.MethodInfo>>
    getClassDefiners(org.apache.bcel.classfile.JavaClass cls)
    returns a map of method information for each public method for each interface this class implements
    getPublicMethodInfos(org.apache.bcel.classfile.JavaClass cls)
    returns a list of method information of all public or protected methods in this class
    private boolean
    looks to see if this method has an overloaded method in actuality, this isn't precise and returns true for methods that are named the same, and have same number of args This will miss some cases, but in practicality doesn't matter.
    private boolean
    isaConversionClass(org.apache.bcel.classfile.JavaClass conversionCls)
    returns whether this class is used to convert types of some sort, such that you don't want to suggest reducing the class specified to be more generic
    private boolean
    returns whether this exception is handled either in a try/catch or throws clause at this pc
    private boolean
    methodHasSyntheticTwin(String methodName, String methodSig)
    returns whether this method has an equivalent method that is synthetic, which implies this method is constrained by some Generified interface.
    private static boolean
    methodIsSpecial(String methodName, String methodSig)
    determines whether the method is a baked in special method of the jdk
    private void
    removeInheritedInterfaces(Map<org.apache.bcel.classfile.JavaClass,List<OverlyConcreteParameter.MethodInfo>> definers)
     
    private void
    removeParmDefiner(edu.umd.cs.findbugs.OpcodeStack.Item itm)
    removes a parameter from the definer list, if the item is in fact a parameter
    private void
    parses through the interface that 'may' define a parameter defined by reg, and look to see if we can rule it out, because a method is called on the object that can't be satisfied by the interface, if so remove that candidate interface.
    private void
    removeUselessDefiners(String parmSig, int reg)
     
    private void
    implements the post processing steps to report the remaining unremoved parameter definers, ie those, that can be defined more abstractly.
    void
    sawOpcode(int seen)
    implements the visitor to filter out parameter use where the actual defined type of the method declaration is needed.
    void
    visitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext)
    implements the visitor to collect classes that constrains this class (super classes/interfaces) and to reset the opcode stack
    void
    visitCode(org.apache.bcel.classfile.Code obj)
    implements the visitor to collect information about the parameters of a this method
    void
    visitMethod(org.apache.bcel.classfile.Method obj)
    implements the visitor to look to see if this method is constrained by a superclass or interface.

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

    • CONVERSION_ANNOTATIONS

      private static final Set<String> CONVERSION_ANNOTATIONS
    • CONVERSION_SUPER_CLASSES

      private static final Set<String> CONVERSION_SUPER_CLASSES
    • OVERLY_CONCRETE_INTERFACES

      private static final Set<String> OVERLY_CONCRETE_INTERFACES
    • IGNORED_INTERFACES

      private static final Set<String> IGNORED_INTERFACES
    • bugReporter

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

      private org.apache.bcel.classfile.JavaClass[] constrainingClasses
    • parameterDefiners

      private Map<Integer,Map<org.apache.bcel.classfile.JavaClass,List<OverlyConcreteParameter.MethodInfo>>> parameterDefiners
    • usedParameters

      private BitSet usedParameters
    • objectClass

      private org.apache.bcel.classfile.JavaClass objectClass
    • cls

      private org.apache.bcel.classfile.JavaClass cls
    • stack

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

      private int parmCount
    • methodSignatureIsConstrained

      private boolean methodSignatureIsConstrained
    • methodIsStatic

      private boolean methodIsStatic
    • ternary1Value

      private edu.umd.cs.findbugs.OpcodeStack.Item ternary1Value
    • ternary2Value

      private edu.umd.cs.findbugs.OpcodeStack.Item ternary2Value
    • ternaryTarget

      private int ternaryTarget
  • Constructor Details

    • OverlyConcreteParameter

      public OverlyConcreteParameter(edu.umd.cs.findbugs.BugReporter bugReporter)
      constructs a OCP 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 collect classes that constrains this class (super classes/interfaces) and to reset the opcode stack
      Specified by:
      visitClassContext in interface edu.umd.cs.findbugs.Detector
      Overrides:
      visitClassContext in class edu.umd.cs.findbugs.BytecodeScanningDetector
      Parameters:
      classContext - the currently parse class
    • visitMethod

      public void visitMethod(org.apache.bcel.classfile.Method obj)
      implements the visitor to look to see if this method is constrained by a superclass or interface.
      Specified by:
      visitMethod in interface org.apache.bcel.classfile.Visitor
      Overrides:
      visitMethod in class edu.umd.cs.findbugs.visitclass.BetterVisitor
      Parameters:
      obj - the currently parsed method
    • visitCode

      public void visitCode(org.apache.bcel.classfile.Code obj)
      implements the visitor to collect information about the parameters of a this method
      Specified by:
      visitCode in interface org.apache.bcel.classfile.Visitor
      Overrides:
      visitCode in class edu.umd.cs.findbugs.visitclass.PreorderVisitor
      Parameters:
      obj - the currently parsed code block
    • sawOpcode

      public void sawOpcode(int seen)
      implements the visitor to filter out parameter use where the actual defined type of the method declaration is needed. What remains could be more abstractly defined.
      Overrides:
      sawOpcode in class edu.umd.cs.findbugs.visitclass.DismantleBytecode
      Parameters:
      seen - the currently parsed opcode
    • removeParmDefiner

      private void removeParmDefiner(edu.umd.cs.findbugs.OpcodeStack.Item itm)
      removes a parameter from the definer list, if the item is in fact a parameter
      Parameters:
      itm - the possible parameter
    • methodIsSpecial

      private static boolean methodIsSpecial(String methodName, String methodSig)
      determines whether the method is a baked in special method of the jdk
      Parameters:
      methodName - the method name to check
      methodSig - the parameter signature of the method to check
      Returns:
      if it is a well known baked in method
    • methodHasSyntheticTwin

      private boolean methodHasSyntheticTwin(String methodName, String methodSig)
      returns whether this method has an equivalent method that is synthetic, which implies this method is constrained by some Generified interface. We could compare parameters but that is a bunch of work that probably doesn't make this test any more precise, so just return true if method name and synthetic is found.
      Parameters:
      methodName - the method name to look for a synthetic twin of
      methodSig - the method signature to lookfor a synthetic twin of
      Returns:
      if a synthetic twin is found
    • reportBugs

      private void reportBugs()
      implements the post processing steps to report the remaining unremoved parameter definers, ie those, that can be defined more abstractly.
    • hasOverloadedMethod

      private boolean hasOverloadedMethod()
      looks to see if this method has an overloaded method in actuality, this isn't precise and returns true for methods that are named the same, and have same number of args This will miss some cases, but in practicality doesn't matter.
      Returns:
      whether there is a method in this class that overrides the given method
    • removeInheritedInterfaces

      private void removeInheritedInterfaces(Map<org.apache.bcel.classfile.JavaClass,List<OverlyConcreteParameter.MethodInfo>> definers) throws ClassNotFoundException
      Throws:
      ClassNotFoundException
    • getCardinality

      private static String getCardinality(int num)
      returns a string defining what parameter in the signature a certain one is, for the bug report
      Parameters:
      num - the parameter number
      Returns:
      a string describing in english the parameter position
    • buildParameterDefiners

      private boolean buildParameterDefiners() throws ClassNotFoundException
      builds a map of method information for each method of each interface that each parameter implements of this method
      Returns:
      a map by parameter id of all the method signatures that interfaces of that parameter implements
      Throws:
      ClassNotFoundException - if the class can't be loaded
    • getClassDefiners

      private static Map<org.apache.bcel.classfile.JavaClass,List<OverlyConcreteParameter.MethodInfo>> getClassDefiners(org.apache.bcel.classfile.JavaClass cls) throws ClassNotFoundException
      returns a map of method information for each public method for each interface this class implements
      Parameters:
      cls - the class whose interfaces to record
      Returns:
      a map of (method name)(method sig) by interface
      Throws:
      ClassNotFoundException - if unable to load the class
    • getPublicMethodInfos

      private static List<OverlyConcreteParameter.MethodInfo> getPublicMethodInfos(org.apache.bcel.classfile.JavaClass cls)
      returns a list of method information of all public or protected methods in this class
      Parameters:
      cls - the class to look for methods
      Returns:
      a map of (method name)(method signature)
    • removeUselessDefiners

      private void removeUselessDefiners(int reg)
      parses through the interface that 'may' define a parameter defined by reg, and look to see if we can rule it out, because a method is called on the object that can't be satisfied by the interface, if so remove that candidate interface.
      Parameters:
      reg - the parameter register number to look at
    • isExceptionHandled

      private boolean isExceptionHandled(String ex)
      returns whether this exception is handled either in a try/catch or throws clause at this pc
      Parameters:
      ex - the name of the exception
      Returns:
      whether the exception is handled
    • removeUselessDefiners

      private void removeUselessDefiners(String parmSig, int reg)
    • isaConversionClass

      private boolean isaConversionClass(org.apache.bcel.classfile.JavaClass conversionCls)
      returns whether this class is used to convert types of some sort, such that you don't want to suggest reducing the class specified to be more generic
      Parameters:
      conversionCls - the class to check
      Returns:
      whether this class is used in conversions