[nullsafe] Aggregate meta-issues for top-level classes

Summary:
This diff changes way we treat classes w.r.t. to Nullsafe modes when
issuing meta-issues.

Previously, we considered nested class independently of the outer one.
This was leading to a tricky case: when the class is clean but nested
class needs fixing, meta-info told that class can be Nullsafe.

This is counter-intutive and lead to problems when users tried to follow
wrong nullsafe suggestions for this case.

After this diff we:
1. Start calculating meta-issues only on the outermost level. This will simplify
reasoning about nullsafe stats.
2. Aggregate all nested issues counters to corresponding outer-level class.

Among others, CLASS_CAN_BE_NULLSAFE Advice will finally become
actionable in all known cases.

Reviewed By: artempyanykh

Differential Revision: D21353607

fbshipit-source-id: a17c6958a
master
Mitya Lyubarskiy 5 years ago committed by Facebook GitHub Bot
parent 57fce4315a
commit 045649abaf

@ -9,11 +9,30 @@ open! IStd
module ClassInfo = struct
type t =
{summaries: NullsafeSummary.t list; nested_anonymous_classes: anonymous_class_to_summaries}
{ class_name: JavaClassName.t
; summaries: NullsafeSummary.t list
; mutable nested_classes_info: t list
; nested_anonymous_classes: anonymous_class_to_summaries }
and anonymous_class_to_summaries = NullsafeSummary.t list JavaClassName.Map.t
let make_empty () = {summaries= []; nested_anonymous_classes= JavaClassName.Map.empty}
let get_class_name {class_name} = class_name
let get_summaries {summaries} = summaries
let get_nested_anonymous_summaries {nested_anonymous_classes} = nested_anonymous_classes
let get_nested_classes_info {nested_classes_info} = nested_classes_info
(** Add a link between this class and a nested class info *)
let add_nested_class_info ~nested t = t.nested_classes_info <- nested :: t.nested_classes_info
let make_empty class_name =
{ class_name
; summaries= []
; nested_classes_info= []
; nested_anonymous_classes= JavaClassName.Map.empty }
(** Add top level (not anonymous) summary belonging to this class *)
let add_class_summary summary t = {t with summaries= summary :: t.summaries}
@ -28,48 +47,86 @@ module ClassInfo = struct
{t with nested_anonymous_classes= updated_anonymous_classes}
let get_anonymous_summaries {nested_anonymous_classes} =
JavaClassName.Map.fold
(fun class_name summaries acc -> (class_name, summaries) :: acc)
nested_anonymous_classes []
let get_all_summaries t =
let rec get_recursive_summaries t =
let this_summaries = List.map t.summaries ~f:(fun summary -> (t.class_name, summary)) in
let anonymous_summaries =
get_anonymous_summaries t
|> List.map ~f:(fun (_, summaries) -> summaries)
|> List.fold ~init:[] ~f:( @ )
JavaClassName.Map.bindings t.nested_anonymous_classes
|> List.map ~f:(fun (class_name, summaries) ->
List.map summaries ~f:(fun summary -> (class_name, summary)) )
|> List.concat
in
t.summaries @ anonymous_summaries
let nested_summaries =
List.map t.nested_classes_info ~f:get_recursive_summaries |> List.concat
in
this_summaries @ nested_summaries @ anonymous_summaries
end
type t = ClassInfo.t JavaClassName.Map.t
let make_empty () = JavaClassName.Map.empty
(* If key (class_name) was not in the map yet, add it, otherwise modify the existing value.
[update] is a function that modifies value.
*)
let update_in_map class_name ~update t =
JavaClassName.Map.update class_name
(fun class_info ->
let info_to_update = Option.value class_info ~default:(ClassInfo.make_empty ()) in
let info_to_update = Option.value class_info ~default:(ClassInfo.make_empty class_name) in
Some (update info_to_update) )
t
let register_summary java_class_name summary t =
match JavaClassName.get_user_defined_class_if_anonymous_inner java_class_name with
(* Add (empty) class info for all outer classes for this class recursively,
if it did not exist yet *)
let rec register_ancestors user_defined_class map =
match JavaClassName.get_outer_class_name user_defined_class with
| Some outer_class ->
(* add to the map if not added and to the same for parent *)
update_in_map outer_class ~update:ident map |> register_ancestors outer_class
| None ->
map
(* Register this class and all it ancestor classes, if not registered yet,
and update list of summaries for this class.
*)
let register_classes_and_add_summary class_name summary map =
match JavaClassName.get_user_defined_class_if_anonymous_inner class_name with
| Some outer_class_name ->
(* That was a nested anonymous class.
We don't register it at top level, registed outer class instead. *)
update_in_map outer_class_name
~update:(ClassInfo.add_anonymous_summary java_class_name summary)
t
~update:(ClassInfo.add_anonymous_summary class_name summary)
map
|> register_ancestors outer_class_name
| None ->
(* This is not an anonymous class, register it as is *)
update_in_map java_class_name ~update:(ClassInfo.add_class_summary summary) t
let group_by_user_class t =
JavaClassName.Map.fold (fun class_name class_info acc -> (class_name, class_info) :: acc) t []
update_in_map class_name ~update:(ClassInfo.add_class_summary summary) map
|> register_ancestors class_name
(* the result is the map from all class names (including all ancestors) to corresponding info with summaries,
without links to nested classes *)
let create_initial_map all_summaries =
List.fold all_summaries ~init:JavaClassName.Map.empty ~f:(fun map (class_name, summary) ->
register_classes_and_add_summary class_name summary map )
(* given a map containing all nested and parent class names (excluding anonymous classes),
update [nested_classes_info] links for all outer classes
*)
let set_links map =
JavaClassName.Map.iter
(fun class_name class_info ->
Option.iter (JavaClassName.get_outer_class_name class_name) ~f:(fun outer_class_name ->
let outer_info = JavaClassName.Map.find outer_class_name map in
ClassInfo.add_nested_class_info ~nested:class_info outer_info ) )
map
let aggregate all_summaries =
let class_name_to_info = create_initial_map all_summaries in
set_links class_name_to_info ;
(* Return only list of top level classes that are not nested *)
JavaClassName.Map.bindings class_name_to_info
|> List.filter_map ~f:(fun (class_name, class_info) ->
if Option.is_none (JavaClassName.get_outer_class_name class_name) then
(* This class is the outermost, leave it *)
Some class_info
else None )

@ -14,17 +14,21 @@ open! IStd
module ClassInfo : sig
type t
val get_all_summaries : t -> NullsafeSummary.t list
(** List of all summaries, user-level and anonymous, combined together *)
end
val get_class_name : t -> JavaClassName.t
val get_summaries : t -> NullsafeSummary.t list
type t
val get_nested_classes_info : t -> t list
val make_empty : unit -> t
val get_nested_anonymous_summaries : t -> NullsafeSummary.t list JavaClassName.Map.t
(** List of all anonymous class summaries belonging to this class, together with name of anonymous
class. This is a flattenned list, so we don't care if one anonymous class is nested inside the
other. *)
val register_summary : JavaClassName.t -> NullsafeSummary.t -> t -> t
(** Add information about summary to the class map. Depending on if this an anonymous or
user-defined class, adds it to corresponding lists. *)
val get_recursive_summaries : t -> (JavaClassName.t * NullsafeSummary.t) list
(** A flattened list of all summaries, user-level, nested, and anonymous, combined together *)
end
val group_by_user_class : t -> (JavaClassName.t * ClassInfo.t) list
(** List of pairs <user defined class name, info about this class *)
val aggregate : (JavaClassName.t * NullsafeSummary.t) list -> ClassInfo.t list
(** Given a list of all summaries and their classes, group them by names and aggregate in a list of
top-level classes. *)

@ -34,8 +34,14 @@ let is_reportable_typing_rules_violation ~nullsafe_mode issue =
is_typing_rules_violation issue && TypeErr.is_reportable ~nullsafe_mode issue
let get_reportable_typing_rules_violations ~nullsafe_mode issues =
List.filter issues ~f:(is_reportable_typing_rules_violation ~nullsafe_mode)
let get_reportable_typing_rules_violations modes_with_issues =
List.filter modes_with_issues ~f:(fun (nullsafe_mode, issue) ->
is_reportable_typing_rules_violation ~nullsafe_mode issue )
|> List.map ~f:(fun (_, a) -> a)
let get_reportable_typing_rules_violations_for_mode ~nullsafe_mode issues =
List.map issues ~f:(fun issue -> (nullsafe_mode, issue)) |> get_reportable_typing_rules_violations
type meta_issue =
@ -60,7 +66,7 @@ let mode_to_json mode =
let is_clean_in_mode nullsafe_mode all_issues =
get_reportable_typing_rules_violations ~nullsafe_mode all_issues |> List.is_empty
get_reportable_typing_rules_violations_for_mode ~nullsafe_mode all_issues |> List.is_empty
(* Return the maximum mode where we still have zero issues, or None if no such mode exists.
@ -79,23 +85,32 @@ let calc_mode_to_promote_to curr_mode all_issues =
else None
(* analyze all issues for the current class and classify them into one meta-issue.
(* analyze all issues for the current class (including all nested and anonymous classes recursively)
and classify them into one meta-issue.
*)
let make_meta_issue all_issues current_mode class_name =
let issue_count_in_curr_mode =
get_reportable_typing_rules_violations ~nullsafe_mode:current_mode all_issues |> List.length
let make_meta_issue modes_and_issues top_level_class_mode top_level_class_name =
let currently_reportable_issues = get_reportable_typing_rules_violations modes_and_issues in
List.iter currently_reportable_issues ~f:(fun issue ->
Logging.debug Analysis Medium "Issue: %a@\n" TypeErr.pp_err_instance issue ) ;
let currently_reportable_issue_count = List.length currently_reportable_issues in
let all_issues = List.map modes_and_issues ~f:(fun (_, a) -> a) in
let mode_to_promote_to =
if currently_reportable_issue_count > 0 then
(* This is not an optimization - consider a class with a nested class that is in the stricter mode than top level mode,
and has issues in this mode, but not in the top level mode.
This class is already broken now, so mode to promote to should be None.
But [calc_mode_to_promote_to] can return some mode for this case, which would be wrong. *)
None
else calc_mode_to_promote_to top_level_class_mode all_issues
in
List.iter (get_reportable_typing_rules_violations ~nullsafe_mode:current_mode all_issues)
~f:(fun issue -> Logging.debug Analysis Medium "Issue: %a@\n" TypeErr.pp_err_instance issue) ;
let mode_to_promote_to = calc_mode_to_promote_to current_mode all_issues in
let meta_issue_info =
Jsonbug_t.
{ num_issues= issue_count_in_curr_mode
; curr_nullsafe_mode= mode_to_json current_mode
{ num_issues= currently_reportable_issue_count
; curr_nullsafe_mode= mode_to_json top_level_class_mode
; can_be_promoted_to= Option.map mode_to_promote_to ~f:mode_to_json }
in
let issue_type, description, severity =
if NullsafeMode.equal current_mode Default then
if NullsafeMode.equal top_level_class_mode Default then
match mode_to_promote_to with
| Some mode_to_promote_to ->
(* This class is not @Nullsafe yet, but can become such! *)
@ -118,45 +133,38 @@ let make_meta_issue all_issues current_mode class_name =
| NullsafeMode.Default | NullsafeMode.Local (NullsafeMode.Trust.Only _) ->
Logging.die InternalError "Unexpected promotion mode"
in
let severity, message =
if Option.is_some (JavaClassName.get_outer_class_name class_name) then
(* This is a nested class. We don't recommend explicitly marking it as @Nullsafe to the users:
recommended granularity is outer level class. However, we still report meta-issue for statistics/metric reasons.
*)
( Exceptions.Info
, Format.sprintf "`%s` is free of nullability issues."
(JavaClassName.classname class_name) )
else
( Exceptions.Advice
, Format.sprintf
"Congrats! `%s` is free of nullability issues. Mark it %s to prevent regressions."
(JavaClassName.classname class_name)
promo_recommendation )
let message =
Format.sprintf
"Congrats! `%s` is free of nullability issues. Mark it %s to prevent regressions."
(JavaClassName.classname top_level_class_name)
promo_recommendation
in
(IssueType.eradicate_meta_class_can_be_nullsafe, message, severity)
(IssueType.eradicate_meta_class_can_be_nullsafe, message, Exceptions.Advice)
| None ->
(* This class can not be made @Nullsafe without extra work *)
let issue_count_to_make_nullsafe =
get_reportable_typing_rules_violations
get_reportable_typing_rules_violations_for_mode
~nullsafe_mode:(NullsafeMode.Local NullsafeMode.Trust.All) all_issues
|> List.length
in
( IssueType.eradicate_meta_class_needs_improvement
, Format.asprintf "`%s` needs %d issues to be fixed in order to be marked @Nullsafe."
(JavaClassName.classname class_name)
(JavaClassName.classname top_level_class_name)
issue_count_to_make_nullsafe
, Exceptions.Info )
else if issue_count_in_curr_mode > 0 then
(* This class is already nullsafe *)
else if currently_reportable_issue_count > 0 then
(* This class is @Nullsafe, but broken. This should not happen often if there is enforcement for
@Nullsafe mode error in the target codebase. *)
( IssueType.eradicate_meta_class_needs_improvement
, Format.asprintf
"@Nullsafe classes should have exactly zero nullability issues. `%s` has %d."
(JavaClassName.classname class_name)
issue_count_in_curr_mode
(JavaClassName.classname top_level_class_name)
currently_reportable_issue_count
, Exceptions.Info )
else
( IssueType.eradicate_meta_class_is_nullsafe
, Format.asprintf "Class %a is free of nullability issues." JavaClassName.pp class_name
, Format.asprintf "Class %a is free of nullability issues." JavaClassName.pp
top_level_class_name
, Exceptions.Info )
in
{issue_type; description; severity; meta_issue_info}
@ -172,19 +180,30 @@ let get_class_loc source_file Struct.{java_class_info} =
(* Meta issues are those related to null-safety of the class in general, not concrete nullability violations *)
let report_meta_issues tenv source_file class_name class_struct class_info issue_log =
(* For purposes of aggregation, we consider all nested anonymous summaries as belonging to this class *)
let current_mode = NullsafeMode.of_class tenv class_name in
let summaries = AggregatedSummaries.ClassInfo.get_all_summaries class_info in
let class_loc = get_class_loc source_file class_struct in
let all_issues = List.concat_map summaries ~f:(fun {NullsafeSummary.issues} -> issues) in
let {issue_type; description; severity; meta_issue_info} =
make_meta_issue all_issues current_mode class_name
in
let package = JavaClassName.package class_name in
let class_name = JavaClassName.classname class_name in
let nullsafe_extra = Jsonbug_t.{class_name; package; meta_issue_info= Some meta_issue_info} in
log_issue ~issue_log ~loc:class_loc ~severity ~nullsafe_extra issue_type description
let report_meta_issue_for_top_level_class tenv source_file class_name class_struct class_info
issue_log =
if Option.is_some (JavaClassName.get_outer_class_name class_name) then
(* We record meta-issues only for top-level classes *) issue_log
else
let current_mode = NullsafeMode.of_class tenv class_name in
(* For purposes of aggregation, we consider all nested summaries as belonging to this class *)
let class_names_and_summaries =
AggregatedSummaries.ClassInfo.get_recursive_summaries class_info
in
let class_loc = get_class_loc source_file class_struct in
let all_issues =
List.map class_names_and_summaries ~f:(fun (class_name, NullsafeSummary.{issues}) ->
let mode_for_class_name = NullsafeMode.of_class tenv class_name in
List.map issues ~f:(fun issue -> (mode_for_class_name, issue)) )
|> List.fold ~init:[] ~f:( @ )
in
let {issue_type; description; severity; meta_issue_info} =
make_meta_issue all_issues current_mode class_name
in
let package = JavaClassName.package class_name in
let class_name = JavaClassName.classname class_name in
let nullsafe_extra = Jsonbug_t.{class_name; package; meta_issue_info= Some meta_issue_info} in
log_issue ~issue_log ~loc:class_loc ~severity ~nullsafe_extra issue_type description
(* Optimization - if issues are disabled, don't bother analyzing them *)
@ -194,9 +213,11 @@ let should_analyze_meta_issues () =
|| IssueType.eradicate_meta_class_is_nullsafe.enabled
let analyze_meta_issues tenv source_file class_name class_struct class_info issue_log =
let analyze_meta_issue_for_top_level_class tenv source_file class_name class_struct class_info
issue_log =
if should_analyze_meta_issues () then
report_meta_issues tenv source_file class_name class_struct class_info issue_log
report_meta_issue_for_top_level_class tenv source_file class_name class_struct class_info
issue_log
else issue_log
@ -243,11 +264,12 @@ let analyze_nullsafe_annotations tenv source_file class_name class_struct issue_
let analyze_class_impl tenv source_file class_name class_struct class_info issue_log =
issue_log
|> analyze_meta_issues tenv source_file class_name class_struct class_info
|> analyze_meta_issue_for_top_level_class tenv source_file class_name class_struct class_info
|> analyze_nullsafe_annotations tenv source_file class_name class_struct
let analyze_class tenv source_file class_name class_info issue_log =
let analyze_class tenv source_file class_info issue_log =
let class_name = AggregatedSummaries.ClassInfo.get_class_name class_info in
match Tenv.lookup tenv (Typ.JavaClass class_name) with
| Some class_struct ->
analyze_class_impl tenv source_file class_name class_struct class_info issue_log

@ -10,11 +10,13 @@ open! IStd
(** This stage is called for each Java class after all corresponding proc summaries are calculated. *)
val analyze_class :
Tenv.t
-> SourceFile.t
-> JavaClassName.t
-> AggregatedSummaries.ClassInfo.t
-> IssueLog.t
-> IssueLog.t
(** Given all summaries for given class, analyze them in combination, and update issue log, if
necessary *)
Tenv.t -> SourceFile.t -> AggregatedSummaries.ClassInfo.t -> IssueLog.t -> IssueLog.t
(** Given aggregated summary for a class, analyze it, and return updated issue log, if necessary.
This function will be called for each non-trivial{^ 1} anonymous class in the file, including
nested classes. Order of calls is not specified.
{^ 1}The class is non-trivial if it has at least one procedure, or contains at least one nested
non-trivial class.
(Note that [IssueLog.t] is a mutable type so it can be actually mutated by this function:
returning [IssueLog.t] is done for convenient chaining.) *)

@ -14,32 +14,40 @@ let get_java_class_name = function
None
(* aggregate all of the procedures in the file env by their declaring
class. this lets us analyze each class individually *)
let aggregate_by_class {InterproceduralAnalysis.procedures; analyze_file_dependency; _} =
(* Fetch the class and summaries for each procedure *)
let get_summaries
({procedures; analyze_file_dependency} : NullsafeSummary.t InterproceduralAnalysis.file_t) =
let open IOption.Let_syntax in
List.fold procedures ~init:(AggregatedSummaries.make_empty ()) ~f:(fun map_to_update procname ->
(let* class_name = Procname.get_class_type_name procname in
let* java_class_name = get_java_class_name class_name in
let* _proc_desc, summary = analyze_file_dependency procname in
return (AggregatedSummaries.register_summary java_class_name summary map_to_update))
|> Option.value ~default:map_to_update )
List.filter_map procedures ~f:(fun procname ->
let* class_name = Procname.get_class_type_name procname in
let* java_class_name = get_java_class_name class_name in
let* _proc_desc, summary = analyze_file_dependency procname in
return (java_class_name, summary) )
(* Given list of proc summaries belonging to a class, aggregate it and add issues to the log, if needed *)
let analyze_class tenv source_file issue_log (class_name, class_info) =
(* Analyze the class and all its nested children recursively *)
let rec analyze_class_and_nested tenv source_file issue_log class_info =
(* Analyze the class itself *)
let updated_log = ClassLevelAnalysis.analyze_class tenv source_file class_info issue_log in
(* Analyze its nested children *)
AggregatedSummaries.ClassInfo.get_nested_classes_info class_info
|> List.fold ~init:updated_log ~f:(analyze_class_and_nested tenv source_file)
(* Given aggregated information about the top-level class, analyze it and its nested children *)
let analyze_top_level_class tenv source_file issue_log top_level_class_info =
let is_from_third_party =
ThirdPartyAnnotationInfo.is_third_party_class_name
(ThirdPartyAnnotationGlobalRepo.get_repo ())
class_name
(AggregatedSummaries.ClassInfo.get_class_name top_level_class_info)
in
if is_from_third_party then (* Don't analyze third party classes *)
issue_log
else ClassLevelAnalysis.analyze_class tenv source_file class_name class_info issue_log
else analyze_class_and_nested tenv source_file issue_log top_level_class_info
let analyze_file ({InterproceduralAnalysis.file_exe_env; source_file} as analysis_data) =
let class_map = aggregate_by_class analysis_data in
let all_summaries = get_summaries analysis_data in
let tenv = Exe_env.load_java_global_tenv file_exe_env in
let user_class_info = AggregatedSummaries.group_by_user_class class_map in
List.fold user_class_info ~init:IssueLog.empty ~f:(analyze_class tenv source_file)
let top_level_classes = AggregatedSummaries.aggregate all_summaries in
List.fold top_level_classes ~init:IssueLog.empty ~f:(analyze_top_level_class tenv source_file)

@ -0,0 +1,212 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
open OUnit2
open AggregatedSummaries
module F = Format
let test_package = Some "test.package"
let mock_summary id =
(* For simplicity, mock summaries will be represented as a list with the single issue where id is encoded in description. *)
let mock_issue =
TypeErr.Condition_redundant
{ is_always_true= true
; condition_descr= Some (Int.to_string id)
; nonnull_origin= TypeOrigin.New }
in
NullsafeSummary.{issues= [mock_issue]}
let get_mock_summary_id NullsafeSummary.{issues} =
match issues with
| [TypeErr.Condition_redundant {condition_descr= Some id}] ->
Int.of_string id
| _ ->
assert_failure "Expected mock summary, got something else"
type expected_class_info =
{ name: string
; nested: expected_class_info list
; anm: (string * int list) list
(* List of nested anonymous names together with list of their expected summary ids *)
; summary_ids: int list (** sorted for convenience *) }
let assert_summaries_equal actual_summaries expected_ids class_name case_name =
let actual_summaries_ids =
actual_summaries |> List.map ~f:get_mock_summary_id |> List.sort ~compare:Int.compare
in
assert_equal expected_ids actual_summaries_ids
~msg:(F.sprintf "%s: summary ids for %s did not match" case_name class_name)
let assert_anonymous_equal actual expected_name_to_ids case_name =
List.iter expected_name_to_ids ~f:(fun (anonymous_name, expected_summary_ids) ->
let actual_summaries =
JavaClassName.Map.find_opt
(JavaClassName.make ~package:test_package ~classname:anonymous_name)
actual
|> IOption.if_none_eval ~f:(fun () ->
assert_failure
(F.sprintf "%s: Did not find anonymous class info for %s" case_name anonymous_name)
)
in
assert_summaries_equal actual_summaries expected_summary_ids anonymous_name case_name )
let rec assert_expected_list actual expected case_name =
assert_equal (List.length actual) (List.length expected)
~msg:
(Format.sprintf "%s: Expected list of %d, got %d" case_name (List.length expected)
(List.length actual)) ;
List.iter expected ~f:(fun {name; summary_ids; nested; anm} ->
(* For each expected info find corresponding actual and compare *)
let actual_info =
List.find actual ~f:(fun actual_info ->
JavaClassName.equal
(ClassInfo.get_class_name actual_info)
(JavaClassName.make ~package:test_package ~classname:name) )
|> IOption.if_none_eval ~f:(fun () ->
assert_failure (F.sprintf "%s: Did not find class info for %s" case_name name) )
in
assert_summaries_equal (ClassInfo.get_summaries actual_info) summary_ids name case_name ;
assert_anonymous_equal (ClassInfo.get_nested_anonymous_summaries actual_info) anm case_name ;
(* Now recursively check all children and match them with expected *)
assert_expected_list
(ClassInfo.get_nested_classes_info actual_info)
nested
(F.sprintf "%s:%s" case_name name) )
let aggregate list =
List.map list ~f:(fun (classname, summary_id) ->
(JavaClassName.make ~package:test_package ~classname, mock_summary summary_id) )
|> AggregatedSummaries.aggregate
let single_class =
"single_class"
>:: fun _ ->
assert_expected_list (aggregate []) [] "empty" ;
assert_expected_list
(aggregate [("A", 1)])
[{name= "A"; summary_ids= [1]; anm= []; nested= []}]
"single method" ;
assert_expected_list
(aggregate [("A", 1); ("A", 5); ("A", 2)])
[{name= "A"; summary_ids= [1; 2; 5]; anm= []; nested= []}]
"several methods"
let several_top_classes =
"several_top_classes"
>:: fun _ ->
assert_expected_list
(aggregate [("A", 1); ("B", 2)])
[ {name= "A"; summary_ids= [1]; anm= []; nested= []}
; {name= "B"; summary_ids= [2]; anm= []; nested= []} ]
"two simple classes" ;
assert_expected_list
(aggregate [("A", 1); ("B", 5); ("A", 2); ("C", 7); ("A", 8); ("B", 9)])
[ {name= "A"; summary_ids= [1; 2; 8]; anm= []; nested= []}
; {name= "B"; summary_ids= [5; 9]; anm= []; nested= []}
; {name= "C"; summary_ids= [7]; anm= []; nested= []} ]
"several classes"
let one_top_class_with_nested =
"several_top_classes"
>:: fun _ ->
assert_expected_list
(aggregate [("A$B", 1); ("A", 2)])
[ { name= "A"
; summary_ids= [2]
; anm= []
; nested= [{name= "A$B"; summary_ids= [1]; anm= []; nested= []}] } ]
"simple nested" ;
assert_expected_list
(aggregate [("A$B", 1); ("A", 2); ("A$B", 3); ("A", 4); ("A$C", 6); ("A$D", 7)])
[ { name= "A"
; summary_ids= [2; 4]
; anm= []
; nested=
[ {name= "A$B"; summary_ids= [1; 3]; anm= []; nested= []}
; {name= "A$C"; summary_ids= [6]; anm= []; nested= []}
; {name= "A$D"; summary_ids= [7]; anm= []; nested= []} ] } ]
"simple nested, several summaries" ;
assert_expected_list
(aggregate [("A$B", 1)])
[ { name= "A"
; summary_ids= []
; anm= []
; nested= [{name= "A$B"; summary_ids= [1]; anm= []; nested= []}] } ]
"nested should also create ancestors even if they have no summaries" ;
assert_expected_list
(aggregate [("A$B$D$F", 1); ("A$B$C", 2)])
[ { name= "A"
; summary_ids= []
; anm= []
; nested=
[ { name= "A$B"
; summary_ids= []
; anm= []
; nested=
[ {name= "A$B$C"; summary_ids= [2]; anm= []; nested= []}
; { name= "A$B$D"
; summary_ids= []
; anm= []
; nested= [{name= "A$B$D$F"; summary_ids= [1]; anm= []; nested= []}] } ] } ] } ]
"nested should also create ancestors even if they have no summaries"
let with_anonymous =
"with_anonymous"
>:: fun _ ->
assert_expected_list
(aggregate [("A$B$C$3$4", 1); ("A$5$6", 2); ("A$5", 3); ("A", 4); ("A$5$7", 5); ("A$5$6", 6)])
[ { name= "A"
; summary_ids= [4]
; anm= [("A$5$6", [2; 6]); ("A$5", [3]); ("A$5$7", [5])]
; nested=
[ { name= "A$B"
; summary_ids= []
; anm= []
; nested= [{name= "A$B$C"; summary_ids= []; anm= [("A$B$C$3$4", [1])]; nested= []}] } ]
} ]
"with_anonymous"
let several_top_classes_with_nested =
"several_top_classes_with_nested"
>:: fun _ ->
assert_expected_list
(aggregate [("B", 1); ("A", 2); ("C$D", 3); ("A$B$D", 4); ("A$B$D", 5); ("A", 6)])
[ { name= "A"
; summary_ids= [2; 6]
; anm= []
; nested=
[ { name= "A$B"
; summary_ids= []
; anm= []
; nested= [{name= "A$B$D"; summary_ids= [4; 5]; anm= []; nested= []}] } ] }
; {name= "B"; summary_ids= [1]; anm= []; nested= []}
; { name= "C"
; summary_ids= []
; anm= []
; nested= [{name= "C$D"; summary_ids= [3]; anm= []; nested= []}] } ]
"several_top_classes_with_nested"
let test =
"AggregatedSummariesTest"
>::: [ single_class
; several_top_classes
; one_top_class_with_nested
; with_anonymous
; several_top_classes_with_nested ]

@ -7,4 +7,5 @@
open! IStd
let tests = [ThirdPartyMethodTests.test; ThirdPartyAnnotationInfoTests.test]
let tests =
[ThirdPartyMethodTests.test; ThirdPartyAnnotationInfoTests.test; AggregatedSummariesTest.test]

@ -3,8 +3,7 @@ codetoanalyze/java/nullsafe/AlternativeRecommendations.java, codetoanalyze.java.
codetoanalyze/java/nullsafe/AlternativeRecommendations.java, codetoanalyze.java.nullsafe_default.AlternativeRecommendations.dereference_ShouldSuggestAlternative(android.view.View):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`view.findViewById(...)` is nullable and is not locally checked for null when calling `setId(...)`: call to View.findViewById(...) at line 22 (nullable according to nullsafe internal models). If this is intentional, use `androidx.core.view.ViewCompat.requireViewById()` instead.]
codetoanalyze/java/nullsafe/AlternativeRecommendations.java, codetoanalyze.java.nullsafe_default.AlternativeRecommendations.passingParam_ShouldSuggestAlternative(android.view.View):void, 1, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`AlternativeRecommendations.acceptsNonnullView(...)`: parameter #1(`view`) is declared non-nullable but the argument `view.findViewById(...)` is nullable: call to View.findViewById(...) at line 26 (nullable according to nullsafe internal models). If you don't expect null, use `androidx.core.view.ViewCompat.requireViewById()` instead.]
codetoanalyze/java/nullsafe/AlternativeRecommendations.java, codetoanalyze.java.nullsafe_default.AlternativeRecommendations.returnValue_ShouldSuggestAlternative(android.view.View):android.view.View, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [`returnValue_ShouldSuggestAlternative(...)`: return type is declared non-nullable but the method returns a nullable value: call to View.findViewById(...) at line 30 (nullable according to nullsafe internal models). If you don't expect null, use `androidx.core.view.ViewCompat.requireViewById()` instead.]
codetoanalyze/java/nullsafe/ButterKnife.java, Linters_dummy_method, 15, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ButterKnife, codetoanalyze.java.nullsafe_default, issues: 4, curr_mode: "Default"
codetoanalyze/java/nullsafe/ButterKnife.java, Linters_dummy_method, 79, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ButterKnife$TestNotInitialized, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/ButterKnife.java, Linters_dummy_method, 15, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ButterKnife, codetoanalyze.java.nullsafe_default, issues: 5, curr_mode: "Default"
codetoanalyze/java/nullsafe/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife$TestNotInitialized.<init>(codetoanalyze.java.nullsafe_default.ButterKnife), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `notInitializedNormalIsBAD` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method]
codetoanalyze/java/nullsafe/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.<init>(), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `ButterKnife.nullable` is always initialized in the constructor but is declared `@Nullable`]
codetoanalyze/java/nullsafe/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.assignNullToNormalIsBAD():void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`normal` is declared non-nullable but is assigned `null`: null constant at line 76.]
@ -36,22 +35,8 @@ codetoanalyze/java/nullsafe/ConditionRedundant.java, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.ternary_NonnullInBothBranchesIsBAD(java.lang.String,java.lang.String,int):void, 2, ERADICATE_CONDITION_REDUNDANT, no_bucket, ADVICE, [The condition s2 might be always false according to the existing annotations.]
codetoanalyze/java/nullsafe/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.testFlowSensitivity(java.lang.String,java.lang.String):void, 2, ERADICATE_CONDITION_REDUNDANT, no_bucket, ADVICE, [The condition nullable1 might be always true according to the existing annotations.]
codetoanalyze/java/nullsafe/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.testFlowSensitivity(java.lang.String,java.lang.String):void, 4, ERADICATE_CONDITION_REDUNDANT, no_bucket, ADVICE, [The condition nullable1 might be always true according to the existing annotations.]
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 25, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `FieldNotInitialized` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], FieldNotInitialized, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 28, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$Suppression, codetoanalyze.java.nullsafe_default, issues: 11, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 67, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$OnlyRead, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 75, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$WriteItselfIsBAD, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 85, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$InitializationOrder, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 100, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$OnlyReadIndirect, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 114, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$ShouldInitializeInAllBranches, codetoanalyze.java.nullsafe_default, issues: 3, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 140, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$InitIfNull, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 155, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$InitCircular, codetoanalyze.java.nullsafe_default, issues: 2, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 172, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$InitWithOtherClass, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 173, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], FieldNotInitialized$InitWithOtherClass$OtherClass, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 189, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized$InitWithTheSameClass, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 206, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `TestKnownInitializers` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], TestKnownInitializers, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 209, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestKnownInitializers$KnownInitializers, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 230, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], TestKnownInitializers$FakeActivity, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 234, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestKnownInitializers$SimplyOnCreateWontDoATrick, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 25, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], FieldNotInitialized, codetoanalyze.java.nullsafe_default, issues: 23, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 206, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestKnownInitializers, codetoanalyze.java.nullsafe_default, issues: 2, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, Linters_dummy_method, 253, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestInitializerAnnotation, codetoanalyze.java.nullsafe_default, issues: 3, curr_mode: "Default"
codetoanalyze/java/nullsafe/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitCircular.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `stillBad` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method]
codetoanalyze/java/nullsafe/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitCircular.<init>(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `bad` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method]
@ -113,8 +98,6 @@ codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_m
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_method, 120, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NoOverrideSinceDifferentTypesOK, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default"
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_method, 137, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], OverloadExistingIncorrectBAD, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_method, 146, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `ConstructorsAreExcluded` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], ConstructorsAreExcluded, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_method, 147, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], ConstructorsAreExcluded$Base, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_method, 151, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], ConstructorsAreExcluded$Derived, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_method, 160, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ExtendsExternalLibrary, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_method, 177, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], JavaLangEquals, codetoanalyze.java.nullsafe_default, issues: 2, curr_mode: "Default"
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, Linters_dummy_method, 197, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `NonNullableConcreteGetterOK` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], NonNullableConcreteGetterOK, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
@ -127,12 +110,7 @@ codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, codetoanalyze.j
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.NullableConcreteGetterBAD.get():java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Child method `NullableConcreteGetterBAD.get()` is not substitution-compatible with its parent: the return type is declared as nullable, but parent method `NonNullableInterfaceGetterOK.get()` is missing `@Nullable` declaration. Either mark the parent as `@Nullable` or ensure the child does not return `null`.]
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.OverloadExistingIncorrectBAD.overload(java.lang.String,java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Child method `OverloadExistingIncorrectBAD.overload(...)` is not substitution-compatible with its parent: the return type is declared as nullable, but parent method `Overloads.overload(...)` is missing `@Nullable` declaration. Either mark the parent as `@Nullable` or ensure the child does not return `null`.]
codetoanalyze/java/nullsafe/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.ReturnValToNullBAD.valBoth(java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Child method `ReturnValToNullBAD.valBoth(...)` is not substitution-compatible with its parent: the return type is declared as nullable, but parent method `VariousMethods.valBoth(...)` is missing `@Nullable` declaration. Either mark the parent as `@Nullable` or ensure the child does not return `null`.]
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, Linters_dummy_method, 14, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `InheritanceForStrictMode` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], InheritanceForStrictMode, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, Linters_dummy_method, 15, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], InheritanceForStrictMode$NonStrictBase, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, Linters_dummy_method, 30, ERADICATE_META_CLASS_IS_NULLSAFE, no_bucket, INFO, [], InheritanceForStrictMode$StrictBase, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Strict"
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, Linters_dummy_method, 47, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], InheritanceForStrictMode$StrictExtendingNonstrict, codetoanalyze.java.nullsafe_default, issues: 2, curr_mode: "Strict"
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, Linters_dummy_method, 62, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], InheritanceForStrictMode$StrictExtendingStrict, codetoanalyze.java.nullsafe_default, issues: 2, curr_mode: "Strict"
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, Linters_dummy_method, 76, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], InheritanceForStrictMode$NonStrictExtendingStrict, codetoanalyze.java.nullsafe_default, issues: 2, curr_mode: "Default"
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, Linters_dummy_method, 14, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], InheritanceForStrictMode, codetoanalyze.java.nullsafe_default, issues: 6, curr_mode: "Default"
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, codetoanalyze.java.nullsafe_default.InheritanceForStrictMode$NonStrictExtendingStrict.badToAddNullableInChildren():java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, WARNING, [Child method `InheritanceForStrictMode$NonStrictExtendingStrict.badToAddNullableInChildren()` is not substitution-compatible with its parent: the return type is declared as nullable, but parent method `InheritanceForStrictMode$StrictBase.badToAddNullableInChildren()` is missing `@Nullable` declaration. Either mark the parent as `@Nullable` or ensure the child does not return `null`.]
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, codetoanalyze.java.nullsafe_default.InheritanceForStrictMode$NonStrictExtendingStrict.params(java.lang.String,java.lang.String):void, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `badToRemoveNullableInChildren` of method `InheritanceForStrictMode$NonStrictExtendingStrict.params(...)` is missing `@Nullable` declaration when overriding `InheritanceForStrictMode$StrictBase.params(...)`. The parent method declared it can handle `null` for this param, so the child should also declare that.]
codetoanalyze/java/nullsafe/InheritanceForStrictMode.java, codetoanalyze.java.nullsafe_default.InheritanceForStrictMode$StrictExtendingNonstrict.badToAddNullableInChildren():java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, ERROR, [Child method `InheritanceForStrictMode$StrictExtendingNonstrict.badToAddNullableInChildren()` is not substitution-compatible with its parent: the return type is declared as nullable, but parent method `InheritanceForStrictMode$NonStrictBase.badToAddNullableInChildren()` is missing `@Nullable` declaration. Either mark the parent as `@Nullable` or ensure the child does not return `null`.]
@ -146,9 +124,7 @@ codetoanalyze/java/nullsafe/LibraryCalls.java, codetoanalyze.java.nullsafe_defau
codetoanalyze/java/nullsafe/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badReferenceDereference(java.lang.ref.Reference):java.lang.String, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ref.get()` is nullable and is not locally checked for null when calling `toString()`: call to Reference.get() at line 19 (nullable according to nullsafe internal models).]
codetoanalyze/java/nullsafe/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badSoftReferenceDereference(java.lang.ref.SoftReference):java.lang.String, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ref.get()` is nullable and is not locally checked for null when calling `toString()`: call to SoftReference.get() at line 31 (nullable according to nullsafe internal models).]
codetoanalyze/java/nullsafe/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badWeakReferenceDereference(java.lang.ref.WeakReference):java.lang.String, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ref.get()` is nullable and is not locally checked for null when calling `toString()`: call to Reference.get() at line 23 (nullable according to nullsafe internal models).]
codetoanalyze/java/nullsafe/MapNullability.java, Linters_dummy_method, 13, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `MapNullability` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], MapNullability, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/MapNullability.java, Linters_dummy_method, 15, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], MapNullability$TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked, codetoanalyze.java.nullsafe_default, issues: 4, curr_mode: "Default"
codetoanalyze/java/nullsafe/MapNullability.java, Linters_dummy_method, 64, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], MapNullability$TestThatGetAfterPutIsAllowed, codetoanalyze.java.nullsafe_default, issues: 9, curr_mode: "Default"
codetoanalyze/java/nullsafe/MapNullability.java, Linters_dummy_method, 13, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], MapNullability, codetoanalyze.java.nullsafe_default, issues: 13, curr_mode: "Default"
codetoanalyze/java/nullsafe/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterConditionalPutWrongKeyIsBAD(java.util.Map,java.lang.String,java.lang.String):void, 5, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`dontAssignNull` is declared non-nullable but is assigned a nullable: call to Map.get(...) at line 137 (nullable according to nullsafe internal models).]
codetoanalyze/java/nullsafe/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterPutNullableIsBAD(java.util.Map,java.lang.String):void, 2, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`Map.put(...)`: parameter #2 is declared non-nullable (according to nullsafe internal models) but the argument `nullableValue` is nullable.]
codetoanalyze/java/nullsafe/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterPutNullableIsBAD(java.util.Map,java.lang.String):void, 3, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`dontAssignNull` is declared non-nullable but is assigned a nullable: method parameter nullableValue.]
@ -175,12 +151,7 @@ codetoanalyze/java/nullsafe/ModePromotions.java, Linters_dummy_method, 96, ERADI
codetoanalyze/java/nullsafe/ModePromotions.java, Linters_dummy_method, 105, ERADICATE_META_CLASS_IS_NULLSAFE, no_bucket, INFO, [], TrustSome_TrustStrictIsNotNeeded_CanBePromotedToStrict, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "LocalTrustSome", promote_mode: "Strict"
codetoanalyze/java/nullsafe/ModePromotions.java, Linters_dummy_method, 112, ERADICATE_META_CLASS_IS_NULLSAFE, no_bucket, INFO, [], TrustNone_CanBePromotedToStrict, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "LocalTrustNone", promote_mode: "Strict"
codetoanalyze/java/nullsafe/MyPreconditions.java, Linters_dummy_method, 11, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `MyPreconditions` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], MyPreconditions, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NestedFieldAccess.java, Linters_dummy_method, 12, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `NestedFieldAccess` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], NestedFieldAccess, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NestedFieldAccess.java, Linters_dummy_method, 14, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NestedFieldAccess$C, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NestedFieldAccess.java, Linters_dummy_method, 18, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NestedFieldAccess$CC, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NestedFieldAccess.java, Linters_dummy_method, 22, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NestedFieldAccess$CCC, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NestedFieldAccess.java, Linters_dummy_method, 30, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NestedFieldAccess$TestNullableChains, codetoanalyze.java.nullsafe_default, issues: 7, curr_mode: "Default"
codetoanalyze/java/nullsafe/NestedFieldAccess.java, Linters_dummy_method, 124, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NestedFieldAccess$TestFunctionsIdempotent, codetoanalyze.java.nullsafe_default, issues: 8, curr_mode: "Default"
codetoanalyze/java/nullsafe/NestedFieldAccess.java, Linters_dummy_method, 12, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NestedFieldAccess, codetoanalyze.java.nullsafe_default, issues: 15, curr_mode: "Default"
codetoanalyze/java/nullsafe/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf0VsChainOf0ParamsMismatchIsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`dontAssignNull` is declared non-nullable but is assigned a nullable: call to nullable(...) at line 145.]
codetoanalyze/java/nullsafe/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf0VsChainOf1IsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`dontAssignNull` is declared non-nullable but is assigned a nullable: call to nullable(...) at line 169.]
codetoanalyze/java/nullsafe/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf1VsChainOf0IsBad():void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`dontAssignNull` is declared non-nullable but is assigned a nullable: call to nullable(...) at line 175.]
@ -198,7 +169,6 @@ codetoanalyze/java/nullsafe/NestedFieldAccess.java, codetoanalyze.java.nullsafe_
codetoanalyze/java/nullsafe/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.veryDeep_IncompleteAccessViaOrEarlyReturnIsBad(codetoanalyze.java.nullsafe_default.NestedFieldAccess$CCC):void, 3, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ccc.cc.c.s` is nullable and is not locally checked for null when calling `length()`.]
codetoanalyze/java/nullsafe/NoReuseUndefFunctionValues.java, Linters_dummy_method, 12, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `NoReuseUndefFunctionValues` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], NoReuseUndefFunctionValues, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullFieldAccess.java, Linters_dummy_method, 12, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullFieldAccess, codetoanalyze.java.nullsafe_default, issues: 5, curr_mode: "Default"
codetoanalyze/java/nullsafe/NullFieldAccess.java, Linters_dummy_method, 14, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullFieldAccess$I, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.<init>(), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `NullFieldAccess.nullableArray` is always initialized in the constructor but is declared `@Nullable`]
codetoanalyze/java/nullsafe/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.<init>(), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `NullFieldAccess.nullable` is always initialized in the constructor but is declared `@Nullable`]
codetoanalyze/java/nullsafe/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.testArray():void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [Array `NullFieldAccess.nullableArray` is nullable and is not locally checked for null when accessing its length.]
@ -206,14 +176,7 @@ codetoanalyze/java/nullsafe/NullFieldAccess.java, codetoanalyze.java.nullsafe_de
codetoanalyze/java/nullsafe/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.testInterface():void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`bad` is nullable and is not locally checked for null when calling `toString()`: field nullable at line 52.]
codetoanalyze/java/nullsafe/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.testNonStaticFields():void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`bad` is nullable and is not locally checked for null when calling `toString()`: field nullable at line 36.]
codetoanalyze/java/nullsafe/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.testStatic():void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`bad` is nullable and is not locally checked for null when calling `toString()`: field nullableStatic at line 44.]
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 22, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullMethodCall, codetoanalyze.java.nullsafe_default, issues: 22, curr_mode: "Default"
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 60, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullMethodCall$S, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 67, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullMethodCall$Inner, codetoanalyze.java.nullsafe_default, issues: 2, curr_mode: "Default"
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 142, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullMethodCall$Inner$InnerInner, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 190, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullMethodCall$InitializeAndExceptions, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 202, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullMethodCall$InitializeViaPrivateMethod, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 218, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullMethodCall$CheckNotNullVararg, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 244, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullMethodCall$SystemExitDoesNotReturn, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullMethodCall.java, Linters_dummy_method, 22, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullMethodCall, codetoanalyze.java.nullsafe_default, issues: 24, curr_mode: "Default"
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall$Inner.outerField():int, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s` is nullable and is not locally checked for null when calling `length()`: field fld at line 69.]
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall$Inner.outerPrivateField():int, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s` is nullable and is not locally checked for null when calling `length()`: field pfld at line 80.]
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.FP_propagatesNonNullAfterComparisonFieldOkay(java.lang.Object):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`NullMethodCall.nullableField` is nullable and is not locally checked for null when calling `toString()`.]
@ -238,16 +201,7 @@ codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe_def
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.testSystemGetenvBad():int, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`envValue` is nullable and is not locally checked for null when calling `length()`: call to System.getenv(...) at line 240 (nullable according to nullsafe internal models).]
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.withConditionalAssignemnt(codetoanalyze.java.nullsafe_default.NullMethodCall$AnotherI,boolean,java.lang.Object,java.lang.Object):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withObjectParameter(...)`.]
codetoanalyze/java/nullsafe/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.withConjuction(codetoanalyze.java.nullsafe_default.NullMethodCall$AnotherI,boolean,boolean):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withBooleanParameter(...)`.]
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 16, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `NullsafeMode` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], NullsafeMode, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 17, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullsafeMode$VariousMethods, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 28, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeMode$NonNullsafe, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 54, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullsafeMode$AnotherNonNullsafe, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 56, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], NullsafeMode$UncheckedParams, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 77, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeMode$TrustAllNullsafe, codetoanalyze.java.nullsafe_default, issues: 5, curr_mode: "LocalTrustAll"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 124, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeMode$TrustSomeNullsafe, codetoanalyze.java.nullsafe_default, issues: 3, curr_mode: "LocalTrustSome"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 153, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeMode$TrustNoneNullsafe, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustNone"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 164, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeMode$NullsafeWithStrictMode, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 184, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeMode$StrictNullsafe, codetoanalyze.java.nullsafe_default, issues: 3, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeMode.java, Linters_dummy_method, 16, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeMode, codetoanalyze.java.nullsafe_default, issues: 13, curr_mode: "Default"
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$NullsafeWithStrictMode.BAD_returnFromNonStrict():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$VariousMethods.returnVal()`: `@NullsafeStrict` mode prohibits using values coming from non-strict classes without a check. Result of this call is used at line 174. Either add a local check for null or assertion, or make `NullsafeMode$VariousMethods` nullsafe strict.]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$StrictNullsafe.BAD_dereferenceNotAnnotatedThirdParty():void, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.returnUnspecified()`: `@NullsafeStrict` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 218. Either add a local check for null or assertion, or add the correct signature to nullsafe/third-party-signatures/some.test.pckg.sig.]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$StrictNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe_default.NullsafeMode$UncheckedParams, 1, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.getUncheckedLong(...)`: `@NullsafeStrict` mode prohibits using values coming from not vetted third party methods without a check. Result of this call is used at line 214. Either add a local check for null or assertion, or add the correct signature to nullsafe/third-party-signatures/some.test.pckg.sig.]
@ -262,29 +216,17 @@ codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe_defau
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.BAD_returnNullFromNonNulsafe():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`BAD_returnNullFromNonNulsafe()`: return type is declared non-nullable but the method returns a nullable value: call to returnNull() at line 144.]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.FP_OK_accessFieldFromNonNullsafe():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NullsafeMode$NonNullsafe.valField`: `@NullsafeLocal(trust=selected)` mode prohibits using values coming from non-nullsafe classes without a check. This field is used at line 147. Either add a local check for null or assertion, or make `NullsafeMode$NonNullsafe` @Nullsafe (or add it to trust list).]
codetoanalyze/java/nullsafe/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.OK_returnFromUntrustedNonNullsafeAsNullable():java.lang.String, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, ADVICE, [Method `OK_returnFromUntrustedNonNullsafeAsNullable()` is annotated with `@Nullable` but never returns null.]
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 14, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeLocal, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustAll"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 21, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeLocal$Nested, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustAll"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 27, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeLocal$Nested$DeeplyNested, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustAll"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 41, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeLocal$NestedStrict, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 49, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeLocal$NestedExplicitLocal, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustAll"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 14, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeLocal, codetoanalyze.java.nullsafe_default, issues: 5, curr_mode: "LocalTrustAll"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 49, ERADICATE_REDUNDANT_NESTED_CLASS_ANNOTATION, no_bucket, ADVICE, [`NullsafeLocal$NestedExplicitLocal`: the same @Nullsafe mode is already specified in the outer class, so this annotation can be removed.], NullsafeLocal$NestedExplicitLocal, codetoanalyze.java.nullsafe_default
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 57, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeStrict, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 63, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeStrict$Nested, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 57, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeStrict, codetoanalyze.java.nullsafe_default, issues: 4, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 71, ERADICATE_BAD_NESTED_CLASS_ANNOTATION, no_bucket, WARNING, [`NullsafeStrict$Nested$DeeplyNestedLocalIsStillStrict`: nested classes are disallowed to weaken @Nullsafe mode specified in the outer class. This annotation will be ignored.], NullsafeStrict$Nested$DeeplyNestedLocalIsStillStrict, codetoanalyze.java.nullsafe_default
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 71, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeStrict$Nested$DeeplyNestedLocalIsStillStrict, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 80, ERADICATE_BAD_NESTED_CLASS_ANNOTATION, no_bucket, WARNING, [`NullsafeStrict$NestedLocalIsStillStrict`: nested classes are disallowed to weaken @Nullsafe mode specified in the outer class. This annotation will be ignored.], NullsafeStrict$NestedLocalIsStillStrict, codetoanalyze.java.nullsafe_default
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 80, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], NullsafeStrict$NestedLocalIsStillStrict, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 87, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `Default` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], Default, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 94, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], Default$NestedLocal, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustAll"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 106, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], Default$NestedLocal$DeeplyNestedStrict, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 87, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], Default, codetoanalyze.java.nullsafe_default, issues: 2, curr_mode: "Default"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 114, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `A` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], A, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 120, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `B` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], B, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 122, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `C` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], C, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 129, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrustSome, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustSome"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 140, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrustSome$NotAnnotatedNested, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustSome"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 152, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrustSome$CanRemoveFromTrustList, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustSome"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 129, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrustSome, codetoanalyze.java.nullsafe_default, issues: 4, curr_mode: "LocalTrustSome"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 161, ERADICATE_BAD_NESTED_CLASS_ANNOTATION, no_bucket, WARNING, [Nested classes cannot add classes to trust list if they are not in the outer class trust list. Remove `C` from trust list.], TrustSome$CanNotAddToTrustList, codetoanalyze.java.nullsafe_default
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, Linters_dummy_method, 161, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrustSome$CanNotAddToTrustList, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "LocalTrustSome"
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, codetoanalyze.java.nullsafe_default.Default$NestedLocal$DeeplyNestedStrict.returningDefaultNotNullIsError():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`Default.getString()`: `@NullsafeStrict` mode prohibits using values coming from non-strict classes without a check. Result of this call is used at line 107. Either add a local check for null or assertion, or make `Default` nullsafe strict.]
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, codetoanalyze.java.nullsafe_default.Default$NestedLocal.shouldBeNullsafeModeError():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`shouldBeNullsafeModeError()`: return type is declared non-nullable but the method returns `null`: null constant at line 96.]
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, codetoanalyze.java.nullsafe_default.NullsafeLocal$Nested$DeeplyNested.shouldBeNullsafeModeError():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, ERROR, [`shouldBeNullsafeModeError()`: return type is declared non-nullable but the method returns `null`: null constant at line 29.]
@ -300,9 +242,7 @@ codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, codetoanalyze.java.n
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, codetoanalyze.java.nullsafe_default.TrustSome$CanRemoveFromTrustList.dontTrustA_BAD():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`A.getString()`: `@NullsafeLocal(trust=selected)` mode prohibits using values coming from non-nullsafe classes without a check. Result of this call is used at line 153. Either add a local check for null or assertion, or make `A` @Nullsafe (or add it to trust list).]
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, codetoanalyze.java.nullsafe_default.TrustSome$NotAnnotatedNested.dontTrustC_Bad():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`C.getString()`: `@NullsafeLocal(trust=selected)` mode prohibits using values coming from non-nullsafe classes without a check. Result of this call is used at line 145. Either add a local check for null or assertion, or make `C` @Nullsafe (or add it to trust list).]
codetoanalyze/java/nullsafe/NullsafeModeNestedClasses.java, codetoanalyze.java.nullsafe_default.TrustSome.dontTrustC_Bad():java.lang.String, 1, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`C.getString()`: `@NullsafeLocal(trust=selected)` mode prohibits using values coming from non-nullsafe classes without a check. Result of this call is used at line 135. Either add a local check for null or assertion, or make `C` @Nullsafe (or add it to trust list).]
codetoanalyze/java/nullsafe/ParameterNotNullable.java, Linters_dummy_method, 20, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ParameterNotNullable, codetoanalyze.java.nullsafe_default, issues: 37, curr_mode: "Default"
codetoanalyze/java/nullsafe/ParameterNotNullable.java, Linters_dummy_method, 64, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], ParameterNotNullable$Builder, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/ParameterNotNullable.java, Linters_dummy_method, 93, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ParameterNotNullable$ConstructorCall, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/ParameterNotNullable.java, Linters_dummy_method, 20, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ParameterNotNullable, codetoanalyze.java.nullsafe_default, issues: 38, curr_mode: "Default"
codetoanalyze/java/nullsafe/ParameterNotNullable.java, Linters_dummy_method, 195, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `SomeClass` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], SomeClass, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable$ConstructorCall.<init>(codetoanalyze.java.nullsafe_default.ParameterNotNullable,int), 0, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable$ConstructorCall(...)`: parameter #2(`s`) is declared non-nullable but the argument is `null`.]
codetoanalyze/java/nullsafe/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.callNull():void, 2, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.test(...)`: parameter #1(`s`) is declared non-nullable but the argument `s` is `null`: null constant at line 39.]
@ -341,11 +281,7 @@ codetoanalyze/java/nullsafe/ParameterNotNullable.java, codetoanalyze.java.nullsa
codetoanalyze/java/nullsafe/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.testThreeParameters():void, 2, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.threeParameters(...)`: parameter #1(`s1`) is declared non-nullable but the argument is `null`.]
codetoanalyze/java/nullsafe/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.testThreeParameters():void, 3, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.threeParameters(...)`: parameter #2(`s2`) is declared non-nullable but the argument is `null`.]
codetoanalyze/java/nullsafe/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.testThreeParameters():void, 4, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.threeParameters(...)`: parameter #3(`s3`) is declared non-nullable but the argument is `null`.]
codetoanalyze/java/nullsafe/PropagatesNullable.java, Linters_dummy_method, 14, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `TestPropagatesNullable` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], TestPropagatesNullable, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/PropagatesNullable.java, Linters_dummy_method, 16, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestPropagatesNullable$TestOneParameter, codetoanalyze.java.nullsafe_default, issues: 8, curr_mode: "Default"
codetoanalyze/java/nullsafe/PropagatesNullable.java, Linters_dummy_method, 64, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestPropagatesNullable$TestSecondParameter, codetoanalyze.java.nullsafe_default, issues: 6, curr_mode: "Default"
codetoanalyze/java/nullsafe/PropagatesNullable.java, Linters_dummy_method, 96, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestPropagatesNullable$TestBothParams, codetoanalyze.java.nullsafe_default, issues: 3, curr_mode: "Default"
codetoanalyze/java/nullsafe/PropagatesNullable.java, Linters_dummy_method, 113, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestPropagatesNullable$TestReturnValueAnnotationIsAutomaticallyInferred, codetoanalyze.java.nullsafe_default, issues: 3, curr_mode: "Default"
codetoanalyze/java/nullsafe/PropagatesNullable.java, Linters_dummy_method, 14, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TestPropagatesNullable, codetoanalyze.java.nullsafe_default, issues: 20, curr_mode: "Default"
codetoanalyze/java/nullsafe/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.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()`: method parameter sNullable.]
codetoanalyze/java/nullsafe/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.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()`: method parameter sNullable.]
codetoanalyze/java/nullsafe/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.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()`: method parameter sNullable.]
@ -366,9 +302,7 @@ codetoanalyze/java/nullsafe/PropagatesNullable.java, codetoanalyze.java.nullsafe
codetoanalyze/java/nullsafe/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.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()`.]
codetoanalyze/java/nullsafe/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.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()`.]
codetoanalyze/java/nullsafe/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.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()`.]
codetoanalyze/java/nullsafe/ReturnNotNullable.java, Linters_dummy_method, 19, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ReturnNotNullable, codetoanalyze.java.nullsafe_default, issues: 8, curr_mode: "Default"
codetoanalyze/java/nullsafe/ReturnNotNullable.java, Linters_dummy_method, 154, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], ReturnNotNullable$E, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/ReturnNotNullable.java, Linters_dummy_method, 191, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ReturnNotNullable$ConditionalAssignment, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/ReturnNotNullable.java, Linters_dummy_method, 19, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], ReturnNotNullable, codetoanalyze.java.nullsafe_default, issues: 9, curr_mode: "Default"
codetoanalyze/java/nullsafe/ReturnNotNullable.java, codetoanalyze.java.nullsafe_default.ReturnNotNullable$ConditionalAssignment.test(boolean):java.lang.Object, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [`test(...)`: return type is declared non-nullable but the method returns a nullable value: field f1 at line 199.]
codetoanalyze/java/nullsafe/ReturnNotNullable.java, codetoanalyze.java.nullsafe_default.ReturnNotNullable.constantToNullableIsOverannotated():java.lang.String, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, ADVICE, [Method `constantToNullableIsOverannotated()` is annotated with `@Nullable` but never returns null.]
codetoanalyze/java/nullsafe/ReturnNotNullable.java, codetoanalyze.java.nullsafe_default.ReturnNotNullable.getResourceNullable(java.lang.Class,java.lang.String):java.net.URL, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [`getResourceNullable(...)`: return type is declared non-nullable but the method returns a nullable value: call to Class.getResource(...) at line 177 (nullable according to nullsafe internal models).]
@ -416,17 +350,7 @@ codetoanalyze/java/nullsafe/SwitchCase.java, Linters_dummy_method, 63, ERADICATE
codetoanalyze/java/nullsafe/SwitchCase.java, codetoanalyze.java.nullsafe_default.SwitchCase.getNullableColor():codetoanalyze.java.nullsafe_default.Color, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, ADVICE, [Method `getNullableColor()` is annotated with `@Nullable` but never returns null.]
codetoanalyze/java/nullsafe/SwitchCase.java, codetoanalyze.java.nullsafe_default.SwitchCase.switchOnNullIsBad():java.lang.String, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [NullPointerException will be thrown at this line! `color` is `null` and is dereferenced via calling `ordinal()`: null constant at line 14.]
codetoanalyze/java/nullsafe/SwitchCase.java, codetoanalyze.java.nullsafe_default.SwitchCase.switchOnNullableIsBad():java.lang.String, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`color` is nullable and is not locally checked for null when calling `ordinal()`: call to getNullableColor() at line 28.]
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 17, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, ADVICE, [Congrats! `TrueFalseOnNull` is free of nullability issues. Mark it `@Nullsafe(value = Nullsafe.Mode.LOCAL, trustOnly = @Nullsafe.TrustList({}))` to prevent regressions.], TrueFalseOnNull, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 19, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], TrueFalseOnNull$StaticOneParam, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 35, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], TrueFalseOnNull$NonStaticOneParam, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 57, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], TrueFalseOnNull$NonStaticSeveralParams, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 87, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrueFalseOnNull$TestStaticOneParam, codetoanalyze.java.nullsafe_default, issues: 4, curr_mode: "Default"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 126, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrueFalseOnNull$TestNonStaticOneParam, codetoanalyze.java.nullsafe_default, issues: 4, curr_mode: "Default"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 166, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrueFalseOnNull$TestNonStaticSeveralParams, codetoanalyze.java.nullsafe_default, issues: 8, curr_mode: "Default"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 212, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], TrueFalseOnNull$TestModels, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 228, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], TrueFalseOnNull$TestEqualsIsFalseOnNull, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 230, ERADICATE_META_CLASS_CAN_BE_NULLSAFE, no_bucket, INFO, [], TrueFalseOnNull$TestEqualsIsFalseOnNull$SomeObject, codetoanalyze.java.nullsafe_default, issues: 0, curr_mode: "Default", promote_mode: "Strict"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 273, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrueFalseOnNull$EarlyReturn, codetoanalyze.java.nullsafe_default, issues: 1, curr_mode: "Default"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, Linters_dummy_method, 17, ERADICATE_META_CLASS_NEEDS_IMPROVEMENT, no_bucket, INFO, [], TrueFalseOnNull, codetoanalyze.java.nullsafe_default, issues: 17, curr_mode: "Default"
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, codetoanalyze.java.nullsafe_default.TrueFalseOnNull$EarlyReturn.testEarlyReturn(java.lang.CharSequence,java.lang.CharSequence):void, 6, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s2` is nullable and is not locally checked for null when calling `toString()`.]
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, codetoanalyze.java.nullsafe_default.TrueFalseOnNull$TestNonStaticOneParam.falseOnNullNegativeBranchIsBAD(java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s` is nullable and is not locally checked for null when calling `toString()`.]
codetoanalyze/java/nullsafe/TrueFalseOnNull.java, codetoanalyze.java.nullsafe_default.TrueFalseOnNull$TestNonStaticOneParam.notAnnotatedNegativeBranchIsBAD(java.lang.String):void, 2, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s` is nullable and is not locally checked for null when calling `toString()`.]

Loading…
Cancel
Save