[nullsafe][annotation graph] Support `Object.equals()`

Summary:
There is a feature in Nullsafe that is interfering with "annotation
graph" feature. Because of this we would not detect provisional
violations for misuses of params of equals() (They will be recorded
as user facing rather than provisional issues).

This diff turns this feature off for annotation graph mode.

Reviewed By: artempyanykh

Differential Revision: D24726655

fbshipit-source-id: 4b7577667
master
Mitya Lyubarskiy 4 years ago committed by Facebook GitHub Bot
parent 192de51707
commit dc16825ba7

@ -25,8 +25,19 @@ let callback1 ({IntraproceduralAnalysis.proc_desc= curr_pdesc; _} as analysis_da
has very special meaning and nullability limitations (it can never be null). has very special meaning and nullability limitations (it can never be null).
*) *)
TypeOrigin.This TypeOrigin.This
else if PatternMatch.Java.is_override_of_lang_object_equals curr_pname then (* An extra feature of Nullsafe. If the method overrides `Object.equals()`, but does not specify @Nullable annotation for the param,
TypeOrigin.CurrMethodParameter ObjectEqualsOverride a normal "inconsistent subclass parameter annotation" will be issued.
But apart from this we want to issue additional violations every time the value is used as a non-nullable.
This is to distinct "benign" cases where the value is simply not annotated from real bugs where e.g. the value is actually dereferenced.
We achieve this via having a special TypeOrigin for this param, which will be considered as nullable in relevant places.
*)
else if
PatternMatch.Java.is_override_of_lang_object_equals curr_pname
&& (* Turn this feature off for annotation graph mode. In this mode not annotated, but potentially nullable params
are treated in special way, and this conflicts with the trick that is being made here.
*)
not Config.nullsafe_annotation_graph
then TypeOrigin.CurrMethodParameter ObjectEqualsOverride
else TypeOrigin.CurrMethodParameter (Normal param_signature) else TypeOrigin.CurrMethodParameter (Normal param_signature)
in in
let inferred_nullability = InferredNullability.create origin in let inferred_nullability = InferredNullability.create origin in

@ -72,6 +72,12 @@ public class AnnotationGraph {
methodC().toString(); // violation for methodC methodC().toString(); // violation for methodC
} }
@Override
public boolean equals(Object obj) {
// violation for obj
return toString() == obj.toString();
}
} }
class SomeExternalClass { class SomeExternalClass {

@ -19,20 +19,20 @@ AnnotationGraph:
kind: Field kind: Field
field_name: fieldD field_name: fieldD
num_violations: 1 num_violations: 1
dependent_point_ids: [m3] dependent_point_ids: [m4]
Annotation point: Annotation point:
id: m3 id: m4
kind: Method kind: Method
method_info: method_info:
method_name: methodA method_name: methodA
params: java.lang.String, boolean params: java.lang.String, boolean
access_level: Private access_level: Private
num_violations: 0 num_violations: 0
dependent_point_ids: [m5] dependent_point_ids: [m6]
Annotation point: Annotation point:
id: m5 id: m6
kind: Method kind: Method
method_info: method_info:
method_name: methodB method_name: methodB
@ -42,7 +42,7 @@ AnnotationGraph:
dependent_point_ids: [] dependent_point_ids: []
Annotation point: Annotation point:
id: m6 id: m7
kind: Method kind: Method
method_info: method_info:
method_name: methodC method_name: methodC
@ -52,7 +52,18 @@ AnnotationGraph:
dependent_point_ids: [] dependent_point_ids: []
Annotation point: Annotation point:
id: p4 id: p3
kind: Param
method_info:
method_name: equals
params: java.lang.Object
access_level: Public
param_num: 0
num_violations: 1
dependent_point_ids: []
Annotation point:
id: p5
kind: Param kind: Param
method_info: method_info:
method_name: methodA method_name: methodA
@ -60,11 +71,11 @@ AnnotationGraph:
access_level: Private access_level: Private
param_num: 0 param_num: 0
num_violations: 0 num_violations: 0
dependent_point_ids: [f0, m3] dependent_point_ids: [f0, m4]
codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, Linters_dummy_method, 12, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph, issues: 3, curr_mode: "Default" codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, Linters_dummy_method, 12, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph, issues: 4, curr_mode: "Default"
codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, Linters_dummy_method, 77, ERADICATE_ANNOTATION_GRAPH, no_bucket, INFO, [], SomeExternalClass, codetoanalyze.java.nullsafe_annotation_graph codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, Linters_dummy_method, 83, ERADICATE_ANNOTATION_GRAPH, no_bucket, INFO, [], SomeExternalClass, codetoanalyze.java.nullsafe_annotation_graph
AnnotationGraph: AnnotationGraph:
Annotation point: Annotation point:
id: p0 id: p0
@ -78,7 +89,8 @@ AnnotationGraph:
dependent_point_ids: [] dependent_point_ids: []
codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, Linters_dummy_method, 77, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `SomeExternalClass` is free of nullability issues. Mark it `@Nullsafe(Nullsafe.Mode.LOCAL)` to prevent regressions.], SomeExternalClass, codetoanalyze.java.nullsafe_annotation_graph, issues: 0, curr_mode: "Default", promote_mode: "Strict" codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, Linters_dummy_method, 83, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `SomeExternalClass` is free of nullability issues. Mark it `@Nullsafe(Nullsafe.Mode.LOCAL)` to prevent regressions.], SomeExternalClass, codetoanalyze.java.nullsafe_annotation_graph, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, codetoanalyze.java.nullsafe_annotation_graph.AnnotationGraph.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `fieldD` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, codetoanalyze.java.nullsafe_annotation_graph.AnnotationGraph.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `fieldD` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph
codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, codetoanalyze.java.nullsafe_annotation_graph.AnnotationGraph.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `fieldB` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, codetoanalyze.java.nullsafe_annotation_graph.AnnotationGraph.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `fieldB` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph
codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, codetoanalyze.java.nullsafe_annotation_graph.AnnotationGraph.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `fieldA` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, codetoanalyze.java.nullsafe_annotation_graph.AnnotationGraph.<init>(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `fieldA` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph
codetoanalyze/java/nullsafe-annotation-graph/AnnotationGraph.java, codetoanalyze.java.nullsafe_annotation_graph.AnnotationGraph.equals(java.lang.Object):boolean, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [Parameter `obj` is missing `@Nullable` declaration: according to the Java Specification, for any object `x` call `x.equals(null)` should properly return false.], AnnotationGraph, codetoanalyze.java.nullsafe_annotation_graph

Loading…
Cancel
Save