[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. this information is inferred according to flow-sensitive inferrence rule.
*) *)
(* TODO(T52947663) add notion of unknown nullability *) type t =
type t = Nullable of nullable_origin | Nonnull of nonnull_origin [@@deriving compare] | Nullable of nullable_origin
| DeclaredNonnull of declared_nonnull_origin (** See {Nullability.t} for explanation *)
| Nonnull of nonnull_origin
[@@deriving compare]
and nullable_origin = and nullable_origin =
| AnnotatedNullable (** The type is expicitly annotated with @Nullable in the code *) | 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 *) | ModelledNullable (** nullsafe knows it is nullable via its internal models *)
[@@deriving compare] [@@deriving compare]
and nonnull_origin = and declared_nonnull_origin =
| AnnotatedNonnull | AnnotatedNonnull
(** The type is explicitly annotated as non nullable via one of nonnull annotations Nullsafe recognizes *) (** 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 *) (** 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 *) | ModelledNonnull (** nullsafe knows it is non-nullable via its internal models *)
[@@deriving compare] [@@deriving compare]
let get_nullability = function let get_nullability = function
| Nullable _ -> | Nullable _ ->
Nullability.Nullable Nullability.Nullable
| DeclaredNonnull _ ->
Nullability.DeclaredNonnull
| Nonnull _ -> | Nonnull _ ->
Nullability.Nonnull Nullability.Nonnull
@ -55,20 +62,19 @@ let pp fmt t =
| ModelledNullable -> | ModelledNullable ->
"model" "model"
in in
let string_of_declared_nonnull_origin origin =
match origin with AnnotatedNonnull -> "@" | ImplicitlyNonnull -> "implicit"
in
let string_of_nonnull_origin nonnull_origin = let string_of_nonnull_origin nonnull_origin =
match nonnull_origin with match nonnull_origin with ModelledNonnull -> "model"
| AnnotatedNonnull ->
"@"
| NotAnnotatedHenceNullableMode ->
"default"
| ModelledNonnull ->
"model"
in in
match t with match t with
| Nullable nullable_origin -> | Nullable origin ->
F.fprintf fmt "Nullable[%s]" (string_of_nullable_origin nullable_origin) F.fprintf fmt "Nullable[%s]" (string_of_nullable_origin origin)
| Nonnull nonnull_origin -> | DeclaredNonnull origin ->
F.fprintf fmt "Nonnull[%s]" (string_of_nonnull_origin nonnull_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 = let of_annot_item ia =
@ -78,6 +84,6 @@ let of_annot_item ia =
else AnnotatedNullable else AnnotatedNullable
in in
Nullable nullable_origin 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 *) (* 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. 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 = and nullable_origin =
| AnnotatedNullable (** The type is expicitly annotated with @Nullable in the code *) | 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 *) | ModelledNullable (** nullsafe knows it is nullable via its internal models *)
[@@deriving compare] [@@deriving compare]
and nonnull_origin = and declared_nonnull_origin =
| AnnotatedNonnull | AnnotatedNonnull
(** The type is explicitly annotated as non nullable via one of nonnull annotations Nullsafe recognizes *) (** 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 *) (** 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 *) | ModelledNonnull (** nullsafe knows it is non-nullable via its internal models *)
[@@deriving compare] [@@deriving compare]

@ -17,8 +17,15 @@ type assignment_type =
| ReturningFromFunction of Typ.Procname.t | ReturningFromFunction of Typ.Procname.t
[@@deriving compare] [@@deriving compare]
let is_whitelisted_assignment ~lhs ~rhs =
match (lhs, rhs) with Nullability.Nonnull, Nullability.DeclaredNonnull -> true | _ -> false
let check ~lhs ~rhs = 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 = let violation_description _ assignment_type ~rhs_origin_descr =

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

@ -11,9 +11,17 @@ type t = {nullability: Nullability.t; origin: TypeOrigin.t} [@@deriving compare]
let get_nullability {nullability} = nullability 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_origin t =
let descr_opt = TypeOrigin.get_description t.origin in let descr_opt = TypeOrigin.get_description t.origin in
@ -71,5 +79,7 @@ let of_annotated_nullability annotated_nullability origin =
match annotated_nullability with match annotated_nullability with
| AnnotatedNullability.Nullable _ -> | AnnotatedNullability.Nullable _ ->
{origin; nullability= Nullability.Nullable} {origin; nullability= Nullability.Nullable}
| AnnotatedNullability.DeclaredNonnull _ ->
{origin; nullability= Nullability.DeclaredNonnull}
| AnnotatedNullability.Nonnull _ -> | AnnotatedNullability.Nonnull _ ->
{origin; nullability= Nullability.Nonnull} {origin; nullability= Nullability.Nonnull}

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

@ -10,6 +10,18 @@ type violation = {base: Nullability.t; overridden: Nullability.t} [@@deriving co
type type_role = Param | Ret 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 check type_role ~base ~overridden =
let subtype, supertype = let subtype, supertype =
match type_role with match type_role with
@ -20,7 +32,9 @@ let check type_role ~base ~overridden =
(* contravariance for param *) (* contravariance for param *)
(base, overridden) (base, overridden)
in 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 = type violation_type =

@ -9,6 +9,11 @@ open! IStd
type t = type t =
| Nullable (** No guarantees on the nullability *) | 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 | Nonnull
(** We believe that this value can not be null. If it is not the case, this is (** 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 an unsoundness issue for Nullsafe, and we aim to minimize number of such issues
@ -18,7 +23,13 @@ type t =
let top = Nullable let top = Nullable
let join x y = 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 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) 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 = type t =
| Nullable (** No guarantees on the nullability *) | 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 | Nonnull
(** We believe that this value can not be null. If it is not the case, this is (** 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 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] type violation = {lhs: Nullability.t; rhs_upper_bound: Nullability.t} [@@deriving compare]
let check ~lhs ~rhs_upper_bound = let check ~lhs ~rhs_upper_bound =
if Nullability.is_strict_subtype ~subtype:rhs_upper_bound ~supertype:lhs then if
Error {lhs; rhs_upper_bound} 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 () else Ok ()

@ -91,7 +91,8 @@ let check_condition tenv case_zero find_canonical_duplicate curr_pdesc node e ty
in in
let is_temp = Idenv.exp_is_temp idenv e in let is_temp = Idenv.exp_is_temp idenv e in
let should_report = 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) && Config.eradicate_condition_redundant && true_branch && (not is_temp)
&& PatternMatch.type_is_class typ && PatternMatch.type_is_class typ
&& (not (from_try_with_resources ())) && (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 ) (Some instr_ref) loc curr_pdesc )
let is_nonnull AnnotatedField.{annotated_type} = let is_declared_nonnull AnnotatedField.{annotated_type} =
match annotated_type.nullability with match annotated_type.nullability with
| AnnotatedNullability.Nullable _ -> | AnnotatedNullability.Nullable _ ->
false false
| AnnotatedNullability.DeclaredNonnull _ ->
true
| AnnotatedNullability.Nonnull _ -> | AnnotatedNullability.Nonnull _ ->
true true
(* Do we have evidence that the field is annotated as non-nullable? *) (* Is field declared as non-nullable (implicitly or explicitly)? *)
let is_field_annotated_as_nonnull annotated_field_opt = let is_field_declared_as_nonnull annotated_field_opt =
(* If the field is not present, we optimistically assume it is not nullable. (* If the field is not present, we optimistically assume it is not nullable.
TODO(T54687014) investigate if this leads to unsoundness issues in practice 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 = 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 ( if should_check_field_initialization then (
(* Check if non-null field is not initialized. *) (* Check if non-null field is not initialized. *)
if if
is_field_annotated_as_nonnull annotated_field is_field_declared_as_nonnull annotated_field
&& not is_initialized_in_either_constructor_or_initializer && not is_initialized_in_either_constructor_or_initializer
then then
report_error tenv find_canonical_duplicate 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) -> | Some (t, nullability) ->
let should_report = let should_report =
Config.eradicate_condition_redundant 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) && not (InferredNullability.origin_is_fun_library nullability)
in in
( if checks.eradicate && should_report then ( 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 in
EradicateChecks.{num; formal= formal_param; actual; is_formal_propagates_nullable} EradicateChecks.{num; formal= formal_param; actual; is_formal_propagates_nullable}
in in
(* If the function has @PropagatesNullable params, and inferred type for each of (* If the function has @PropagatesNullable params the nullability of result is determined by
corresponding actual param is non-nullable, inferred type for the whole result nullability of actual values of these params.
can be strengthened to non-nullable as well.
*) *)
let clarify_ret_by_propagates_nullable ret let clarify_ret_by_propagates_nullable ret
(resolved_params : EradicateChecks.resolved_param list) = (resolved_params : EradicateChecks.resolved_param list) =
let propagates_nullable_params = (* Nullability of actual values of params that are marked as propagating nullables *)
List.filter resolved_params ~f:(fun (param : EradicateChecks.resolved_param) -> let nullability_of_propagates_nullable_params =
param.is_formal_propagates_nullable ) 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 in
if List.is_empty propagates_nullable_params then ret match nullability_of_propagates_nullable_params with
else if | [] ->
List.for_all propagates_nullable_params ret
~f:(fun EradicateChecks.{actual= _, inferred_nullability_actual} -> | head :: tail ->
InferredNullability.is_nonnull inferred_nullability_actual ) (* We got non-empty list of params that propagate null.
then It means that nullability of the return value will be determined by actual (inferred) nullability of them.
(* All params' inferred types are non-nullable. Joining their nullability will give us the least upper bound of nullability of the result *)
Strengten the result to be non-nullable as well! *) let upper_bound_nullability =
let ret_type_annotation, ret_typ = ret in List.fold tail ~init:head ~f:(fun acc nullability ->
(InferredNullability.set_nonnull ret_type_annotation, ret_typ) InferredNullability.join acc nullability )
else in
(* At least one param's inferred type is nullable, can not strengthen the result *) let _, ret_typ = ret in
ret (upper_bound_nullability, ret_typ)
in in
(* Infer nullability of function call result based on its signature *) (* Infer nullability of function call result based on its signature *)
let preliminary_resolved_ret = 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.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, 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$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, 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: 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, 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: call to propagatesNullable(...) at line 196)] 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: call to propagatesNullable(...) at line 120)] 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, 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, 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, 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, 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$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.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: call to notAnnotatedReturn(...) at line 234)] 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$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, 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, 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, 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)] 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