From f291f9324848fc25a3af93a7e802bbf4baad429a Mon Sep 17 00:00:00 2001 From: Mitya Lyubarskiy Date: Mon, 16 Mar 2020 08:07:52 -0700 Subject: [PATCH] [nullsafe] Implement class-level analysis and calculate meta-issues. Summary: This diff is doing three things: 1. Finishes work paved in D20115024, and applies it to nullsafe. In that diff, we hardened API for file level analysis. Here we use this API in nullsafe, so now we can analyze things on file-level, not only in proc-level like it was before! 2. Introduces a class-level analysis. For Nullsafe purposes, file is not an interesting granularity, but we want to analyze a lot of things on file level. Interesting part here is anonymous classes and how we link them to their corresponding user-defined classes. 3. Introduces a first (yet to be improved) implementation of class-level analysis. Namely it is "meta-issues" that tell what is going with class on high level. For now these are two primitive issues, and we will refine them in follow up diffs. They are disabled by default. Follow ups include: 1. Refining semantics of meta-issues. 2. Adding other issues that we could not analyze before or analyzed not user friendly. Most importantly, we will use it to improve reporting for FIELD NOT INITIALIZED, which is not very user friendly exactly because of lack of class-level aggregation. Reviewed By: artempyanykh Differential Revision: D20417841 fbshipit-source-id: 59ba7d2e3 --- infer/man/man1/infer-full.txt | 2 + infer/man/man1/infer-report.txt | 2 + infer/man/man1/infer.txt | 2 + infer/src/IR/JavaClassName.ml | 6 + infer/src/IR/JavaClassName.mli | 2 + infer/src/backend/Payloads.ml | 6 +- infer/src/backend/Payloads.mli | 2 +- infer/src/base/Config.ml | 2 + infer/src/base/Config.mli | 2 + infer/src/base/IssueType.ml | 18 +++ infer/src/base/IssueType.mli | 4 + infer/src/checkers/registerCheckers.ml | 7 +- infer/src/nullsafe/AggregatedSummaries.ml | 76 ++++++++++++ infer/src/nullsafe/AggregatedSummaries.mli | 33 +++++ infer/src/nullsafe/ClassLevelAnalysis.ml | 48 ++++++++ infer/src/nullsafe/ClassLevelAnalysis.mli | 15 +++ infer/src/nullsafe/FileLevelAnalysis.ml | 44 +++++++ infer/src/nullsafe/FileLevelAnalysis.mli | 12 ++ infer/src/nullsafe/NullsafeSummary.ml | 14 +++ infer/src/nullsafe/NullsafeSummary.mli | 14 +++ .../src/nullsafe/ThirdPartyAnnotationInfo.ml | 25 ++-- .../src/nullsafe/ThirdPartyAnnotationInfo.mli | 3 + infer/src/nullsafe/eradicate.ml | 38 ++++-- infer/src/nullsafe/eradicate.mli | 11 +- infer/src/nullsafe/typeErr.ml | 6 + infer/src/nullsafe/typeErr.mli | 2 + .../java/nullsafe-default/issues.exp | 114 ++++++++++++++++++ 27 files changed, 483 insertions(+), 27 deletions(-) create mode 100644 infer/src/nullsafe/AggregatedSummaries.ml create mode 100644 infer/src/nullsafe/AggregatedSummaries.mli create mode 100644 infer/src/nullsafe/ClassLevelAnalysis.ml create mode 100644 infer/src/nullsafe/ClassLevelAnalysis.mli create mode 100644 infer/src/nullsafe/FileLevelAnalysis.ml create mode 100644 infer/src/nullsafe/FileLevelAnalysis.mli create mode 100644 infer/src/nullsafe/NullsafeSummary.ml create mode 100644 infer/src/nullsafe/NullsafeSummary.mli diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index be016da1e..cfafd9143 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -406,6 +406,8 @@ OPTIONS by default), ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION (enabled by default), + ERADICATE_META_CLASS_IS_CLEAN (disabled by default), + ERADICATE_META_CLASS_NEEDS_FIXING (disabled by default), ERADICATE_NULLABLE_DEREFERENCE (enabled by default), ERADICATE_PARAMETER_NOT_NULLABLE (enabled by default), ERADICATE_RETURN_NOT_NULLABLE (enabled by default), diff --git a/infer/man/man1/infer-report.txt b/infer/man/man1/infer-report.txt index ce8040447..fff901c66 100644 --- a/infer/man/man1/infer-report.txt +++ b/infer/man/man1/infer-report.txt @@ -137,6 +137,8 @@ OPTIONS by default), ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION (enabled by default), + ERADICATE_META_CLASS_IS_CLEAN (disabled by default), + ERADICATE_META_CLASS_NEEDS_FIXING (disabled by default), ERADICATE_NULLABLE_DEREFERENCE (enabled by default), ERADICATE_PARAMETER_NOT_NULLABLE (enabled by default), ERADICATE_RETURN_NOT_NULLABLE (enabled by default), diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index 77ac88d0d..52d120802 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -406,6 +406,8 @@ OPTIONS by default), ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION (enabled by default), + ERADICATE_META_CLASS_IS_CLEAN (disabled by default), + ERADICATE_META_CLASS_NEEDS_FIXING (disabled by default), ERADICATE_NULLABLE_DEREFERENCE (enabled by default), ERADICATE_PARAMETER_NOT_NULLABLE (enabled by default), ERADICATE_RETURN_NOT_NULLABLE (enabled by default), diff --git a/infer/src/IR/JavaClassName.ml b/infer/src/IR/JavaClassName.ml index c199287cf..bfa6e3c47 100644 --- a/infer/src/IR/JavaClassName.ml +++ b/infer/src/IR/JavaClassName.ml @@ -12,6 +12,12 @@ module L = Logging (** invariant: if [package = Some str] then [not (String.equal str "")] *) type t = {classname: string; package: string option} [@@deriving compare, equal] +module Map = Caml.Map.Make (struct + type nonrec t = t + + let compare = compare +end) + let make ~package ~classname = match package with Some "" -> {package= None; classname} | _ -> {package; classname} diff --git a/infer/src/IR/JavaClassName.mli b/infer/src/IR/JavaClassName.mli index 835bb410f..06ea98f88 100644 --- a/infer/src/IR/JavaClassName.mli +++ b/infer/src/IR/JavaClassName.mli @@ -9,6 +9,8 @@ open! IStd type t [@@deriving compare, equal] +module Map : Caml.Map.S with type key = t + val make : package:string option -> classname:string -> t val from_string : string -> t diff --git a/infer/src/backend/Payloads.ml b/infer/src/backend/Payloads.ml index da2979446..34c210274 100644 --- a/infer/src/backend/Payloads.ml +++ b/infer/src/backend/Payloads.ml @@ -23,7 +23,7 @@ type t = ; racerd: RacerDDomain.summary option ; siof: SiofDomain.Summary.t option ; starvation: StarvationDomain.summary option - ; typestate: TypeState.t option + ; nullsafe: NullsafeSummary.t option ; uninit: UninitDomain.Summary.t option } [@@deriving fields] @@ -49,7 +49,7 @@ let fields = ~lab_resource_leaks:(fun f -> mk f "Resource Leaks Lab" ResourceLeakDomain.pp) ~siof:(fun f -> mk f "Siof" SiofDomain.Summary.pp) ~starvation:(fun f -> mk f "Starvation" StarvationDomain.pp_summary) - ~typestate:(fun f -> mk f "TypeState" TypeState.pp) + ~nullsafe:(fun f -> mk f "Nullsafe" NullsafeSummary.pp) ~uninit:(fun f -> mk f "Uninitialised" UninitDomain.Summary.pp) @@ -74,5 +74,5 @@ let empty = ; racerd= None ; siof= None ; starvation= None - ; typestate= None + ; nullsafe= None ; uninit= None } diff --git a/infer/src/backend/Payloads.mli b/infer/src/backend/Payloads.mli index 9b7122f37..fe2ba797a 100644 --- a/infer/src/backend/Payloads.mli +++ b/infer/src/backend/Payloads.mli @@ -27,7 +27,7 @@ include sig ; racerd: RacerDDomain.summary option ; siof: SiofDomain.Summary.t option ; starvation: StarvationDomain.summary option - ; typestate: TypeState.t option + ; nullsafe: NullsafeSummary.t option ; uninit: UninitDomain.Summary.t option } [@@deriving fields] end diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index 5e1874fb8..96664dbff 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -199,6 +199,8 @@ let meet_level = 1 let nsnotification_center_checker_backend = false +let nullsafe_file_level_issues_dir_name = "nullsafe_file_level" + let proc_stats_filename = "proc_stats.json" let procnames_locks_dir_name = "procnames_locks" diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 02c55b401..cf6249f83 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -440,6 +440,8 @@ val no_translate_libs : bool val nullable_annotation : string option +val nullsafe_file_level_issues_dir_name : string + val nullsafe_disable_field_not_initialized_in_nonstrict_classes : bool val nullsafe_optimistic_third_party_params_in_non_strict : bool diff --git a/infer/src/base/IssueType.ml b/infer/src/base/IssueType.ml index f9323cfe9..09cdccba1 100644 --- a/infer/src/base/IssueType.ml +++ b/infer/src/base/IssueType.ml @@ -287,6 +287,24 @@ let eradicate_unvetted_third_party_in_nullsafe = ~hum:"Nullsafe mode: unchecked usage of unvetted third-party" +(* Meta issues in eradicate are technical issues reflecting null-safety state of classes in general, + in contrast with concrete nullability type violations *) + +(* Experimental issue, meaning might be changed *) +let eradicate_meta_class_is_clean = + register_from_string "ERADICATE_META_CLASS_IS_CLEAN" + ~hum:"Class is clean of nullability issues" (* Should be enabled for special integrations *) + ~enabled:false + + +(* Experimental issue, meaning might be changed *) +let eradicate_meta_class_needs_fixing = + register_from_string "ERADICATE_META_CLASS_NEEDS_FIXING" + ~hum: + "Class is not null-safe and needs fixing nullability issues" + (* Should be enabled for special integrations *) ~enabled:false + + let expensive_cost_call ~kind ~is_on_cold_start ~is_on_ui_thread = register_from_cost_string ~enabled:false ~kind ~is_on_cold_start ~is_on_ui_thread "EXPENSIVE_%s" diff --git a/infer/src/base/IssueType.mli b/infer/src/base/IssueType.mli index 9fafd756c..fa07e56e0 100644 --- a/infer/src/base/IssueType.mli +++ b/infer/src/base/IssueType.mli @@ -170,6 +170,10 @@ val eradicate_unvetted_third_party_in_nullsafe : t val eradicate_unchecked_usage_in_nullsafe : t +val eradicate_meta_class_is_clean : t + +val eradicate_meta_class_needs_fixing : t + val expensive_cost_call : kind:CostKind.t -> is_on_cold_start:bool -> is_on_ui_thread:bool -> t val exposed_insecure_intent_handling : t diff --git a/infer/src/checkers/registerCheckers.ml b/infer/src/checkers/registerCheckers.ml index b14e649bb..33855d4dd 100644 --- a/infer/src/checkers/registerCheckers.ml +++ b/infer/src/checkers/registerCheckers.ml @@ -55,7 +55,12 @@ let all_checkers = ; (Procedure BufferOverrunChecker.checker, Language.Java) ] } ; { name= "eradicate" ; active= Config.is_checker_enabled Eradicate - ; callbacks= [(Procedure Eradicate.callback_eradicate, Language.Java)] } + ; callbacks= + [ (Procedure Eradicate.proc_callback, Language.Java) + ; ( File + { callback= Eradicate.file_callback + ; issue_dir= Config.nullsafe_file_level_issues_dir_name } + , Language.Java ) ] } ; { name= "fragment retains view" ; active= Config.is_checker_enabled FragmentRetainsView ; callbacks= diff --git a/infer/src/nullsafe/AggregatedSummaries.ml b/infer/src/nullsafe/AggregatedSummaries.ml new file mode 100644 index 000000000..e913cbe96 --- /dev/null +++ b/infer/src/nullsafe/AggregatedSummaries.ml @@ -0,0 +1,76 @@ +(* + * 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 + +module ClassInfo = struct + type t = {summaries: Summary.t list; nested_anonymous_classes: anonymous_class_to_summaries} + + and anonymous_class_to_summaries = Summary.t list JavaClassName.Map.t + + let make_empty () = {summaries= []; nested_anonymous_classes= JavaClassName.Map.empty} + + let get_class_summaries {summaries} = summaries + + (** Add top level (not anonymous) summary belonging to this class *) + let add_class_summary summary t = {t with summaries= summary :: t.summaries} + + (** Add summary for the nested anonymous class belonging to this class *) + let add_anonymous_summary anonymous_class_name summary t = + let updated_anonymous_classes = + JavaClassName.Map.update anonymous_class_name + (function None -> Some [summary] | Some summaries -> Some (summary :: summaries)) + t.nested_anonymous_classes + in + {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 anonymous_summaries = + get_anonymous_summaries t + |> List.map ~f:(fun (_, summaries) -> summaries) + |> List.fold ~init:[] ~f:( @ ) + in + t.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 + 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 + | 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 + | 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 [] diff --git a/infer/src/nullsafe/AggregatedSummaries.mli b/infer/src/nullsafe/AggregatedSummaries.mli new file mode 100644 index 000000000..499aaa5b2 --- /dev/null +++ b/infer/src/nullsafe/AggregatedSummaries.mli @@ -0,0 +1,33 @@ +(* + * 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 + +(** Results of proc-level analysis, grouped by Java class they belong to. Useful for class-level + analysis, when summaries for all methods are calculated and need to be combined together. *) + +(** Aggregated information for each user defined (not anonymous) Java class *) +module ClassInfo : sig + type t + + val get_class_summaries : t -> Summary.t list + (** Summaries for all procedures in this class (not counting anonymous nested classes) *) + + val get_all_summaries : t -> Summary.t list + (** List of all summaries, user-level and anonymous, combined together *) +end + +type t + +val make_empty : unit -> t + +val register_summary : JavaClassName.t -> Summary.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 group_by_user_class : t -> (JavaClassName.t * ClassInfo.t) list +(** List of pairs + Option.value_map nullsafe + ~f:(fun NullsafeSummary.{type_violation_count} -> type_violation_count) + ~default:0 ) + |> List.fold ~init:0 ~f:( + ) + in + let description = + Format.asprintf "Class %a: Total type violations: %d" JavaClassName.pp class_name total_count + in + let trace = [Errlog.make_trace_element 0 loc description []] in + let issue_type = + if total_count > 0 then IssueType.eradicate_meta_class_needs_fixing + else IssueType.eradicate_meta_class_is_clean + in + log_issue ~issue_log ~loc ~trace issue_type description + + +(* Optimization - if issues are disabled, don't bother analyzing them *) +let should_analyze_meta_issues () = + (not Config.filtering) || IssueType.eradicate_meta_class_is_clean.IssueType.enabled + || IssueType.eradicate_meta_class_needs_fixing.IssueType.enabled + + +let analyze_class source_file class_name class_info issue_log = + if should_analyze_meta_issues () then + report_meta_issues source_file class_name class_info issue_log + else issue_log diff --git a/infer/src/nullsafe/ClassLevelAnalysis.mli b/infer/src/nullsafe/ClassLevelAnalysis.mli new file mode 100644 index 000000000..226c316f0 --- /dev/null +++ b/infer/src/nullsafe/ClassLevelAnalysis.mli @@ -0,0 +1,15 @@ +(* + * 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 + +(** This stage is called for each Java class after all corresponding proc summaries are calculated. *) + +val analyze_class : + 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 *) diff --git a/infer/src/nullsafe/FileLevelAnalysis.ml b/infer/src/nullsafe/FileLevelAnalysis.ml new file mode 100644 index 000000000..a08a3a0c6 --- /dev/null +++ b/infer/src/nullsafe/FileLevelAnalysis.ml @@ -0,0 +1,44 @@ +(* + * 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 + +let get_java_class_name = function + | Typ.JavaClass java_class_name -> + Some java_class_name + | _ -> + 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 procedures = + 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* summary = Ondemand.analyze_proc_name_no_caller procname in + return (AggregatedSummaries.register_summary java_class_name summary map_to_update)) + |> Option.value ~default:map_to_update ) + + +(* Given list of proc summaries belonging to a class, aggregate it and add issues to the log, if needed *) +let analyze_class source_file issue_log (class_name, class_info) = + let is_from_third_party = + ThirdPartyAnnotationInfo.is_third_party_class_name + (ThirdPartyAnnotationGlobalRepo.get_repo ()) + class_name + in + if is_from_third_party then (* Don't analyze third party classes *) + issue_log + else ClassLevelAnalysis.analyze_class source_file class_name class_info issue_log + + +let analyze_file ({procedures; source_file} : Callbacks.file_callback_args) = + let class_map = aggregate_by_class procedures in + let user_class_info = AggregatedSummaries.group_by_user_class class_map in + List.fold user_class_info ~init:IssueLog.empty ~f:(analyze_class source_file) diff --git a/infer/src/nullsafe/FileLevelAnalysis.mli b/infer/src/nullsafe/FileLevelAnalysis.mli new file mode 100644 index 000000000..ab234a63a --- /dev/null +++ b/infer/src/nullsafe/FileLevelAnalysis.mli @@ -0,0 +1,12 @@ +(* + * 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 + +val analyze_file : Callbacks.file_callback_t +(** File-level callback for nullsafe. Is called after all proc-level callbacks are called and + calculated their summaries. At this stage, additional issues can be emitted. *) diff --git a/infer/src/nullsafe/NullsafeSummary.ml b/infer/src/nullsafe/NullsafeSummary.ml new file mode 100644 index 000000000..e6e84f4bb --- /dev/null +++ b/infer/src/nullsafe/NullsafeSummary.ml @@ -0,0 +1,14 @@ +(* + * 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 + +(** Summary of per-procedure nullsafe result analysis *) + +type t = {type_violation_count: int} + +let pp fmt {type_violation_count} = Format.fprintf fmt "%d" type_violation_count diff --git a/infer/src/nullsafe/NullsafeSummary.mli b/infer/src/nullsafe/NullsafeSummary.mli new file mode 100644 index 000000000..230237bd1 --- /dev/null +++ b/infer/src/nullsafe/NullsafeSummary.mli @@ -0,0 +1,14 @@ +(* + * 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 + +(** Summary of per-procedure nullsafe result analysis *) + +type t = {type_violation_count: int} + +val pp : Format.formatter -> t -> unit diff --git a/infer/src/nullsafe/ThirdPartyAnnotationInfo.ml b/infer/src/nullsafe/ThirdPartyAnnotationInfo.ml index f0e644756..1a0f10097 100644 --- a/infer/src/nullsafe/ThirdPartyAnnotationInfo.ml +++ b/infer/src/nullsafe/ThirdPartyAnnotationInfo.ml @@ -99,19 +99,22 @@ let is_third_party_proc storage procname = is_from_config || Option.is_some (lookup_sig_file ()) -(* There is a bit of duplication relative to [is_third_party_proc] due to mismatch between - [Typ.Name.Java] and [JavaClassName]. When those types are consolidated would be a good - idea to refactor this function. *) -let is_third_party_typ storage typ = +let is_third_party_class_name storage java_class_name = IOption.Let_syntax.( - let* typ_name = Typ.name typ in - let+ class_name = - match typ_name with Typ.JavaClass class_name -> return class_name | _ -> None - in - let is_from_config = JavaClassName.is_external_via_config class_name in + let is_from_config = JavaClassName.is_external_via_config java_class_name in let lookup_sig_file _ = - let* package = JavaClassName.package class_name in + let* package = JavaClassName.package java_class_name in lookup_related_sig_file storage ~package in is_from_config || Option.is_some (lookup_sig_file ())) - |> Option.value ~default:false + + +(* There is a bit of duplication relative to [is_third_party_proc] due to mismatch between + [Typ.Name.Java] and [JavaClassName]. When those types are consolidated would be a good + idea to refactor this function. *) +let is_third_party_typ storage typ = + match Typ.name typ with + | Some (Typ.JavaClass java_class_name) -> + is_third_party_class_name storage java_class_name + | _ -> + false diff --git a/infer/src/nullsafe/ThirdPartyAnnotationInfo.mli b/infer/src/nullsafe/ThirdPartyAnnotationInfo.mli index cc2ab0527..28ce62e55 100644 --- a/infer/src/nullsafe/ThirdPartyAnnotationInfo.mli +++ b/infer/src/nullsafe/ThirdPartyAnnotationInfo.mli @@ -43,3 +43,6 @@ val is_third_party_proc : storage -> Procname.t -> bool val is_third_party_typ : storage -> Typ.t -> bool (** See [is_third_party_proc]. *) + +val is_third_party_class_name : storage -> JavaClassName.t -> bool +(** See [is_third_party_proc]. *) diff --git a/infer/src/nullsafe/eradicate.ml b/infer/src/nullsafe/eradicate.ml index 89d3f20d9..022d1c450 100644 --- a/infer/src/nullsafe/eradicate.ml +++ b/infer/src/nullsafe/eradicate.ml @@ -10,16 +10,20 @@ module L = Logging module F = Format open Dataflow +module Payload = SummaryPayload.Make (struct + type t = NullsafeSummary.t + + let field = Payloads.Fields.nullsafe +end) + (** Type for a module that provides a main callback function *) module type CallBackT = sig val callback : TypeCheck.checks -> Callbacks.proc_callback_t end -(* CallBackT *) - (** Extension to the type checker. *) module type ExtensionT = sig - val update_payloads : TypeState.t option -> Payloads.t -> Payloads.t + val update_payloads : NullsafeSummary.t option -> Payloads.t -> Payloads.t end (** Create a module with the toplevel callback. *) @@ -197,6 +201,17 @@ module MkCallback (Extension : ExtensionT) : CallBackT = struct Some "not a Java method" + let is_important err_instance = + match err_instance with + | TypeErr.Bad_assignment _ + | TypeErr.Nullable_dereference _ + | TypeErr.Inconsistent_subclass _ + | TypeErr.Field_not_initialized _ -> + true + | TypeErr.Condition_redundant _ | TypeErr.Over_annotation _ -> + false + + (** Entry point for the nullsafe procedure-level analysis. *) let callback checks ({Callbacks.summary} as callback_args) : Summary.t = let proc_desc = Summary.get_proc_desc summary in @@ -221,15 +236,20 @@ module MkCallback (Extension : ExtensionT) : CallBackT = struct TypeErr.reset () ; analyze_procedure tenv proc_name proc_desc calls_this checks callback_args annotated_signature linereader loc ; + let type_violation_count = + TypeErr.get_errors () + |> List.filter_map ~f:(fun (err_instance, _) -> + if is_important err_instance then Some err_instance else None ) + |> List.length + in TypeErr.report_forall_checks_and_reset (EradicateCheckers.report_error tenv) proc_desc ; - summary + Payload.update_summary NullsafeSummary.{type_violation_count} summary end (* MkCallback *) module EmptyExtension : ExtensionT = struct - let update_payloads typestate_opt (payloads : Payloads.t) = - {payloads with typestate= typestate_opt} + let update_payloads new_summary (payloads : Payloads.t) = {payloads with nullsafe= new_summary} end module Main = struct @@ -238,13 +258,13 @@ module Main = struct let callback = Callback.callback end -(** Eradicate checker for Java [@Nullable] annotations. *) -let callback_eradicate = +let proc_callback = let checks = {TypeCheck.eradicate= true; check_ret_type= []} in Main.callback checks -(** Call the given check_return_type at the end of every procedure. *) +let file_callback = FileLevelAnalysis.analyze_file + let callback_check_return_type check_return_type callback_args = let checks = {TypeCheck.eradicate= false; check_ret_type= [check_return_type]} in Main.callback checks callback_args diff --git a/infer/src/nullsafe/eradicate.mli b/infer/src/nullsafe/eradicate.mli index 24c2156d6..f2314df45 100644 --- a/infer/src/nullsafe/eradicate.mli +++ b/infer/src/nullsafe/eradicate.mli @@ -9,9 +9,16 @@ open! IStd (** The main entry point for Nullsafe typechecker. *) -val callback_eradicate : Callbacks.proc_callback_t +val proc_callback : Callbacks.proc_callback_t +(** Proc-level callback for nullsafe. *) + +val file_callback : Callbacks.file_callback_t +(** File-level callback for nullsafe. Is called after all proc-level callbacks are called and + calculated their summaries *) val callback_check_return_type : TypeCheck.check_return_type -> Callbacks.proc_callback_t +(** For checkers that explore eradicate/nullsafe infra, but not part of nullsafe.Annot Call the + given check_return_type at the end of every procedure. *) (** Type for a module that provides a main callback function *) module type CallBackT = sig @@ -20,5 +27,5 @@ end (** Extension to the type checker. *) module type ExtensionT = sig - val update_payloads : TypeState.t option -> Payloads.t -> Payloads.t + val update_payloads : NullsafeSummary.t option -> Payloads.t -> Payloads.t end diff --git a/infer/src/nullsafe/typeErr.ml b/infer/src/nullsafe/typeErr.ml index ac548a988..2797b691b 100644 --- a/infer/src/nullsafe/typeErr.ml +++ b/infer/src/nullsafe/typeErr.ml @@ -316,3 +316,9 @@ let report_forall_checks_and_reset st_report_error proc_desc = () in H.iter iter err_tbl ; reset () + + +let get_errors () = + H.fold + (fun (err_instance, instr_ref_opt) _err_state acc -> (err_instance, instr_ref_opt) :: acc) + err_tbl [] diff --git a/infer/src/nullsafe/typeErr.mli b/infer/src/nullsafe/typeErr.mli index 280c6871e..fbcdb7756 100644 --- a/infer/src/nullsafe/typeErr.mli +++ b/infer/src/nullsafe/typeErr.mli @@ -83,3 +83,5 @@ val report_error : val report_forall_checks_and_reset : st_report_error -> Procdesc.t -> unit val reset : unit -> unit + +val get_errors : unit -> (err_instance * InstrRef.t option) list diff --git a/infer/tests/codetoanalyze/java/nullsafe-default/issues.exp b/infer/tests/codetoanalyze/java/nullsafe-default/issues.exp index 3ddc634a1..905455963 100644 --- a/infer/tests/codetoanalyze/java/nullsafe-default/issues.exp +++ b/infer/tests/codetoanalyze/java/nullsafe-default/issues.exp @@ -1,14 +1,19 @@ +codetoanalyze/java/nullsafe-default/AlternativeRecommendations.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/AlternativeRecommendations.java, codetoanalyze.java.nullsafe_default.AlternativeRecommendations.assigningField_ShouldSuggestAlternative(android.view.View):void, 0, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`field` is declared non-nullable but is assigned a nullable: call to View.findViewById(...) at line 34 (nullable according to nullsafe internal models). If you don't expect null, use `View.requireViewById()` instead.] codetoanalyze/java/nullsafe-default/AlternativeRecommendations.java, codetoanalyze.java.nullsafe_default.AlternativeRecommendations.dereference_ShouldSuggestAlternative(android.view.View):void, 0, 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 `View.requireViewById()` instead.] codetoanalyze/java/nullsafe-default/AlternativeRecommendations.java, codetoanalyze.java.nullsafe_default.AlternativeRecommendations.passingParam_ShouldSuggestAlternative(android.view.View):void, 0, 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 `View.requireViewById()` instead.] codetoanalyze/java/nullsafe-default/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 `View.requireViewById()` instead.] +codetoanalyze/java/nullsafe-default/ButterKnife.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/ButterKnife.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife$TestNotInitialized.(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-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.(), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `ButterKnife.nullable` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.assignNullToNormalIsBAD():void, 0, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`normal` is declared non-nullable but is assigned `null`: null constant at line 76.] codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.convertingToNotNullableForNullableIsBAD():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [`convertingToNotNullableForNullableIsBAD()`: return type is declared non-nullable but the method returns a nullable value: field nullable at line 47.] codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.dereferencingNullableIsBAD():void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ButterKnife.nullable` is nullable and is not locally checked for null when calling `length()`.] codetoanalyze/java/nullsafe-default/ButterKnife.java, codetoanalyze.java.nullsafe_default.ButterKnife.passingToNullableForNullableIsBAD():void, 0, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ButterKnife.f(...)`: parameter #1(`nonNullable`) is declared non-nullable but the argument `ButterKnife.nullable` is nullable.] +codetoanalyze/java/nullsafe-default/CapturedParam.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/CapturedParam.java, codetoanalyze.java.nullsafe_default.CapturedParam.dereferencingNullableIsBAD(java.lang.Object):void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`parameter` is nullable and is not locally checked for null when calling `toString()`.] +codetoanalyze/java/nullsafe-default/ConditionRedundant.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.(), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `ConditionRedundant.fieldNullable` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.FP_ternary_NonnullInOneBranch_SecondBranch_ShouldBeOK(java.lang.String,java.lang.String,int):void, 0, ERADICATE_CONDITION_REDUNDANT, no_bucket, ADVICE, [The condition s2 might be always false according to the existing annotations.] codetoanalyze/java/nullsafe-default/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.assertNotNull_NonnullIsBAD(java.lang.String):void, 0, ERADICATE_CONDITION_REDUNDANT, no_bucket, ADVICE, [The condition (s!=null) might be always true according to the existing annotations.] @@ -31,6 +36,23 @@ codetoanalyze/java/nullsafe-default/ConditionRedundant.java, codetoanalyze.java. codetoanalyze/java/nullsafe-default/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.ternary_NonnullInBothBranchesIsBAD(java.lang.String,java.lang.String,int):void, 0, ERADICATE_CONDITION_REDUNDANT, no_bucket, ADVICE, [The condition s2 might be always false according to the existing annotations.] codetoanalyze/java/nullsafe-default/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.testFlowSensitivity(java.lang.String,java.lang.String):void, 1, ERADICATE_CONDITION_REDUNDANT, no_bucket, ADVICE, [The condition nullable1 might be always true according to the existing annotations.] codetoanalyze/java/nullsafe-default/ConditionRedundant.java, codetoanalyze.java.nullsafe_default.ConditionRedundant.testFlowSensitivity(java.lang.String,java.lang.String):void, 3, ERADICATE_CONDITION_REDUNDANT, no_bucket, ADVICE, [The condition nullable1 might be always true according to the existing annotations.] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitCircular.(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-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitCircular.(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] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.FieldNotInitialized$InitIfNull.(codetoanalyze.java.nullsafe_default.FieldNotInitialized), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `shouldBeGood_FIXME` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method] @@ -60,6 +82,8 @@ codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestInitializerAnnotation.set4(java.lang.String):void, 0, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`initByNullableInInitializedMethodIsBAD` is declared non-nullable but is assigned a nullable: method parameter value.] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestKnownInitializers$KnownInitializers.(codetoanalyze.java.nullsafe_default.TestKnownInitializers), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `initInUnknownMethodIsBAD` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method] codetoanalyze/java/nullsafe-default/FieldNotInitialized.java, codetoanalyze.java.nullsafe_default.TestKnownInitializers$SimplyOnCreateWontDoATrick.(codetoanalyze.java.nullsafe_default.TestKnownInitializers), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, WARNING, [Field `initInUnknownMethodIsBAD` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method] +codetoanalyze/java/nullsafe-default/FieldNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/FieldNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.CanAssignNullInCleanupMethods.assignNullInAnyOtherMethodIsBAD():void, 0, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`someObject` is declared non-nullable but is assigned `null`: null constant at line 44.] codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.(), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `FieldNotNullable.nullable` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.(), 4, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`initializeNonNullableWithNullIsBAD` is declared non-nullable but is assigned `null`: null constant at line 52.] @@ -67,14 +91,34 @@ codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nu codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.setNullableToNotNullableIsBAD(java.lang.String):void, 0, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`notNullable` is declared non-nullable but is assigned `null`: null constant at line 65.] codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.setNullableToNotNullableIsBAD(java.lang.String):void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`notNullable` is declared non-nullable but is assigned a nullable: method parameter s.] codetoanalyze/java/nullsafe-default/FieldNotNullable.java, codetoanalyze.java.nullsafe_default.FieldNotNullable.setNullableToNotNullableIsBAD(java.lang.String):void, 2, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`notNullable` is declared non-nullable but is assigned a nullable: call to getNullable() at line 67.] +codetoanalyze/java/nullsafe-default/FieldNullabilityMemoization.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/FieldNullabilityMemoization.java, codetoanalyze.java.nullsafe_default.FieldNullabilityMemoization.dereferenceIsBAD():void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`FieldNullabilityMemoization.nullable` is nullable and is not locally checked for null when calling `toString()`.] codetoanalyze/java/nullsafe-default/FieldNullabilityMemoization.java, codetoanalyze.java.nullsafe_default.FieldNullabilityMemoization.dereferenceViaLocalVarIsBAD():void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`a` is nullable and is not locally checked for null when calling `toString()`: field nullable at line 35.] +codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.(int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `FieldOverAnnotated.initializedInAllConstructorsIsBAD` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.(int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `FieldOverAnnotated.FP_initializedInAllConstructorsButSetToNullInAPublicMethodShouldBeOK` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.(int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `FieldOverAnnotated.initilizedInAllConstructorsAndAllBranchesIsBAD` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.(int,int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `FieldOverAnnotated.initializedInAllConstructorsIsBAD` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.(int,int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `FieldOverAnnotated.FP_initializedInAllConstructorsButSetToNullInAPublicMethodShouldBeOK` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/FieldOverAnnotated.java, codetoanalyze.java.nullsafe_default.FieldOverAnnotated.(int,int), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `FieldOverAnnotated.initilizedInAllConstructorsAndAllBranchesIsBAD` is always initialized in the constructor but is declared `@Nullable`] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.ArgNullToValBAD.nullableArg(java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `arg` of method `ArgNullToValBAD.nullableArg(...)` is missing `@Nullable` declaration when overriding `VariousMethods.nullableArg(...)`. The parent method declared it can handle `null` for this param, so the child should also declare that.] codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.ArgNullToValForInterfaceInAnotherFileBAD.implementInAnotherFile(java.lang.String):java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `s` of method `ArgNullToValForInterfaceInAnotherFileBAD.implementInAnotherFile(...)` is missing `@Nullable` declaration when overriding `InconsistentSubclassAnnotationInterface.implementInAnotherFile(...)`. The parent method declared it can handle `null` for this param, so the child should also declare that.] codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoanalyze.java.nullsafe_default.ExtendsExternalLibrary.externalMethod2(java.lang.Object):void, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, WARNING, [First parameter `object` of method `ExtendsExternalLibrary.externalMethod2(...)` is missing `@Nullable` declaration when overriding `SomeExternalClass.externalMethod2(...)`. The parent method declared it can handle `null` for this param, so the child should also declare that.] @@ -83,17 +127,28 @@ codetoanalyze/java/nullsafe-default/InconsistentSubclassAnnotation.java, codetoa codetoanalyze/java/nullsafe-default/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-default/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-default/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-default/InheritanceForStrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InheritanceForStrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InheritanceForStrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InheritanceForStrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InheritanceForStrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/InheritanceForStrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/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-default/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-default/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`.] codetoanalyze/java/nullsafe-default/InheritanceForStrictMode.java, codetoanalyze.java.nullsafe_default.InheritanceForStrictMode$StrictExtendingNonstrict.params(java.lang.String,java.lang.String):void, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, ERROR, [First parameter `badToRemoveNullableInChildren` of method `InheritanceForStrictMode$StrictExtendingNonstrict.params(...)` is missing `@Nullable` declaration when overriding `InheritanceForStrictMode$NonStrictBase.params(...)`. The parent method declared it can handle `null` for this param, so the child should also declare that.] codetoanalyze/java/nullsafe-default/InheritanceForStrictMode.java, codetoanalyze.java.nullsafe_default.InheritanceForStrictMode$StrictExtendingStrict.badToAddNullableInChildren():java.lang.String, 0, ERADICATE_INCONSISTENT_SUBCLASS_RETURN_ANNOTATION, no_bucket, ERROR, [Child method `InheritanceForStrictMode$StrictExtendingStrict.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-default/InheritanceForStrictMode.java, codetoanalyze.java.nullsafe_default.InheritanceForStrictMode$StrictExtendingStrict.params(java.lang.String,java.lang.String):void, 0, ERADICATE_INCONSISTENT_SUBCLASS_PARAMETER_ANNOTATION, no_bucket, ERROR, [First parameter `badToRemoveNullableInChildren` of method `InheritanceForStrictMode$StrictExtendingStrict.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-default/JunitExample.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/LibraryCalls.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badAtomicReferenceDereference(java.util.concurrent.atomic.AtomicReference):java.lang.String, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ref.get()` is nullable and is not locally checked for null when calling `toString()`: call to AtomicReference.get() at line 35 (nullable according to nullsafe internal models).] codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badPhantomReferenceDereference(java.lang.ref.PhantomReference):java.lang.String, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`ref.get()` is nullable and is not locally checked for null when calling `toString()`: call to PhantomReference.get() at line 27 (nullable according to nullsafe internal models).] codetoanalyze/java/nullsafe-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badReferenceDereference(java.lang.ref.Reference):java.lang.String, 0, 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-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badSoftReferenceDereference(java.lang.ref.SoftReference):java.lang.String, 0, 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-default/LibraryCalls.java, codetoanalyze.java.nullsafe_default.LibraryCalls.badWeakReferenceDereference(java.lang.ref.WeakReference):java.lang.String, 0, 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-default/MapNullability.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/MapNullability.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/MapNullability.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterConditionalPutWrongKeyIsBAD(java.util.Map,java.lang.String,java.lang.String):void, 3, 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-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterPutNullableIsBAD(java.util.Map,java.lang.String):void, 0, 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-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetAfterPutIsAllowed.getAfterPutNullableIsBAD(java.util.Map,java.lang.String):void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`dontAssignNull` is declared non-nullable but is assigned a nullable: method parameter nullableValue.] @@ -107,6 +162,13 @@ codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.null codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked.usingGetAfterWrongKeyWasCheckedInWhileLoopIsBAD(java.util.Map):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`m.get(...)` is nullable and is not locally checked for null when calling `isEmpty()`: call to Map.get(...) at line 44 (nullable according to nullsafe internal models).] codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked.usingGetAfterWrongKeyWasCheckedIsBAD(java.util.Map):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`m.get(...)` is nullable and is not locally checked for null when calling `isEmpty()`: call to Map.get(...) at line 29 (nullable according to nullsafe internal models).] codetoanalyze/java/nullsafe-default/MapNullability.java, codetoanalyze.java.nullsafe_default.MapNullability$TestThatGetIsAllowedOnlyAfterContainsKeyWasChecked.usingGetWithoutCheckingKeyIsBAD(java.util.Map):void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`m.get(...)` is nullable and is not locally checked for null when calling `isEmpty()`: call to Map.get(...) at line 24 (nullable according to nullsafe internal models).] +codetoanalyze/java/nullsafe-default/MyPreconditions.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf0VsChainOf0ParamsMismatchIsBad():void, 1, 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-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf0VsChainOf1IsBad():void, 1, 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-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestFunctionsIdempotent.chainOf1VsChainOf0IsBad():void, 1, ERADICATE_FIELD_NOT_NULLABLE, no_bucket, WARNING, [`dontAssignNull` is declared non-nullable but is assigned a nullable: call to nullable(...) at line 175.] @@ -122,6 +184,9 @@ codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.n codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.param_AccessWithoutNullCheckIsBad(codetoanalyze.java.nullsafe_default.NestedFieldAccess$C):void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`c.s` is nullable and is not locally checked for null when calling `length()`.] codetoanalyze/java/nullsafe-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.veryDeep_AccessWithoutNullCheckIsBad(codetoanalyze.java.nullsafe_default.NestedFieldAccess$CCC):void, 1, 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-default/NestedFieldAccess.java, codetoanalyze.java.nullsafe_default.NestedFieldAccess$TestNullableChains.veryDeep_IncompleteAccessViaOrEarlyReturnIsBad(codetoanalyze.java.nullsafe_default.NestedFieldAccess$CCC):void, 2, 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-default/NoReuseUndefFunctionValues.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullFieldAccess.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullFieldAccess.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.(), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `NullFieldAccess.nullableArray` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.(), 0, ERADICATE_FIELD_OVER_ANNOTATED, no_bucket, ADVICE, [Field `NullFieldAccess.nullable` is always initialized in the constructor but is declared `@Nullable`] codetoanalyze/java/nullsafe-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.testArray():void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [Array `NullFieldAccess.nullableArray` is nullable and is not locally checked for null when accessing its length.] @@ -129,6 +194,14 @@ codetoanalyze/java/nullsafe-default/NullFieldAccess.java, codetoanalyze.java.nul codetoanalyze/java/nullsafe-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.testInterface():void, 1, 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-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.testNonStaticFields():void, 1, 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-default/NullFieldAccess.java, codetoanalyze.java.nullsafe_default.NullFieldAccess.testStatic():void, 1, 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-default/NullMethodCall.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullMethodCall.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullMethodCall.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullMethodCall.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullMethodCall.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullMethodCall.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullMethodCall.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullMethodCall.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall$Inner.outerField():int, 1, 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-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall$Inner.outerPrivateField():int, 1, 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-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.FP_propagatesNonNullAfterComparisonFieldOkay(java.lang.Object):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`NullMethodCall.nullableField` is nullable and is not locally checked for null when calling `toString()`.] @@ -153,6 +226,16 @@ codetoanalyze/java/nullsafe-default/NullMethodCall.java, codetoanalyze.java.null codetoanalyze/java/nullsafe-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.testSystemGetenvBad():int, 1, 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-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.withConditionalAssignemnt(codetoanalyze.java.nullsafe_default.NullMethodCall$AnotherI,boolean,java.lang.Object,java.lang.Object):void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withObjectParameter(...)`.] codetoanalyze/java/nullsafe-default/NullMethodCall.java, codetoanalyze.java.nullsafe_default.NullMethodCall.withConjuction(codetoanalyze.java.nullsafe_default.NullMethodCall$AnotherI,boolean,boolean):void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`i` is nullable and is not locally checked for null when calling `withBooleanParameter(...)`.] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/NullsafeMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$NullsafeWithStrictMode.BAD_returnFromNonStrict():java.lang.String, 0, 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 175. Either add a local check for null or assertion, or make NullsafeMode$VariousMethods nullsafe strict.] codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$StrictNullsafe.BAD_dereferenceNotAnnotatedThirdParty():void, 0, 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-default/third-party-signatures/some.test.pckg.sig.] codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$StrictNullsafe.BAD_passThirdPartyToUnchecked():codetoanalyze.java.nullsafe_default.NullsafeMode$UncheckedParams, 0, 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-default/third-party-signatures/some.test.pckg.sig.] @@ -167,6 +250,10 @@ codetoanalyze/java/nullsafe-default/NullsafeMode.java, codetoanalyze.java.nullsa codetoanalyze/java/nullsafe-default/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-default/NullsafeMode.java, codetoanalyze.java.nullsafe_default.NullsafeMode$TrustSomeNullsafe.FP_OK_accessFieldFromNonNullsafe():java.lang.String, 0, 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 148. Either add a local check for null or assertion, or make NullsafeMode$NonNullsafe nullsafe.] codetoanalyze/java/nullsafe-default/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-default/ParameterNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable$ConstructorCall.(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-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.callNull():void, 1, 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.] codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.callNullable(java.lang.String):void, 0, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.test(...)`: parameter #1(`s`) is declared non-nullable but the argument `s` is nullable.] @@ -204,6 +291,11 @@ codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.jav codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.testThreeParameters():void, 1, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.threeParameters(...)`: parameter #1(`s1`) is declared non-nullable but the argument is `null`.] codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.testThreeParameters():void, 2, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.threeParameters(...)`: parameter #2(`s2`) is declared non-nullable but the argument is `null`.] codetoanalyze/java/nullsafe-default/ParameterNotNullable.java, codetoanalyze.java.nullsafe_default.ParameterNotNullable.testThreeParameters():void, 3, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, WARNING, [`ParameterNotNullable.threeParameters(...)`: parameter #3(`s3`) is declared non-nullable but the argument is `null`.] +codetoanalyze/java/nullsafe-default/PropagatesNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/PropagatesNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/PropagatesNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/PropagatesNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/PropagatesNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.TestPropagatesNullable$TestBothParams.testBothParamsShouldBeNonnull(java.lang.String,java.lang.String):void, 0, 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-default/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-default/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.] @@ -224,6 +316,10 @@ codetoanalyze/java/nullsafe-default/PropagatesNullable.java, codetoanalyze.java. codetoanalyze/java/nullsafe-default/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 5, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`.] codetoanalyze/java/nullsafe-default/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 9, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`.] codetoanalyze/java/nullsafe-default/PropagatesNullable.java, codetoanalyze.java.nullsafe_default.TestPropagatesNullable$TestSecondParameter.test(java.lang.String,java.lang.String):void, 13, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`nullable(...)` is nullable and is not locally checked for null when calling `length()`.] +codetoanalyze/java/nullsafe-default/ReturnNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/ReturnNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/ReturnNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/ReturnNotNullable.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/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-default/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-default/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).] @@ -236,6 +332,10 @@ codetoanalyze/java/nullsafe-default/ReturnNotNullable.java, codetoanalyze.java.n codetoanalyze/java/nullsafe-default/ReturnNotNullable.java, codetoanalyze.java.nullsafe_default.ReturnNotNullable.return_null_in_catch():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [`return_null_in_catch()`: return type is declared non-nullable but the method returns `null`: null constant at line 160.] codetoanalyze/java/nullsafe-default/ReturnNotNullable.java, codetoanalyze.java.nullsafe_default.ReturnNotNullable.return_null_in_catch_after_throw():java.lang.String, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [`return_null_in_catch_after_throw()`: return type is declared non-nullable but the method returns `null`: null constant at line 172.] codetoanalyze/java/nullsafe-default/ReturnNotNullable.java, codetoanalyze.java.nullsafe_default.ReturnNotNullable.tryWithResourcesReturnNullable(java.lang.String):java.lang.Object, 0, ERADICATE_RETURN_NOT_NULLABLE, no_bucket, WARNING, [`tryWithResourcesReturnNullable(...)`: return type is declared non-nullable but the method returns a nullable value: call to nullToNullableIsOK() at line 142.] +codetoanalyze/java/nullsafe-default/StrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/StrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/StrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/StrictMode.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/StrictMode.java, codetoanalyze.java.nullsafe_default.Strict.(), 0, ERADICATE_FIELD_NOT_INITIALIZED, no_bucket, ERROR, [Field `notInitializedIsBAD` is declared non-nullable, so it should be initialized in the constructor or in an `@Initializer` method] codetoanalyze/java/nullsafe-default/StrictMode.java, codetoanalyze.java.nullsafe_default.Strict.nonStrictClass_convertingNonnullToNonnullIsBad():java.lang.String, 0, ERADICATE_UNCHECKED_USAGE_IN_NULLSAFE, no_bucket, ERROR, [`NonStrict.getNonnull()`: `@NullsafeStrict` mode prohibits using values coming from non-strict classes without a check. Result of this call is used at line 163. Either add a local check for null or assertion, or make NonStrict nullsafe strict.] codetoanalyze/java/nullsafe-default/StrictMode.java, codetoanalyze.java.nullsafe_default.Strict.nonStrictClass_convertingNonnullToNullableIsOK():java.lang.String, 0, ERADICATE_RETURN_OVER_ANNOTATED, no_bucket, ADVICE, [Method `nonStrictClass_convertingNonnullToNullableIsOK()` is annotated with `@Nullable` but never returns null.] @@ -256,14 +356,28 @@ codetoanalyze/java/nullsafe-default/StrictMode.java, codetoanalyze.java.nullsafe codetoanalyze/java/nullsafe-default/StrictMode.java, codetoanalyze.java.nullsafe_default.Strict.strictClass_dereferenceNullableFieldIsBad():void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [`__new(...).nullable` is nullable and is not locally checked for null when calling `toString()`.] codetoanalyze/java/nullsafe-default/StrictMode.java, codetoanalyze.java.nullsafe_default.Strict.strictClass_dereferenceNullableMethodIsBad():void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [`__new(...).getNullable()` is nullable and is not locally checked for null when calling `toString()`.] codetoanalyze/java/nullsafe-default/StrictMode.java, codetoanalyze.java.nullsafe_default.Strict.strictClass_dereferenceNullableStaticMethodIsBad():void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [`staticNullable()` is nullable and is not locally checked for null when calling `toString()`.] +codetoanalyze/java/nullsafe-default/StrictModeForThirdParty.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/StrictModeForThirdParty.java, codetoanalyze.java.nullsafe_default.StrictModeForThirdParty.dereferenceFieldIsBAD():void, 0, ERADICATE_UNVETTED_THIRD_PARTY_IN_NULLSAFE, no_bucket, ERROR, [`ThirdPartyTestClass.nonNullableField`: `@NullsafeStrict` mode prohibits using values coming from third-party classes without a check. This field is used at line 49. Either add a local check for null or assertion, or access `nonNullableField` via a nullsafe strict getter.] codetoanalyze/java/nullsafe-default/StrictModeForThirdParty.java, codetoanalyze.java.nullsafe_default.StrictModeForThirdParty.dereferenceSpecifiedAsNullableIsBAD():void, 0, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, ERROR, [`StrictModeForThirdParty.obj.returnSpecifiedAsNullable()` is nullable and is not locally checked for null when calling `toString()`: call to ThirdPartyTestClass.returnSpecifiedAsNullable() at line 45 (declared nullable in nullsafe-default/third-party-signatures/some.test.pckg.sig at line 2).] codetoanalyze/java/nullsafe-default/StrictModeForThirdParty.java, codetoanalyze.java.nullsafe_default.StrictModeForThirdParty.dereferenceUnspecifiedIsBAD():void, 0, 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 41. Either add a local check for null or assertion, or add the correct signature to nullsafe-default/third-party-signatures/some.test.pckg.sig.] codetoanalyze/java/nullsafe-default/StrictModeForThirdParty.java, codetoanalyze.java.nullsafe_default.StrictModeForThirdParty.passingNullableParamToUnspecifiedIsBAD():void, 0, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, ERROR, [Third-party `ThirdPartyTestClass.paramUnspecified(...)` is missing a signature that would allow passing a nullable to param #1(`param`). Actual argument `getNullable()` is nullable. Consider adding the correct signature of `ThirdPartyTestClass.paramUnspecified(...)` to nullsafe-default/third-party-signatures/some.test.pckg.sig.] codetoanalyze/java/nullsafe-default/StrictModeForThirdParty.java, codetoanalyze.java.nullsafe_default.StrictModeForThirdParty.passingNullableToParamSpecifiedAsNonnullIsBAD():void, 0, ERADICATE_PARAMETER_NOT_NULLABLE, no_bucket, ERROR, [`ThirdPartyTestClass.secondParamSpecifiedAsNonnull(...)`: parameter #2(`specifiedAsNonnull`) is declared non-nullable (see nullsafe-default/third-party-signatures/some.test.pckg.sig at line 3) but the argument `getNullable()` is nullable.] +codetoanalyze/java/nullsafe-default/SwitchCase.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/SwitchCase.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/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-default/SwitchCase.java, codetoanalyze.java.nullsafe_default.SwitchCase.switchOnNullIsBad():java.lang.String, 1, 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-default/SwitchCase.java, codetoanalyze.java.nullsafe_default.SwitchCase.switchOnNullableIsBad():java.lang.String, 1, 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-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_IS_CLEAN, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] +codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, Linters_dummy_method, 1, ERADICATE_META_CLASS_NEEDS_FIXING, no_bucket, INFO, [] codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, codetoanalyze.java.nullsafe_default.TrueFalseOnNull$EarlyReturn.testEarlyReturn(java.lang.CharSequence,java.lang.CharSequence):void, 5, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s2` is nullable and is not locally checked for null when calling `toString()`.] codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, codetoanalyze.java.nullsafe_default.TrueFalseOnNull$TestNonStaticOneParam.falseOnNullNegativeBranchIsBAD(java.lang.String):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s` is nullable and is not locally checked for null when calling `toString()`.] codetoanalyze/java/nullsafe-default/TrueFalseOnNull.java, codetoanalyze.java.nullsafe_default.TrueFalseOnNull$TestNonStaticOneParam.notAnnotatedNegativeBranchIsBAD(java.lang.String):void, 1, ERADICATE_NULLABLE_DEREFERENCE, no_bucket, WARNING, [`s` is nullable and is not locally checked for null when calling `toString()`.]