From 69b39dacb0cf9439db9b5e4311893dfd5ab404cb Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Thu, 8 Dec 2016 07:41:34 -0800 Subject: [PATCH] [DB] Create module for SourceFile Summary: Functions related to source files were already namespaced by `source_file_` prefix. Make separate module for them. In high level it replaces all `source_file_` with `SourceFile.` and then fixes all remaining compilation errors Reviewed By: jvillard Differential Revision: D4299053 fbshipit-source-id: 20b1d39 --- infer/src/IR/AttributesTable.re | 6 +- infer/src/IR/AttributesTable.rei | 2 +- infer/src/IR/Cfg.rei | 2 +- infer/src/IR/Cg.re | 6 +- infer/src/IR/Cg.rei | 6 +- infer/src/IR/Errlog.mli | 2 +- infer/src/IR/Exceptions.ml | 2 +- infer/src/IR/Io_infer.ml | 2 +- infer/src/IR/Io_infer.mli | 8 +- infer/src/IR/Location.re | 4 +- infer/src/IR/Location.rei | 2 +- infer/src/IR/ProcAttributes.re | 6 +- infer/src/IR/ProcAttributes.rei | 4 +- infer/src/IR/Pvar.re | 4 +- infer/src/IR/Pvar.rei | 4 +- infer/src/IR/Sil.re | 2 +- infer/src/backend/InferPrint.re | 22 +- infer/src/backend/dotty.ml | 6 +- infer/src/backend/dotty.mli | 2 +- infer/src/backend/exe_env.ml | 22 +- infer/src/backend/exe_env.mli | 4 +- infer/src/backend/inferconfig.ml | 20 +- infer/src/backend/inferconfig.mli | 8 +- infer/src/backend/interproc.ml | 2 +- infer/src/backend/ondemand.ml | 8 +- infer/src/backend/ondemand.mli | 2 +- infer/src/backend/printer.ml | 22 +- infer/src/backend/printer.mli | 12 +- infer/src/backend/specs.mli | 2 +- infer/src/base/DB.ml | 307 +++++++++--------- infer/src/base/DB.mli | 116 +++---- infer/src/checkers/BoundedCallTree.ml | 2 +- infer/src/checkers/Siof.ml | 8 +- infer/src/checkers/Stacktrace.ml | 2 +- infer/src/checkers/abstractInterpreter.ml | 2 +- infer/src/checkers/checkers.ml | 6 +- infer/src/checkers/repeatedCallsChecker.ml | 2 +- infer/src/clang/Capture.re | 8 +- infer/src/clang/ComponentKit.ml | 6 +- infer/src/clang/cFrontend.ml | 4 +- infer/src/clang/cFrontend_checkers_main.ml | 6 +- infer/src/clang/cFrontend_config.ml | 2 +- infer/src/clang/cFrontend_config.mli | 2 +- infer/src/clang/cFrontend_utils.ml | 4 +- infer/src/clang/cLocation.ml | 22 +- infer/src/clang/cTL.ml | 2 +- infer/src/clang/cTL.mli | 2 +- infer/src/eradicate/typeErr.ml | 2 +- .../integration/CaptureCompilationDatabase.ml | 8 +- infer/src/integration/CompilationDatabase.ml | 14 +- infer/src/integration/CompilationDatabase.mli | 4 +- infer/src/java/jAnnotation.ml | 2 +- infer/src/java/jClasspath.ml | 8 +- infer/src/java/jClasspath.mli | 4 +- infer/src/java/jContext.ml | 2 +- infer/src/java/jContext.mli | 4 +- infer/src/java/jFrontend.mli | 4 +- infer/src/java/jMain.ml | 8 +- infer/src/java/jTrans.mli | 2 +- infer/src/quandary/TaintAnalysis.ml | 2 +- 60 files changed, 384 insertions(+), 377 deletions(-) diff --git a/infer/src/IR/AttributesTable.re b/infer/src/IR/AttributesTable.re index 43678cc30..b34717be3 100644 --- a/infer/src/IR/AttributesTable.re +++ b/infer/src/IR/AttributesTable.re @@ -77,7 +77,7 @@ let store_attributes (proc_attributes: ProcAttributes.t) => { | Some proc_attributes_on_disk => let higher_rank_than_on_disk () => proc_attributes.is_defined && - DB.compare_source_file proc_attributes.loc.file proc_attributes_on_disk.loc.file > 0; + DB.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; /* Only overwrite the attribute file if the procedure becomes defined 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 */ let pname_is_cpp_model callee_pname => switch (load_attributes callee_pname) { - | Some attrs => DB.source_file_is_cpp_model attrs.ProcAttributes.loc.Location.file + | Some attrs => DB.SourceFile.is_cpp_model attrs.ProcAttributes.loc.Location.file | None => false }; @@ -217,7 +217,7 @@ let find_file_capturing_procedure pname => let origin = /* Procedure coming from include files if it has different location than the file where it was captured. */ - DB.compare_source_file source_file proc_attributes.ProcAttributes.loc.file != 0 ? + DB.SourceFile.compare source_file proc_attributes.ProcAttributes.loc.file != 0 ? `Include : `Source; 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); diff --git a/infer/src/IR/AttributesTable.rei b/infer/src/IR/AttributesTable.rei index 371ca4288..9e945d974 100644 --- a/infer/src/IR/AttributesTable.rei +++ b/infer/src/IR/AttributesTable.rei @@ -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. Return also a boolean indicating whether the procedure is defined in an include file. */ -let find_file_capturing_procedure: Procname.t => option (DB.source_file, [ | `Include | `Source]); +let find_file_capturing_procedure: Procname.t => option (DB.SourceFile.t, [ | `Include | `Source]); let is_whitelisted_cpp_method: string => bool; diff --git a/infer/src/IR/Cfg.rei b/infer/src/IR/Cfg.rei index f2f7712e8..7ea3305c5 100644 --- a/infer/src/IR/Cfg.rei +++ b/infer/src/IR/Cfg.rei @@ -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 */ -let store_cfg_to_file: source_file::DB.source_file => DB.filename => cfg => unit; +let store_cfg_to_file: source_file::DB.SourceFile.t => DB.filename => cfg => unit; /** {2 Functions for manipulating an interprocedural CFG} */ diff --git a/infer/src/IR/Cg.re b/infer/src/IR/Cg.re index c43189c5f..d7318b94a 100644 --- a/infer/src/IR/Cg.re +++ b/infer/src/IR/Cg.re @@ -43,14 +43,14 @@ type node_info = { /** Type for call graph */ type t = { - source: DB.source_file, /** path for the source file */ + source: DB.SourceFile.t, /** path for the source file */ node_map: Procname.Hash.t node_info /** map from node to node_info */ }; let create source_opt => { let source = switch source_opt { - | None => DB.source_file_empty + | None => DB.SourceFile.empty | Some source => source }; {source, node_map: Procname.Hash.create 3} @@ -350,7 +350,7 @@ let extend cg_old cg_new => { /** Begin support for serialization */ -let callgraph_serializer: Serialization.serializer (DB.source_file, nodes_and_edges) = Serialization.create_serializer Serialization.cg_key; +let callgraph_serializer: Serialization.serializer (DB.SourceFile.t, nodes_and_edges) = Serialization.create_serializer Serialization.cg_key; /** Load a call graph from a file */ diff --git a/infer/src/IR/Cg.rei b/infer/src/IR/Cg.rei index 4f7d9c3fe..a530a04a5 100644 --- a/infer/src/IR/Cg.rei +++ b/infer/src/IR/Cg.rei @@ -43,7 +43,7 @@ let calls_recursively: t => Procname.t => Procname.t => bool; /** Create an empty call graph */ -let create: option DB.source_file => t; +let create: option DB.SourceFile.t => t; /** [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 */ -let get_source: t => DB.source_file; +let get_source: t => DB.SourceFile.t; /** 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. */ -let save_call_graph_dotty: DB.source_file => (Procname.t => list 'a) => t => unit; +let save_call_graph_dotty: DB.SourceFile.t => (Procname.t => list 'a) => t => unit; /** Save a call graph into a file */ diff --git a/infer/src/IR/Errlog.mli b/infer/src/IR/Errlog.mli index 0d6d439bb..41948fc33 100644 --- a/infer/src/IR/Errlog.mli +++ b/infer/src/IR/Errlog.mli @@ -54,7 +54,7 @@ val pp_errors : Format.formatter -> t -> unit val pp_warnings : Format.formatter -> t -> unit (** Print an error log in html format *) -val pp_html : DB.source_file -> DB.Results_dir.path -> Format.formatter -> t -> unit +val pp_html : DB.SourceFile.t -> DB.Results_dir.path -> Format.formatter -> t -> unit (** Return the number of elements in the error log which satisfy the filter. *) val size : (Exceptions.err_kind -> bool -> bool) -> t -> int diff --git a/infer/src/IR/Exceptions.ml b/infer/src/IR/Exceptions.ml index 5297ab791..a23c359c6 100644 --- a/infer/src/IR/Exceptions.ml +++ b/infer/src/IR/Exceptions.ml @@ -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 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" - DB.source_file_pp loc.Location.file + DB.SourceFile.pp loc.Location.file loc.Location.line kind Localise.pp ex_name diff --git a/infer/src/IR/Io_infer.ml b/infer/src/IR/Io_infer.ml index ef6ba48b9..056025e80 100644 --- a/infer/src/IR/Io_infer.ml +++ b/infer/src/IR/Io_infer.ml @@ -223,7 +223,7 @@ struct (** 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 fname = DB.source_file_encoding source in + let fname = DB.SourceFile.encoding source in let linenum_str = string_of_int linenum in let name = "LINE" ^ linenum_str in pp_link diff --git a/infer/src/IR/Io_infer.mli b/infer/src/IR/Io_infer.mli index 747fa7ade..6696d0668 100644 --- a/infer/src/IR/Io_infer.mli +++ b/infer/src/IR/Io_infer.mli @@ -21,18 +21,18 @@ module Html : sig 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 *) - val modified_during_analysis : DB.source_file -> DB.Results_dir.path -> bool + val modified_during_analysis : DB.SourceFile.t -> DB.Results_dir.path -> bool (** File name for the node, given the procedure name and node id *) val node_filename : Procname.t -> int -> string (** Open an Html file to append data *) - val open_out : DB.source_file -> DB.Results_dir.path -> Unix.file_descr * Format.formatter + val open_out : DB.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 *) val pp_line_link : ?with_name: bool -> ?text: (string option) -> - DB.source_file -> DB.Results_dir.path -> Format.formatter -> int -> unit + DB.SourceFile.t -> DB.Results_dir.path -> Format.formatter -> int -> unit (** Print a horizontal line *) val pp_hline : Format.formatter -> unit -> unit @@ -55,7 +55,7 @@ module Html : sig (** Print an html link given node id and session *) val pp_session_link : - ?with_name: bool -> DB.source_file -> string list -> Format.formatter -> int * int * int -> unit + ?with_name: bool -> DB.SourceFile.t -> string list -> Format.formatter -> int * int * int -> unit (** Print start color *) val pp_start_color : Format.formatter -> color -> unit diff --git a/infer/src/IR/Location.re b/infer/src/IR/Location.re index 1bc9bc4cb..78c80d767 100644 --- a/infer/src/IR/Location.re +++ b/infer/src/IR/Location.re @@ -17,7 +17,7 @@ let module L = Logging; type t = { line: int, /** The line number. -1 means "do not know" */ col: int, /** The column number. -1 means "do not know" */ - file: DB.source_file /** The name of the source file */ + file: DB.SourceFile.t /** The name of the source file */ } [@@deriving compare]; @@ -29,7 +29,7 @@ let d (loc: t) => L.add_print_action (L.PTloc, Obj.repr loc); /** Dummy location */ -let dummy = {line: (-1), col: (-1), file: DB.source_file_empty}; +let dummy = {line: (-1), col: (-1), file: DB.SourceFile.empty}; /** Pretty print a location */ diff --git a/infer/src/IR/Location.rei b/infer/src/IR/Location.rei index 12a996ea4..77dcea89b 100644 --- a/infer/src/IR/Location.rei +++ b/infer/src/IR/Location.rei @@ -13,7 +13,7 @@ open! Utils; type t = { line: int, /** The line number. -1 means "do not know" */ col: int, /** The column number. -1 means "do not know" */ - file: DB.source_file /** The name of the source file */ + file: DB.SourceFile.t /** The name of the source file */ } [@@deriving compare]; diff --git a/infer/src/IR/ProcAttributes.re b/infer/src/IR/ProcAttributes.re index 3ef7afbd0..0343304fe 100644 --- a/infer/src/IR/ProcAttributes.re +++ b/infer/src/IR/ProcAttributes.re @@ -40,14 +40,14 @@ type t = { is_synthetic_method: bool, /** the procedure is a synthetic method */ language: Config.language, /** language of the procedure */ loc: Location.t, /** location of this procedure in the source code */ - translation_unit: option DB.source_file, /** translation unit to which the procedure belongs */ + translation_unit: option DB.SourceFile.t, /** translation unit to which the procedure belongs */ mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */ method_annotation: Annot.Method.t, /** annotations for java methods */ objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */ proc_flags: proc_flags, /** flags of the procedure */ proc_name: Procname.t, /** name of the procedure */ ret_type: Typ.t, /** return type */ - source_file_captured: DB.source_file /** source file where the procedure was captured */ + source_file_captured: DB.SourceFile.t /** source file where the procedure was captured */ } [@@deriving compare]; @@ -77,5 +77,5 @@ let default proc_name language => { proc_flags: proc_flags_empty (), proc_name, ret_type: Typ.Tvoid, - source_file_captured: DB.source_file_empty + source_file_captured: DB.SourceFile.empty }; diff --git a/infer/src/IR/ProcAttributes.rei b/infer/src/IR/ProcAttributes.rei index 16a56fa6a..4ea9f7373 100644 --- a/infer/src/IR/ProcAttributes.rei +++ b/infer/src/IR/ProcAttributes.rei @@ -34,14 +34,14 @@ type t = { is_synthetic_method: bool, /** the procedure is a synthetic method */ language: Config.language, /** language of the procedure */ loc: Location.t, /** location of this procedure in the source code */ - translation_unit: option DB.source_file, /** translation unit to which the procedure belongs */ + translation_unit: option DB.SourceFile.t, /** translation unit to which the procedure belongs */ mutable locals: list (Mangled.t, Typ.t), /** name and type of local variables */ method_annotation: Annot.Method.t, /** annotations for java methods */ objc_accessor: option objc_accessor_type, /** type of ObjC accessor, if any */ proc_flags: proc_flags, /** flags of the procedure */ proc_name: Procname.t, /** name of the procedure */ ret_type: Typ.t, /** return type */ - source_file_captured: DB.source_file /** source file where the procedure was captured */ + source_file_captured: DB.SourceFile.t /** source file where the procedure was captured */ } [@@deriving compare]; diff --git a/infer/src/IR/Pvar.re b/infer/src/IR/Pvar.re index c3a796dc5..976169e9c 100644 --- a/infer/src/IR/Pvar.re +++ b/infer/src/IR/Pvar.re @@ -26,7 +26,7 @@ type pvar_kind = | Abduced_retvar Procname.t Location.t /** synthetic variable to represent return value */ | Abduced_ref_param Procname.t t Location.t /** synthetic variable to represent param passed by reference */ - | Global_var (DB.source_file, bool, bool, bool) + | Global_var (DB.SourceFile.t, bool, bool, bool) /** global variable: translation unit + is it compile constant? + is it POD? + is it a static local? */ | Seed_var /** variable used to store the initial value of formal parameters */ @@ -70,7 +70,7 @@ let rec _pp f pv => { F.fprintf f "#GB<%a%s%s>$%a" - DB.source_file_pp + DB.SourceFile.pp fname (if is_const {"|const"} else {""}) ( diff --git a/infer/src/IR/Pvar.rei b/infer/src/IR/Pvar.rei index 58e43a1ec..97d870faf 100644 --- a/infer/src/IR/Pvar.rei +++ b/infer/src/IR/Pvar.rei @@ -113,7 +113,7 @@ let mk_global: is_pod::bool? => is_static_local::bool? => Mangled.t => - DB.source_file => + DB.SourceFile.t => t; @@ -146,7 +146,7 @@ let to_string: t => string; /** Get the source file corresponding to a global, if known. Returns [None] if not a global. */ -let get_source_file: t => option DB.source_file; +let get_source_file: t => option DB.SourceFile.t; /** Is the variable's value a compile-time constant? Always (potentially incorrectly) returns diff --git a/infer/src/IR/Sil.re b/infer/src/IR/Sil.re index aeee8f040..652faf37a 100644 --- a/infer/src/IR/Sil.re +++ b/infer/src/IR/Sil.re @@ -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) }; -let custom_error = Pvar.mk_global (Mangled.from_string "INFER_CUSTOM_ERROR") DB.source_file_empty; +let custom_error = Pvar.mk_global (Mangled.from_string "INFER_CUSTOM_ERROR") DB.SourceFile.empty; diff --git a/infer/src/backend/InferPrint.re b/infer/src/backend/InferPrint.re index 1cb375d82..5bd8773df 100644 --- a/infer/src/backend/InferPrint.re +++ b/infer/src/backend/InferPrint.re @@ -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; let trace_item_to_record trace_item => { Jsonbug_j.level: trace_item.Errlog.lt_level, - filename: DB.source_file_to_string trace_item.Errlog.lt_loc.Location.file, + filename: DB.SourceFile.to_string trace_item.Errlog.lt_loc.Location.file, line_number: trace_item.Errlog.lt_loc.Location.line, description: trace_item.Errlog.lt_description, node_tags: node_tags_to_records trace_item.Errlog.lt_node_tags @@ -193,7 +193,7 @@ let summary_values top_proc_set summary => { verr: Errlog.size (fun ekind in_footprint => ekind == Exceptions.Kerror && in_footprint) err_log, vflags: attributes.ProcAttributes.proc_flags, - vfile: DB.source_file_to_string attributes.ProcAttributes.loc.Location.file, + vfile: DB.SourceFile.to_string attributes.ProcAttributes.loc.Location.file, vline: attributes.ProcAttributes.loc.Location.line, vtop: if is_top {"Y"} else {"N"}, vsignature: signature, @@ -435,7 +435,7 @@ let module IssuesCsv = { let kind = Exceptions.err_kind_string ekind; let type_str = Localise.to_string error_name; let procedure_id = Procname.to_filename procname; - let filename = DB.source_file_to_string source_file; + let filename = DB.SourceFile.to_string source_file; let always_report = switch (Localise.error_desc_extract_tag_value error_desc "always_report") { | "" => "false" @@ -491,7 +491,7 @@ let module IssuesJson = { | None => (loc.Location.file, 0) }; let should_report_source_file = - not (DB.source_file_is_infer_model source_file) || + not (DB.SourceFile.is_infer_model source_file) || Config.debug_mode || Config.debug_exceptions; if ( in_footprint && @@ -501,7 +501,7 @@ let module IssuesJson = { let kind = Exceptions.err_kind_string ekind; let bug_type = Localise.to_string error_name; let procedure_id = Procname.to_filename procname; - let file = DB.source_file_to_string source_file; + let file = DB.SourceFile.to_string source_file; let json_ml_loc = switch ml_loc_opt { | Some (file, lnum, cnum, enum) when Config.reports_include_ml_loc => @@ -629,7 +629,7 @@ let module IssuesXml = { [("num", string_of_int !num)] [ level_to_xml lt.Errlog.lt_level, - file_to_xml (DB.source_file_to_string loc.Location.file), + file_to_xml (DB.SourceFile.to_string loc.Location.file), line_to_xml loc.Location.line, code_to_xml code, description_to_xml lt.Errlog.lt_description, @@ -660,7 +660,7 @@ let module IssuesXml = { let error_line = string_of_int loc.Location.line; let procedure_name = Procname.to_string proc_name; let procedure_id = Procname.to_filename proc_name; - let filename = DB.source_file_to_string source_file; + let filename = DB.SourceFile.to_string source_file; let bug_hash = get_bug_hash kind type_str procedure_id filename node_key error_desc; let forest = [ subtree Io_infer.Xml.tag_class error_class, @@ -706,7 +706,7 @@ let module CallsCsv = { pp "\"%s\"," (Escape.escape_csv (Procname.to_string callee_name)); pp "\"%s\"," (Escape.escape_csv (Procname.to_filename callee_name)); pp - "%s," (DB.source_file_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 "%a@\n" Specs.CallStats.pp_trace trace }; @@ -740,7 +740,7 @@ let module TopProcedures: { let module Stats = { type t = { - files: Hashtbl.t DB.source_file unit, + files: Hashtbl.t DB.SourceFile.t unit, mutable nchecked: int, mutable ndefective: int, mutable nerrors: int, @@ -817,7 +817,7 @@ let module Stats = { let error_strs = { let pp1 fmt () => F.fprintf fmt "%d: %s" stats.nerrors type_str; let pp2 fmt () => - F.fprintf fmt " %a:%d" DB.source_file_pp loc.Location.file loc.Location.line; + F.fprintf fmt " %a:%d" DB.SourceFile.pp loc.Location.file loc.Location.line; 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 ()] }; @@ -1245,7 +1245,7 @@ let module AnalysisResults = { apply_without_gc (IList.iter load_file) (spec_files_from_cmdline ()); let summ_cmp (_, summ1) (_, summ2) => { let n = - DB.compare_source_file + DB.SourceFile.compare summ1.Specs.attributes.ProcAttributes.loc.Location.file summ2.Specs.attributes.ProcAttributes.loc.Location.file; if (n != 0) { diff --git a/infer/src/backend/dotty.ml b/infer/src/backend/dotty.ml index 5cb59d2de..e3e4854cb 100644 --- a/infer/src/backend/dotty.ml +++ b/infer/src/backend/dotty.ml @@ -1017,7 +1017,7 @@ let pp_cfgnode pdesc fmt (n: Procdesc.Node.t) = let print_icfg source fmt cfg = let print_node pdesc node = let loc = Procdesc.Node.get_loc node in - if (Config.dotty_cfg_libs || DB.equal_source_file loc.Location.file source) then + if (Config.dotty_cfg_libs || DB.SourceFile.equal loc.Location.file source) then F.fprintf fmt "%a\n" (pp_cfgnode pdesc) node in 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 | Some file -> file | None when Config.frontend_tests = true -> - (DB.source_file_to_abs_path source) ^ ".test.dot" + (DB.SourceFile.to_abs_path source) ^ ".test.dot" | None -> DB.filename_to_string (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_signature = Io_infer.Xml.create_tree "signature" [("name", signature)] [] in let proc_summary = Io_infer.Xml.create_tree "procedure" - [("file", DB.source_file_to_string loc.Location.file); + [("file", DB.SourceFile.to_string loc.Location.file); ("line", string_of_int loc.Location.line)] [xml_signature; xml_specifications] in Io_infer.Xml.pp_document true fmt proc_summary diff --git a/infer/src/backend/dotty.mli b/infer/src/backend/dotty.mli index 502f9e880..9201ac6ab 100644 --- a/infer/src/backend/dotty.mli +++ b/infer/src/backend/dotty.mli @@ -34,7 +34,7 @@ val pp_proplist_parsed2dotty_file : string -> Prop.normal Prop.t list -> unit (** {2 Contol-Flow Graph} *) (** Print the cfg *) -val print_icfg_dotty : DB.source_file -> Cfg.cfg -> unit +val print_icfg_dotty : DB.SourceFile.t -> Cfg.cfg -> unit (** {2 Specs} *) val reset_dotty_spec_counter : unit -> unit diff --git a/infer/src/backend/exe_env.ml b/infer/src/backend/exe_env.ml index cb12296f3..eddc77528 100644 --- a/infer/src/backend/exe_env.ml +++ b/infer/src/backend/exe_env.ml @@ -16,7 +16,7 @@ module L = Logging (** per-file data: type environment and cfg *) type file_data = - { source: DB.source_file; + { source: DB.SourceFile.t; tenv_file: DB.filename; mutable tenv: Tenv.t option; cfg_file: DB.filename; @@ -64,7 +64,7 @@ type t = { cg: Cg.t; (** global call graph *) 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 *) - mutable source_files : DB.SourceFileSet.t; (** Source files in the execution environment *) + mutable source_files : DB.SourceFile.Set.t; (** Source files in the execution environment *) } (** initial state, used to add cg's *) @@ -78,7 +78,7 @@ let create () = { cg = Cg.create None; proc_map = Procname.Hash.create 17; file_map = FilenameHash.create 1; - source_files = DB.SourceFileSet.empty; + source_files = DB.SourceFile.Set.empty; } (** 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) | Some cg -> let source = Cg.get_source cg in - exe_env.source_files <- DB.SourceFileSet.add source exe_env.source_files; + exe_env.source_files <- DB.SourceFile.Set.add source exe_env.source_files; let defined_procs = Cg.get_defined_nodes cg in IList.iter @@ -99,14 +99,14 @@ let add_cg (exe_env: t) (source_dir : DB.source_dir) = | None -> () | Some (source_captured, origin) -> - let multiply_defined = DB.compare_source_file source source_captured <> 0 in + let multiply_defined = DB.SourceFile.compare source source_captured <> 0 in if multiply_defined then Cg.remove_node_defined cg pname; if Config.check_duplicate_symbols && multiply_defined && origin <> `Include then L.stderr "@.DUPLICATE_SYMBOLS source: %a source_captured:%a pname:%a@." - DB.source_file_pp source - DB.source_file_pp source_captured + DB.SourceFile.pp source + DB.SourceFile.pp source_captured Procname.pp pname )) defined_procs; @@ -190,13 +190,13 @@ let get_proc_desc exe_env pname = let iter_files f exe_env = let do_file _ file_data seen_files_acc = let fname = file_data.source in - if DB.SourceFileSet.mem fname seen_files_acc || + if DB.SourceFile.Set.mem fname seen_files_acc || (* only files added with add_cg* functions *) - not (DB.SourceFileSet.mem fname exe_env.source_files) + not (DB.SourceFile.Set.mem fname exe_env.source_files) then seen_files_acc else begin Option.may (fun cfg -> f fname cfg) (file_data_to_cfg file_data); - DB.SourceFileSet.add fname seen_files_acc + DB.SourceFile.Set.add fname seen_files_acc end in - ignore (Procname.Hash.fold do_file exe_env.proc_map DB.SourceFileSet.empty) + ignore (Procname.Hash.fold do_file exe_env.proc_map DB.SourceFile.Set.empty) diff --git a/infer/src/backend/exe_env.mli b/infer/src/backend/exe_env.mli index 13c4c3582..cbc851291 100644 --- a/infer/src/backend/exe_env.mli +++ b/infer/src/backend/exe_env.mli @@ -32,7 +32,7 @@ val add_cg : initial -> DB.source_dir -> unit val get_cg : t -> Cg.t (** return the source file associated to the procedure *) -val get_source : t -> Procname.t -> DB.source_file option +val get_source : t -> Procname.t -> DB.SourceFile.t option (** return the type environment associated to the procedure *) 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 (** [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.source_file -> Cfg.cfg -> unit) -> t -> unit +val iter_files : (DB.SourceFile.t -> Cfg.cfg -> unit) -> t -> unit diff --git a/infer/src/backend/inferconfig.ml b/infer/src/backend/inferconfig.ml index a38b7a5f4..11d2bedbf 100644 --- a/infer/src/backend/inferconfig.ml +++ b/infer/src/backend/inferconfig.ml @@ -11,7 +11,7 @@ open! Utils module L = Logging -type path_filter = DB.source_file -> bool +type path_filter = DB.SourceFile.t -> bool type error_filter = Localise.t -> bool type proc_filter = Procname.t -> bool @@ -43,7 +43,7 @@ type filter_config = let is_matching patterns = fun source_file -> - let path = DB.source_file_to_rel_path source_file in + let path = DB.SourceFile.to_rel_path source_file in IList.exists (fun pattern -> 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 FileContainsStringMatcher = struct - type matcher = DB.source_file -> bool + type matcher = DB.SourceFile.t -> bool let default_matcher : matcher = fun _ -> false @@ -77,18 +77,18 @@ module FileContainsStringMatcher = struct if s_patterns = [] then default_matcher else - let source_map = ref DB.SourceFileMap.empty in + let source_map = ref DB.SourceFile.Map.empty in let regexp = Str.regexp (join_strings "\\|" s_patterns) in fun source_file -> try - DB.SourceFileMap.find source_file !source_map + DB.SourceFile.Map.find source_file !source_map with Not_found -> try - let file_in = open_in (DB.source_file_to_abs_path source_file) in + let file_in = open_in (DB.SourceFile.to_abs_path source_file) in let pattern_found = file_contains regexp file_in in close_in file_in; - source_map := DB.SourceFileMap.add source_file pattern_found !source_map; + source_map := DB.SourceFile.Map.add source_file pattern_found !source_map; pattern_found with Sys_error _ -> false end @@ -96,7 +96,7 @@ end (* Module to create matcher based on source file names or class names and method names *) module FileOrProcMatcher = struct - type matcher = DB.source_file -> Procname.t -> bool + type matcher = DB.SourceFile.t -> Procname.t -> bool let default_matcher : matcher = fun _ _ -> false @@ -262,11 +262,11 @@ let test () = directory_iter (fun path -> if DB.is_source_file path then - let source_file = DB.source_file_from_abs_path path in + let source_file = DB.SourceFile.from_abs_path path in let matching = matching_analyzers source_file in if matching <> [] then let matching_s = join_strings ", " (IList.map fst matching) in L.stderr "%s -> {%s}@." - (DB.source_file_to_rel_path source_file) + (DB.SourceFile.to_rel_path source_file) matching_s) (Sys.getcwd ()) diff --git a/infer/src/backend/inferconfig.mli b/infer/src/backend/inferconfig.mli index 2b7e20a86..311d154c2 100644 --- a/infer/src/backend/inferconfig.mli +++ b/infer/src/backend/inferconfig.mli @@ -10,7 +10,7 @@ open! Utils (** Filter type for a source file *) -type path_filter = DB.source_file -> bool +type path_filter = DB.SourceFile.t -> bool (** Filter type for an error name. *) type error_filter = Localise.t -> bool @@ -31,9 +31,9 @@ val do_not_filter : filters (** Create filters based on the config file *) val create_filters : Config.analyzer -> filters -val never_return_null_matcher : DB.source_file -> Procname.t -> bool -val suppress_warnings_matcher : DB.source_file -> Procname.t -> bool -val skip_translation_matcher : DB.source_file -> Procname.t -> bool +val never_return_null_matcher : DB.SourceFile.t -> Procname.t -> bool +val suppress_warnings_matcher : DB.SourceFile.t -> Procname.t -> bool +val skip_translation_matcher : DB.SourceFile.t -> Procname.t -> bool val modeled_expensive_matcher : (string -> bool) -> Procname.t -> bool (** Load the config file and list the files to report on *) diff --git a/infer/src/backend/interproc.ml b/infer/src/backend/interproc.ml index 82411cd1a..d9d8693a8 100644 --- a/infer/src/backend/interproc.ml +++ b/infer/src/backend/interproc.ml @@ -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 "@\n++++++++++++++++++++++++++++++++++++++++++++++++++@\n"; F.fprintf fmt "+ FILE: %a VISITED: %d/%d SYMOPS: %d@\n" - DB.source_file_pp source + DB.SourceFile.pp source (IList.length nodes_visited) (IList.length nodes_total) !tot_symops; diff --git a/infer/src/backend/ondemand.ml b/infer/src/backend/ondemand.ml index 886f89375..f063a4610 100644 --- a/infer/src/backend/ondemand.ml +++ b/infer/src/backend/ondemand.ml @@ -17,15 +17,15 @@ module F = Format (** Directories to analyze from the ondemand file. *) let dirs_to_analyze = let process_changed_files changed_files = - DB.SourceFileSet.fold + DB.SourceFile.Set.fold (fun source_file source_dir_set -> let source_dir = DB.source_dir_from_source_file source_file in StringSet.add (DB.source_dir_to_string source_dir) source_dir_set ) changed_files StringSet.empty in - Option.map process_changed_files DB.changed_source_files_set + Option.map process_changed_files DB.SourceFile.changed_files_set -type analyze_ondemand = DB.source_file -> Procdesc.t -> unit +type analyze_ondemand = DB.SourceFile.t -> Procdesc.t -> unit 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) ^" not equal to "^(Procname.to_string attribute_pname)); attributes.loc.file) - DB.source_file_empty + DB.SourceFile.empty attributes_opt in let call_graph = let cg = Cg.create (Some source) in diff --git a/infer/src/backend/ondemand.mli b/infer/src/backend/ondemand.mli index 8b39f41a7..c0ab240fb 100644 --- a/infer/src/backend/ondemand.mli +++ b/infer/src/backend/ondemand.mli @@ -14,7 +14,7 @@ open! Utils (** Optional set of source dirs to analyze in on-demand mode. *) val dirs_to_analyze : StringSet.t option -type analyze_ondemand = DB.source_file -> Procdesc.t -> unit +type analyze_ondemand = DB.SourceFile.t -> Procdesc.t -> unit type get_proc_desc = Procname.t -> Procdesc.t option diff --git a/infer/src/backend/printer.ml b/infer/src/backend/printer.ml index b79c52355..8d48be6c3 100644 --- a/infer/src/backend/printer.ml +++ b/infer/src/backend/printer.ml @@ -20,7 +20,7 @@ module F = Format module LineReader = struct (** Map a file name to an array of string, one for each line in the file. *) - type t = (DB.source_file, string array) Hashtbl.t + type t = (DB.SourceFile.t, string array) Hashtbl.t let create () = Hashtbl.create 1 @@ -48,7 +48,7 @@ struct Some (Hashtbl.find hash fname) with Not_found -> try - let lines_arr = read_file (DB.source_file_to_abs_path fname) in + let lines_arr = read_file (DB.SourceFile.to_abs_path fname) in Hashtbl.add hash fname lines_arr; Some lines_arr with exn when SymOp.exn_not_failure exn -> None @@ -98,8 +98,8 @@ module NodesHtml : sig val start_node : int -> Location.t -> Procname.t -> Procdesc.Node.t list -> Procdesc.Node.t list -> Procdesc.Node.t list -> - DB.source_file -> bool - val finish_node : Procname.t -> int -> DB.source_file -> unit + DB.SourceFile.t -> bool + val finish_node : Procname.t -> int -> DB.SourceFile.t -> unit end = struct 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 process_proc = Procdesc.is_defined proc_desc && - DB.equal_source_file proc_loc.Location.file source && + DB.SourceFile.equal proc_loc.Location.file source && match AttributesTable.find_file_capturing_procedure proc_name with | None -> true | Some (source_captured, _) -> - DB.equal_source_file source_captured (Procdesc.get_loc proc_desc).file in + DB.SourceFile.equal source_captured (Procdesc.get_loc proc_desc).file in if process_proc then begin 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. *) let write_html_file linereader filename procs = - let fname_encoding = DB.source_file_encoding filename in + let fname_encoding = DB.SourceFile.encoding filename in let (fd, fmt) = Io_infer.Html.create (DB.Results_dir.Abs_source_dir filename) [".."; fname_encoding] in let pp_prelude () = F.fprintf fmt "

File %a

\n\n" - DB.source_file_pp filename in + DB.SourceFile.pp filename in let print_one_line proof_cover table_nodes_at_linenum table_err_per_line line_number = let line_html = 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 (fun _ cfg -> let source_files_in_cfg = - let files = ref DB.SourceFileSet.empty in + let files = ref DB.SourceFile.Set.empty in Cfg.iter_proc_desc cfg (fun _ proc_desc -> if Procdesc.is_defined proc_desc then let file = (Procdesc.get_loc proc_desc).Location.file in - files := DB.SourceFileSet.add file !files); + files := DB.SourceFile.Set.add file !files); !files in - DB.SourceFileSet.iter + DB.SourceFile.Set.iter (fun file -> write_html_file linereader file (Cfg.get_all_procs cfg)) source_files_in_cfg) diff --git a/infer/src/backend/printer.mli b/infer/src/backend/printer.mli index a2d20ee4d..0efd51072 100644 --- a/infer/src/backend/printer.mli +++ b/infer/src/backend/printer.mli @@ -21,10 +21,10 @@ module LineReader : sig val create : unit -> t (** get the line from a source file and line number *) - val from_file_linenum_original : t -> DB.source_file -> int -> string option + val from_file_linenum_original : t -> DB.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 *) - val from_file_linenum : t -> DB.source_file -> int -> string option + val from_file_linenum : t -> DB.SourceFile.t -> int -> string option (** 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 @@ -37,20 +37,20 @@ val curr_html_formatter : Format.formatter ref val force_delayed_prints : unit -> unit (** Finish a session, and perform delayed print actions if required *) -val node_finish_session : Procdesc.Node.t -> DB.source_file -> unit +val node_finish_session : Procdesc.Node.t -> DB.SourceFile.t -> unit (** Return true if the node was visited during footprint and during re-execution *) 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 *) val node_start_session : - Procdesc.Node.t -> Location.t -> Procname.t -> int -> DB.source_file -> unit + Procdesc.Node.t -> Location.t -> Procname.t -> int -> DB.SourceFile.t -> unit (** Write html file for the procedure. The boolean indicates whether to print whole seconds only. *) -val write_proc_html : DB.source_file -> bool -> Procdesc.t -> unit +val write_proc_html : DB.SourceFile.t -> bool -> Procdesc.t -> unit -val write_html_file : LineReader.t -> DB.source_file -> Procdesc.t list -> unit +val write_html_file : LineReader.t -> DB.SourceFile.t -> Procdesc.t list -> unit (** Create filename.ext.html for each file in the exe_env. *) val write_all_html_files : Exe_env.t -> unit diff --git a/infer/src/backend/specs.mli b/infer/src/backend/specs.mli index fb460fb57..cb9aad531 100644 --- a/infer/src/backend/specs.mli +++ b/infer/src/backend/specs.mli @@ -242,7 +242,7 @@ val pp_specs : printenv -> Format.formatter -> Prop.normal spec list -> unit (** Print the summary in html format *) val pp_summary_html : - whole_seconds:bool -> DB.source_file -> color -> Format.formatter -> summary -> unit + whole_seconds:bool -> DB.SourceFile.t -> color -> Format.formatter -> summary -> unit (** Print the summary in latext format *) val pp_summary_latex : whole_seconds:bool -> color -> Format.formatter -> summary -> unit diff --git a/infer/src/base/DB.ml b/infer/src/base/DB.ml index 2f61734ec..a4f47ddd9 100644 --- a/infer/src/base/DB.ml +++ b/infer/src/base/DB.ml @@ -17,157 +17,162 @@ module L = Logging (** {2 Source Files} *) -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 source_file = - | Absolute of string - | RelativeProjectRoot of string (* relative to project root *) - | RelativeInferModel of string (* relative to infer models *) -[@@deriving compare] - -let equal_source_file sf1 sf2 = - compare_source_file sf1 sf2 = 0 - -module OrderedSourceFile = -struct - type t = source_file [@@deriving compare] -end +module SourceFile = struct -module SourceFileMap = Map.Make(OrderedSourceFile) - -module SourceFileSet = 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 source_file_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 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 -let curr_encoding = `Enc_crc - -let source_file_to_string fname = - match fname with - | RelativeInferModel path -> "INFER_MODEL/" ^ path - | RelativeProjectRoot path - | Absolute path -> path - -let source_file_pp fmt fname = - Format.fprintf fmt "%s" (source_file_to_string fname) - -(* Checking if the path exists may be needed only in some cases, hence the flag check_exists *) -let source_file_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 source_file_line_count source_file = - let abs_path = source_file_to_abs_path source_file in - count_newlines abs_path - -let source_file_to_rel_path fname = - match fname with - | RelativeProjectRoot path -> path - | _ -> source_file_to_abs_path fname - -(** string encoding of a source file (including path) as a single filename *) -let source_file_encoding source_file = - let prefix = match source_file with - | RelativeProjectRoot _ -> "P" - | RelativeInferModel _ -> "MOD" - | Absolute _ -> "ABS" in - let source_file_s = source_file_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 source_file_empty = Absolute "" - -let source_file_is_infer_model source_file = match source_file with - | RelativeProjectRoot _ | Absolute _ -> false - | RelativeInferModel _ -> true - -(** Returns true if the file is a C++ model *) -let source_file_is_cpp_model file = - match file with - | RelativeInferModel path -> - string_is_prefix Config.relative_cpp_models_dir path - | _ -> false - -let source_file_is_under_project_root = function - | RelativeProjectRoot _ -> true - | Absolute _ | RelativeInferModel _ -> false - -let source_file_exists_cache = Hashtbl.create 256 - -let source_file_path_exists abs_path = - try Hashtbl.find source_file_exists_cache abs_path - with Not_found -> - let result = Sys.file_exists abs_path in - Hashtbl.add source_file_exists_cache abs_path result; - result - -let source_file_of_header header_file = - let abs_path = source_file_to_abs_path header_file in - let source_file_exts = ["c"; "cc"; "cpp"; "cxx"; "m"; "mm"] in - let header_file_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_file_exts -> ( - let possible_files = IList.map (fun ext -> file_no_ext ^ "." ^ ext) source_file_exts in - try Some (IList.find source_file_path_exists possible_files) - with Not_found -> None - ) - | _ -> None in - Option.map source_file_from_abs_path file_opt - -let changed_source_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 - source_file_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' = SourceFileSet.add source_file changed_files in - (* Add source corresponding to changed header if it exists *) - match source_file_of_header source_file with - | Some src -> SourceFileSet.add src changed_files' - | None -> changed_files' + 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 *) ) - SourceFileSet.empty - ) + + 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} *) @@ -189,7 +194,7 @@ let captured_dir = (** get the source directory corresponding to a source file *) let source_dir_from_source_file source_file = - Filename.concat captured_dir (source_file_encoding source_file) + Filename.concat captured_dir (SourceFile.encoding source_file) (** Find the source directories in the results dir *) let find_source_dirs () = @@ -312,7 +317,7 @@ module Results_dir = struct type path_kind = | Abs_root (** absolute path implicitly rooted at the root of the results dir *) - | Abs_source_dir of source_file + | Abs_source_dir of SourceFile.t (** absolute path implicitly rooted at the source directory for the file *) | Rel (** relative path *) @@ -343,7 +348,7 @@ module Results_dir = struct create_dir specs_dir; create_dir (path_to_filename Abs_root [Config.attributes_dir_name]); create_dir (path_to_filename Abs_root [Config.captured_dir_name]); - if not (equal_source_file source source_file_empty) then + if not (SourceFile.equal source SourceFile.empty) then create_dir (path_to_filename (Abs_source_dir source) []) let clean_specs_dir () = diff --git a/infer/src/base/DB.mli b/infer/src/base/DB.mli index 311bcc505..bb82f1d2b 100644 --- a/infer/src/base/DB.mli +++ b/infer/src/base/DB.mli @@ -38,10 +38,63 @@ val mark_file_updated : string -> unit (** Return whether filename was updated after analysis started. File doesn't have to exist *) val file_was_updated_after_start : filename -> bool -type source_file [@@deriving compare] +(** {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 -(** equality of source files *) -val equal_source_file : source_file -> source_file -> bool + (** 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} *) @@ -53,7 +106,7 @@ module Results_dir : sig type path_kind = | Abs_root (** absolute path implicitly rooted at the root of the results dir *) - | Abs_source_dir of source_file + | Abs_source_dir of SourceFile.t (** absolute path implicitly rooted at the source directory for the file *) | Rel (** relative path *) @@ -65,7 +118,7 @@ module Results_dir : sig val specs_dir : filename (** Initialize the results directory *) - val init : source_file -> unit + val init : SourceFile.t -> unit (** Clean up specs directory *) val clean_specs_dir : unit -> unit @@ -80,57 +133,6 @@ type origin = | Spec_lib | Models -(** {2 Source Files} *) - -(** Maps from source_file *) -module SourceFileMap : Map.S with type key = source_file - -(** Set of source files *) -module SourceFileSet : Set.S with type elt = source_file - -(** compute line count of a source file *) -val source_file_line_count : source_file -> int - -(** empty source file *) -val source_file_empty : source_file - -(** create source file from absolute path *) -val source_file_from_abs_path : string -> source_file - -(** string encoding of a source file (including path) as a single filename *) -val source_file_encoding : source_file -> 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 source_file_to_string : source_file -> string - -(** pretty print source_file *) -val source_file_pp : Format.formatter -> source_file -> unit - -(** get the full path of a source file *) -val source_file_to_abs_path : source_file -> string - -(** get the relative path of a source file *) -val source_file_to_rel_path : source_file -> string - -val source_file_is_infer_model : source_file -> bool - -(** Returns true if the file is a C++ model *) -val source_file_is_cpp_model : source_file -> bool - -(** Returns true if the file is in project root *) -val source_file_is_under_project_root : source_file -> bool - -(** Return approximate source file corresponding to the parameter if it's header file and - file exists. returns None otherwise *) -val source_file_of_header : source_file -> source_file 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_source_files_set : SourceFileSet.t option - (** {2 Source Dirs} *) (** source directory: the directory inside the results dir corresponding to a source file *) @@ -143,7 +145,7 @@ val source_dir_to_string : source_dir -> string val source_dir_get_internal_file : source_dir -> string -> filename (** get the source directory corresponding to a source file *) -val source_dir_from_source_file : source_file -> source_dir +val source_dir_from_source_file : SourceFile.t -> source_dir (** directory where the results of the capture phase are stored *) val captured_dir : filename diff --git a/infer/src/checkers/BoundedCallTree.ml b/infer/src/checkers/BoundedCallTree.ml index 1066a932a..81731b40e 100644 --- a/infer/src/checkers/BoundedCallTree.ml +++ b/infer/src/checkers/BoundedCallTree.ml @@ -60,7 +60,7 @@ let stacktree_of_pdesc let procname = Procdesc.get_proc_name pdesc in let frame_loc = Some { Stacktree_j.location_type = location_type; - file = DB.source_file_to_string loc.Location.file; + file = DB.SourceFile.to_string loc.Location.file; line = Some loc.Location.line; blame_range = [line_range_of_pdesc pdesc] } in { Stacktree_j.method_name = Procname.to_unique_id procname; diff --git a/infer/src/checkers/Siof.ml b/infer/src/checkers/Siof.ml index a3adba8c4..b030a831a 100644 --- a/infer/src/checkers/Siof.ml +++ b/infer/src/checkers/Siof.ml @@ -94,8 +94,8 @@ module Interprocedural = Analyzer.Interprocedural (Summary) let is_foreign tu_opt v = let is_orig_file f = match tu_opt with | Some orig_file -> - let orig_path = DB.source_file_to_abs_path orig_file in - Core.Std.String.equal orig_path (DB.source_file_to_abs_path f) + let orig_path = DB.SourceFile.to_abs_path orig_file in + Core.Std.String.equal orig_path (DB.SourceFile.to_abs_path f) | None -> assert false in Option.map_default (fun f -> not (is_orig_file f)) false (Pvar.get_source_file v) @@ -110,8 +110,8 @@ let report_siof trace pdesc gname loc = let pp_sink f sink = let pp_source f v = match Pvar.get_source_file v with - | Some source_file when not (DB.equal_source_file DB.source_file_empty source_file) -> - F.fprintf f " from file %a" DB.source_file_pp source_file + | Some source_file when not (DB.SourceFile.equal DB.SourceFile.empty source_file) -> + F.fprintf f " from file %a" DB.SourceFile.pp source_file | _ -> () in let v = SiofTrace.Sink.kind sink in diff --git a/infer/src/checkers/Stacktrace.ml b/infer/src/checkers/Stacktrace.ml index 092a4f75a..009447fff 100644 --- a/infer/src/checkers/Stacktrace.ml +++ b/infer/src/checkers/Stacktrace.ml @@ -43,7 +43,7 @@ let make_frame class_str method_str file_str line_num = { class_str; method_str; file_str; line_num; } let frame_matches_location frame_obj loc = - let lfname = DB.source_file_to_string loc.Location.file in + let lfname = DB.SourceFile.to_string loc.Location.file in let matches_file = Utils.string_is_suffix frame_obj.file_str lfname in let matches_line = match frame_obj.line_num with | None -> false diff --git a/infer/src/checkers/abstractInterpreter.ml b/infer/src/checkers/abstractInterpreter.ml index 9026f4ccf..6586ef745 100644 --- a/infer/src/checkers/abstractInterpreter.ml +++ b/infer/src/checkers/abstractInterpreter.ml @@ -150,7 +150,7 @@ module MakeNoCFG then begin Ondemand.set_callbacks callbacks; - let post_opt = analyze_ondemand_ DB.source_file_empty proc_desc in + let post_opt = analyze_ondemand_ DB.SourceFile.empty proc_desc in Ondemand.unset_callbacks (); post_opt end diff --git a/infer/src/checkers/checkers.ml b/infer/src/checkers/checkers.ml index d8903b4fe..bd8fbeb90 100644 --- a/infer/src/checkers/checkers.ml +++ b/infer/src/checkers/checkers.ml @@ -25,7 +25,7 @@ module PP = struct 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 | _ -> () in - F.fprintf fmt "%a:%d@\n" DB.source_file_pp loc.Location.file loc.Location.line; + F.fprintf fmt "%a:%d@\n" DB.SourceFile.pp loc.Location.file loc.Location.line; for n = loc.Location.line - nbefore to loc.Location.line + nafter do printline n done end (* PP *) @@ -144,7 +144,7 @@ module ST = struct begin L.stdout "%s: %a: %s@." kind - DB.source_file_pp loc.Location.file + DB.SourceFile.pp loc.Location.file (Procname.to_string proc_name); L.stdout "%s@." description 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 loc = Procdesc.get_loc proc_desc in let pp_file_loc fmt () = - F.fprintf fmt "%a:%d" DB.source_file_pp loc.Location.file loc.Location.line in + F.fprintf fmt "%a:%d" DB.SourceFile.pp loc.Location.file loc.Location.line in L.stdout "Null Checks of Formal Parameters: "; L.stdout "%d out of %d parameters checked (missing checks on: %a)[%a]@." nchecks nformals (pp_seq Mangled.pp) missing pp_file_loc (); diff --git a/infer/src/checkers/repeatedCallsChecker.ml b/infer/src/checkers/repeatedCallsChecker.ml index 3e137b95c..19f413a58 100644 --- a/infer/src/checkers/repeatedCallsChecker.ml +++ b/infer/src/checkers/repeatedCallsChecker.ml @@ -132,7 +132,7 @@ struct Format.asprintf "call to %s seen before on line %d (may allocate at %a:%d)" (Procname.to_simplified_string callee_pname) loc_old.Location.line - DB.source_file_pp alloc_loc.Location.file + DB.SourceFile.pp alloc_loc.Location.file alloc_loc.Location.line in Checkers.ST.report_error tenv curr_pname curr_pdesc checkers_repeated_calls_name loc description diff --git a/infer/src/clang/Capture.re b/infer/src/clang/Capture.re index 824bc0852..627626718 100644 --- a/infer/src/clang/Capture.re +++ b/infer/src/clang/Capture.re @@ -35,7 +35,7 @@ let validate_decl_from_channel chan => let register_perf_stats_report source_file => { let stats_dir = Filename.concat Config.results_dir Config.frontend_stats_dir_name; - let abbrev_source_file = DB.source_file_encoding source_file; + let abbrev_source_file = DB.SourceFile.encoding source_file; let stats_file = Config.perf_stats_prefix ^ "_" ^ abbrev_source_file ^ ".json"; create_dir Config.results_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 => { Logging.set_log_file_identifier - CommandLineOption.Clang (Some (Filename.basename (DB.source_file_to_abs_path source_file))); + CommandLineOption.Clang (Some (Filename.basename (DB.SourceFile.to_abs_path source_file))); register_perf_stats_report source_file; Config.curr_language := Config.Clang; DB.Results_dir.init source_file; @@ -67,7 +67,7 @@ let run_clang_frontend ast_source => { switch ast_decl { | Clang_ast_t.TranslationUnitDecl (_, _, _, info) => Config.arc_mode := info.Clang_ast_t.tudi_arc_enabled; - let source_file = DB.source_file_from_abs_path info.Clang_ast_t.tudi_input_path; + let source_file = DB.SourceFile.from_abs_path info.Clang_ast_t.tudi_input_path; init_global_state_for_capture_and_linters source_file; let lang = switch info.Clang_ast_t.tudi_input_kind { @@ -85,7 +85,7 @@ let run_clang_frontend ast_source => { | `File path => Format.fprintf fmt "%s" path | `Pipe _ => Format.fprintf - fmt "stdin of %a" DB.source_file_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; CFrontend_config.pointer_decl_index := decl_index; diff --git a/infer/src/clang/ComponentKit.ml b/infer/src/clang/ComponentKit.ml index 5cf2241ca..0ac791eb4 100644 --- a/infer/src/clang/ComponentKit.ml +++ b/infer/src/clang/ComponentKit.ml @@ -25,8 +25,8 @@ let is_in_main_file translation_unit_context an = | None -> false | Some file -> - DB.equal_source_file - (DB.source_file_from_abs_path file) + DB.SourceFile.equal + (DB.SourceFile.from_abs_path file) translation_unit_context.CFrontend_config.source_file 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 -> let source_file = context.translation_unit_context.CFrontend_config.source_file in - let line_count = DB.source_file_line_count source_file in + let line_count = DB.SourceFile.line_count source_file in IList.map (fun i -> { CIssue.issue = CIssue.Component_file_line_count; CIssue.description = "Line count analytics"; diff --git a/infer/src/clang/cFrontend.ml b/infer/src/clang/cFrontend.ml index dfdf65840..62218ac1a 100644 --- a/infer/src/clang/cFrontend.ml +++ b/infer/src/clang/cFrontend.ml @@ -45,10 +45,10 @@ let do_source_file translation_unit_context ast = init_global_state_capture (); let source_file = translation_unit_context.CFrontend_config.source_file in Logging.out_debug "@\n Start building call/cfg graph for '%a'....@\n" - DB.source_file_pp source_file; + DB.SourceFile.pp source_file; let call_graph, cfg = compute_icfg translation_unit_context tenv ast in Logging.out_debug "@\n End building call/cfg graph for '%a'.@\n" - DB.source_file_pp source_file; + DB.SourceFile.pp source_file; (* This part below is a boilerplate in every frontends. *) (* This could be moved in the cfg_infer module *) let source_dir = DB.source_dir_from_source_file source_file in diff --git a/infer/src/clang/cFrontend_checkers_main.ml b/infer/src/clang/cFrontend_checkers_main.ml index 0bea896e9..ffbc5acdd 100644 --- a/infer/src/clang/cFrontend_checkers_main.ml +++ b/infer/src/clang/cFrontend_checkers_main.ml @@ -107,7 +107,7 @@ let context_with_ck_set context decl_list = context let store_issues source_file = - let abbrev_source_file = DB.source_file_encoding source_file in + let abbrev_source_file = DB.SourceFile.encoding source_file in let lint_issues_dir = Config.results_dir // Config.lint_issues_dir_name in create_dir lint_issues_dir; let lint_issues_file = @@ -118,7 +118,7 @@ let do_frontend_checks trans_unit_ctx ast = try parse_ctl_file Config.linters_def_file; let source_file = trans_unit_ctx.CFrontend_config.source_file in - Logging.out "Start linting file %a@\n" DB.source_file_pp source_file; + Logging.out "Start linting file %a@\n" DB.SourceFile.pp source_file; match ast with | Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) -> let context = @@ -132,7 +132,7 @@ let do_frontend_checks trans_unit_ctx ast = IList.iter (do_frontend_checks_decl context) allowed_decls; if (LintIssues.exists_issues ()) then store_issues source_file; - Logging.out "End linting file %a@\n" DB.source_file_pp source_file; + Logging.out "End linting file %a@\n" DB.SourceFile.pp 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 *) with diff --git a/infer/src/clang/cFrontend_config.ml b/infer/src/clang/cFrontend_config.ml index f1c99418f..9459a052d 100644 --- a/infer/src/clang/cFrontend_config.ml +++ b/infer/src/clang/cFrontend_config.ml @@ -15,7 +15,7 @@ type clang_lang = C | CPP | ObjC | ObjCPP type translation_unit_context = { lang : clang_lang; - source_file : DB.source_file + source_file : DB.SourceFile.t } (** Constants *) diff --git a/infer/src/clang/cFrontend_config.mli b/infer/src/clang/cFrontend_config.mli index 7f1351a41..a7e2538fc 100644 --- a/infer/src/clang/cFrontend_config.mli +++ b/infer/src/clang/cFrontend_config.mli @@ -15,7 +15,7 @@ type clang_lang = C | CPP | ObjC | ObjCPP type translation_unit_context = { lang : clang_lang; - source_file : DB.source_file + source_file : DB.SourceFile.t } (** Constants *) diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index fb939a48a..04bc39217 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -657,7 +657,7 @@ struct let get_rel_file_path file_opt = match file_opt with | Some file -> - DB.source_file_to_string (DB.source_file_from_abs_path file) + DB.SourceFile.to_string (DB.SourceFile.from_abs_path file) | None -> "" in let file = match function_decl_info_opt with @@ -747,7 +747,7 @@ struct | Some "extern", None -> (* 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... *) - DB.source_file_empty + DB.SourceFile.empty | _ -> source_file in let is_constexpr = var_decl_info.Clang_ast_t.vdi_is_const_expr in diff --git a/infer/src/clang/cLocation.ml b/infer/src/clang/cLocation.ml index 533a05805..7be007726 100644 --- a/infer/src/clang/cLocation.ml +++ b/infer/src/clang/cLocation.ml @@ -14,13 +14,13 @@ open! Utils let clang_to_sil_location trans_unit_ctx clang_loc = 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 file = Option.map_default DB.source_file_from_abs_path + let file = Option.map_default DB.SourceFile.from_abs_path trans_unit_ctx.CFrontend_config.source_file clang_loc.Clang_ast_t.sl_file in Location.{line; col; file} let source_file_in_project source_file = - let file_in_project = DB.source_file_is_under_project_root source_file in - let rel_source_file = DB.source_file_to_string source_file in + let file_in_project = DB.SourceFile.is_under_project_root source_file in + let rel_source_file = DB.SourceFile.to_string source_file in let file_should_be_skipped = IList.exists (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, _) = match loc_start.Clang_ast_t.sl_file with | Some file -> - let source_file = (DB.source_file_from_abs_path file) in - DB.equal_source_file source_file trans_unit_ctx.CFrontend_config.source_file || + let source_file = (DB.SourceFile.from_abs_path file) in + DB.SourceFile.equal source_file trans_unit_ctx.CFrontend_config.source_file || (source_file_in_project source_file && not Config.testing_mode) | None -> false @@ -46,24 +46,24 @@ let should_translate trans_unit_ctx (loc_start, loc_end) decl_trans_context ~tra | None -> false in let map_file_of pred loc = - let path_pred path = pred (DB.source_file_from_abs_path path) in + let path_pred path = pred (DB.SourceFile.from_abs_path path) in map_path_of path_pred loc in (* 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 which uses same logic to produce both files *) - let equal_current_source = DB.equal_source_file trans_unit_ctx.CFrontend_config.source_file + let equal_current_source = DB.SourceFile.equal trans_unit_ctx.CFrontend_config.source_file in let equal_header_of_current_source maybe_header = - (* DB.source_file_of_header will cache calls to filesystem *) - let source_of_header_opt = DB.source_file_of_header maybe_header in + (* DB.SourceFile.of_header will cache calls to filesystem *) + let source_of_header_opt = DB.SourceFile.of_header maybe_header in Option.map_default equal_current_source false source_of_header_opt in let file_in_project = map_file_of source_file_in_project loc_end || 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 file_in_models = map_file_of DB.source_file_is_cpp_model loc_end - || map_file_of DB.source_file_is_cpp_model loc_start in + let file_in_models = map_file_of DB.SourceFile.is_cpp_model loc_end + || map_file_of DB.SourceFile.is_cpp_model loc_start in map_file_of equal_current_source loc_end || map_file_of equal_current_source loc_start || file_in_models diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index a16fffb15..986a98afb 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -252,7 +252,7 @@ let save_dotty_when_in_debug_mode source_file = | Some tracker -> let dotty_dir = Config.results_dir // Config.lint_dotty_dir_name in create_dir dotty_dir; - let source_file_basename = Filename.basename (DB.source_file_to_abs_path source_file) in + let source_file_basename = Filename.basename (DB.SourceFile.to_abs_path source_file) in let file = dotty_dir // (source_file_basename ^ ".dot") in let dotty = Debug.EvaluationTracker.DottyPrinter.dotty_of_ctl_evaluation !tracker in with_file file ~f:(fun oc -> output_string oc dotty) diff --git a/infer/src/clang/cTL.mli b/infer/src/clang/cTL.mli index 7fb62d1a3..ef417e2d2 100644 --- a/infer/src/clang/cTL.mli +++ b/infer/src/clang/cTL.mli @@ -61,7 +61,7 @@ type ast_node = val eval_formula : t -> ast_node -> CLintersContext.context -> bool -val save_dotty_when_in_debug_mode : DB.source_file -> unit +val save_dotty_when_in_debug_mode : DB.SourceFile.t -> unit module Debug : sig diff --git a/infer/src/eradicate/typeErr.ml b/infer/src/eradicate/typeErr.ml index 6c3b3079a..ca6241c7d 100644 --- a/infer/src/eradicate/typeErr.ml +++ b/infer/src/eradicate/typeErr.ml @@ -241,7 +241,7 @@ let report_error_now tenv (st_report_error : st_report_error) err_instance loc pdesc : unit = let pname = Procdesc.get_proc_name pdesc in let do_print ew_string kind_s s = - L.stdout "%a:%d " DB.source_file_pp loc.Location.file loc.Location.line; + L.stdout "%a:%d " DB.SourceFile.pp loc.Location.file loc.Location.line; let mname = match pname with | Procname.Java pname_java -> Procname.java_get_method pname_java diff --git a/infer/src/integration/CaptureCompilationDatabase.ml b/infer/src/integration/CaptureCompilationDatabase.ml index 54aec80b2..ad13bfb5d 100644 --- a/infer/src/integration/CaptureCompilationDatabase.ml +++ b/infer/src/integration/CaptureCompilationDatabase.ml @@ -18,14 +18,14 @@ let capture_text = (** Read the files to compile from the changed files index. *) let should_capture_file_from_index () = - match DB.changed_source_files_set with + match DB.SourceFile.changed_files_set with | None -> (match Config.changed_files_index with | Some index -> Process.print_error_and_exit "Error reading the changed files index %s.\n%!" index | None -> function _ -> true) | Some files_set -> - function source_file -> DB.SourceFileSet.mem source_file files_set + function source_file -> DB.SourceFile.Set.mem source_file files_set (** The buck targets are assumed to start with //, aliases are not supported. *) 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) with Not_found -> Process.print_error_and_exit "Failed to find compilation data for %a \n%!" - DB.source_file_pp file + DB.SourceFile.pp file let run_compilation_database compilation_database should_capture_file = 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 capture_text_upper = String.capitalize capture_text in let job_to_string = - fun file -> Format.asprintf "%s %a" capture_text_upper DB.source_file_pp file in + fun file -> Format.asprintf "%s %a" capture_text_upper DB.SourceFile.pp file in Process.run_jobs_in_parallel jobs_stack (run_compilation_file compilation_database) job_to_string (** Computes the compilation database files. *) diff --git a/infer/src/integration/CompilationDatabase.ml b/infer/src/integration/CompilationDatabase.ml index a6742336f..095892e52 100644 --- a/infer/src/integration/CompilationDatabase.ml +++ b/infer/src/integration/CompilationDatabase.ml @@ -15,14 +15,14 @@ type compilation_data = { args : string; } -type t = compilation_data DB.SourceFileMap.t ref -let empty () = ref DB.SourceFileMap.empty +type t = compilation_data DB.SourceFile.Map.t ref +let empty () = ref DB.SourceFile.Map.empty -let get_size database = DB.SourceFileMap.cardinal !database +let get_size database = DB.SourceFile.Map.cardinal !database -let iter database f = DB.SourceFileMap.iter f !database +let iter database f = DB.SourceFile.Map.iter f !database -let find database key = DB.SourceFileMap.find key !database +let find database key = DB.SourceFile.Map.find key !database let parse_command_and_arguments command_and_arguments = let regexp = Str.regexp "[^\\][ ]" in @@ -68,8 +68,8 @@ let decode_json_file (database : t) json_path = | None -> exit_format_error () in let command, args = parse_command_and_arguments cmd in let compilation_data = { dir; command; args;} in - let source_file = DB.source_file_from_abs_path file in - database := DB.SourceFileMap.add source_file compilation_data !database + let source_file = DB.SourceFile.from_abs_path file in + database := DB.SourceFile.Map.add source_file compilation_data !database | _ -> exit_format_error () in parse_json json diff --git a/infer/src/integration/CompilationDatabase.mli b/infer/src/integration/CompilationDatabase.mli index b6ce98ac3..064dacdb8 100644 --- a/infer/src/integration/CompilationDatabase.mli +++ b/infer/src/integration/CompilationDatabase.mli @@ -21,9 +21,9 @@ val empty : unit -> t val get_size : t -> int -val iter : t -> (DB.source_file -> compilation_data -> unit) -> unit +val iter : t -> (DB.SourceFile.t -> compilation_data -> unit) -> unit -val find : t -> DB.source_file -> compilation_data +val find : t -> DB.SourceFile.t -> compilation_data val decode_json_file : t -> string -> unit diff --git a/infer/src/java/jAnnotation.ml b/infer/src/java/jAnnotation.ml index 4beebb6db..e619810e6 100644 --- a/infer/src/java/jAnnotation.ml +++ b/infer/src/java/jAnnotation.ml @@ -14,7 +14,7 @@ open Javalib_pack let is_suppress_warnings_annotated = - Inferconfig.suppress_warnings_matcher DB.source_file_empty + Inferconfig.suppress_warnings_matcher DB.SourceFile.empty let suppress_warnings = ({ Annot. diff --git a/infer/src/java/jClasspath.ml b/infer/src/java/jClasspath.ml index 9967b00b1..d36682cb0 100644 --- a/infer/src/java/jClasspath.ml +++ b/infer/src/java/jClasspath.ml @@ -84,13 +84,13 @@ let append_path classpath path = type file_entry = - | Singleton of DB.source_file - | Duplicate of (string * DB.source_file) list + | Singleton of DB.SourceFile.t + | Duplicate of (string * DB.SourceFile.t) list (* Open the source file and search for the package declaration. Only the case where the package is declared in a single line is supported *) let read_package_declaration source_file = - let path = DB.source_file_to_abs_path source_file in + let path = DB.SourceFile.to_abs_path source_file in let file_in = open_in path in let remove_trailing_semicolon = Str.replace_first (Str.regexp ";") "" in @@ -117,7 +117,7 @@ let add_source_file path map = let basename = Filename.basename path in let entry = let current_source_file = - DB.source_file_from_abs_path (convert_to_absolute path) in + DB.SourceFile.from_abs_path (convert_to_absolute path) in try match StringMap.find basename map with | Singleton previous_source_file -> diff --git a/infer/src/java/jClasspath.mli b/infer/src/java/jClasspath.mli index 19aba12b6..c36617927 100644 --- a/infer/src/java/jClasspath.mli +++ b/infer/src/java/jClasspath.mli @@ -29,8 +29,8 @@ val split_classpath : string -> string list (** map entry for source files with potential basname collision within the same compiler call *) type file_entry = - | Singleton of DB.source_file - | Duplicate of (string * DB.source_file) list + | Singleton of DB.SourceFile.t + | Duplicate of (string * DB.SourceFile.t) list (** load the list of source files and the list of classes from the javac verbose file *) val load_sources_and_classes : unit -> diff --git a/infer/src/java/jContext.ml b/infer/src/java/jContext.ml index c368af6fa..5fb422d18 100644 --- a/infer/src/java/jContext.ml +++ b/infer/src/java/jContext.ml @@ -35,7 +35,7 @@ type t = if_jumps : int NodeTbl.t; goto_jumps : (int, jump_kind) Hashtbl.t; cn : JBasics.class_name; - source_file : DB.source_file; + source_file : DB.SourceFile.t; program : JClasspath.program; } diff --git a/infer/src/java/jContext.mli b/infer/src/java/jContext.mli index 7a0e39e6e..46a4b0dbb 100644 --- a/infer/src/java/jContext.mli +++ b/infer/src/java/jContext.mli @@ -43,7 +43,7 @@ type t = private if_jumps : int NodeTbl.t; goto_jumps : (int, jump_kind) Hashtbl.t; cn : JBasics.class_name; - source_file : DB.source_file; + source_file : DB.SourceFile.t; program : JClasspath.program; } @@ -54,7 +54,7 @@ val create_context : Procdesc.t -> JBir.t -> JBasics.class_name -> - DB.source_file -> + DB.SourceFile.t -> JClasspath.program -> t diff --git a/infer/src/java/jFrontend.mli b/infer/src/java/jFrontend.mli index bc545eb16..5119b9ac9 100644 --- a/infer/src/java/jFrontend.mli +++ b/infer/src/java/jFrontend.mli @@ -29,12 +29,12 @@ val compute_source_icfg : Tenv.t -> string -> string option -> - DB.source_file -> + DB.SourceFile.t -> Cg.t * Cfg.cfg (** Compute the CFG for a class *) val compute_class_icfg : - DB.source_file -> + DB.SourceFile.t -> Printer.LineReader.t -> JClasspath.program -> Tenv.t -> diff --git a/infer/src/java/jMain.ml b/infer/src/java/jMain.ml index fd6690ac6..4803a30b2 100644 --- a/infer/src/java/jMain.ml +++ b/infer/src/java/jMain.ml @@ -28,7 +28,7 @@ let () = let register_perf_stats_report source_file = let stats_dir = Filename.concat Config.results_dir Config.frontend_stats_dir_name in - let abbrev_source_file = DB.source_file_encoding source_file in + let abbrev_source_file = DB.SourceFile.encoding source_file in let stats_file = Config.perf_stats_prefix ^ "_" ^ abbrev_source_file ^ ".json" in create_dir Config.results_dir ; create_dir stats_dir ; @@ -65,7 +65,7 @@ let do_source_file linereader classes program tenv source_basename package_opt source_file = L.out_debug "\nfilename: %a (%s)@." - DB.source_file_pp source_file source_basename; + DB.SourceFile.pp source_file source_basename; let call_graph, cfg = JFrontend.compute_source_icfg linereader classes program tenv @@ -81,7 +81,7 @@ let capture_libs linereader program tenv = | Javalib.JClass _ -> begin let fake_source_file = - DB.source_file_from_abs_path (JFrontend.path_of_cached_classname cn) in + DB.SourceFile.from_abs_path (JFrontend.path_of_cached_classname cn) in init_global_state fake_source_file; let call_graph, cfg = 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 (fun pattern -> Str.string_match (Str.regexp pattern) path 0) Config.skip_analysis_in_path in - is_path_matching (DB.source_file_to_rel_path source_file) + is_path_matching (DB.SourceFile.to_rel_path source_file) || Inferconfig.skip_translation_matcher source_file Procname.empty_block in let translate_source_file basename (package_opt, _) source_file = init_global_state source_file; diff --git a/infer/src/java/jTrans.mli b/infer/src/java/jTrans.mli index 3c74663a2..ac1a0967b 100644 --- a/infer/src/java/jTrans.mli +++ b/infer/src/java/jTrans.mli @@ -37,7 +37,7 @@ val create_native_procdesc : (** [create_procdesc source_file program linereader icfg cm proc_name] creates a procedure description for the concrete method cm and adds it to cfg *) val create_cm_procdesc : - DB.source_file -> + DB.SourceFile.t -> JClasspath.program -> Printer.LineReader.t -> JContext.icfg -> diff --git a/infer/src/quandary/TaintAnalysis.ml b/infer/src/quandary/TaintAnalysis.ml index fd4efff91..84955ee05 100644 --- a/infer/src/quandary/TaintAnalysis.ml +++ b/infer/src/quandary/TaintAnalysis.ml @@ -579,7 +579,7 @@ module Make (TaintSpecification : TaintSpec.S) = struct then begin Ondemand.set_callbacks callbacks; - analyze_ondemand DB.source_file_empty proc_desc; + analyze_ondemand DB.SourceFile.empty proc_desc; Ondemand.unset_callbacks (); end