You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
3.9 KiB

(*
* Copyright (c) 2015-present, Facebook, Inc.
*
* 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 for error logs. *)
type node_tag =
| Condition of bool
| Exception of Typ.name
| Procedure_start of Typ.Procname.t
| Procedure_end of Typ.Procname.t
(** Element of a loc trace *)
type loc_trace_elem = private
{ lt_level: int (** nesting level of procedure calls *)
; lt_loc: Location.t (** source location at the current step in the trace *)
; lt_description: string (** description of the current step in the trace *)
; lt_node_tags: node_tag list (** tags describing the node at the current location *) }
val make_trace_element : int -> Location.t -> string -> node_tag list -> loc_trace_elem
(** build a loc_trace_elem from its constituents (unambiguously identified by their types). *)
(** Trace of locations *)
type loc_trace = loc_trace_elem list
val compute_local_exception_line : loc_trace -> int option
(** Look at all the trace steps and find those that are arising any exception,
then bind them to the closest step at level 0.
This extra information adds value to the report itself, and may avoid
digging into the trace to understand the cause of the report. *)
type node =
| UnknownNode
| FrontendNode of {node_key: Procdesc.NodeKey.t}
| BackendNode of {node: Procdesc.Node.t}
type err_key = private
{severity: Exceptions.severity; err_name: IssueType.t; err_desc: Localise.error_desc}
[@@deriving compare]
(* Merges two error keys, setting the result's severity to the maximum
of that of the two arguments and giving the user the opportunity
to pass a function to merge the IssueTypes and descriptions
of the two. *)
val merge_err_key :
err_key
-> err_key
-> merge_issues:(IssueType.t -> IssueType.t -> IssueType.t)
-> merge_descriptions:(string list -> string list -> string)
-> err_key
(** Data associated to a specific error *)
type err_data = private
{ node_id: int
; node_key: Procdesc.NodeKey.t option
; session: int
; loc: Location.t
; loc_in_ml_source: Logging.ocaml_pos option
; loc_trace: loc_trace
; err_class: Exceptions.err_class
; visibility: Exceptions.visibility
; linters_def_file: string option
; doc_url: string option (** url to documentation of the issue type *)
; access: string option
; extras: Jsonbug_t.extra option }
(* Merges two err_datas, throwing out most information and setting the trace of the
result to the concatenation of the traces of the two arguments with a
separator in between. Used specifically for QuandaryBO. *)
val merge_err_data : err_data -> err_data -> err_data
(** Type of the error log *)
type t
[explore] print only non-default values in the attributes Summary: Attributes have lots of fields, but the majority is usually the same from one procedure to the other. This attempts to print only non-default values, where the default is the "empty" attributes (as opposed to the "most commonly seen value" for each field), in an attempt to be predictible. This is largely something that should be done with a ppx but since there's only one use case it didn't seem worth the trouble. Output of `infer explore --procedures --procedures-attributes --procedures-name` before: ``` test: examples/hello.c test <defined> {access= <Default>; captured= []; did_preanalysis= false; err_log= [ ]; exceptions= []; formals= []; const_formals= []; by_vals= []; func_attributes= []; is_abstract= false; is_bridge_method= false; is_defined= true; is_cpp_noexcept_method= false; is_java_synchronized_method= false; is_model= false; is_specialized= false; is_synthetic_method= false; clang_method_kind= C_FUNCTION; loc= line 12, column 1; translation_unit= Some examples/hello.c; locals= [{name= s;typ= ;attributes= }]; method_annotation= <> (); objc_accessor= None; proc_flags= []; proc_name= test; ret_type= ; source_file_captured=examples/hello.c} int Hello.test(): examples/Hello.java int Hello.test() <defined> {access= <Default>; captured= []; did_preanalysis= false; err_log= [ ]; exceptions= []; formals= [(this,)]; const_formals= []; by_vals= [ ]; func_attributes= []; is_abstract= false; is_bridge_method= false; is_defined= true; is_cpp_noexcept_method= false; is_java_synchronized_method= false; is_model= false; is_specialized= false; is_synthetic_method= false; clang_method_kind= C_FUNCTION; loc= line 11; translation_unit= None; locals= [{name= $irvar0;typ= ;attributes= }; {name= s;typ= ;attributes= }]; method_annotation= <> (); objc_accessor= None; proc_flags= []; proc_name= int Hello.test(); ret_type= ; source_file_captured=examples/Hello.java} Hello.<init>(): examples/Hello.java Hello.<init>() <defined> {access= <Default>; captured= []; did_preanalysis= false; err_log= [ ]; exceptions= []; formals= [(this,)]; const_formals= []; by_vals= [ ]; func_attributes= []; is_abstract= false; is_bridge_method= false; is_defined= true; is_cpp_noexcept_method= false; is_java_synchronized_method= false; is_model= false; is_specialized= false; is_synthetic_method= false; clang_method_kind= C_FUNCTION; loc= line 10; translation_unit= None; locals= []; method_annotation= <> (); objc_accessor= None; proc_flags= []; proc_name= Hello.<init>(); ret_type= ; source_file_captured=examples/Hello.java} ``` Now: ``` test source_file: examples/hello.c proc_name: test attribute_kind: <defined> attributes: { proc_name= test ; source_file_captured= examples/hello.c ; formals= [] ; is_defined= true ; loc= line 12, column 1 ; translation_unit= <Some examples/hello.c> ; locals= [{ name= s; typ= int* }] ; ret_type= void } int Hello.test() source_file: examples/Hello.java proc_name: int Hello.test() attribute_kind: <defined> attributes: { proc_name= int Hello.test() ; source_file_captured= examples/Hello.java ; formals= [(this,Hello*)] ; is_defined= true ; loc= line 11 ; locals= [{ name= $irvar0; typ= void }; { name= s; typ= java.lang.String* }] ; ret_type= int } Hello.<init>() source_file: examples/Hello.java proc_name: Hello.<init>() attribute_kind: <defined> attributes: { proc_name= Hello.<init>() ; source_file_captured= examples/Hello.java ; formals= [(this,Hello*)] ; is_defined= true ; loc= line 10 ; ret_type= void } ``` Reviewed By: mbouaziz Differential Revision: D7757890 fbshipit-source-id: 5507ec6
7 years ago
val empty : unit -> t
(** Empty error log *)
(** type of the function to be passed to iter *)
type iter_fun = err_key -> err_data -> unit
val iter : iter_fun -> t -> unit
(** Apply f to nodes and error names *)
val fold : (err_key -> err_data -> 'a -> 'a) -> t -> 'a -> 'a
val pp_loc_trace_elem : Format.formatter -> loc_trace_elem -> unit [@@warning "-32"]
val pp_loc_trace : Format.formatter -> loc_trace -> unit
val pp_errors : Format.formatter -> t -> unit
(** Print errors from error log *)
val pp_warnings : Format.formatter -> t -> unit
(** Print warnings from error log *)
val pp_html : SourceFile.t -> DB.Results_dir.path -> Format.formatter -> t -> unit
(** Print an error log in html format *)
val size : (Exceptions.severity -> bool) -> t -> int
(** Return the number of elements in the error log which satisfy the filter. *)
val update : t -> t -> unit
(** Update an old error log with a new one *)
val log_issue :
Typ.Procname.t
-> clang_method_kind:ClangMethodKind.t option
-> Exceptions.severity
-> t
-> loc:Location.t
-> node:node
-> session:int
-> ltr:loc_trace
-> linters_def_file:string option
-> doc_url:string option
-> access:string option
-> extras:Jsonbug_t.extra option
-> exn
-> unit