Skip to content

Commit

Permalink
[racerd] litho-specific messaging
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ngorogiannis authored and facebook-github-bot committed May 26, 2021
1 parent a1855de commit 98c0419
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 11 deletions.
6 changes: 3 additions & 3 deletions infer/src/concurrency/RacerDFileAnalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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."
MF.pp_monospaced "@ThreadSafe")
else
match FbThreadSafety.get_fbthreadsafe_class_annot pname tenv with
| Some (qual, annot) ->
Some (FbThreadSafety.message_fbthreadsafe_class qual annot)
match RacerDModels.get_litho_explanation tenv pname with
| Some _ as expl_opt ->
expl_opt
| None -> (
match get_current_class_and_threadsafe_superclasses tenv pname with
| Some (current_class, (thread_safe_class :: _ as thread_safe_annotated_classes)) ->
Expand Down
56 changes: 56 additions & 0 deletions infer/src/concurrency/RacerDModels.ml
Original file line number Diff line number Diff line change
Expand Up @@ -573,3 +573,59 @@ let is_synchronized_container callee_pname (access_exp : HilExp.AccessExpression

let is_initializer 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
3 changes: 3 additions & 0 deletions infer/src/concurrency/RacerDModels.mli
Original file line number Diff line number Diff line change
Expand Up @@ -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
(** 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 *)
4 changes: 0 additions & 4 deletions infer/src/opensource/FbThreadSafety.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,3 @@
let is_custom_init _ _ = false

let is_logging_method _ = false

let get_fbthreadsafe_class_annot _ _ = None

let message_fbthreadsafe_class _ _ = ""
4 changes: 0 additions & 4 deletions infer/src/opensource/FbThreadSafety.mli
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,3 @@
val is_custom_init : 'tenv_t -> '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

0 comments on commit 98c0419

Please sign in to comment.