From 25b6d87c1bb76c6fe8666c8971d4fb903646576b Mon Sep 17 00:00:00 2001 From: Ilya Zorin Date: Wed, 6 Nov 2024 08:56:03 -0800 Subject: [PATCH] [hack][builder pattern] Migrate builder pattern config to yojson ppx deriving Summary: Migrate builder pattern config to yojson ppx deriving since I'm planning to add more config options so we won't need to parse them manually Reviewed By: ngorogiannis Differential Revision: D65540798 fbshipit-source-id: dfe835183c818ff5a8ecc543f8a2f076827a2ac8 --- infer/src/base/Config.ml | 17 ++++++++++++----- infer/src/base/Config.mli | 6 +++++- infer/src/base/dune | 1 + infer/src/pulse/Pulse.ml | 8 ++++---- infer/src/pulse/PulseModelsDSL.ml | 4 ++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index ebd582b7fc5..136fc10280a 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -62,6 +62,11 @@ type pulse_taint_config = ; policies: Pulse_config_t.taint_policies ; data_flow_kinds: string list } +type pulse_hack_builder_pattern = {class_name: string [@yojson.key "class"]; finalizers: string list} +[@@deriving of_yojson] + +type pulse_hack_builder_patterns = pulse_hack_builder_pattern list [@@deriving of_yojson] + (* List of ([build system], [executable name]). Several executables may map to the same build system. In that case, the first one in the list will be used for printing, eg, in which mode infer is running. *) @@ -4211,12 +4216,14 @@ and global_tenv = !global_tenv and hackc_binary = !hackc_binary and hack_builder_patterns = - let open Yojson.Safe.Util in let json = !hack_builder_patterns in - let class_of j = j |> member "class" |> to_string in - let finalizers j = j |> member "finalizers" |> to_list |> List.map ~f:to_string in - let pattern j = (class_of j, finalizers j) in - json |> to_list |> List.map ~f:pattern + match json with + | `List [] -> + [] + | json -> ( + try pulse_hack_builder_patterns_of_yojson json + with _ -> + L.die UserError "Failed parsing hack-builder-patterns from %a!@\n" Yojson.Safe.pp json ) and hack_builtin_models = !hack_builtin_models diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index 648b8b8532a..60db55ee341 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -415,7 +415,11 @@ val global_tenv : bool val hackc_binary : string option -val hack_builder_patterns : (string * string list) list +type pulse_hack_builder_pattern = {class_name: string; finalizers: string list} + +type pulse_hack_builder_patterns = pulse_hack_builder_pattern list + +val hack_builder_patterns : pulse_hack_builder_patterns val hack_builtin_models : string diff --git a/infer/src/base/dune b/infer/src/base/dune index 1effe24292a..7ccb4514fbc 100644 --- a/infer/src/base/dune +++ b/infer/src/base/dune @@ -48,6 +48,7 @@ ppx_sexp_conv ppx_show ppx_variants_conv + ppx_yojson_conv inferppx)) (preprocessor_deps (glob_files ../../documentation/checkers/*.md) diff --git a/infer/src/pulse/Pulse.ml b/infer/src/pulse/Pulse.ml index 338c94d2334..6be27c6e998 100644 --- a/infer/src/pulse/Pulse.ml +++ b/infer/src/pulse/Pulse.ml @@ -57,7 +57,7 @@ let is_hack_builder_procname tenv pname = else match Procname.get_class_type_name pname with | Some (HackClass _ as tn) -> - List.exists Config.hack_builder_patterns ~f:(fun (class_name, _) -> + List.exists Config.hack_builder_patterns ~f:(fun Config.{class_name} -> PatternMatch.is_subtype tenv tn (HackClass (HackClassName.make class_name)) ) | _ -> false @@ -67,11 +67,11 @@ let is_hack_builder_consumer tenv pname = match Procname.get_class_type_name pname with | Some (HackClass _ as tn) -> let res = - List.exists Config.hack_builder_patterns ~f:(fun (class_name, consumer_names) -> + List.exists Config.hack_builder_patterns ~f:(fun Config.{class_name; finalizers} -> PatternMatch.is_subtype tenv tn (HackClass (HackClassName.make class_name)) - && List.mem consumer_names (Procname.get_method pname) ~equal:String.equal ) + && List.mem finalizers (Procname.get_method pname) ~equal:String.equal ) in - L.d_printfln "doing builder consumer check, result is %b" res ; + L.d_printfln "doing builder finalizer check, result is %b" res ; res | _ -> false diff --git a/infer/src/pulse/PulseModelsDSL.ml b/infer/src/pulse/PulseModelsDSL.ml index ad24651dce8..e1c5afe13e4 100644 --- a/infer/src/pulse/PulseModelsDSL.ml +++ b/infer/src/pulse/PulseModelsDSL.ml @@ -606,8 +606,8 @@ module Syntax = struct let is_hack_builder_in_config tenv hacktypname = L.d_printfln "typname = %a" HackClassName.pp hacktypname ; (* TODO: deal with namespaces properly! *) - List.exists Config.hack_builder_patterns ~f:(fun (builder_class_name, _) -> - let builder_class_name = Typ.HackClass (HackClassName.make builder_class_name) in + List.exists Config.hack_builder_patterns ~f:(fun Config.{class_name} -> + let builder_class_name = Typ.HackClass (HackClassName.make class_name) in PatternMatch.is_subtype tenv (HackClass hacktypname) builder_class_name )