[SourceFile] Move DB.SourceFile into separate file

Reviewed By: jvillard

Differential Revision: D4299387

fbshipit-source-id: ee8ea3d
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent e5863f5420
commit 56f8757337

@ -77,7 +77,7 @@ let store_attributes (proc_attributes: ProcAttributes.t) => {
| Some proc_attributes_on_disk => | Some proc_attributes_on_disk =>
let higher_rank_than_on_disk () => let higher_rank_than_on_disk () =>
proc_attributes.is_defined && proc_attributes.is_defined &&
DB.SourceFile.compare proc_attributes.loc.file proc_attributes_on_disk.loc.file > 0; SourceFile.compare proc_attributes.loc.file proc_attributes_on_disk.loc.file > 0;
let becomes_defined = proc_attributes.is_defined && not proc_attributes_on_disk.is_defined; let becomes_defined = proc_attributes.is_defined && not proc_attributes_on_disk.is_defined;
/* Only overwrite the attribute file if the procedure becomes defined /* Only overwrite the attribute file if the procedure becomes defined
or its associated file has higher rank (alphabetically) than on disk. */ or its associated file has higher rank (alphabetically) than on disk. */
@ -133,7 +133,7 @@ let get_correct_type_from_objc_class_name type_name =>
/** Returns true if the method is defined as a C++ model */ /** Returns true if the method is defined as a C++ model */
let pname_is_cpp_model callee_pname => let pname_is_cpp_model callee_pname =>
switch (load_attributes callee_pname) { switch (load_attributes callee_pname) {
| Some attrs => DB.SourceFile.is_cpp_model attrs.ProcAttributes.loc.Location.file | Some attrs => SourceFile.is_cpp_model attrs.ProcAttributes.loc.Location.file
| None => false | None => false
}; };
@ -217,7 +217,7 @@ let find_file_capturing_procedure pname =>
let origin = let origin =
/* Procedure coming from include files if it has different location /* Procedure coming from include files if it has different location
than the file where it was captured. */ than the file where it was captured. */
DB.SourceFile.compare source_file proc_attributes.ProcAttributes.loc.file != 0 ? SourceFile.compare source_file proc_attributes.ProcAttributes.loc.file != 0 ?
`Include : `Source; `Include : `Source;
let cfg_fname = DB.source_dir_get_internal_file source_dir ".cfg"; let cfg_fname = DB.source_dir_get_internal_file source_dir ".cfg";
let cfg_fname_exists = Sys.file_exists (DB.filename_to_string cfg_fname); let cfg_fname_exists = Sys.file_exists (DB.filename_to_string cfg_fname);

@ -35,7 +35,7 @@ let pname_is_cpp_model: Procname.t => bool;
/* Find the file where the procedure was captured, if a cfg for that file exists. /* Find the file where the procedure was captured, if a cfg for that file exists.
Return also a boolean indicating whether the procedure is defined in an Return also a boolean indicating whether the procedure is defined in an
include file. */ include file. */
let find_file_capturing_procedure: Procname.t => option (DB.SourceFile.t, [ | `Include | `Source]); let find_file_capturing_procedure: Procname.t => option (SourceFile.t, [ | `Include | `Source]);
let is_whitelisted_cpp_method: string => bool; let is_whitelisted_cpp_method: string => bool;

@ -24,7 +24,7 @@ let load_cfg_from_file: DB.filename => option cfg;
/** Save a cfg into a file, and save a copy of the source files if the boolean is true */ /** Save a cfg into a file, and save a copy of the source files if the boolean is true */
let store_cfg_to_file: source_file::DB.SourceFile.t => DB.filename => cfg => unit; let store_cfg_to_file: source_file::SourceFile.t => DB.filename => cfg => unit;
/** {2 Functions for manipulating an interprocedural CFG} */ /** {2 Functions for manipulating an interprocedural CFG} */

@ -43,14 +43,14 @@ type node_info = {
/** Type for call graph */ /** Type for call graph */
type t = { type t = {
source: DB.SourceFile.t, /** path for the source file */ source: SourceFile.t, /** path for the source file */
node_map: Procname.Hash.t node_info /** map from node to node_info */ node_map: Procname.Hash.t node_info /** map from node to node_info */
}; };
let create source_opt => { let create source_opt => {
let source = let source =
switch source_opt { switch source_opt {
| None => DB.SourceFile.empty | None => SourceFile.empty
| Some source => source | Some source => source
}; };
{source, node_map: Procname.Hash.create 3} {source, node_map: Procname.Hash.create 3}
@ -350,7 +350,7 @@ let extend cg_old cg_new => {
/** Begin support for serialization */ /** Begin support for serialization */
let callgraph_serializer: Serialization.serializer (DB.SourceFile.t, nodes_and_edges) = Serialization.create_serializer Serialization.cg_key; let callgraph_serializer: Serialization.serializer (SourceFile.t, nodes_and_edges) = Serialization.create_serializer Serialization.cg_key;
/** Load a call graph from a file */ /** Load a call graph from a file */

@ -43,7 +43,7 @@ let calls_recursively: t => Procname.t => Procname.t => bool;
/** Create an empty call graph */ /** Create an empty call graph */
let create: option DB.SourceFile.t => t; let create: option SourceFile.t => t;
/** [extend cg1 gc2] extends [cg1] in place with nodes and edges from [gc2]; /** [extend cg1 gc2] extends [cg1] in place with nodes and edges from [gc2];
@ -104,7 +104,7 @@ let get_recursive_dependents: t => Procname.t => Procname.Set.t;
/** Return the path of the source file */ /** Return the path of the source file */
let get_source: t => DB.SourceFile.t; let get_source: t => SourceFile.t;
/** Load a call graph from a file */ /** Load a call graph from a file */
@ -120,7 +120,7 @@ let remove_node_defined: t => Procname.t => unit;
/** Print the call graph as a dotty file. */ /** Print the call graph as a dotty file. */
let save_call_graph_dotty: DB.SourceFile.t => (Procname.t => list 'a) => t => unit; let save_call_graph_dotty: SourceFile.t => (Procname.t => list 'a) => t => unit;
/** Save a call graph into a file */ /** Save a call graph into a file */

@ -54,7 +54,7 @@ val pp_errors : Format.formatter -> t -> unit
val pp_warnings : Format.formatter -> t -> unit val pp_warnings : Format.formatter -> t -> unit
(** Print an error log in html format *) (** Print an error log in html format *)
val pp_html : DB.SourceFile.t -> DB.Results_dir.path -> Format.formatter -> t -> unit val pp_html : SourceFile.t -> DB.Results_dir.path -> Format.formatter -> t -> unit
(** Return the number of elements in the error log which satisfy the filter. *) (** Return the number of elements in the error log which satisfy the filter. *)
val size : (Exceptions.err_kind -> bool -> bool) -> t -> int val size : (Exceptions.err_kind -> bool -> bool) -> t -> int

@ -344,7 +344,7 @@ let pp_err (_, node_key) loc ekind ex_name desc ml_loc_opt fmt () =
let kind = err_kind_string (if ekind = Kinfo then Kwarning else ekind) (* eclipse does not know about infos: treat as warning *) in let kind = err_kind_string (if ekind = Kinfo then Kwarning else ekind) (* eclipse does not know about infos: treat as warning *) in
let pp_key fmt k = if print_key then F.fprintf fmt " key: %d " k else () in let pp_key fmt k = if print_key then F.fprintf fmt " key: %d " k else () in
F.fprintf fmt "%a:%d: %s: %a %a%a%a@\n" F.fprintf fmt "%a:%d: %s: %a %a%a%a@\n"
DB.SourceFile.pp loc.Location.file SourceFile.pp loc.Location.file
loc.Location.line loc.Location.line
kind kind
Localise.pp ex_name Localise.pp ex_name

@ -223,7 +223,7 @@ struct
(** Print an html link to the given line number of the current source file *) (** Print an html link to the given line number of the current source file *)
let pp_line_link ?(with_name = false) ?(text = None) source path_to_root fmt linenum = let pp_line_link ?(with_name = false) ?(text = None) source path_to_root fmt linenum =
let fname = DB.SourceFile.encoding source in let fname = SourceFile.encoding source in
let linenum_str = string_of_int linenum in let linenum_str = string_of_int linenum in
let name = "LINE" ^ linenum_str in let name = "LINE" ^ linenum_str in
pp_link pp_link

@ -21,18 +21,18 @@ module Html : sig
DB.Results_dir.path_kind -> DB.Results_dir.path -> Unix.file_descr * Format.formatter DB.Results_dir.path_kind -> DB.Results_dir.path -> Unix.file_descr * Format.formatter
(** Return true if the html file was modified since the beginning of the analysis *) (** Return true if the html file was modified since the beginning of the analysis *)
val modified_during_analysis : DB.SourceFile.t -> DB.Results_dir.path -> bool val modified_during_analysis : SourceFile.t -> DB.Results_dir.path -> bool
(** File name for the node, given the procedure name and node id *) (** File name for the node, given the procedure name and node id *)
val node_filename : Procname.t -> int -> string val node_filename : Procname.t -> int -> string
(** Open an Html file to append data *) (** Open an Html file to append data *)
val open_out : DB.SourceFile.t -> DB.Results_dir.path -> Unix.file_descr * Format.formatter val open_out : SourceFile.t -> DB.Results_dir.path -> Unix.file_descr * Format.formatter
(** Print an html link to the given line number of the current source file *) (** Print an html link to the given line number of the current source file *)
val pp_line_link : val pp_line_link :
?with_name: bool -> ?text: (string option) -> ?with_name: bool -> ?text: (string option) ->
DB.SourceFile.t -> DB.Results_dir.path -> Format.formatter -> int -> unit SourceFile.t -> DB.Results_dir.path -> Format.formatter -> int -> unit
(** Print a horizontal line *) (** Print a horizontal line *)
val pp_hline : Format.formatter -> unit -> unit val pp_hline : Format.formatter -> unit -> unit
@ -55,7 +55,7 @@ module Html : sig
(** Print an html link given node id and session *) (** Print an html link given node id and session *)
val pp_session_link : val pp_session_link :
?with_name: bool -> DB.SourceFile.t -> string list -> Format.formatter -> int * int * int -> unit ?with_name: bool -> SourceFile.t -> string list -> Format.formatter -> int * int * int -> unit
(** Print start color *) (** Print start color *)
val pp_start_color : Format.formatter -> color -> unit val pp_start_color : Format.formatter -> color -> unit

@ -17,7 +17,7 @@ let module L = Logging;
type t = { type t = {
line: int, /** The line number. -1 means "do not know" */ line: int, /** The line number. -1 means "do not know" */
col: int, /** The column number. -1 means "do not know" */ col: int, /** The column number. -1 means "do not know" */
file: DB.SourceFile.t /** The name of the source file */ file: SourceFile.t /** The name of the source file */
} }
[@@deriving compare]; [@@deriving compare];
@ -29,7 +29,7 @@ let d (loc: t) => L.add_print_action (L.PTloc, Obj.repr loc);
/** Dummy location */ /** Dummy location */
let dummy = {line: (-1), col: (-1), file: DB.SourceFile.empty}; let dummy = {line: (-1), col: (-1), file: SourceFile.empty};
/** Pretty print a location */ /** Pretty print a location */

@ -13,7 +13,7 @@ open! Utils;
type t = { type t = {
line: int, /** The line number. -1 means "do not know" */ line: int, /** The line number. -1 means "do not know" */
col: int, /** The column number. -1 means "do not know" */ col: int, /** The column number. -1 means "do not know" */
file: DB.SourceFile.t /** The name of the source file */ file: SourceFile.t /** The name of the source file */
} }
[@@deriving compare]; [@@deriving compare];

@ -40,14 +40,14 @@ type t = {
is_synthetic_method: bool, /** the procedure is a synthetic method */ is_synthetic_method: bool, /** the procedure is a synthetic method */
language: Config.language, /** language of the procedure */ language: Config.language, /** language of the procedure */
loc: Location.t, /** location of this procedure in the source code */ loc: Location.t, /** location of this procedure in the source code */
translation_unit: option DB.SourceFile.t, /** translation unit to which the procedure belongs */ translation_unit: option SourceFile.t, /** translation unit to which the procedure belongs */
mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */ mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */
method_annotation: Annot.Method.t, /** annotations for java methods */ method_annotation: Annot.Method.t, /** annotations for java methods */
objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */ objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */
proc_flags: proc_flags, /** flags of the procedure */ proc_flags: proc_flags, /** flags of the procedure */
proc_name: Procname.t, /** name of the procedure */ proc_name: Procname.t, /** name of the procedure */
ret_type: Typ.t, /** return type */ ret_type: Typ.t, /** return type */
source_file_captured: DB.SourceFile.t /** source file where the procedure was captured */ source_file_captured: SourceFile.t /** source file where the procedure was captured */
} }
[@@deriving compare]; [@@deriving compare];
@ -77,5 +77,5 @@ let default proc_name language => {
proc_flags: proc_flags_empty (), proc_flags: proc_flags_empty (),
proc_name, proc_name,
ret_type: Typ.Tvoid, ret_type: Typ.Tvoid,
source_file_captured: DB.SourceFile.empty source_file_captured: SourceFile.empty
}; };

@ -34,14 +34,14 @@ type t = {
is_synthetic_method: bool, /** the procedure is a synthetic method */ is_synthetic_method: bool, /** the procedure is a synthetic method */
language: Config.language, /** language of the procedure */ language: Config.language, /** language of the procedure */
loc: Location.t, /** location of this procedure in the source code */ loc: Location.t, /** location of this procedure in the source code */
translation_unit: option DB.SourceFile.t, /** translation unit to which the procedure belongs */ translation_unit: option SourceFile.t, /** translation unit to which the procedure belongs */
mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */ mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */
method_annotation: Annot.Method.t, /** annotations for java methods */ method_annotation: Annot.Method.t, /** annotations for java methods */
objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */ objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */
proc_flags: proc_flags, /** flags of the procedure */ proc_flags: proc_flags, /** flags of the procedure */
proc_name: Procname.t, /** name of the procedure */ proc_name: Procname.t, /** name of the procedure */
ret_type: Typ.t, /** return type */ ret_type: Typ.t, /** return type */
source_file_captured: DB.SourceFile.t /** source file where the procedure was captured */ source_file_captured: SourceFile.t /** source file where the procedure was captured */
} }
[@@deriving compare]; [@@deriving compare];

@ -26,7 +26,7 @@ type pvar_kind =
| Abduced_retvar Procname.t Location.t /** synthetic variable to represent return value */ | Abduced_retvar Procname.t Location.t /** synthetic variable to represent return value */
| Abduced_ref_param Procname.t t Location.t | Abduced_ref_param Procname.t t Location.t
/** synthetic variable to represent param passed by reference */ /** synthetic variable to represent param passed by reference */
| Global_var (DB.SourceFile.t, bool, bool, bool) | Global_var (SourceFile.t, bool, bool, bool)
/** global variable: translation unit + is it compile constant? + is it POD? + is it a static /** global variable: translation unit + is it compile constant? + is it POD? + is it a static
local? */ local? */
| Seed_var /** variable used to store the initial value of formal parameters */ | Seed_var /** variable used to store the initial value of formal parameters */
@ -70,7 +70,7 @@ let rec _pp f pv => {
F.fprintf F.fprintf
f f
"#GB<%a%s%s>$%a" "#GB<%a%s%s>$%a"
DB.SourceFile.pp SourceFile.pp
fname fname
(if is_const {"|const"} else {""}) (if is_const {"|const"} else {""})
( (

@ -109,12 +109,7 @@ let mk_callee: Mangled.t => Procname.t => t;
/** create a global variable with the given name */ /** create a global variable with the given name */
let mk_global: let mk_global:
is_constexpr::bool? => is_constexpr::bool? => is_pod::bool? => is_static_local::bool? => Mangled.t => SourceFile.t => t;
is_pod::bool? =>
is_static_local::bool? =>
Mangled.t =>
DB.SourceFile.t =>
t;
/** create a fresh temporary variable local to procedure [pname]. for use in the frontends only! */ /** create a fresh temporary variable local to procedure [pname]. for use in the frontends only! */
@ -146,7 +141,7 @@ let to_string: t => string;
/** Get the source file corresponding to a global, if known. Returns [None] if not a global. */ /** Get the source file corresponding to a global, if known. Returns [None] if not a global. */
let get_source_file: t => option DB.SourceFile.t; let get_source_file: t => option SourceFile.t;
/** Is the variable's value a compile-time constant? Always (potentially incorrectly) returns /** Is the variable's value a compile-time constant? Always (potentially incorrectly) returns

@ -2465,4 +2465,4 @@ let hpara_dll_instantiate (para: hpara_dll) cell blink flink elist => {
(ids_evars, IList.map (hpred_sub subst) para.body_dll) (ids_evars, IList.map (hpred_sub subst) para.body_dll)
}; };
let custom_error = Pvar.mk_global (Mangled.from_string "INFER_CUSTOM_ERROR") DB.SourceFile.empty; let custom_error = Pvar.mk_global (Mangled.from_string "INFER_CUSTOM_ERROR") SourceFile.empty;

@ -104,7 +104,7 @@ let loc_trace_to_jsonbug_record trace_list ekind =>
IList.map (fun tag => {Jsonbug_j.tag: fst tag, value: snd tag}) tags_list; IList.map (fun tag => {Jsonbug_j.tag: fst tag, value: snd tag}) tags_list;
let trace_item_to_record trace_item => { let trace_item_to_record trace_item => {
Jsonbug_j.level: trace_item.Errlog.lt_level, Jsonbug_j.level: trace_item.Errlog.lt_level,
filename: DB.SourceFile.to_string trace_item.Errlog.lt_loc.Location.file, filename: SourceFile.to_string trace_item.Errlog.lt_loc.Location.file,
line_number: trace_item.Errlog.lt_loc.Location.line, line_number: trace_item.Errlog.lt_loc.Location.line,
description: trace_item.Errlog.lt_description, description: trace_item.Errlog.lt_description,
node_tags: node_tags_to_records trace_item.Errlog.lt_node_tags node_tags: node_tags_to_records trace_item.Errlog.lt_node_tags
@ -193,7 +193,7 @@ let summary_values top_proc_set summary => {
verr: verr:
Errlog.size (fun ekind in_footprint => ekind == Exceptions.Kerror && in_footprint) err_log, Errlog.size (fun ekind in_footprint => ekind == Exceptions.Kerror && in_footprint) err_log,
vflags: attributes.ProcAttributes.proc_flags, vflags: attributes.ProcAttributes.proc_flags,
vfile: DB.SourceFile.to_string attributes.ProcAttributes.loc.Location.file, vfile: SourceFile.to_string attributes.ProcAttributes.loc.Location.file,
vline: attributes.ProcAttributes.loc.Location.line, vline: attributes.ProcAttributes.loc.Location.line,
vtop: if is_top {"Y"} else {"N"}, vtop: if is_top {"Y"} else {"N"},
vsignature: signature, vsignature: signature,
@ -435,7 +435,7 @@ let module IssuesCsv = {
let kind = Exceptions.err_kind_string ekind; let kind = Exceptions.err_kind_string ekind;
let type_str = Localise.to_string error_name; let type_str = Localise.to_string error_name;
let procedure_id = Procname.to_filename procname; let procedure_id = Procname.to_filename procname;
let filename = DB.SourceFile.to_string source_file; let filename = SourceFile.to_string source_file;
let always_report = let always_report =
switch (Localise.error_desc_extract_tag_value error_desc "always_report") { switch (Localise.error_desc_extract_tag_value error_desc "always_report") {
| "" => "false" | "" => "false"
@ -491,7 +491,7 @@ let module IssuesJson = {
| None => (loc.Location.file, 0) | None => (loc.Location.file, 0)
}; };
let should_report_source_file = let should_report_source_file =
not (DB.SourceFile.is_infer_model source_file) || not (SourceFile.is_infer_model source_file) ||
Config.debug_mode || Config.debug_exceptions; Config.debug_mode || Config.debug_exceptions;
if ( if (
in_footprint && in_footprint &&
@ -501,7 +501,7 @@ let module IssuesJson = {
let kind = Exceptions.err_kind_string ekind; let kind = Exceptions.err_kind_string ekind;
let bug_type = Localise.to_string error_name; let bug_type = Localise.to_string error_name;
let procedure_id = Procname.to_filename procname; let procedure_id = Procname.to_filename procname;
let file = DB.SourceFile.to_string source_file; let file = SourceFile.to_string source_file;
let json_ml_loc = let json_ml_loc =
switch ml_loc_opt { switch ml_loc_opt {
| Some (file, lnum, cnum, enum) when Config.reports_include_ml_loc => | Some (file, lnum, cnum, enum) when Config.reports_include_ml_loc =>
@ -629,7 +629,7 @@ let module IssuesXml = {
[("num", string_of_int !num)] [("num", string_of_int !num)]
[ [
level_to_xml lt.Errlog.lt_level, level_to_xml lt.Errlog.lt_level,
file_to_xml (DB.SourceFile.to_string loc.Location.file), file_to_xml (SourceFile.to_string loc.Location.file),
line_to_xml loc.Location.line, line_to_xml loc.Location.line,
code_to_xml code, code_to_xml code,
description_to_xml lt.Errlog.lt_description, description_to_xml lt.Errlog.lt_description,
@ -660,7 +660,7 @@ let module IssuesXml = {
let error_line = string_of_int loc.Location.line; let error_line = string_of_int loc.Location.line;
let procedure_name = Procname.to_string proc_name; let procedure_name = Procname.to_string proc_name;
let procedure_id = Procname.to_filename proc_name; let procedure_id = Procname.to_filename proc_name;
let filename = DB.SourceFile.to_string source_file; let filename = SourceFile.to_string source_file;
let bug_hash = get_bug_hash kind type_str procedure_id filename node_key error_desc; let bug_hash = get_bug_hash kind type_str procedure_id filename node_key error_desc;
let forest = [ let forest = [
subtree Io_infer.Xml.tag_class error_class, subtree Io_infer.Xml.tag_class error_class,
@ -705,8 +705,7 @@ let module CallsCsv = {
pp "\"%s\"," (Escape.escape_csv (Procname.to_filename caller_name)); pp "\"%s\"," (Escape.escape_csv (Procname.to_filename caller_name));
pp "\"%s\"," (Escape.escape_csv (Procname.to_string callee_name)); pp "\"%s\"," (Escape.escape_csv (Procname.to_string callee_name));
pp "\"%s\"," (Escape.escape_csv (Procname.to_filename callee_name)); pp "\"%s\"," (Escape.escape_csv (Procname.to_filename callee_name));
pp pp "%s," (SourceFile.to_string summary.Specs.attributes.ProcAttributes.loc.Location.file);
"%s," (DB.SourceFile.to_string summary.Specs.attributes.ProcAttributes.loc.Location.file);
pp "%d," loc.Location.line; pp "%d," loc.Location.line;
pp "%a@\n" Specs.CallStats.pp_trace trace pp "%a@\n" Specs.CallStats.pp_trace trace
}; };
@ -740,7 +739,7 @@ let module TopProcedures: {
let module Stats = { let module Stats = {
type t = { type t = {
files: Hashtbl.t DB.SourceFile.t unit, files: Hashtbl.t SourceFile.t unit,
mutable nchecked: int, mutable nchecked: int,
mutable ndefective: int, mutable ndefective: int,
mutable nerrors: int, mutable nerrors: int,
@ -817,7 +816,7 @@ let module Stats = {
let error_strs = { let error_strs = {
let pp1 fmt () => F.fprintf fmt "%d: %s" stats.nerrors type_str; let pp1 fmt () => F.fprintf fmt "%d: %s" stats.nerrors type_str;
let pp2 fmt () => let pp2 fmt () =>
F.fprintf fmt " %a:%d" DB.SourceFile.pp loc.Location.file loc.Location.line; F.fprintf fmt " %a:%d" SourceFile.pp loc.Location.file loc.Location.line;
let pp3 fmt () => F.fprintf fmt " (%a)" Localise.pp_error_desc error_desc; let pp3 fmt () => F.fprintf fmt " (%a)" Localise.pp_error_desc error_desc;
[pp_to_string pp1 (), pp_to_string pp2 (), pp_to_string pp3 ()] [pp_to_string pp1 (), pp_to_string pp2 (), pp_to_string pp3 ()]
}; };
@ -1245,7 +1244,7 @@ let module AnalysisResults = {
apply_without_gc (IList.iter load_file) (spec_files_from_cmdline ()); apply_without_gc (IList.iter load_file) (spec_files_from_cmdline ());
let summ_cmp (_, summ1) (_, summ2) => { let summ_cmp (_, summ1) (_, summ2) => {
let n = let n =
DB.SourceFile.compare SourceFile.compare
summ1.Specs.attributes.ProcAttributes.loc.Location.file summ1.Specs.attributes.ProcAttributes.loc.Location.file
summ2.Specs.attributes.ProcAttributes.loc.Location.file; summ2.Specs.attributes.ProcAttributes.loc.Location.file;
if (n != 0) { if (n != 0) {

@ -1017,7 +1017,7 @@ let pp_cfgnode pdesc fmt (n: Procdesc.Node.t) =
let print_icfg source fmt cfg = let print_icfg source fmt cfg =
let print_node pdesc node = let print_node pdesc node =
let loc = Procdesc.Node.get_loc node in let loc = Procdesc.Node.get_loc node in
if (Config.dotty_cfg_libs || DB.SourceFile.equal loc.Location.file source) then if (Config.dotty_cfg_libs || SourceFile.equal loc.Location.file source) then
F.fprintf fmt "%a\n" (pp_cfgnode pdesc) node in F.fprintf fmt "%a\n" (pp_cfgnode pdesc) node in
Cfg.iter_all_nodes ~sorted:true print_node cfg Cfg.iter_all_nodes ~sorted:true print_node cfg
@ -1035,7 +1035,7 @@ let print_icfg_dotty source cfg =
match Config.icfg_dotty_outfile with match Config.icfg_dotty_outfile with
| Some file -> file | Some file -> file
| None when Config.frontend_tests = true -> | None when Config.frontend_tests = true ->
(DB.SourceFile.to_abs_path source) ^ ".test.dot" (SourceFile.to_abs_path source) ^ ".test.dot"
| None -> | None ->
DB.filename_to_string DB.filename_to_string
(DB.Results_dir.path_to_filename (DB.Results_dir.path_to_filename
@ -1402,7 +1402,7 @@ let print_specs_xml signature specs loc fmt =
let xml_specifications = Io_infer.Xml.create_tree "specifications" [] list_of_specs_xml in let xml_specifications = Io_infer.Xml.create_tree "specifications" [] list_of_specs_xml in
let xml_signature = Io_infer.Xml.create_tree "signature" [("name", signature)] [] in let xml_signature = Io_infer.Xml.create_tree "signature" [("name", signature)] [] in
let proc_summary = Io_infer.Xml.create_tree "procedure" let proc_summary = Io_infer.Xml.create_tree "procedure"
[("file", DB.SourceFile.to_string loc.Location.file); [("file", SourceFile.to_string loc.Location.file);
("line", string_of_int loc.Location.line)] ("line", string_of_int loc.Location.line)]
[xml_signature; xml_specifications] in [xml_signature; xml_specifications] in
Io_infer.Xml.pp_document true fmt proc_summary Io_infer.Xml.pp_document true fmt proc_summary

@ -34,7 +34,7 @@ val pp_proplist_parsed2dotty_file : string -> Prop.normal Prop.t list -> unit
(** {2 Contol-Flow Graph} *) (** {2 Contol-Flow Graph} *)
(** Print the cfg *) (** Print the cfg *)
val print_icfg_dotty : DB.SourceFile.t -> Cfg.cfg -> unit val print_icfg_dotty : SourceFile.t -> Cfg.cfg -> unit
(** {2 Specs} *) (** {2 Specs} *)
val reset_dotty_spec_counter : unit -> unit val reset_dotty_spec_counter : unit -> unit

@ -16,7 +16,7 @@ module L = Logging
(** per-file data: type environment and cfg *) (** per-file data: type environment and cfg *)
type file_data = type file_data =
{ source: DB.SourceFile.t; { source: SourceFile.t;
tenv_file: DB.filename; tenv_file: DB.filename;
mutable tenv: Tenv.t option; mutable tenv: Tenv.t option;
cfg_file: DB.filename; cfg_file: DB.filename;
@ -64,7 +64,7 @@ type t =
{ cg: Cg.t; (** global call graph *) { cg: Cg.t; (** global call graph *)
proc_map: file_data Procname.Hash.t; (** map from procedure name to file data *) proc_map: file_data Procname.Hash.t; (** map from procedure name to file data *)
file_map: file_data FilenameHash.t; (** map from cg fname to file data *) file_map: file_data FilenameHash.t; (** map from cg fname to file data *)
mutable source_files : DB.SourceFile.Set.t; (** Source files in the execution environment *) mutable source_files : SourceFile.Set.t; (** Source files in the execution environment *)
} }
(** initial state, used to add cg's *) (** initial state, used to add cg's *)
@ -78,7 +78,7 @@ let create () =
{ cg = Cg.create None; { cg = Cg.create None;
proc_map = Procname.Hash.create 17; proc_map = Procname.Hash.create 17;
file_map = FilenameHash.create 1; file_map = FilenameHash.create 1;
source_files = DB.SourceFile.Set.empty; source_files = SourceFile.Set.empty;
} }
(** add call graph from fname in the spec db, (** add call graph from fname in the spec db,
@ -90,7 +90,7 @@ let add_cg (exe_env: t) (source_dir : DB.source_dir) =
L.stderr "cannot load %s@." (DB.filename_to_string cg_fname) L.stderr "cannot load %s@." (DB.filename_to_string cg_fname)
| Some cg -> | Some cg ->
let source = Cg.get_source cg in let source = Cg.get_source cg in
exe_env.source_files <- DB.SourceFile.Set.add source exe_env.source_files; exe_env.source_files <- SourceFile.Set.add source exe_env.source_files;
let defined_procs = Cg.get_defined_nodes cg in let defined_procs = Cg.get_defined_nodes cg in
IList.iter IList.iter
@ -99,14 +99,14 @@ let add_cg (exe_env: t) (source_dir : DB.source_dir) =
| None -> | None ->
() ()
| Some (source_captured, origin) -> | Some (source_captured, origin) ->
let multiply_defined = DB.SourceFile.compare source source_captured <> 0 in let multiply_defined = SourceFile.compare source source_captured <> 0 in
if multiply_defined then Cg.remove_node_defined cg pname; if multiply_defined then Cg.remove_node_defined cg pname;
if Config.check_duplicate_symbols && if Config.check_duplicate_symbols &&
multiply_defined && multiply_defined &&
origin <> `Include then origin <> `Include then
L.stderr "@.DUPLICATE_SYMBOLS source: %a source_captured:%a pname:%a@." L.stderr "@.DUPLICATE_SYMBOLS source: %a source_captured:%a pname:%a@."
DB.SourceFile.pp source SourceFile.pp source
DB.SourceFile.pp source_captured SourceFile.pp source_captured
Procname.pp pname Procname.pp pname
)) ))
defined_procs; defined_procs;
@ -190,13 +190,13 @@ let get_proc_desc exe_env pname =
let iter_files f exe_env = let iter_files f exe_env =
let do_file _ file_data seen_files_acc = let do_file _ file_data seen_files_acc =
let fname = file_data.source in let fname = file_data.source in
if DB.SourceFile.Set.mem fname seen_files_acc || if SourceFile.Set.mem fname seen_files_acc ||
(* only files added with add_cg* functions *) (* only files added with add_cg* functions *)
not (DB.SourceFile.Set.mem fname exe_env.source_files) not (SourceFile.Set.mem fname exe_env.source_files)
then seen_files_acc then seen_files_acc
else else
begin begin
Option.may (fun cfg -> f fname cfg) (file_data_to_cfg file_data); Option.may (fun cfg -> f fname cfg) (file_data_to_cfg file_data);
DB.SourceFile.Set.add fname seen_files_acc SourceFile.Set.add fname seen_files_acc
end in end in
ignore (Procname.Hash.fold do_file exe_env.proc_map DB.SourceFile.Set.empty) ignore (Procname.Hash.fold do_file exe_env.proc_map SourceFile.Set.empty)

@ -32,7 +32,7 @@ val add_cg : initial -> DB.source_dir -> unit
val get_cg : t -> Cg.t val get_cg : t -> Cg.t
(** return the source file associated to the procedure *) (** return the source file associated to the procedure *)
val get_source : t -> Procname.t -> DB.SourceFile.t option val get_source : t -> Procname.t -> SourceFile.t option
(** return the type environment associated to the procedure *) (** return the type environment associated to the procedure *)
val get_tenv : ?create:bool -> t -> Procname.t -> Tenv.t val get_tenv : ?create:bool -> t -> Procname.t -> Tenv.t
@ -44,4 +44,4 @@ val get_cfg : t -> Procname.t -> Cfg.cfg option
val get_proc_desc : t -> Procname.t -> Procdesc.t option val get_proc_desc : t -> Procname.t -> Procdesc.t option
(** [iter_files f exe_env] applies [f] to the source file and tenv and cfg for each file in [exe_env] *) (** [iter_files f exe_env] applies [f] to the source file and tenv and cfg for each file in [exe_env] *)
val iter_files : (DB.SourceFile.t -> Cfg.cfg -> unit) -> t -> unit val iter_files : (SourceFile.t -> Cfg.cfg -> unit) -> t -> unit

@ -11,7 +11,7 @@ open! Utils
module L = Logging module L = Logging
type path_filter = DB.SourceFile.t -> bool type path_filter = SourceFile.t -> bool
type error_filter = Localise.t -> bool type error_filter = Localise.t -> bool
type proc_filter = Procname.t -> bool type proc_filter = Procname.t -> bool
@ -43,7 +43,7 @@ type filter_config =
let is_matching patterns = let is_matching patterns =
fun source_file -> fun source_file ->
let path = DB.SourceFile.to_rel_path source_file in let path = SourceFile.to_rel_path source_file in
IList.exists IList.exists
(fun pattern -> (fun pattern ->
try try
@ -60,7 +60,7 @@ let match_method language proc_name method_name =
(* Module to create matcher based on strings present in the source file *) (* Module to create matcher based on strings present in the source file *)
module FileContainsStringMatcher = struct module FileContainsStringMatcher = struct
type matcher = DB.SourceFile.t -> bool type matcher = SourceFile.t -> bool
let default_matcher : matcher = fun _ -> false let default_matcher : matcher = fun _ -> false
@ -77,18 +77,18 @@ module FileContainsStringMatcher = struct
if s_patterns = [] then if s_patterns = [] then
default_matcher default_matcher
else else
let source_map = ref DB.SourceFile.Map.empty in let source_map = ref SourceFile.Map.empty in
let regexp = let regexp =
Str.regexp (join_strings "\\|" s_patterns) in Str.regexp (join_strings "\\|" s_patterns) in
fun source_file -> fun source_file ->
try try
DB.SourceFile.Map.find source_file !source_map SourceFile.Map.find source_file !source_map
with Not_found -> with Not_found ->
try try
let file_in = open_in (DB.SourceFile.to_abs_path source_file) in let file_in = open_in (SourceFile.to_abs_path source_file) in
let pattern_found = file_contains regexp file_in in let pattern_found = file_contains regexp file_in in
close_in file_in; close_in file_in;
source_map := DB.SourceFile.Map.add source_file pattern_found !source_map; source_map := SourceFile.Map.add source_file pattern_found !source_map;
pattern_found pattern_found
with Sys_error _ -> false with Sys_error _ -> false
end end
@ -96,7 +96,7 @@ end
(* Module to create matcher based on source file names or class names and method names *) (* Module to create matcher based on source file names or class names and method names *)
module FileOrProcMatcher = struct module FileOrProcMatcher = struct
type matcher = DB.SourceFile.t -> Procname.t -> bool type matcher = SourceFile.t -> Procname.t -> bool
let default_matcher : matcher = let default_matcher : matcher =
fun _ _ -> false fun _ _ -> false
@ -262,11 +262,11 @@ let test () =
directory_iter directory_iter
(fun path -> (fun path ->
if DB.is_source_file path then if DB.is_source_file path then
let source_file = DB.SourceFile.from_abs_path path in let source_file = SourceFile.from_abs_path path in
let matching = matching_analyzers source_file in let matching = matching_analyzers source_file in
if matching <> [] then if matching <> [] then
let matching_s = join_strings ", " (IList.map fst matching) in let matching_s = join_strings ", " (IList.map fst matching) in
L.stderr "%s -> {%s}@." L.stderr "%s -> {%s}@."
(DB.SourceFile.to_rel_path source_file) (SourceFile.to_rel_path source_file)
matching_s) matching_s)
(Sys.getcwd ()) (Sys.getcwd ())

@ -10,7 +10,7 @@
open! Utils open! Utils
(** Filter type for a source file *) (** Filter type for a source file *)
type path_filter = DB.SourceFile.t -> bool type path_filter = SourceFile.t -> bool
(** Filter type for an error name. *) (** Filter type for an error name. *)
type error_filter = Localise.t -> bool type error_filter = Localise.t -> bool
@ -31,9 +31,9 @@ val do_not_filter : filters
(** Create filters based on the config file *) (** Create filters based on the config file *)
val create_filters : Config.analyzer -> filters val create_filters : Config.analyzer -> filters
val never_return_null_matcher : DB.SourceFile.t -> Procname.t -> bool val never_return_null_matcher : SourceFile.t -> Procname.t -> bool
val suppress_warnings_matcher : DB.SourceFile.t -> Procname.t -> bool val suppress_warnings_matcher : SourceFile.t -> Procname.t -> bool
val skip_translation_matcher : DB.SourceFile.t -> Procname.t -> bool val skip_translation_matcher : SourceFile.t -> Procname.t -> bool
val modeled_expensive_matcher : (string -> bool) -> Procname.t -> bool val modeled_expensive_matcher : (string -> bool) -> Procname.t -> bool
(** Load the config file and list the files to report on *) (** Load the config file and list the files to report on *)

@ -1576,7 +1576,7 @@ let print_stats_cfg proc_shadowed source cfg =
F.fprintf fmt "TOTAL: %a@\n" (pp_seq pp_node) nodes_total; *) F.fprintf fmt "TOTAL: %a@\n" (pp_seq pp_node) nodes_total; *)
F.fprintf fmt "@\n++++++++++++++++++++++++++++++++++++++++++++++++++@\n"; F.fprintf fmt "@\n++++++++++++++++++++++++++++++++++++++++++++++++++@\n";
F.fprintf fmt "+ FILE: %a VISITED: %d/%d SYMOPS: %d@\n" F.fprintf fmt "+ FILE: %a VISITED: %d/%d SYMOPS: %d@\n"
DB.SourceFile.pp source SourceFile.pp source
(IList.length nodes_visited) (IList.length nodes_visited)
(IList.length nodes_total) (IList.length nodes_total)
!tot_symops; !tot_symops;

@ -17,15 +17,15 @@ module F = Format
(** Directories to analyze from the ondemand file. *) (** Directories to analyze from the ondemand file. *)
let dirs_to_analyze = let dirs_to_analyze =
let process_changed_files changed_files = let process_changed_files changed_files =
DB.SourceFile.Set.fold SourceFile.Set.fold
(fun source_file source_dir_set -> (fun source_file source_dir_set ->
let source_dir = DB.source_dir_from_source_file source_file in let source_dir = DB.source_dir_from_source_file source_file in
StringSet.add (DB.source_dir_to_string source_dir) source_dir_set StringSet.add (DB.source_dir_to_string source_dir) source_dir_set
) )
changed_files StringSet.empty in changed_files StringSet.empty in
Option.map process_changed_files DB.SourceFile.changed_files_set Option.map process_changed_files SourceFile.changed_files_set
type analyze_ondemand = DB.SourceFile.t -> Procdesc.t -> unit type analyze_ondemand = SourceFile.t -> Procdesc.t -> unit
type get_proc_desc = Procname.t -> Procdesc.t option type get_proc_desc = Procname.t -> Procdesc.t option
@ -124,7 +124,7 @@ let run_proc_analysis ~propagate_exceptions analyze_proc curr_pdesc callee_pdesc
failwith ("ERROR: "^(Procname.to_string callee_pname) failwith ("ERROR: "^(Procname.to_string callee_pname)
^" not equal to "^(Procname.to_string attribute_pname)); ^" not equal to "^(Procname.to_string attribute_pname));
attributes.loc.file) attributes.loc.file)
DB.SourceFile.empty SourceFile.empty
attributes_opt in attributes_opt in
let call_graph = let call_graph =
let cg = Cg.create (Some source) in let cg = Cg.create (Some source) in

@ -14,7 +14,7 @@ open! Utils
(** Optional set of source dirs to analyze in on-demand mode. *) (** Optional set of source dirs to analyze in on-demand mode. *)
val dirs_to_analyze : StringSet.t option val dirs_to_analyze : StringSet.t option
type analyze_ondemand = DB.SourceFile.t -> Procdesc.t -> unit type analyze_ondemand = SourceFile.t -> Procdesc.t -> unit
type get_proc_desc = Procname.t -> Procdesc.t option type get_proc_desc = Procname.t -> Procdesc.t option

@ -20,7 +20,7 @@ module F = Format
module LineReader = module LineReader =
struct struct
(** Map a file name to an array of string, one for each line in the file. *) (** Map a file name to an array of string, one for each line in the file. *)
type t = (DB.SourceFile.t, string array) Hashtbl.t type t = (SourceFile.t, string array) Hashtbl.t
let create () = let create () =
Hashtbl.create 1 Hashtbl.create 1
@ -48,7 +48,7 @@ struct
Some (Hashtbl.find hash fname) Some (Hashtbl.find hash fname)
with Not_found -> with Not_found ->
try try
let lines_arr = read_file (DB.SourceFile.to_abs_path fname) in let lines_arr = read_file (SourceFile.to_abs_path fname) in
Hashtbl.add hash fname lines_arr; Hashtbl.add hash fname lines_arr;
Some lines_arr Some lines_arr
with exn when SymOp.exn_not_failure exn -> None with exn when SymOp.exn_not_failure exn -> None
@ -98,8 +98,8 @@ module NodesHtml : sig
val start_node : val start_node :
int -> Location.t -> Procname.t -> Procdesc.Node.t list -> int -> Location.t -> Procname.t -> Procdesc.Node.t list ->
Procdesc.Node.t list -> Procdesc.Node.t list -> Procdesc.Node.t list -> Procdesc.Node.t list ->
DB.SourceFile.t -> bool SourceFile.t -> bool
val finish_node : Procname.t -> int -> DB.SourceFile.t -> unit val finish_node : Procname.t -> int -> SourceFile.t -> unit
end = struct end = struct
let log_files = Hashtbl.create 11 let log_files = Hashtbl.create 11
@ -478,11 +478,11 @@ let write_html_proc source proof_cover table_nodes_at_linenum global_err_log pro
let proc_loc = Procdesc.get_loc proc_desc in let proc_loc = Procdesc.get_loc proc_desc in
let process_proc = let process_proc =
Procdesc.is_defined proc_desc && Procdesc.is_defined proc_desc &&
DB.SourceFile.equal proc_loc.Location.file source && SourceFile.equal proc_loc.Location.file source &&
match AttributesTable.find_file_capturing_procedure proc_name with match AttributesTable.find_file_capturing_procedure proc_name with
| None -> true | None -> true
| Some (source_captured, _) -> | Some (source_captured, _) ->
DB.SourceFile.equal source_captured (Procdesc.get_loc proc_desc).file in SourceFile.equal source_captured (Procdesc.get_loc proc_desc).file in
if process_proc then if process_proc then
begin begin
IList.iter process_node (Procdesc.get_nodes proc_desc); IList.iter process_node (Procdesc.get_nodes proc_desc);
@ -499,14 +499,14 @@ let write_html_proc source proof_cover table_nodes_at_linenum global_err_log pro
(** Create filename.ext.html. *) (** Create filename.ext.html. *)
let write_html_file linereader filename procs = let write_html_file linereader filename procs =
let fname_encoding = DB.SourceFile.encoding filename in let fname_encoding = SourceFile.encoding filename in
let (fd, fmt) = let (fd, fmt) =
Io_infer.Html.create Io_infer.Html.create
(DB.Results_dir.Abs_source_dir filename) (DB.Results_dir.Abs_source_dir filename)
[".."; fname_encoding] in [".."; fname_encoding] in
let pp_prelude () = let pp_prelude () =
F.fprintf fmt "<center><h1>File %a </h1></center>\n<table class=\"code\">\n" F.fprintf fmt "<center><h1>File %a </h1></center>\n<table class=\"code\">\n"
DB.SourceFile.pp filename in SourceFile.pp filename in
let print_one_line proof_cover table_nodes_at_linenum table_err_per_line line_number = let print_one_line proof_cover table_nodes_at_linenum table_err_per_line line_number =
let line_html = let line_html =
match LineReader.from_file_linenum linereader filename line_number with match LineReader.from_file_linenum linereader filename line_number with
@ -592,15 +592,15 @@ let write_all_html_files exe_env =
Exe_env.iter_files Exe_env.iter_files
(fun _ cfg -> (fun _ cfg ->
let source_files_in_cfg = let source_files_in_cfg =
let files = ref DB.SourceFile.Set.empty in let files = ref SourceFile.Set.empty in
Cfg.iter_proc_desc cfg Cfg.iter_proc_desc cfg
(fun _ proc_desc -> (fun _ proc_desc ->
if Procdesc.is_defined proc_desc if Procdesc.is_defined proc_desc
then then
let file = (Procdesc.get_loc proc_desc).Location.file in let file = (Procdesc.get_loc proc_desc).Location.file in
files := DB.SourceFile.Set.add file !files); files := SourceFile.Set.add file !files);
!files in !files in
DB.SourceFile.Set.iter SourceFile.Set.iter
(fun file -> (fun file ->
write_html_file linereader file (Cfg.get_all_procs cfg)) write_html_file linereader file (Cfg.get_all_procs cfg))
source_files_in_cfg) source_files_in_cfg)

@ -21,10 +21,10 @@ module LineReader : sig
val create : unit -> t val create : unit -> t
(** get the line from a source file and line number *) (** get the line from a source file and line number *)
val from_file_linenum_original : t -> DB.SourceFile.t -> int -> string option val from_file_linenum_original : t -> SourceFile.t -> int -> string option
(** get the line from a source file and line number looking for the copy of the file in the results dir *) (** get the line from a source file and line number looking for the copy of the file in the results dir *)
val from_file_linenum : t -> DB.SourceFile.t -> int -> string option val from_file_linenum : t -> SourceFile.t -> int -> string option
(** get the line from a location looking for the copy of the file in the results dir *) (** get the line from a location looking for the copy of the file in the results dir *)
val from_loc : t -> Location.t -> string option val from_loc : t -> Location.t -> string option
@ -37,20 +37,20 @@ val curr_html_formatter : Format.formatter ref
val force_delayed_prints : unit -> unit val force_delayed_prints : unit -> unit
(** Finish a session, and perform delayed print actions if required *) (** Finish a session, and perform delayed print actions if required *)
val node_finish_session : Procdesc.Node.t -> DB.SourceFile.t -> unit val node_finish_session : Procdesc.Node.t -> SourceFile.t -> unit
(** Return true if the node was visited during footprint and during re-execution *) (** Return true if the node was visited during footprint and during re-execution *)
val node_is_visited : Procname.t -> Procdesc.Node.t -> bool * bool val node_is_visited : Procname.t -> Procdesc.Node.t -> bool * bool
(** Start a session, and create a new html fine for the node if it does not exist yet *) (** Start a session, and create a new html fine for the node if it does not exist yet *)
val node_start_session : val node_start_session :
Procdesc.Node.t -> Location.t -> Procname.t -> int -> DB.SourceFile.t -> unit Procdesc.Node.t -> Location.t -> Procname.t -> int -> SourceFile.t -> unit
(** Write html file for the procedure. (** Write html file for the procedure.
The boolean indicates whether to print whole seconds only. *) The boolean indicates whether to print whole seconds only. *)
val write_proc_html : DB.SourceFile.t -> bool -> Procdesc.t -> unit val write_proc_html : SourceFile.t -> bool -> Procdesc.t -> unit
val write_html_file : LineReader.t -> DB.SourceFile.t -> Procdesc.t list -> unit val write_html_file : LineReader.t -> SourceFile.t -> Procdesc.t list -> unit
(** Create filename.ext.html for each file in the exe_env. *) (** Create filename.ext.html for each file in the exe_env. *)
val write_all_html_files : Exe_env.t -> unit val write_all_html_files : Exe_env.t -> unit

@ -242,7 +242,7 @@ val pp_specs : printenv -> Format.formatter -> Prop.normal spec list -> unit
(** Print the summary in html format *) (** Print the summary in html format *)
val pp_summary_html : val pp_summary_html :
whole_seconds:bool -> DB.SourceFile.t -> color -> Format.formatter -> summary -> unit whole_seconds:bool -> SourceFile.t -> color -> Format.formatter -> summary -> unit
(** Print the summary in latext format *) (** Print the summary in latext format *)
val pp_summary_latex : whole_seconds:bool -> color -> Format.formatter -> summary -> unit val pp_summary_latex : whole_seconds:bool -> color -> Format.formatter -> summary -> unit

@ -15,165 +15,6 @@ open! Utils
module F = Format module F = Format
module L = Logging module L = Logging
(** {2 Source Files} *)
module SourceFile = struct
let count_newlines (path: string): int =
let open Core.Std in
let f file = In_channel.fold_lines file ~init:0 ~f:(fun i _ -> i + 1) in
In_channel.with_file path ~f
type t =
| Absolute of string
| RelativeProjectRoot of string (* relative to project root *)
| RelativeInferModel of string (* relative to infer models *)
[@@deriving compare]
let equal sf1 sf2 =
compare sf1 sf2 = 0
module OrderedSourceFile =
struct
(* Don't use nonrec due to https://github.com/janestreet/ppx_compare/issues/2 *)
type _t = t [@@deriving compare]
type t = _t [@@deriving compare]
end
module Map = Map.Make(OrderedSourceFile)
module Set = Set.Make(OrderedSourceFile)
let rel_path_from_abs_path root fname =
let relative_complemented_fname = filename_to_relative root fname in
if string_is_prefix root fname &&
Filename.is_relative relative_complemented_fname then
Some relative_complemented_fname
else None (* The project root is not a prefix of the file name *)
let from_abs_path fname =
if Filename.is_relative fname then
(failwithf
"ERROR: Path %s is relative, when absolute path was expected .@."
fname);
(* try to get realpath of source file. Use original if it fails *)
let fname_real = try realpath fname with Unix.Unix_error _ -> fname in
let project_root_real = realpath Config.project_root in
let models_dir_real = Config.models_src_dir in
match rel_path_from_abs_path project_root_real fname_real with
| Some path -> RelativeProjectRoot path
| None -> (
match rel_path_from_abs_path models_dir_real fname_real with
| Some path -> RelativeInferModel path
| None -> Absolute fname (* fname is absolute already *)
)
let curr_encoding = `Enc_crc
let to_string fname =
match fname with
| RelativeInferModel path -> "INFER_MODEL/" ^ path
| RelativeProjectRoot path
| Absolute path -> path
let pp fmt fname =
Format.fprintf fmt "%s" (to_string fname)
(* Checking if the path exists may be needed only in some cases, hence the flag check_exists *)
let to_abs_path fname =
match fname with
| RelativeProjectRoot path -> Filename.concat Config.project_root path
| RelativeInferModel path -> Filename.concat Config.models_src_dir path
| Absolute path -> path
let line_count source_file =
let abs_path = to_abs_path source_file in
count_newlines abs_path
let to_rel_path fname =
match fname with
| RelativeProjectRoot path -> path
| _ -> to_abs_path fname
(** string encoding of a source file (including path) as a single filename *)
let encoding source_file =
let prefix = match source_file with
| RelativeProjectRoot _ -> "P"
| RelativeInferModel _ -> "MOD"
| Absolute _ -> "ABS" in
let source_file_s = to_string source_file in
match curr_encoding with
| `Enc_base ->
Filename.basename source_file_s
| `Enc_path_with_underscores ->
prefix ^ Escape.escape_path source_file_s
| `Enc_crc ->
let base = Filename.basename source_file_s in
let dir = prefix ^ Filename.dirname source_file_s in
string_append_crc_cutoff ~key:dir base
let empty = Absolute ""
let is_infer_model source_file = match source_file with
| RelativeProjectRoot _ | Absolute _ -> false
| RelativeInferModel _ -> true
(** Returns true if the file is a C++ model *)
let is_cpp_model file =
match file with
| RelativeInferModel path ->
string_is_prefix Config.relative_cpp_models_dir path
| _ -> false
let is_under_project_root = function
| RelativeProjectRoot _ -> true
| Absolute _ | RelativeInferModel _ -> false
let exists_cache = Hashtbl.create 256
let path_exists abs_path =
try Hashtbl.find exists_cache abs_path
with Not_found ->
let result = Sys.file_exists abs_path in
Hashtbl.add exists_cache abs_path result;
result
let of_header header_file =
let abs_path = to_abs_path header_file in
let source_exts = ["c"; "cc"; "cpp"; "cxx"; "m"; "mm"] in
let header_exts = ["h"; "hh"; "hpp"; "hxx"] in
let file_no_ext, ext_opt = Core.Std.Filename.split_extension abs_path in
let file_opt = match ext_opt with
| Some ext when IList.mem Core.Std.String.equal ext header_exts -> (
let possible_files = IList.map (fun ext -> file_no_ext ^ "." ^ ext) source_exts in
try Some (IList.find path_exists possible_files)
with Not_found -> None
)
| _ -> None in
Option.map from_abs_path file_opt
let changed_files_set =
let create_source_file path =
if Filename.is_relative path then
(* sources in changed-files-index may be specified relative to project root *)
RelativeProjectRoot path
else
from_abs_path path in
Option.map_default read_file None Config.changed_files_index |>
Option.map (
IList.fold_left
(fun changed_files line ->
let source_file = create_source_file line in
let changed_files' = Set.add source_file changed_files in
(* Add source corresponding to changed header if it exists *)
match of_header source_file with
| Some src -> Set.add src changed_files'
| None -> changed_files'
)
Set.empty
)
end
(** {2 Source Dirs} *) (** {2 Source Dirs} *)
(** source directory: the directory inside the results dir corresponding to a source file *) (** source directory: the directory inside the results dir corresponding to a source file *)

@ -38,64 +38,6 @@ val mark_file_updated : string -> unit
(** Return whether filename was updated after analysis started. File doesn't have to exist *) (** Return whether filename was updated after analysis started. File doesn't have to exist *)
val file_was_updated_after_start : filename -> bool val file_was_updated_after_start : filename -> bool
(** {2 Source Files} *)
module SourceFile : sig
type t [@@deriving compare]
(** equality of source files *)
val equal : t -> t -> bool
(** Maps from source_file *)
module Map : Map.S with type key = t
(** Set of source files *)
module Set : Set.S with type elt = t
(** compute line count of a source file *)
val line_count : t -> int
(** empty source file *)
val empty : t
(** create source file from absolute path *)
val from_abs_path : string -> t
(** string encoding of a source file (including path) as a single filename *)
val encoding : t -> string
(** convert a source file to a string
WARNING: result may not be valid file path, do not use this function to perform operations
on filenames *)
val to_string : t -> string
(** pretty print t *)
val pp : Format.formatter -> t -> unit
(** get the full path of a source file *)
val to_abs_path : t -> string
(** get the relative path of a source file *)
val to_rel_path : t -> string
val is_infer_model : t -> bool
(** Returns true if the file is a C++ model *)
val is_cpp_model : t -> bool
(** Returns true if the file is in project root *)
val is_under_project_root : t -> bool
(** Return approximate source file corresponding to the parameter if it's header file and
file exists. returns None otherwise *)
val of_header : t -> t option
(** Set of files read from --changed-files-index file, None if option not specified
NOTE: it may include extra source_files if --changed-files-index contains paths to
header files *)
val changed_files_set : Set.t option
end
(** {2 Results Directory} *) (** {2 Results Directory} *)
module Results_dir : sig module Results_dir : sig

@ -0,0 +1,163 @@
(*
* Copyright (c) 2016 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! Utils
let count_newlines (path: string): int =
let open Core.Std in
let f file = In_channel.fold_lines file ~init:0 ~f:(fun i _ -> i + 1) in
In_channel.with_file path ~f
type t =
| Absolute of string
| RelativeProjectRoot of string (* relative to project root *)
| RelativeInferModel of string (* relative to infer models *)
[@@deriving compare]
let equal sf1 sf2 =
compare sf1 sf2 = 0
module OrderedSourceFile =
struct
type _t = t [@@deriving compare]
type t = _t [@@deriving compare]
end
module Map = Map.Make(OrderedSourceFile)
module Set = Set.Make(OrderedSourceFile)
let rel_path_from_abs_path root fname =
let relative_complemented_fname = filename_to_relative root fname in
if string_is_prefix root fname &&
Filename.is_relative relative_complemented_fname then
Some relative_complemented_fname
else None (* The project root is not a prefix of the file name *)
let from_abs_path fname =
if Filename.is_relative fname then
(failwithf
"ERROR: Path %s is relative, when absolute path was expected .@."
fname);
(* try to get realpath of source file. Use original if it fails *)
let fname_real = try realpath fname with Unix.Unix_error _ -> fname in
let project_root_real = realpath Config.project_root in
let models_dir_real = Config.models_src_dir in
match rel_path_from_abs_path project_root_real fname_real with
| Some path -> RelativeProjectRoot path
| None -> (
match rel_path_from_abs_path models_dir_real fname_real with
| Some path -> RelativeInferModel path
| None -> Absolute fname (* fname is absolute already *)
)
let curr_encoding = `Enc_crc
let to_string fname =
match fname with
| RelativeInferModel path -> "INFER_MODEL/" ^ path
| RelativeProjectRoot path
| Absolute path -> path
let pp fmt fname =
Format.fprintf fmt "%s" (to_string fname)
(* Checking if the path exists may be needed only in some cases, hence the flag check_exists *)
let to_abs_path fname =
match fname with
| RelativeProjectRoot path -> Filename.concat Config.project_root path
| RelativeInferModel path -> Filename.concat Config.models_src_dir path
| Absolute path -> path
let line_count source_file =
let abs_path = to_abs_path source_file in
count_newlines abs_path
let to_rel_path fname =
match fname with
| RelativeProjectRoot path -> path
| _ -> to_abs_path fname
(** string encoding of a source file (including path) as a single filename *)
let encoding source_file =
let prefix = match source_file with
| RelativeProjectRoot _ -> "P"
| RelativeInferModel _ -> "MOD"
| Absolute _ -> "ABS" in
let source_file_s = to_string source_file in
match curr_encoding with
| `Enc_base ->
Filename.basename source_file_s
| `Enc_path_with_underscores ->
prefix ^ Escape.escape_path source_file_s
| `Enc_crc ->
let base = Filename.basename source_file_s in
let dir = prefix ^ Filename.dirname source_file_s in
string_append_crc_cutoff ~key:dir base
let empty = Absolute ""
let is_infer_model source_file = match source_file with
| RelativeProjectRoot _ | Absolute _ -> false
| RelativeInferModel _ -> true
(** Returns true if the file is a C++ model *)
let is_cpp_model file =
match file with
| RelativeInferModel path ->
string_is_prefix Config.relative_cpp_models_dir path
| _ -> false
let is_under_project_root = function
| RelativeProjectRoot _ -> true
| Absolute _ | RelativeInferModel _ -> false
let exists_cache = Hashtbl.create 256
let path_exists abs_path =
try Hashtbl.find exists_cache abs_path
with Not_found ->
let result = Sys.file_exists abs_path in
Hashtbl.add exists_cache abs_path result;
result
let of_header header_file =
let abs_path = to_abs_path header_file in
let source_exts = ["c"; "cc"; "cpp"; "cxx"; "m"; "mm"] in
let header_exts = ["h"; "hh"; "hpp"; "hxx"] in
let file_no_ext, ext_opt = Core.Std.Filename.split_extension abs_path in
let file_opt = match ext_opt with
| Some ext when IList.mem Core.Std.String.equal ext header_exts -> (
let possible_files = IList.map (fun ext -> file_no_ext ^ "." ^ ext) source_exts in
try Some (IList.find path_exists possible_files)
with Not_found -> None
)
| _ -> None in
Option.map from_abs_path file_opt
let changed_files_set =
let create_source_file path =
if Filename.is_relative path then
(* sources in changed-files-index may be specified relative to project root *)
RelativeProjectRoot path
else
from_abs_path path in
Option.map_default read_file None Config.changed_files_index |>
Option.map (
IList.fold_left
(fun changed_files line ->
let source_file = create_source_file line in
let changed_files' = Set.add source_file changed_files in
(* Add source corresponding to changed header if it exists *)
match of_header source_file with
| Some src -> Set.add src changed_files'
| None -> changed_files'
)
Set.empty
)

@ -0,0 +1,62 @@
(*
* Copyright (c) 2016 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
type t [@@deriving compare]
(** equality of source files *)
val equal : t -> t -> bool
(** Maps from source_file *)
module Map : Map.S with type key = t
(** Set of source files *)
module Set : Set.S with type elt = t
(** compute line count of a source file *)
val line_count : t -> int
(** empty source file *)
val empty : t
(** create source file from absolute path *)
val from_abs_path : string -> t
(** string encoding of a source file (including path) as a single filename *)
val encoding : t -> string
(** convert a source file to a string
WARNING: result may not be valid file path, do not use this function to perform operations
on filenames *)
val to_string : t -> string
(** pretty print t *)
val pp : Format.formatter -> t -> unit
(** get the full path of a source file *)
val to_abs_path : t -> string
(** get the relative path of a source file *)
val to_rel_path : t -> string
val is_infer_model : t -> bool
(** Returns true if the file is a C++ model *)
val is_cpp_model : t -> bool
(** Returns true if the file is in project root *)
val is_under_project_root : t -> bool
(** Return approximate source file corresponding to the parameter if it's header file and
file exists. returns None otherwise *)
val of_header : t -> t option
(** Set of files read from --changed-files-index file, None if option not specified
NOTE: it may include extra source_files if --changed-files-index contains paths to
header files *)
val changed_files_set : Set.t option

@ -60,7 +60,7 @@ let stacktree_of_pdesc
let procname = Procdesc.get_proc_name pdesc in let procname = Procdesc.get_proc_name pdesc in
let frame_loc = let frame_loc =
Some { Stacktree_j.location_type = location_type; Some { Stacktree_j.location_type = location_type;
file = DB.SourceFile.to_string loc.Location.file; file = SourceFile.to_string loc.Location.file;
line = Some loc.Location.line; line = Some loc.Location.line;
blame_range = [line_range_of_pdesc pdesc] } in blame_range = [line_range_of_pdesc pdesc] } in
{ Stacktree_j.method_name = Procname.to_unique_id procname; { Stacktree_j.method_name = Procname.to_unique_id procname;

@ -109,8 +109,8 @@ module Interprocedural = Analyzer.Interprocedural (Summary)
let is_foreign tu_opt v = let is_foreign tu_opt v =
let is_orig_file f = match tu_opt with let is_orig_file f = match tu_opt with
| Some orig_file -> | Some orig_file ->
let orig_path = DB.SourceFile.to_abs_path orig_file in let orig_path = SourceFile.to_abs_path orig_file in
Core.Std.String.equal orig_path (DB.SourceFile.to_abs_path f) Core.Std.String.equal orig_path (SourceFile.to_abs_path f)
| None -> assert false in | None -> assert false in
Option.map_default (fun f -> not (is_orig_file f)) false (Pvar.get_source_file v) Option.map_default (fun f -> not (is_orig_file f)) false (Pvar.get_source_file v)
@ -125,8 +125,8 @@ let report_siof trace pdesc gname loc =
let pp_sink f sink = let pp_sink f sink =
let pp_source f v = match Pvar.get_source_file v with let pp_source f v = match Pvar.get_source_file v with
| Some source_file when not (DB.SourceFile.equal DB.SourceFile.empty source_file) -> | Some source_file when not (SourceFile.equal SourceFile.empty source_file) ->
F.fprintf f " from file %a" DB.SourceFile.pp source_file F.fprintf f " from file %a" SourceFile.pp source_file
| _ -> | _ ->
() in () in
let v = SiofTrace.Sink.kind sink in let v = SiofTrace.Sink.kind sink in

@ -43,7 +43,7 @@ let make_frame class_str method_str file_str line_num =
{ class_str; method_str; file_str; line_num; } { class_str; method_str; file_str; line_num; }
let frame_matches_location frame_obj loc = let frame_matches_location frame_obj loc =
let lfname = DB.SourceFile.to_string loc.Location.file in let lfname = SourceFile.to_string loc.Location.file in
let matches_file = Utils.string_is_suffix frame_obj.file_str lfname in let matches_file = Utils.string_is_suffix frame_obj.file_str lfname in
let matches_line = match frame_obj.line_num with let matches_line = match frame_obj.line_num with
| None -> false | None -> false

@ -150,7 +150,7 @@ module MakeNoCFG
then then
begin begin
Ondemand.set_callbacks callbacks; Ondemand.set_callbacks callbacks;
let post_opt = analyze_ondemand_ DB.SourceFile.empty proc_desc in let post_opt = analyze_ondemand_ SourceFile.empty proc_desc in
Ondemand.unset_callbacks (); Ondemand.unset_callbacks ();
post_opt post_opt
end end

@ -25,7 +25,7 @@ module PP = struct
match Printer.LineReader.from_loc linereader { loc with Location.line = n } with match Printer.LineReader.from_loc linereader { loc with Location.line = n } with
| Some s -> F.fprintf fmt "%s%s@\n" (if n = loc.Location.line then "-->" else " ") s | Some s -> F.fprintf fmt "%s%s@\n" (if n = loc.Location.line then "-->" else " ") s
| _ -> () in | _ -> () in
F.fprintf fmt "%a:%d@\n" DB.SourceFile.pp loc.Location.file loc.Location.line; F.fprintf fmt "%a:%d@\n" SourceFile.pp loc.Location.file loc.Location.line;
for n = loc.Location.line - nbefore to loc.Location.line + nafter do printline n done for n = loc.Location.line - nbefore to loc.Location.line + nafter do printline n done
end (* PP *) end (* PP *)
@ -144,7 +144,7 @@ module ST = struct
begin begin
L.stdout "%s: %a: %s@." L.stdout "%s: %a: %s@."
kind kind
DB.SourceFile.pp loc.Location.file SourceFile.pp loc.Location.file
(Procname.to_string proc_name); (Procname.to_string proc_name);
L.stdout "%s@." description L.stdout "%s@." description
end; end;
@ -370,7 +370,7 @@ let callback_monitor_nullcheck { Callbacks.proc_desc; idenv; proc_name } =
let missing = IList.filter was_not_found formal_names in let missing = IList.filter was_not_found formal_names in
let loc = Procdesc.get_loc proc_desc in let loc = Procdesc.get_loc proc_desc in
let pp_file_loc fmt () = let pp_file_loc fmt () =
F.fprintf fmt "%a:%d" DB.SourceFile.pp loc.Location.file loc.Location.line in F.fprintf fmt "%a:%d" SourceFile.pp loc.Location.file loc.Location.line in
L.stdout "Null Checks of Formal Parameters: "; L.stdout "Null Checks of Formal Parameters: ";
L.stdout "%d out of %d parameters checked (missing checks on: %a)[%a]@." L.stdout "%d out of %d parameters checked (missing checks on: %a)[%a]@."
nchecks nformals (pp_seq Mangled.pp) missing pp_file_loc (); nchecks nformals (pp_seq Mangled.pp) missing pp_file_loc ();

@ -132,7 +132,7 @@ struct
Format.asprintf "call to %s seen before on line %d (may allocate at %a:%d)" Format.asprintf "call to %s seen before on line %d (may allocate at %a:%d)"
(Procname.to_simplified_string callee_pname) (Procname.to_simplified_string callee_pname)
loc_old.Location.line loc_old.Location.line
DB.SourceFile.pp alloc_loc.Location.file SourceFile.pp alloc_loc.Location.file
alloc_loc.Location.line in alloc_loc.Location.line in
Checkers.ST.report_error tenv Checkers.ST.report_error tenv
curr_pname curr_pdesc checkers_repeated_calls_name loc description curr_pname curr_pdesc checkers_repeated_calls_name loc description

@ -35,7 +35,7 @@ let validate_decl_from_channel chan =>
let register_perf_stats_report source_file => { let register_perf_stats_report source_file => {
let stats_dir = Filename.concat Config.results_dir Config.frontend_stats_dir_name; let stats_dir = Filename.concat Config.results_dir Config.frontend_stats_dir_name;
let abbrev_source_file = DB.SourceFile.encoding source_file; let abbrev_source_file = SourceFile.encoding source_file;
let stats_file = Config.perf_stats_prefix ^ "_" ^ abbrev_source_file ^ ".json"; let stats_file = Config.perf_stats_prefix ^ "_" ^ abbrev_source_file ^ ".json";
create_dir Config.results_dir; create_dir Config.results_dir;
create_dir stats_dir; create_dir stats_dir;
@ -44,7 +44,7 @@ let register_perf_stats_report source_file => {
let init_global_state_for_capture_and_linters source_file => { let init_global_state_for_capture_and_linters source_file => {
Logging.set_log_file_identifier Logging.set_log_file_identifier
CommandLineOption.Clang (Some (Filename.basename (DB.SourceFile.to_abs_path source_file))); CommandLineOption.Clang (Some (Filename.basename (SourceFile.to_abs_path source_file)));
register_perf_stats_report source_file; register_perf_stats_report source_file;
Config.curr_language := Config.Clang; Config.curr_language := Config.Clang;
DB.Results_dir.init source_file; DB.Results_dir.init source_file;
@ -67,7 +67,7 @@ let run_clang_frontend ast_source => {
switch ast_decl { switch ast_decl {
| Clang_ast_t.TranslationUnitDecl (_, _, _, info) => | Clang_ast_t.TranslationUnitDecl (_, _, _, info) =>
Config.arc_mode := info.Clang_ast_t.tudi_arc_enabled; Config.arc_mode := info.Clang_ast_t.tudi_arc_enabled;
let source_file = DB.SourceFile.from_abs_path info.Clang_ast_t.tudi_input_path; let source_file = SourceFile.from_abs_path info.Clang_ast_t.tudi_input_path;
init_global_state_for_capture_and_linters source_file; init_global_state_for_capture_and_linters source_file;
let lang = let lang =
switch info.Clang_ast_t.tudi_input_kind { switch info.Clang_ast_t.tudi_input_kind {
@ -84,8 +84,7 @@ let run_clang_frontend ast_source => {
switch ast_source { switch ast_source {
| `File path => Format.fprintf fmt "%s" path | `File path => Format.fprintf fmt "%s" path
| `Pipe _ => | `Pipe _ =>
Format.fprintf Format.fprintf fmt "stdin of %a" SourceFile.pp trans_unit_ctx.CFrontend_config.source_file
fmt "stdin of %a" DB.SourceFile.pp trans_unit_ctx.CFrontend_config.source_file
}; };
let (decl_index, stmt_index, type_index, ivar_to_property_index) = Clang_ast_main.index_node_pointers ast_decl; let (decl_index, stmt_index, type_index, ivar_to_property_index) = Clang_ast_main.index_node_pointers ast_decl;
CFrontend_config.pointer_decl_index := decl_index; CFrontend_config.pointer_decl_index := decl_index;

@ -25,8 +25,8 @@ let is_in_main_file translation_unit_context an =
| None -> | None ->
false false
| Some file -> | Some file ->
DB.SourceFile.equal SourceFile.equal
(DB.SourceFile.from_abs_path file) (SourceFile.from_abs_path file)
translation_unit_context.CFrontend_config.source_file translation_unit_context.CFrontend_config.source_file
let is_ck_context (context: CLintersContext.context) an = let is_ck_context (context: CLintersContext.context) an =
@ -316,7 +316,7 @@ let component_file_line_count_info (context: CLintersContext.context) dec =
| Clang_ast_t.TranslationUnitDecl _ when condition -> | Clang_ast_t.TranslationUnitDecl _ when condition ->
let source_file = let source_file =
context.translation_unit_context.CFrontend_config.source_file in context.translation_unit_context.CFrontend_config.source_file in
let line_count = DB.SourceFile.line_count source_file in let line_count = SourceFile.line_count source_file in
IList.map (fun i -> { IList.map (fun i -> {
CIssue.issue = CIssue.Component_file_line_count; CIssue.issue = CIssue.Component_file_line_count;
CIssue.description = "Line count analytics"; CIssue.description = "Line count analytics";

@ -45,10 +45,10 @@ let do_source_file translation_unit_context ast =
init_global_state_capture (); init_global_state_capture ();
let source_file = translation_unit_context.CFrontend_config.source_file in let source_file = translation_unit_context.CFrontend_config.source_file in
Logging.out_debug "@\n Start building call/cfg graph for '%a'....@\n" Logging.out_debug "@\n Start building call/cfg graph for '%a'....@\n"
DB.SourceFile.pp source_file; SourceFile.pp source_file;
let call_graph, cfg = compute_icfg translation_unit_context tenv ast in let call_graph, cfg = compute_icfg translation_unit_context tenv ast in
Logging.out_debug "@\n End building call/cfg graph for '%a'.@\n" Logging.out_debug "@\n End building call/cfg graph for '%a'.@\n"
DB.SourceFile.pp source_file; SourceFile.pp source_file;
(* This part below is a boilerplate in every frontends. *) (* This part below is a boilerplate in every frontends. *)
(* This could be moved in the cfg_infer module *) (* This could be moved in the cfg_infer module *)
let source_dir = DB.source_dir_from_source_file source_file in let source_dir = DB.source_dir_from_source_file source_file in

@ -107,7 +107,7 @@ let context_with_ck_set context decl_list =
context context
let store_issues source_file = let store_issues source_file =
let abbrev_source_file = DB.SourceFile.encoding source_file in let abbrev_source_file = SourceFile.encoding source_file in
let lint_issues_dir = Config.results_dir // Config.lint_issues_dir_name in let lint_issues_dir = Config.results_dir // Config.lint_issues_dir_name in
create_dir lint_issues_dir; create_dir lint_issues_dir;
let lint_issues_file = let lint_issues_file =
@ -118,7 +118,7 @@ let do_frontend_checks trans_unit_ctx ast =
try try
parse_ctl_file Config.linters_def_file; parse_ctl_file Config.linters_def_file;
let source_file = trans_unit_ctx.CFrontend_config.source_file in let source_file = trans_unit_ctx.CFrontend_config.source_file in
Logging.out "Start linting file %a@\n" DB.SourceFile.pp source_file; Logging.out "Start linting file %a@\n" SourceFile.pp source_file;
match ast with match ast with
| Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) -> | Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) ->
let context = let context =
@ -132,7 +132,7 @@ let do_frontend_checks trans_unit_ctx ast =
IList.iter (do_frontend_checks_decl context) allowed_decls; IList.iter (do_frontend_checks_decl context) allowed_decls;
if (LintIssues.exists_issues ()) then if (LintIssues.exists_issues ()) then
store_issues source_file; store_issues source_file;
Logging.out "End linting file %a@\n" DB.SourceFile.pp source_file; Logging.out "End linting file %a@\n" SourceFile.pp source_file;
CTL.save_dotty_when_in_debug_mode trans_unit_ctx.CFrontend_config.source_file; CTL.save_dotty_when_in_debug_mode trans_unit_ctx.CFrontend_config.source_file;
| _ -> assert false (* NOTE: Assumes that an AST alsways starts with a TranslationUnitDecl *) | _ -> assert false (* NOTE: Assumes that an AST alsways starts with a TranslationUnitDecl *)
with with

@ -15,7 +15,7 @@ type clang_lang = C | CPP | ObjC | ObjCPP
type translation_unit_context = { type translation_unit_context = {
lang : clang_lang; lang : clang_lang;
source_file : DB.SourceFile.t source_file : SourceFile.t
} }
(** Constants *) (** Constants *)

@ -15,7 +15,7 @@ type clang_lang = C | CPP | ObjC | ObjCPP
type translation_unit_context = { type translation_unit_context = {
lang : clang_lang; lang : clang_lang;
source_file : DB.SourceFile.t source_file : SourceFile.t
} }
(** Constants *) (** Constants *)

@ -657,7 +657,7 @@ struct
let get_rel_file_path file_opt = let get_rel_file_path file_opt =
match file_opt with match file_opt with
| Some file -> | Some file ->
DB.SourceFile.to_string (DB.SourceFile.from_abs_path file) SourceFile.to_string (SourceFile.from_abs_path file)
| None -> "" in | None -> "" in
let file = let file =
match function_decl_info_opt with match function_decl_info_opt with
@ -747,7 +747,7 @@ struct
| Some "extern", None -> | Some "extern", None ->
(* some compilers simply disregard "extern" when the global is given some initialisation (* some compilers simply disregard "extern" when the global is given some initialisation
code, which is why we make sure that [vdi_init_expr] is None here... *) code, which is why we make sure that [vdi_init_expr] is None here... *)
DB.SourceFile.empty SourceFile.empty
| _ -> | _ ->
source_file in source_file in
let is_constexpr = var_decl_info.Clang_ast_t.vdi_is_const_expr in let is_constexpr = var_decl_info.Clang_ast_t.vdi_is_const_expr in

@ -14,13 +14,13 @@ open! Utils
let clang_to_sil_location trans_unit_ctx clang_loc = let clang_to_sil_location trans_unit_ctx clang_loc =
let line = Option.default (-1) clang_loc.Clang_ast_t.sl_line in let line = Option.default (-1) clang_loc.Clang_ast_t.sl_line in
let col = Option.default (-1) clang_loc.Clang_ast_t.sl_column in let col = Option.default (-1) clang_loc.Clang_ast_t.sl_column in
let file = Option.map_default DB.SourceFile.from_abs_path let file = Option.map_default SourceFile.from_abs_path
trans_unit_ctx.CFrontend_config.source_file clang_loc.Clang_ast_t.sl_file in trans_unit_ctx.CFrontend_config.source_file clang_loc.Clang_ast_t.sl_file in
Location.{line; col; file} Location.{line; col; file}
let source_file_in_project source_file = let source_file_in_project source_file =
let file_in_project = DB.SourceFile.is_under_project_root source_file in let file_in_project = SourceFile.is_under_project_root source_file in
let rel_source_file = DB.SourceFile.to_string source_file in let rel_source_file = SourceFile.to_string source_file in
let file_should_be_skipped = let file_should_be_skipped =
IList.exists IList.exists
(fun path -> string_is_prefix path rel_source_file) (fun path -> string_is_prefix path rel_source_file)
@ -30,8 +30,8 @@ let source_file_in_project source_file =
let should_do_frontend_check trans_unit_ctx (loc_start, _) = let should_do_frontend_check trans_unit_ctx (loc_start, _) =
match loc_start.Clang_ast_t.sl_file with match loc_start.Clang_ast_t.sl_file with
| Some file -> | Some file ->
let source_file = (DB.SourceFile.from_abs_path file) in let source_file = (SourceFile.from_abs_path file) in
DB.SourceFile.equal source_file trans_unit_ctx.CFrontend_config.source_file || SourceFile.equal source_file trans_unit_ctx.CFrontend_config.source_file ||
(source_file_in_project source_file && not Config.testing_mode) (source_file_in_project source_file && not Config.testing_mode)
| None -> false | None -> false
@ -46,24 +46,24 @@ let should_translate trans_unit_ctx (loc_start, loc_end) decl_trans_context ~tra
| None -> false | None -> false
in in
let map_file_of pred loc = let map_file_of pred loc =
let path_pred path = pred (DB.SourceFile.from_abs_path path) in let path_pred path = pred (SourceFile.from_abs_path path) in
map_path_of path_pred loc map_path_of path_pred loc
in in
(* it's not necessary to compare inodes here because both files come from (* it's not necessary to compare inodes here because both files come from
the same context - they are produced by the same invocation of ASTExporter the same context - they are produced by the same invocation of ASTExporter
which uses same logic to produce both files *) which uses same logic to produce both files *)
let equal_current_source = DB.SourceFile.equal trans_unit_ctx.CFrontend_config.source_file let equal_current_source = SourceFile.equal trans_unit_ctx.CFrontend_config.source_file
in in
let equal_header_of_current_source maybe_header = let equal_header_of_current_source maybe_header =
(* DB.SourceFile.of_header will cache calls to filesystem *) (* SourceFile.of_header will cache calls to filesystem *)
let source_of_header_opt = DB.SourceFile.of_header maybe_header in let source_of_header_opt = SourceFile.of_header maybe_header in
Option.map_default equal_current_source false source_of_header_opt Option.map_default equal_current_source false source_of_header_opt
in in
let file_in_project = map_file_of source_file_in_project loc_end let file_in_project = map_file_of source_file_in_project loc_end
|| map_file_of source_file_in_project loc_start in || map_file_of source_file_in_project loc_start in
let translate_on_demand = translate_when_used || file_in_project || Config.models_mode in let translate_on_demand = translate_when_used || file_in_project || Config.models_mode in
let file_in_models = map_file_of DB.SourceFile.is_cpp_model loc_end let file_in_models = map_file_of SourceFile.is_cpp_model loc_end
|| map_file_of DB.SourceFile.is_cpp_model loc_start in || map_file_of SourceFile.is_cpp_model loc_start in
map_file_of equal_current_source loc_end map_file_of equal_current_source loc_end
|| map_file_of equal_current_source loc_start || map_file_of equal_current_source loc_start
|| file_in_models || file_in_models

@ -252,7 +252,7 @@ let save_dotty_when_in_debug_mode source_file =
| Some tracker -> | Some tracker ->
let dotty_dir = Config.results_dir // Config.lint_dotty_dir_name in let dotty_dir = Config.results_dir // Config.lint_dotty_dir_name in
create_dir dotty_dir; create_dir dotty_dir;
let source_file_basename = Filename.basename (DB.SourceFile.to_abs_path source_file) in let source_file_basename = Filename.basename (SourceFile.to_abs_path source_file) in
let file = dotty_dir // (source_file_basename ^ ".dot") in let file = dotty_dir // (source_file_basename ^ ".dot") in
let dotty = Debug.EvaluationTracker.DottyPrinter.dotty_of_ctl_evaluation !tracker in let dotty = Debug.EvaluationTracker.DottyPrinter.dotty_of_ctl_evaluation !tracker in
with_file file ~f:(fun oc -> output_string oc dotty) with_file file ~f:(fun oc -> output_string oc dotty)

@ -61,7 +61,7 @@ type ast_node =
val eval_formula : t -> ast_node -> CLintersContext.context -> bool val eval_formula : t -> ast_node -> CLintersContext.context -> bool
val save_dotty_when_in_debug_mode : DB.SourceFile.t -> unit val save_dotty_when_in_debug_mode : SourceFile.t -> unit
module Debug : sig module Debug : sig

@ -241,7 +241,7 @@ let report_error_now tenv
(st_report_error : st_report_error) err_instance loc pdesc : unit = (st_report_error : st_report_error) err_instance loc pdesc : unit =
let pname = Procdesc.get_proc_name pdesc in let pname = Procdesc.get_proc_name pdesc in
let do_print ew_string kind_s s = let do_print ew_string kind_s s =
L.stdout "%a:%d " DB.SourceFile.pp loc.Location.file loc.Location.line; L.stdout "%a:%d " SourceFile.pp loc.Location.file loc.Location.line;
let mname = match pname with let mname = match pname with
| Procname.Java pname_java -> | Procname.Java pname_java ->
Procname.java_get_method pname_java Procname.java_get_method pname_java

@ -18,14 +18,14 @@ let capture_text =
(** Read the files to compile from the changed files index. *) (** Read the files to compile from the changed files index. *)
let should_capture_file_from_index () = let should_capture_file_from_index () =
match DB.SourceFile.changed_files_set with match SourceFile.changed_files_set with
| None -> | None ->
(match Config.changed_files_index with (match Config.changed_files_index with
| Some index -> | Some index ->
Process.print_error_and_exit "Error reading the changed files index %s.\n%!" index Process.print_error_and_exit "Error reading the changed files index %s.\n%!" index
| None -> function _ -> true) | None -> function _ -> true)
| Some files_set -> | Some files_set ->
function source_file -> DB.SourceFile.Set.mem source_file files_set function source_file -> SourceFile.Set.mem source_file files_set
(** The buck targets are assumed to start with //, aliases are not supported. *) (** The buck targets are assumed to start with //, aliases are not supported. *)
let check_args_for_targets args = let check_args_for_targets args =
@ -90,7 +90,7 @@ let run_compilation_file compilation_database file =
(Some compilation_data.dir, wrapper_cmd, args, env) (Some compilation_data.dir, wrapper_cmd, args, env)
with Not_found -> with Not_found ->
Process.print_error_and_exit "Failed to find compilation data for %a \n%!" Process.print_error_and_exit "Failed to find compilation data for %a \n%!"
DB.SourceFile.pp file SourceFile.pp file
let run_compilation_database compilation_database should_capture_file = let run_compilation_database compilation_database should_capture_file =
let number_of_files = CompilationDatabase.get_size compilation_database in let number_of_files = CompilationDatabase.get_size compilation_database in
@ -99,7 +99,7 @@ let run_compilation_database compilation_database should_capture_file =
let jobs_stack = create_files_stack compilation_database should_capture_file in let jobs_stack = create_files_stack compilation_database should_capture_file in
let capture_text_upper = String.capitalize capture_text in let capture_text_upper = String.capitalize capture_text in
let job_to_string = let job_to_string =
fun file -> Format.asprintf "%s %a" capture_text_upper DB.SourceFile.pp file in fun file -> Format.asprintf "%s %a" capture_text_upper SourceFile.pp file in
Process.run_jobs_in_parallel jobs_stack (run_compilation_file compilation_database) job_to_string Process.run_jobs_in_parallel jobs_stack (run_compilation_file compilation_database) job_to_string
(** Computes the compilation database files. *) (** Computes the compilation database files. *)

@ -15,14 +15,14 @@ type compilation_data = {
args : string; args : string;
} }
type t = compilation_data DB.SourceFile.Map.t ref type t = compilation_data SourceFile.Map.t ref
let empty () = ref DB.SourceFile.Map.empty let empty () = ref SourceFile.Map.empty
let get_size database = DB.SourceFile.Map.cardinal !database let get_size database = SourceFile.Map.cardinal !database
let iter database f = DB.SourceFile.Map.iter f !database let iter database f = SourceFile.Map.iter f !database
let find database key = DB.SourceFile.Map.find key !database let find database key = SourceFile.Map.find key !database
let parse_command_and_arguments command_and_arguments = let parse_command_and_arguments command_and_arguments =
let regexp = Str.regexp "[^\\][ ]" in let regexp = Str.regexp "[^\\][ ]" in
@ -68,8 +68,8 @@ let decode_json_file (database : t) json_path =
| None -> exit_format_error () in | None -> exit_format_error () in
let command, args = parse_command_and_arguments cmd in let command, args = parse_command_and_arguments cmd in
let compilation_data = { dir; command; args;} in let compilation_data = { dir; command; args;} in
let source_file = DB.SourceFile.from_abs_path file in let source_file = SourceFile.from_abs_path file in
database := DB.SourceFile.Map.add source_file compilation_data !database database := SourceFile.Map.add source_file compilation_data !database
| _ -> exit_format_error () in | _ -> exit_format_error () in
parse_json json parse_json json

@ -21,9 +21,9 @@ val empty : unit -> t
val get_size : t -> int val get_size : t -> int
val iter : t -> (DB.SourceFile.t -> compilation_data -> unit) -> unit val iter : t -> (SourceFile.t -> compilation_data -> unit) -> unit
val find : t -> DB.SourceFile.t -> compilation_data val find : t -> SourceFile.t -> compilation_data
val decode_json_file : t -> string -> unit val decode_json_file : t -> string -> unit

@ -14,7 +14,7 @@ open Javalib_pack
let is_suppress_warnings_annotated = let is_suppress_warnings_annotated =
Inferconfig.suppress_warnings_matcher DB.SourceFile.empty Inferconfig.suppress_warnings_matcher SourceFile.empty
let suppress_warnings = let suppress_warnings =
({ Annot. ({ Annot.

@ -84,13 +84,13 @@ let append_path classpath path =
type file_entry = type file_entry =
| Singleton of DB.SourceFile.t | Singleton of SourceFile.t
| Duplicate of (string * DB.SourceFile.t) list | Duplicate of (string * SourceFile.t) list
(* Open the source file and search for the package declaration. (* Open the source file and search for the package declaration.
Only the case where the package is declared in a single line is supported *) Only the case where the package is declared in a single line is supported *)
let read_package_declaration source_file = let read_package_declaration source_file =
let path = DB.SourceFile.to_abs_path source_file in let path = SourceFile.to_abs_path source_file in
let file_in = open_in path in let file_in = open_in path in
let remove_trailing_semicolon = let remove_trailing_semicolon =
Str.replace_first (Str.regexp ";") "" in Str.replace_first (Str.regexp ";") "" in
@ -117,7 +117,7 @@ let add_source_file path map =
let basename = Filename.basename path in let basename = Filename.basename path in
let entry = let entry =
let current_source_file = let current_source_file =
DB.SourceFile.from_abs_path (convert_to_absolute path) in SourceFile.from_abs_path (convert_to_absolute path) in
try try
match StringMap.find basename map with match StringMap.find basename map with
| Singleton previous_source_file -> | Singleton previous_source_file ->

@ -29,8 +29,8 @@ val split_classpath : string -> string list
(** map entry for source files with potential basname collision within the same compiler call *) (** map entry for source files with potential basname collision within the same compiler call *)
type file_entry = type file_entry =
| Singleton of DB.SourceFile.t | Singleton of SourceFile.t
| Duplicate of (string * DB.SourceFile.t) list | Duplicate of (string * SourceFile.t) list
(** load the list of source files and the list of classes from the javac verbose file *) (** load the list of source files and the list of classes from the javac verbose file *)
val load_sources_and_classes : unit -> val load_sources_and_classes : unit ->

@ -35,7 +35,7 @@ type t =
if_jumps : int NodeTbl.t; if_jumps : int NodeTbl.t;
goto_jumps : (int, jump_kind) Hashtbl.t; goto_jumps : (int, jump_kind) Hashtbl.t;
cn : JBasics.class_name; cn : JBasics.class_name;
source_file : DB.SourceFile.t; source_file : SourceFile.t;
program : JClasspath.program; program : JClasspath.program;
} }

@ -43,7 +43,7 @@ type t = private
if_jumps : int NodeTbl.t; if_jumps : int NodeTbl.t;
goto_jumps : (int, jump_kind) Hashtbl.t; goto_jumps : (int, jump_kind) Hashtbl.t;
cn : JBasics.class_name; cn : JBasics.class_name;
source_file : DB.SourceFile.t; source_file : SourceFile.t;
program : JClasspath.program; program : JClasspath.program;
} }
@ -54,7 +54,7 @@ val create_context :
Procdesc.t -> Procdesc.t ->
JBir.t -> JBir.t ->
JBasics.class_name -> JBasics.class_name ->
DB.SourceFile.t -> SourceFile.t ->
JClasspath.program -> JClasspath.program ->
t t

@ -29,12 +29,12 @@ val compute_source_icfg :
Tenv.t -> Tenv.t ->
string -> string ->
string option -> string option ->
DB.SourceFile.t -> SourceFile.t ->
Cg.t * Cfg.cfg Cg.t * Cfg.cfg
(** Compute the CFG for a class *) (** Compute the CFG for a class *)
val compute_class_icfg : val compute_class_icfg :
DB.SourceFile.t -> SourceFile.t ->
Printer.LineReader.t -> Printer.LineReader.t ->
JClasspath.program -> JClasspath.program ->
Tenv.t -> Tenv.t ->

@ -28,7 +28,7 @@ let () =
let register_perf_stats_report source_file = let register_perf_stats_report source_file =
let stats_dir = Filename.concat Config.results_dir Config.frontend_stats_dir_name in let stats_dir = Filename.concat Config.results_dir Config.frontend_stats_dir_name in
let abbrev_source_file = DB.SourceFile.encoding source_file in let abbrev_source_file = SourceFile.encoding source_file in
let stats_file = Config.perf_stats_prefix ^ "_" ^ abbrev_source_file ^ ".json" in let stats_file = Config.perf_stats_prefix ^ "_" ^ abbrev_source_file ^ ".json" in
create_dir Config.results_dir ; create_dir Config.results_dir ;
create_dir stats_dir ; create_dir stats_dir ;
@ -65,7 +65,7 @@ let do_source_file
linereader classes program tenv linereader classes program tenv
source_basename package_opt source_file = source_basename package_opt source_file =
L.out_debug "\nfilename: %a (%s)@." L.out_debug "\nfilename: %a (%s)@."
DB.SourceFile.pp source_file source_basename; SourceFile.pp source_file source_basename;
let call_graph, cfg = let call_graph, cfg =
JFrontend.compute_source_icfg JFrontend.compute_source_icfg
linereader classes program tenv linereader classes program tenv
@ -81,7 +81,7 @@ let capture_libs linereader program tenv =
| Javalib.JClass _ -> | Javalib.JClass _ ->
begin begin
let fake_source_file = let fake_source_file =
DB.SourceFile.from_abs_path (JFrontend.path_of_cached_classname cn) in SourceFile.from_abs_path (JFrontend.path_of_cached_classname cn) in
init_global_state fake_source_file; init_global_state fake_source_file;
let call_graph, cfg = let call_graph, cfg =
JFrontend.compute_class_icfg fake_source_file linereader program tenv node in JFrontend.compute_class_icfg fake_source_file linereader program tenv node in
@ -126,7 +126,7 @@ let do_all_files classpath sources classes =
IList.exists IList.exists
(fun pattern -> Str.string_match (Str.regexp pattern) path 0) (fun pattern -> Str.string_match (Str.regexp pattern) path 0)
Config.skip_analysis_in_path in Config.skip_analysis_in_path in
is_path_matching (DB.SourceFile.to_rel_path source_file) is_path_matching (SourceFile.to_rel_path source_file)
|| Inferconfig.skip_translation_matcher source_file Procname.empty_block in || Inferconfig.skip_translation_matcher source_file Procname.empty_block in
let translate_source_file basename (package_opt, _) source_file = let translate_source_file basename (package_opt, _) source_file =
init_global_state source_file; init_global_state source_file;

@ -37,7 +37,7 @@ val create_native_procdesc :
(** [create_procdesc source_file program linereader icfg cm proc_name] creates (** [create_procdesc source_file program linereader icfg cm proc_name] creates
a procedure description for the concrete method cm and adds it to cfg *) a procedure description for the concrete method cm and adds it to cfg *)
val create_cm_procdesc : val create_cm_procdesc :
DB.SourceFile.t -> SourceFile.t ->
JClasspath.program -> JClasspath.program ->
Printer.LineReader.t -> Printer.LineReader.t ->
JContext.icfg -> JContext.icfg ->

@ -579,7 +579,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct
then then
begin begin
Ondemand.set_callbacks callbacks; Ondemand.set_callbacks callbacks;
analyze_ondemand DB.SourceFile.empty proc_desc; analyze_ondemand SourceFile.empty proc_desc;
Ondemand.unset_callbacks (); Ondemand.unset_callbacks ();
end end

Loading…
Cancel
Save