Class ReflectiveAccessTracker
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/
UWF report 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 from Lookup.unreflect*, java.lang.reflect.Field or
Unsafe; and invocations made on a derived accessor such as the result of MethodHandle.asType,
bindTo or VarHandle.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.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static enum -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final Map<XField, ReflectiveFieldAccessor> private final List<ReflectiveFieldAccessor> private final MultiMap<XField, ReflectiveFieldAccessor> private final List<ReflectiveInvocation> -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate SourceLineAnnotationfindAccessorLineFor(ReflectiveAccessTracker.AccessType accessType, Collection<ReflectiveFieldAccessor> fieldAccessors) private SourceLineAnnotationfirstAccessorLine(Collection<ReflectiveFieldAccessor> fieldAccessors) (package private) Map<XField, SourceLineAnnotation> (package private) Map<XField, SourceLineAnnotation> private SourceLineAnnotationgetMostRelevantAccessorLine(XField actualField) Returns the declaration source line of the most relevant accessor for a bug report.(package private) MultiMap<XField, SourceLineAnnotation> (package private) voidnewAccessorDeclared(ReflectiveFieldAccessor accessor) (package private) voidregisterReflectiveInvocation(ReflectiveInvocation invocation) (package private) voidresolve()private Map<XField, SourceLineAnnotation> selectFieldsWithLines(Predicate<XField> filter)
-
Field Details
-
accessors
-
accessorByAccessorField
-
accessorsByActualField
-
invocations
-
gettersInvoked
-
settersInvoked
-
-
Constructor Details
-
ReflectiveAccessTracker
ReflectiveAccessTracker()
-
-
Method Details
-
newAccessorDeclared
-
registerReflectiveInvocation
-
resolve
void resolve() -
getFieldsNeverWritten
Map<XField, SourceLineAnnotation> getFieldsNeverWritten() -
getFieldsNeverRead
Map<XField, SourceLineAnnotation> getFieldsNeverRead() -
getAllAccessedFields
-
getWrittenFields
-
selectFieldsWithLines
-
getUnusedAccessorDeclarationLines
MultiMap<XField, SourceLineAnnotation> getUnusedAccessorDeclarationLines() -
getMostRelevantAccessorLine
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
-
findAccessorLineFor
private SourceLineAnnotation findAccessorLineFor(ReflectiveAccessTracker.AccessType accessType, Collection<ReflectiveFieldAccessor> fieldAccessors)
-