[nullsafe] Introduce DeclaredNonnull

Summary:
This is an intermediate nullability type powering future Strict mode.
See the next diff.

Reviewed By: artempyanykh

Differential Revision: D17977909

fbshipit-source-id: 2d5ab66d4
master
Mitya Lyubarskiy 5 years ago committed by Facebook Github Bot
parent 681f853b20
commit 4d52e874fc

@ -16,8 +16,11 @@ module F = Format
this information is inferred according to flow-sensitive inferrence rule.
*)
(* TODO(T52947663) add notion of unknown nullability *)
type t = Nullable of nullable_origin | Nonnull of nonnull_origin [@@deriving compare]
type t =
| Nullable of nullable_origin
| DeclaredNonnull of declared_nonnull_origin (** See {Nullability.t} for explanation *)
| Nonnull of nonnull_origin
[@@deriving compare]
and nullable_origin =
| AnnotatedNullable (** The type is expicitly annotated with @Nullable in the code *)
@ -28,17 +31,21 @@ and nullable_origin =
| ModelledNullable (** nullsafe knows it is nullable via its internal models *)
[@@deriving compare]
and nonnull_origin =
and declared_nonnull_origin =
| AnnotatedNonnull
(** The type is explicitly annotated as non nullable via one of nonnull annotations Nullsafe recognizes *)
| NotAnnotatedHenceNullableMode
| ImplicitlyNonnull
(** Infer was run in mode where all not annotated (non local) types are treated as non nullable *)
and nonnull_origin =
| ModelledNonnull (** nullsafe knows it is non-nullable via its internal models *)
[@@deriving compare]
let get_nullability = function
| Nullable _ ->
Nullability.Nullable
| DeclaredNonnull _ ->
Nullability.DeclaredNonnull
| Nonnull _ ->
Nullability.Nonnull
@ -55,20 +62,19 @@ let pp fmt t =
| ModelledNullable ->
"model"
in
let string_of_declared_nonnull_origin origin =
match origin with AnnotatedNonnull -> "@" | ImplicitlyNonnull -> "implicit"
in
let string_of_nonnull_origin nonnull_origin =
match nonnull_origin with
| AnnotatedNonnull ->
"@"
| NotAnnotatedHenceNullableMode ->
"default"
| ModelledNonnull ->
"model"
match nonnull_origin with ModelledNonnull -> "model"
in
match t with
| Nullable nullable_origin ->
F.fprintf fmt "Nullable[%s]" (string_of_nullable_origin nullable_origin)
| Nonnull nonnull_origin ->
F.fprintf fmt "Nonnull[%s]" (string_of_nonnull_origin nonnull_origin)
| Nullable origin ->
F.fprintf fmt "Nullable[%s]" (string_of_nullable_origin origin)
| DeclaredNonnull origin ->
F.fprintf fmt "DeclaredNonnull[%s]" (string_of_declared_nonnull_origin origin)
| Nonnull origin ->
F.fprintf fmt "Nonnull[%s]" (string_of_nonnull_origin origin)
let of_annot_item ia =
@ -78,6 +84,6 @@ let of_annot_item ia =
else AnnotatedNullable
in
Nullable nullable_origin
else if Annotations.ia_is_nonnull ia then Nonnull AnnotatedNonnull
else if Annotations.ia_is_nonnull ia then DeclaredNonnull AnnotatedNonnull
(* Currently, we treat not annotated types as nonnull *)
else Nonnull NotAnnotatedHenceNullableMode
else DeclaredNonnull ImplicitlyNonnull

@ -19,7 +19,11 @@ open! IStd
annotated nullability applies only for types declared at methods and field level.
*)
type t = Nullable of nullable_origin | Nonnull of nonnull_origin [@@deriving compare]
type t =
| Nullable of nullable_origin
| DeclaredNonnull of declared_nonnull_origin (** See {Nullability.t} for explanation *)
| Nonnull of nonnull_origin
[@@deriving compare]
and nullable_origin =
| AnnotatedNullable (** The type is expicitly annotated with @Nullable in the code *)
@ -30,11 +34,13 @@ and nullable_origin =
| ModelledNullable (** nullsafe knows it is nullable via its internal models *)
[@@deriving compare]
and nonnull_origin =
and declared_nonnull_origin =
| AnnotatedNonnull
(** The type is explicitly annotated as non nullable via one of nonnull annotations Nullsafe recognizes *)
| NotAnnotatedHenceNullableMode
| ImplicitlyNonnull
(** Infer was run in mode where all not annotated (non local) types are treated as non nullable *)
and nonnull_origin =
| ModelledNonnull (** nullsafe knows it is non-nullable via its internal models *)
[@@deriving compare]

@ -17,8 +17,15 @@ type assignment_type =
| ReturningFromFunction of Typ.Procname.t
[@@deriving compare]
let is_whitelisted_assignment ~lhs ~rhs =
match (lhs, rhs) with Nullability.Nonnull, Nullability.DeclaredNonnull -> true | _ -> false
let check ~lhs ~rhs =
Result.ok_if_true (Nullability.is_subtype ~subtype:rhs ~supertype:lhs) ~error:{lhs; rhs}
let is_allowed_assignment =
Nullability.is_subtype ~subtype:rhs ~supertype:lhs || is_whitelisted_assignment ~lhs ~rhs
in
Result.ok_if_true is_allowed_assignment ~error:{lhs; rhs}
let violation_description _ assignment_type ~rhs_origin_descr =

@ -18,7 +18,7 @@ type dereference_type =
let check = function
| Nullability.Nullable as nullability ->
Error nullability
| Nullability.Nonnull ->
| Nullability.DeclaredNonnull | Nullability.Nonnull ->
Ok ()

@ -11,9 +11,17 @@ type t = {nullability: Nullability.t; origin: TypeOrigin.t} [@@deriving compare]
let get_nullability {nullability} = nullability
let is_nonnull {nullability} = match nullability with Nullable -> false | Nonnull -> true
let is_nonnull_or_declared_nonnull {nullability} =
match nullability with Nullable -> false | DeclaredNonnull -> true | Nonnull -> true
let set_nonnull t = {t with nullability= Nullability.Nonnull}
let is_nonnull {nullability} =
match nullability with Nullable -> false | DeclaredNonnull -> false | Nonnull -> true
let set_nullability nullability t = {t with nullability}
let set_nonnull = set_nullability Nullability.Nonnull
let descr_origin t =
let descr_opt = TypeOrigin.get_description t.origin in
@ -71,5 +79,7 @@ let of_annotated_nullability annotated_nullability origin =
match annotated_nullability with
| AnnotatedNullability.Nullable _ ->
{origin; nullability= Nullability.Nullable}
| AnnotatedNullability.DeclaredNonnull _ ->
{origin; nullability= Nullability.DeclaredNonnull}
| AnnotatedNullability.Nonnull _ ->
{origin; nullability= Nullability.Nonnull}

@ -25,6 +25,8 @@ val create_nullable : TypeOrigin.t -> t
val create_nonnull : TypeOrigin.t -> t
val is_nonnull_or_declared_nonnull : t -> bool
val is_nonnull : t -> bool
val set_nonnull : t -> t

@ -10,6 +10,18 @@ type violation = {base: Nullability.t; overridden: Nullability.t} [@@deriving co
type type_role = Param | Ret
let is_whitelisted_violation ~subtype ~supertype =
match (subtype, supertype) with
| Nullability.DeclaredNonnull, Nullability.Nonnull ->
(* It is a violation that we are currently willing to ignore because
it is hard to obey in practice.
It might lead to unsoundness issues, so this might be reconsidered.
*)
true
| _ ->
false
let check type_role ~base ~overridden =
let subtype, supertype =
match type_role with
@ -20,7 +32,9 @@ let check type_role ~base ~overridden =
(* contravariance for param *)
(base, overridden)
in
Result.ok_if_true (Nullability.is_subtype ~subtype ~supertype) ~error:{base; overridden}
Result.ok_if_true
(Nullability.is_subtype ~subtype ~supertype || is_whitelisted_violation ~subtype ~supertype)
~error:{base; overridden}
type violation_type =

@ -9,6 +9,11 @@ open! IStd
type t =
| Nullable (** No guarantees on the nullability *)
| DeclaredNonnull
(** The type comes from a signature that is annotated (explicitly or implicitly according to conventions)
as non-nullable. Hovewer, it might still contain null since the truthfullness of the declaration was
not checked.
*)
| Nonnull
(** We believe that this value can not be null. If it is not the case, this is
an unsoundness issue for Nullsafe, and we aim to minimize number of such issues
@ -18,7 +23,13 @@ type t =
let top = Nullable
let join x y =
match (x, y) with Nullable, _ | _, Nullable -> Nullable | Nonnull, Nonnull -> Nonnull
match (x, y) with
| Nullable, _ | _, Nullable ->
Nullable
| DeclaredNonnull, _ | _, DeclaredNonnull ->
DeclaredNonnull
| Nonnull, Nonnull ->
Nonnull
let is_subtype ~subtype ~supertype = equal (join subtype supertype) supertype
@ -27,4 +38,10 @@ let is_strict_subtype ~subtype ~supertype =
is_subtype ~subtype ~supertype && not (equal subtype supertype)
let to_string = function Nullable -> "Nullable" | Nonnull -> "Nonnull"
let to_string = function
| Nullable ->
"Nullable"
| DeclaredNonnull ->
"DeclaredNonnull"
| Nonnull ->
"Nonnull"

@ -18,6 +18,11 @@ open! IStd
type t =
| Nullable (** No guarantees on the nullability *)
| DeclaredNonnull
(** The type comes from a signature that is annotated (explicitly or implicitly according to conventions)
as non-nullable. Hovewer, it might still contain null since the truthfullness of the declaration was
not checked.
*)
| Nonnull
(** We believe that this value can not be null. If it is not the case, this is
an unsoundness issue for Nullsafe, and we aim to minimize number of such issues

@ -9,8 +9,16 @@ open! IStd
type violation = {lhs: Nullability.t; rhs_upper_bound: Nullability.t} [@@deriving compare]
let check ~lhs ~rhs_upper_bound =
if Nullability.is_strict_subtype ~subtype:rhs_upper_bound ~supertype:lhs then
Error {lhs; rhs_upper_bound}
if
Nullability.is_strict_subtype ~subtype:rhs_upper_bound ~supertype:lhs
&& (* Suppress violations for anything apart from Nullable since such
issues are not very actionable and/or clear for the user.
E.g. we technically can suggest changing [DeclaredNonnull] to [Nonnull],
but in practice that requires strictification the code, which is a
separate effort.
*)
Nullability.equal lhs Nullable
then Error {lhs; rhs_upper_bound}
else Ok ()

@ -91,7 +91,8 @@ let check_condition tenv case_zero find_canonical_duplicate curr_pdesc node e ty
in
let is_temp = Idenv.exp_is_temp idenv e in
let should_report =
InferredNullability.is_nonnull inferred_nullability
(* TODO: This condition should be extracted into a dedicated rule *)
InferredNullability.is_nonnull_or_declared_nonnull inferred_nullability
&& Config.eradicate_condition_redundant && true_branch && (not is_temp)
&& PatternMatch.type_is_class typ
&& (not (from_try_with_resources ()))
@ -166,20 +167,22 @@ let check_field_assignment tenv find_canonical_duplicate curr_pdesc node instr_r
(Some instr_ref) loc curr_pdesc )
let is_nonnull AnnotatedField.{annotated_type} =
let is_declared_nonnull AnnotatedField.{annotated_type} =
match annotated_type.nullability with
| AnnotatedNullability.Nullable _ ->
false
| AnnotatedNullability.DeclaredNonnull _ ->
true
| AnnotatedNullability.Nonnull _ ->
true
(* Do we have evidence that the field is annotated as non-nullable? *)
let is_field_annotated_as_nonnull annotated_field_opt =
(* Is field declared as non-nullable (implicitly or explicitly)? *)
let is_field_declared_as_nonnull annotated_field_opt =
(* If the field is not present, we optimistically assume it is not nullable.
TODO(T54687014) investigate if this leads to unsoundness issues in practice
*)
Option.exists annotated_field_opt ~f:is_nonnull
Option.exists annotated_field_opt ~f:is_declared_nonnull
let lookup_field_in_typestate pname field_name typestate =
@ -282,7 +285,7 @@ let check_constructor_initialization tenv find_canonical_duplicate curr_construc
if should_check_field_initialization then (
(* Check if non-null field is not initialized. *)
if
is_field_annotated_as_nonnull annotated_field
is_field_declared_as_nonnull annotated_field
&& not is_initialized_in_either_constructor_or_initializer
then
report_error tenv find_canonical_duplicate

@ -538,7 +538,8 @@ let typecheck_instr tenv calls_this checks (node : Procdesc.Node.t) idenv curr_p
| Some (t, nullability) ->
let should_report =
Config.eradicate_condition_redundant
&& InferredNullability.is_nonnull nullability
(* TODO: This condition should be extracted into a dedicated rule *)
&& InferredNullability.is_nonnull_or_declared_nonnull nullability
&& not (InferredNullability.origin_is_fun_library nullability)
in
( if checks.eradicate && should_report then
@ -693,29 +694,31 @@ let typecheck_instr tenv calls_this checks (node : Procdesc.Node.t) idenv curr_p
in
EradicateChecks.{num; formal= formal_param; actual; is_formal_propagates_nullable}
in
(* If the function has @PropagatesNullable params, and inferred type for each of
corresponding actual param is non-nullable, inferred type for the whole result
can be strengthened to non-nullable as well.
(* If the function has @PropagatesNullable params the nullability of result is determined by
nullability of actual values of these params.
*)
let clarify_ret_by_propagates_nullable ret
(resolved_params : EradicateChecks.resolved_param list) =
let propagates_nullable_params =
List.filter resolved_params ~f:(fun (param : EradicateChecks.resolved_param) ->
param.is_formal_propagates_nullable )
(* Nullability of actual values of params that are marked as propagating nullables *)
let nullability_of_propagates_nullable_params =
List.filter_map resolved_params
~f:(fun EradicateChecks.
{is_formal_propagates_nullable; actual= _, inferred_nullability}
-> Option.some_if is_formal_propagates_nullable inferred_nullability )
in
if List.is_empty propagates_nullable_params then ret
else if
List.for_all propagates_nullable_params
~f:(fun EradicateChecks.{actual= _, inferred_nullability_actual} ->
InferredNullability.is_nonnull inferred_nullability_actual )
then
(* All params' inferred types are non-nullable.
Strengten the result to be non-nullable as well! *)
let ret_type_annotation, ret_typ = ret in
(InferredNullability.set_nonnull ret_type_annotation, ret_typ)
else
(* At least one param's inferred type is nullable, can not strengthen the result *)
ret
match nullability_of_propagates_nullable_params with
| [] ->
ret
| head :: tail ->
(* We got non-empty list of params that propagate null.
It means that nullability of the return value will be determined by actual (inferred) nullability of them.
Joining their nullability will give us the least upper bound of nullability of the result *)
let upper_bound_nullability =
List.fold tail ~init:head ~f:(fun acc nullability ->
InferredNullability.join acc nullability )
in
let _, ret_typ = ret in
(upper_bound_nullability, ret_typ)
in
(* Infer nullability of function call result based on its signature *)
let preliminary_resolved_ret =

@ -34,23 +34,23 @@ codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.n
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$Test.testModelledTrueOnNull(java.lang.String):void, 7, ERADICATE_CONDITION_REDUNDANT, no_bucket, WARNING, [The condition s is always false according to the existing annotations.]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$Test.testTrueOnNull(java.lang.CharSequence):void, 8, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s` is nullable and is not locally checked for null when calling `toString()`. (Origin: method parameter s)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$Test.testTrueOnNull(java.lang.CharSequence):void, 12, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s` is nullable and is not locally checked for null when calling `toString()`. (Origin: method parameter s)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestBothParams.testBothParamsShouldBeNonnull(java.lang.String,java.lang.String):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to propagatesNullable(...) at line 194)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestBothParams.testBothParamsShouldBeNonnull(java.lang.String,java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to propagatesNullable(...) at line 195)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestBothParams.testBothParamsShouldBeNonnull(java.lang.String,java.lang.String):void, 3, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to propagatesNullable(...) at line 196)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to propagatesNullable(...) at line 120)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestBothParams.testBothParamsShouldBeNonnull(java.lang.String,java.lang.String):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: method parameter sNullable)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestBothParams.testBothParamsShouldBeNonnull(java.lang.String,java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: method parameter sNullable)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestBothParams.testBothParamsShouldBeNonnull(java.lang.String,java.lang.String):void, 3, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: method parameter sNullable)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: null constant at line 120)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 3, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 121)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 6, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to propagatesNullable(...) at line 124)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 6, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: method parameter sNullable)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 7, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 125)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 11, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 129)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 15, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 133)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 21, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to propagatesNullable(...) at line 124)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 21, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: method parameter sNullable)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestOneParameter.test(java.lang.String,java.lang.String):void, 22, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 125)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestReturnValueAnnotationIsAutomaticallyInferred.annotated_dereferencingAfterPassingNullableIsBAD(java.lang.String):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`annotatedReturn(...)` is nullable and is not locally checked for null when calling `toString()`. (Origin: call to annotatedReturn(...) at line 230)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestReturnValueAnnotationIsAutomaticallyInferred.notAnnotated_dereferencingAfterPassingNullableIsBAD(java.lang.String):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`notAnnotatedReturn(...)` is nullable and is not locally checked for null when calling `toString()`. (Origin: call to notAnnotatedReturn(...) at line 234)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestReturnValueAnnotationIsAutomaticallyInferred.annotated_dereferencingAfterPassingNullableIsBAD(java.lang.String):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`annotatedReturn(...)` is nullable and is not locally checked for null when calling `toString()`. (Origin: method parameter s)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestReturnValueAnnotationIsAutomaticallyInferred.notAnnotated_dereferencingAfterPassingNullableIsBAD(java.lang.String):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`notAnnotatedReturn(...)` is nullable and is not locally checked for null when calling `toString()`. (Origin: method parameter s)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestReturnValueAnnotationIsAutomaticallyInferred.notAnnotatingReturnWhenThereAreNoPropagatesNullableIsBAD(java.lang.String):java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [Method `notAnnotatingReturnWhenThereAreNoPropagatesNullableIsBAD(...)` may return null but it is not annotated with `@Nullable`. (Origin: null constant at line 213)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to propagatesNullable(...) at line 169)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: method parameter sNullable)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 3, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 170)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 6, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to propagatesNullable(...) at line 173)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 6, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`propagatesNullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: method parameter sNullable)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 7, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 174)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 11, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 178)]
codetoanalyze/java/nullsafe-default/CustomAnnotations.java, codetoanalyze.java.nullsafe_default.CustomAnnotations$TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 15, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`. (Origin: call to nullable(...) at line 182)]

Loading…
Cancel
Save