[racerd] litho-specific messaging

Summary: Litho (https://fblitho.com/) does some operations in the background. Add RacerD messaging specific to Litho.

Reviewed By: ezgicicek

Differential Revision: D28675504

fbshipit-source-id: e76f9f538
master
Nikos Gorogiannis 4 years ago committed by Facebook GitHub Bot
parent a1855dee8a
commit 98c0419acc

@ -29,9 +29,9 @@ let get_reporting_explanation_java ~nullsafe report_kind tenv pname thread =
"@\n Reporting because current method is annotated %a or overrides an annotated method." "@\n Reporting because current method is annotated %a or overrides an annotated method."
MF.pp_monospaced "@ThreadSafe") MF.pp_monospaced "@ThreadSafe")
else else
match FbThreadSafety.get_fbthreadsafe_class_annot pname tenv with match RacerDModels.get_litho_explanation tenv pname with
| Some (qual, annot) -> | Some _ as expl_opt ->
Some (FbThreadSafety.message_fbthreadsafe_class qual annot) expl_opt
| None -> ( | None -> (
match get_current_class_and_threadsafe_superclasses tenv pname with match get_current_class_and_threadsafe_superclasses tenv pname with
| Some (current_class, (thread_safe_class :: _ as thread_safe_annotated_classes)) -> | Some (current_class, (thread_safe_class :: _ as thread_safe_annotated_classes)) ->

@ -573,3 +573,59 @@ let is_synchronized_container callee_pname (access_exp : HilExp.AccessExpression
let is_initializer tenv proc_name = let is_initializer tenv proc_name =
Procname.is_constructor proc_name || FbThreadSafety.is_custom_init tenv proc_name Procname.is_constructor proc_name || FbThreadSafety.is_custom_init tenv proc_name
let get_current_class_and_superclasses_satisfying_attr_check check tenv pname =
match pname with
| Procname.Java java_pname ->
let current_class = Procname.Java.get_class_type_name java_pname in
let satisfying_classes =
PatternMatch.Java.find_superclasses_with_attributes check tenv current_class
in
Some (current_class, satisfying_classes)
| _ ->
None
module Litho = struct
let component_annots = ["MountSpec"; "LayoutSpec"]
let section_annots = ["DiffSectionSpec"; "GroupSectionSpec"]
let spec_annots = List.append component_annots section_annots
let get_class_annot pname tenv =
let helper annot =
let is_annotated ia = Annotations.ia_ends_with ia annot in
match get_current_class_and_superclasses_satisfying_attr_check is_annotated tenv pname with
| Some (current_class, (_ :: _ as classes)) ->
if List.mem ~equal:Typ.Name.equal classes current_class then Some ("current ", annot)
else Some ("a super", annot)
| _ ->
None
in
List.find_map ~f:helper spec_annots
(* "ann" is typically a suffix of an annotation, so if ann is "LayoutSpec" the developer would have
written "@LayoutSpec". qualifier is " this " or "a super", the latter corresponding to
superclass. *)
let message (qualifier, ann) =
let mes1 =
if List.mem ~equal:String.equal component_annots ann then
"Litho components are required to be thread safe because of multi-threaded layout."
else if List.mem ~equal:String.equal section_annots ann then
"Sections are required to be thread safe because changesets are calculated in the \
background."
else (*should not get here*)
""
in
(* This "round the houses" way of doing things, where developer writes annotation with @, we pass
around annotation without @, then add it back here, is just because we use ia_ends_with and it
is not worth adding stuff to annotations.ml to make the code here simpler *)
Format.asprintf "@\n %s Reporting because %sclass is annotated %a" mes1 qualifier
MarkupFormatter.pp_monospaced ("@" ^ ann)
end
let get_litho_explanation tenv pname =
Litho.get_class_annot pname tenv |> Option.map ~f:Litho.message

@ -60,3 +60,6 @@ val is_synchronized_container_constructor : Tenv.t -> Procname.t -> HilExp.t lis
val is_converter_to_synchronized_container : Tenv.t -> Procname.t -> HilExp.t list -> bool val is_converter_to_synchronized_container : Tenv.t -> Procname.t -> HilExp.t list -> bool
(** is the given [procname] a method that wraps a container into a thread-safe wrapper? *) (** is the given [procname] a method that wraps a container into a thread-safe wrapper? *)
val get_litho_explanation : Tenv.t -> Procname.t -> string option
(** Get report explanation specific to Litho class methods, if applicable *)

@ -8,7 +8,3 @@
let is_custom_init _ _ = false let is_custom_init _ _ = false
let is_logging_method _ = false let is_logging_method _ = false
let get_fbthreadsafe_class_annot _ _ = None
let message_fbthreadsafe_class _ _ = ""

@ -8,7 +8,3 @@
val is_custom_init : 'tenv_t -> 'procname_t -> bool val is_custom_init : 'tenv_t -> 'procname_t -> bool
val is_logging_method : 'procname_t -> bool val is_logging_method : 'procname_t -> bool
val get_fbthreadsafe_class_annot : 'procname_t -> 'tenv_t -> (string * string) option
val message_fbthreadsafe_class : string -> string -> string

Loading…
Cancel
Save