Package com.mebigfatguy.fbcontrib.detect
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 ClassesModifier and TypeClassDescriptionprivate classholds the description of a scope { } block, be it a for, if, while block(package private) static classrepresents the source of an assignment to a variable, which could be a method call or a field -
Field Summary
FieldsModifier and TypeFieldDescription(package private) edu.umd.cs.findbugs.BugReporterprivate BitSetprivate boolean(package private) BitSetprivate booleanprivate booleanprivate edu.umd.cs.findbugs.OpcodeStackprivate BitSetprivate BitSetFields 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
ConstructorsConstructorDescriptionBloatedAssignmentScope(edu.umd.cs.findbugs.BugReporter bugReporter) constructs a BAS detector given the reporter to report bugs on -
Method Summary
Modifier and TypeMethodDescriptionprivate intfindCatchHandlerFor(int pc) returns the catch handler for a given try blocklooks for the ScopeBlock has the same parent as this given one, but precedes it in the list.findScopeBlock(BloatedAssignmentScope.ScopeBlock sb, int pc) returns the scope block in which this register was assigned, by traversing the scope block treefindScopeBlockWithTarget(BloatedAssignmentScope.ScopeBlock sb, int start, int target) returns an existing scope block that has the same target as the one looked forfindSynchronizedScopeBlock(BloatedAssignmentScope.ScopeBlock sb, int monitorEnterPC) finds the scope block that is the active synchronized blockprivate 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.booleanbooleanisRiskyStoreClass(int reg) private voidsawBranch(int seen, int pc) creates a scope block to describe this branch location.private voidsawIINC(int pc) processes a register IINC by updating the appropriate scope block to mark this register as being stored in the blocksawInstanceCall(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 reportableprivate voidsawLoad(int seen, int pc) processes a register store by updating the appropriate scope block to mark this register as being read in the blockprivate voidsawMonitorEnter(int pc) processes a monitor enter call to create a scope blockprivate voidsawMonitorExit(int pc) processes a monitor exit to set the end of the already created scope blockvoidsawOpcode(int seen) implements the visitor to look for variables assigned below the scope in which they are used.private voidsawPutField(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 voidsawStore(int seen, int pc) processes a register store by updating the appropriate scope block to mark this register as being stored in the blockprivate voidsawSwitch(int pc) creates a new scope block for each case statementvoidvisitClassContext(edu.umd.cs.findbugs.ba.ClassContext classContext) implements the visitor to create and the clear the register to location mapvoidvisitCode(org.apache.bcel.classfile.Code obj) implements the visitor to reset the register to location mapMethods 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
-
dangerousAssignmentClassSources
-
dangerousAssignmentMethodSources
-
dangerousAssignmentMethodPatterns
-
dangerousStoreClassSigs
-
bugReporter
edu.umd.cs.findbugs.BugReporter bugReporter -
stack
private edu.umd.cs.findbugs.OpcodeStack stack -
ignoreRegs
BitSet ignoreRegs -
rootScopeBlock
-
tryBlocks
-
catchHandlers
-
switchTargets
-
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:
visitClassContextin interfaceedu.umd.cs.findbugs.Detector- Overrides:
visitClassContextin classedu.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:
visitCodein interfaceorg.apache.bcel.classfile.Visitor- Overrides:
visitCodein classedu.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:
sawOpcodein classedu.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 opcodepc- 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 opcodepc- 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 opcodepc- 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
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
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
-
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
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 inpc- 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 withstart- the current pctarget- 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 withmonitorEnterPC- 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)
-