Class ReflectiveAccessTracker
- java.lang.Object
-
- edu.umd.cs.findbugs.detect.ReflectiveAccessTracker
-
class ReflectiveAccessTracker extends java.lang.ObjectTracks the fields accessed through reflection such as VarHandles, MethodHandles and AtomicFieldUpdaters.Only one shape is recognized, and every condition below has to hold for a field to be tracked:
- the accessor is created by
Lookup.findVarHandle,Lookup.findGetter,Lookup.findSetter, their static counterpartsLookup.findStaticVarHandle,Lookup.findStaticGetterandLookup.findStaticSetter, ornewUpdateron one of the reference, integer and longAtomicFieldUpdaterclasses. - the accessor is stored into a static field by the instruction immediately following the creating call.
- the accessor is invoked directly on the value loaded from that static field.
- that static field is assigned at a single creation site (see the known limitation below).
Everything else is invisible here, so such a field keeps whatever
UUF/URF/UWFreport the ordinary analysis produces for it. That includes accessors stored into an instance field, kept in a local variable, cached in an array or a map, returned from a factory method or never stored at all; accessors whose accessed class or field name is not a compile-time constant at the creation site; accessors obtained fromLookup.unreflect*,java.lang.reflect.FieldorUnsafe; and invocations made on a derived accessor such as the result ofMethodHandle.asType,bindToorVarHandle.toMethodHandle.Known limitation: if the same static field is assigned at several creation sites, for example in the branches of an
if, every invocation is attributed to the first assignment only. The targets of the other assignments are then reported as if their accessors were never used. - the accessor is created by
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description (package private) static classReflectiveAccessTracker.AccessType
-
Field Summary
Fields Modifier and Type Field Description private java.util.Map<XField,ReflectiveFieldAccessor>accessorByAccessorFieldprivate java.util.List<ReflectiveFieldAccessor>accessorsprivate MultiMap<XField,ReflectiveFieldAccessor>accessorsByActualFieldprivate java.util.Set<XField>gettersInvokedprivate java.util.List<ReflectiveInvocation>invocationsprivate java.util.Set<XField>settersInvoked
-
Constructor Summary
Constructors Constructor Description ReflectiveAccessTracker()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private SourceLineAnnotationfindAccessorLineFor(ReflectiveAccessTracker.AccessType accessType, java.util.Collection<ReflectiveFieldAccessor> fieldAccessors)private SourceLineAnnotationfirstAccessorLine(java.util.Collection<ReflectiveFieldAccessor> fieldAccessors)(package private) java.util.Set<XField>getAllAccessedFields()(package private) java.util.Map<XField,SourceLineAnnotation>getFieldsNeverRead()(package private) java.util.Map<XField,SourceLineAnnotation>getFieldsNeverWritten()private SourceLineAnnotationgetMostRelevantAccessorLine(XField actualField)Returns the declaration source line of the most relevant accessor for a bug report.(package private) MultiMap<XField,SourceLineAnnotation>getUnusedAccessorDeclarationLines()(package private) java.util.Set<XField>getWrittenFields()(package private) voidnewAccessorDeclared(ReflectiveFieldAccessor accessor)(package private) voidregisterReflectiveInvocation(ReflectiveInvocation invocation)(package private) voidresolve()private java.util.Map<XField,SourceLineAnnotation>selectFieldsWithLines(java.util.function.Predicate<XField> filter)
-
-
-
Field Detail
-
accessors
private final java.util.List<ReflectiveFieldAccessor> accessors
-
accessorByAccessorField
private final java.util.Map<XField,ReflectiveFieldAccessor> accessorByAccessorField
-
accessorsByActualField
private final MultiMap<XField,ReflectiveFieldAccessor> accessorsByActualField
-
invocations
private final java.util.List<ReflectiveInvocation> invocations
-
gettersInvoked
private final java.util.Set<XField> gettersInvoked
-
settersInvoked
private final java.util.Set<XField> settersInvoked
-
-
Method Detail
-
newAccessorDeclared
void newAccessorDeclared(ReflectiveFieldAccessor accessor)
-
registerReflectiveInvocation
void registerReflectiveInvocation(ReflectiveInvocation invocation)
-
resolve
void resolve()
-
getFieldsNeverWritten
java.util.Map<XField,SourceLineAnnotation> getFieldsNeverWritten()
-
getFieldsNeverRead
java.util.Map<XField,SourceLineAnnotation> getFieldsNeverRead()
-
getAllAccessedFields
java.util.Set<XField> getAllAccessedFields()
-
getWrittenFields
java.util.Set<XField> getWrittenFields()
-
selectFieldsWithLines
private java.util.Map<XField,SourceLineAnnotation> selectFieldsWithLines(java.util.function.Predicate<XField> filter)
-
getUnusedAccessorDeclarationLines
MultiMap<XField,SourceLineAnnotation> getUnusedAccessorDeclarationLines()
-
getMostRelevantAccessorLine
private SourceLineAnnotation getMostRelevantAccessorLine(XField actualField)
Returns the declaration source line of the most relevant accessor for a bug report. When the field is read but never written, points to the setter-accessor's declaration line. When the field is written but never read, points to the getter-accessor's declaration line. Otherwise falls back to the declaration line of the first registered accessor.
-
firstAccessorLine
private SourceLineAnnotation firstAccessorLine(java.util.Collection<ReflectiveFieldAccessor> fieldAccessors)
-
findAccessorLineFor
private SourceLineAnnotation findAccessorLineFor(ReflectiveAccessTracker.AccessType accessType, java.util.Collection<ReflectiveFieldAccessor> fieldAccessors)
-
-