From 989868f844109eb8b1e8d55035e6a68e9472aa19 Mon Sep 17 00:00:00 2001 From: David Pichardie Date: Thu, 31 Oct 2024 13:12:49 -0700 Subject: [PATCH] [inferpython] better localization Summary: we need to attach a source location to each proc declaration if we want to see summaries in html. Reviewed By: geralt-encore Differential Revision: D65203871 Privacy Context Container: L1208441 fbshipit-source-id: 7df7dce8b9318de2817bf5d8f20ae9e56f2b28cf --- infer/src/python/PyIR.ml | 3 +++ infer/src/python/PyIR.mli | 1 + infer/src/python/PyIR2Textual.ml | 13 +++++++------ infer/src/textual/Textual.ml | 9 +++++++-- infer/src/textual/Textual.mli | 4 +++- infer/src/textual/TextualTransform.ml | 1 + 6 files changed, 22 insertions(+), 9 deletions(-) diff --git a/infer/src/python/PyIR.ml b/infer/src/python/PyIR.ml index f0793a5b78..93f4760265 100644 --- a/infer/src/python/PyIR.ml +++ b/infer/src/python/PyIR.ml @@ -859,6 +859,7 @@ module CodeInfo = struct type t = { (* see https://docs.python.org/3.8/reference/datamodel.html#index-55 *) co_name: Ident.t + ; co_firstlineno: int ; co_nlocals: int ; co_argcount: int ; co_posonlyargcount: int @@ -873,6 +874,7 @@ module CodeInfo = struct let of_code { FFI.Code.co_name + ; co_firstlineno ; co_flags ; co_nlocals ; co_argcount @@ -883,6 +885,7 @@ module CodeInfo = struct ; co_names ; co_varnames } = { co_name= Ident.mk co_name + ; co_firstlineno ; has_star_arguments= co_flags land 0x04 <> 0 ; has_star_keywords= co_flags land 0x08 <> 0 ; is_generator= co_flags land 0x20 <> 0 diff --git a/infer/src/python/PyIR.mli b/infer/src/python/PyIR.mli index 1d7c3d08d2..d1221739a1 100644 --- a/infer/src/python/PyIR.mli +++ b/infer/src/python/PyIR.mli @@ -223,6 +223,7 @@ end module CodeInfo : sig type t = { co_name: Ident.t + ; co_firstlineno: int ; co_nlocals: int ; co_argcount: int ; co_posonlyargcount: int diff --git a/infer/src/python/PyIR2Textual.ml b/infer/src/python/PyIR2Textual.ml index a89e0c1e80..958905e93f 100644 --- a/infer/src/python/PyIR2Textual.ml +++ b/infer/src/python/PyIR2Textual.ml @@ -35,7 +35,7 @@ type proc_kind = ModuleBody of Ident.t | RegularFunction of QualName.t let is_module_body = function ModuleBody _ -> true | _ -> false -let mk_qualified_proc_name kind = +let mk_qualified_proc_name ?loc kind = let qual_name_str = match kind with | ModuleBody name -> @@ -44,11 +44,11 @@ let mk_qualified_proc_name kind = F.asprintf "%a" QualName.pp qual_name in { Textual.QualifiedProcName.enclosing_class= TopLevel - ; name= Textual.ProcName.of_string qual_name_str } + ; name= Textual.ProcName.of_string ?loc qual_name_str } -let mk_procdecl kind = - let qualified_name = mk_qualified_proc_name kind in +let mk_procdecl ?loc kind = + let qualified_name = mk_qualified_proc_name ?loc kind in let formals_types = if is_module_body kind then Some [] else @@ -438,8 +438,9 @@ let of_node is_module_body entry {Node.name; first_loc; last_loc; ssa_parameters {Textual.Node.label; ssa_parameters; exn_succs; last; instrs; last_loc; label_loc} -let mk_procdesc proc_kind {CFG.entry; nodes; code_info= _} = - let procdecl = mk_procdecl proc_kind in +let mk_procdesc proc_kind {CFG.entry; nodes; code_info= {co_firstlineno}} = + let loc = Textual.Location.known ~line:co_firstlineno ~col:(-1) in + let procdecl = mk_procdecl ~loc proc_kind in let is_module_body = is_module_body proc_kind in let nodes_bindings = NodeName.Map.bindings nodes in let nodes = diff --git a/infer/src/textual/Textual.ml b/infer/src/textual/Textual.ml index aa887a6aae..31bd124a83 100644 --- a/infer/src/textual/Textual.ml +++ b/infer/src/textual/Textual.ml @@ -37,6 +37,8 @@ module Location = struct let known ~line ~col = Known {line; col} + let decr_line = function Unknown -> Unknown | Known {line; col} -> Known {line= line - 1; col} + let pp fmt = function | Known {line; col} -> F.fprintf fmt "line %d, column %d" line col @@ -78,7 +80,7 @@ exception TextualTransformError of transform_error list module type NAME = sig type t = {value: string; loc: Location.t [@compare.ignore]} [@@deriving compare, equal, hash] - val of_string : string -> t + val of_string : ?loc:Location.t -> string -> t val pp : F.formatter -> t -> unit @@ -103,7 +105,10 @@ module Name : NAME = struct let replace_dot_with_2colons str = String.substr_replace_all str ~pattern:"." ~with_:"::" - let of_string str = {value= replace_dot_with_2colons str; loc= Location.Unknown} + let of_string ?loc str = + let loc = Option.value loc ~default:Location.Unknown in + {value= replace_dot_with_2colons str; loc} + let pp fmt name = F.pp_print_string fmt name.value diff --git a/infer/src/textual/Textual.mli b/infer/src/textual/Textual.mli index 7177a89a86..95b1e6dfff 100644 --- a/infer/src/textual/Textual.mli +++ b/infer/src/textual/Textual.mli @@ -22,6 +22,8 @@ module Location : sig val known : line:int -> col:int -> t + val decr_line : t -> t + val pp : F.formatter -> t -> unit val pp_line : F.formatter -> t -> unit @@ -30,7 +32,7 @@ end module type NAME = sig type t = {value: string; loc: Location.t} [@@deriving compare, equal, hash] - val of_string : string -> t + val of_string : ?loc:Location.t -> string -> t (** we replace any dot in the string by '::' because dot is a reserved separator in Textual *) val pp : F.formatter -> t -> unit diff --git a/infer/src/textual/TextualTransform.ml b/infer/src/textual/TextualTransform.ml index d19920bfef..93a478f4ea 100644 --- a/infer/src/textual/TextualTransform.ml +++ b/infer/src/textual/TextualTransform.ml @@ -456,6 +456,7 @@ let remove_effects_in_subexprs lang decls_env _module = in let struct_ = TransformClosures.type_declaration typename fields in let state = State.incr_fresh state in + let loc = if Lang.equal lang Python then Location.decr_line loc else loc in let state, call_procdecl = TransformClosures.closure_call_procdesc loc typename state closure fields params in