[DB] Remove source_file_from_string, source_file_to_string no longer returns real path

Summary:
source_file_[to|from]_string were dangerous. While removing source_file_to_string is hard/impossible, source file should never be created from string.
Also include many random changes related to `source_file`:
- improve comments in DB.mli
- define behavior of changed-files-index and improve its description
- move some of the "dangerous" code inline to discourage its reuse

This mostly concludes cleanup of DB.source_file, the last bit is to unify filtering by filename (we have duplicated logic in `InferConfig`, `CLocation` and `JMain`)

Reviewed By: jvillard

Differential Revision: D4258795

fbshipit-source-id: 36735a8
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent b8908282f8
commit bd843b277e

@ -477,18 +477,6 @@ let module IssuesJson = {
let is_first_item = ref true; let is_first_item = ref true;
let pp_json_open fmt () => F.fprintf fmt "[@?"; let pp_json_open fmt () => F.fprintf fmt "[@?";
let pp_json_close fmt () => F.fprintf fmt "]\n@?"; let pp_json_close fmt () => F.fprintf fmt "]\n@?";
let expand_links_under_buck_out file =>
if (Utils.string_is_prefix Config.buck_generated_folder file) {
try {
let file = Unix.readlink file;
let source_file = DB.source_file_from_string file;
DB.source_file_to_rel_path source_file
} {
| Unix.Unix_error _ => file
}
} else {
file
};
/** Write bug report in JSON format */ /** Write bug report in JSON format */
let pp_issues_of_error_log fmt error_filter _ proc_loc_opt procname err_log => { let pp_issues_of_error_log fmt error_filter _ proc_loc_opt procname err_log => {
@ -522,7 +510,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 = expand_links_under_buck_out (DB.source_file_to_string source_file); let file = DB.source_file_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 =>

@ -262,7 +262,7 @@ 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.source_file_from_string path) in let source_file = DB.source_file_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

@ -650,7 +650,8 @@ and calls_csv =
and changed_files_index = and changed_files_index =
CLOpt.mk_path_opt ~long:"changed-files-index" ~exes:CLOpt.[Toplevel] ~meta:"file" CLOpt.mk_path_opt ~long:"changed-files-index" ~exes:CLOpt.[Toplevel] ~meta:"file"
"Specify the file containing the list of files from which reactive analysis should start" "Specify the file containing the list of source files from which reactive analysis should \
start. Source files should be specified relative to project root or be absolute"
and check_duplicate_symbols = and check_duplicate_symbols =
CLOpt.mk_bool ~long:"check-duplicate-symbols" CLOpt.mk_bool ~long:"check-duplicate-symbols"

@ -40,12 +40,6 @@ module SourceFileMap = Map.Make(OrderedSourceFile)
module SourceFileSet = Set.Make(OrderedSourceFile) module SourceFileSet = Set.Make(OrderedSourceFile)
let source_file_from_string path =
if Filename.is_relative path then
RelativeProjectRoot path
else
Absolute path
let rel_path_from_abs_path root fname = let rel_path_from_abs_path root fname =
let relative_complemented_fname = filename_to_relative root fname in let relative_complemented_fname = filename_to_relative root fname in
if string_is_prefix root fname && if string_is_prefix root fname &&
@ -53,7 +47,6 @@ let rel_path_from_abs_path root fname =
Some relative_complemented_fname Some relative_complemented_fname
else None (* The project root is not a prefix of the file name *) else None (* The project root is not a prefix of the file name *)
(** convert a project root directory and a full path to a rooted source file *)
let source_file_from_abs_path fname = let source_file_from_abs_path fname =
(* IMPORTANT: results of realpath are cached to not ruin performance *) (* IMPORTANT: results of realpath are cached to not ruin performance *)
let fname_real = realpath fname in let fname_real = realpath fname in
@ -75,8 +68,8 @@ let curr_encoding = `Enc_crc
let source_file_to_string fname = let source_file_to_string fname =
match fname with match fname with
| RelativeInferModel path -> "INFER_MODEL/" ^ path
| RelativeProjectRoot path | RelativeProjectRoot path
| RelativeInferModel path
| Absolute path -> path | Absolute path -> path
let source_file_pp fmt fname = let source_file_pp fmt fname =
@ -96,7 +89,7 @@ let source_file_line_count source_file =
let source_file_to_rel_path fname = let source_file_to_rel_path fname =
match fname with match fname with
| RelativeProjectRoot path -> path | RelativeProjectRoot path -> path
| _ -> source_file_to_abs_path fname |> filename_to_relative Config.project_root | _ -> source_file_to_abs_path fname
(** string encoding of a source file (including path) as a single filename *) (** string encoding of a source file (including path) as a single filename *)
let source_file_encoding source_file = let source_file_encoding source_file =
@ -155,6 +148,20 @@ let source_file_of_header header_file =
| _ -> None in | _ -> None in
Option.map source_file_from_abs_path file_opt 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 -> SourceFileSet.add (create_source_file line) changed_files)
SourceFileSet.empty
)
(** {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 *)
@ -405,11 +412,3 @@ let fold_paths_matching ~dir ~p ~init ~f =
matcher function p *) matcher function p *)
let paths_matching dir p = let paths_matching dir p =
fold_paths_matching ~dir ~p ~init:[] ~f:(fun x xs -> x :: xs) fold_paths_matching ~dir ~p ~init:[] ~f:(fun x xs -> x :: xs)
let changed_source_files_set =
Option.map_default read_file None Config.changed_files_index |>
Option.map (
IList.fold_left
(fun changed_files line -> SourceFileSet.add (source_file_from_string line) changed_files)
SourceFileSet.empty
)

@ -94,21 +94,21 @@ val source_file_line_count : source_file -> int
(** empty source file *) (** empty source file *)
val source_file_empty : source_file val source_file_empty : source_file
(** create source file from absolute path *)
val source_file_from_abs_path : string -> source_file val source_file_from_abs_path : string -> source_file
(** string encoding of a source file (including path) as a single filename *) (** string encoding of a source file (including path) as a single filename *)
val source_file_encoding : source_file -> string val source_file_encoding : source_file -> string
(** convert a source file to a 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 val source_file_to_string : source_file -> string
(** convert a string obtained by source_file_to_string to a source file *)
val source_file_from_string : string -> source_file
(** pretty print source_file *) (** pretty print source_file *)
val source_file_pp : Format.formatter -> source_file -> unit val source_file_pp : Format.formatter -> source_file -> unit
(** get the full path of a source file, raise No_project_root exception when used with a relative source file and no project root specified *) (** get the full path of a source file *)
val source_file_to_abs_path : source_file -> string val source_file_to_abs_path : source_file -> string
(** get the relative path of a source file *) (** get the relative path of a source file *)
@ -126,6 +126,9 @@ val source_file_is_under_project_root : source_file -> bool
file exists. returns None otherwise *) file exists. returns None otherwise *)
val source_file_of_header : source_file -> source_file option val source_file_of_header : source_file -> source_file option
(** Set of files read from --changed-files-index file, None if option not specified *)
val changed_source_files_set : SourceFileSet.t option
(** {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 *)
@ -170,6 +173,3 @@ val fold_paths_matching :
(** Return all file paths recursively under the given directory which match the given predicate *) (** Return all file paths recursively under the given directory which match the given predicate *)
val paths_matching : string -> (string -> bool) -> string list val paths_matching : string -> (string -> bool) -> string list
(** Set of files read from --changed-files-index file, None if option not specified *)
val changed_source_files_set : SourceFileSet.t option

@ -625,12 +625,6 @@ struct
let class_name = Ast_utils.get_class_name_from_member field_qual_name in let class_name = Ast_utils.get_class_name_from_member field_qual_name in
Ident.create_fieldname (Mangled.mangled field_name class_name) 0 Ident.create_fieldname (Mangled.mangled field_name class_name) 0
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)
| None -> ""
let is_cpp_translation translation_unit_context = let is_cpp_translation translation_unit_context =
let lang = translation_unit_context.CFrontend_config.lang in let lang = translation_unit_context.CFrontend_config.lang in
lang = CFrontend_config.CPP || lang = CFrontend_config.ObjCPP lang = CFrontend_config.CPP || lang = CFrontend_config.ObjCPP
@ -660,6 +654,11 @@ struct
| _ -> assert false) | _ -> assert false)
let mk_procname_from_function translation_unit_context name function_decl_info_opt = let mk_procname_from_function translation_unit_context name function_decl_info_opt =
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)
| None -> "" in
let file = let file =
match function_decl_info_opt with match function_decl_info_opt with
| Some (decl_info, function_decl_info) -> | Some (decl_info, function_decl_info) ->

@ -202,22 +202,18 @@ let inhabit_call tenv (procname, receiver) cfg env =
with Not_found -> env with Not_found -> env
(** create a dummy file for the harness and associate them in the exe_env *) (** create a dummy file for the harness and associate them in the exe_env *)
let create_dummy_harness_file harness_name = let create_dummy_harness_filename harness_name =
let dummy_file_name =
let dummy_file_dir = let dummy_file_dir =
Filename.get_temp_dir_name () in Filename.get_temp_dir_name () in
let file_str = let file_str =
Procname.java_get_class_name Procname.java_get_class_name
harness_name ^ "_" ^Procname.java_get_method harness_name ^ ".java" in harness_name ^ "_" ^Procname.java_get_method harness_name ^ ".java" in
Filename.concat dummy_file_dir file_str in Filename.concat dummy_file_dir file_str
DB.source_file_from_string dummy_file_name
(** write the SIL for the harness to a file *) (** write the SIL for the harness to a file *)
(* TODO (t3040429): fill this file up with Java-like code that matches the SIL *) (* TODO (t3040429): fill this file up with Java-like code that matches the SIL *)
let write_harness_to_file harness_instrs harness_file = let write_harness_to_file harness_instrs harness_file_name =
let harness_file = let harness_file = create_outfile harness_file_name in
let harness_file_name = DB.source_file_to_abs_path harness_file in
create_outfile harness_file_name in
let pp_harness fmt = IList.iter (fun instr -> let pp_harness fmt = IList.iter (fun instr ->
Format.fprintf fmt "%a\n" (Sil.pp_instr pe_text) instr) harness_instrs in Format.fprintf fmt "%a\n" (Sil.pp_instr pe_text) instr) harness_instrs in
do_outf harness_file (fun outf -> do_outf harness_file (fun outf ->
@ -266,7 +262,7 @@ let setup_harness_cfg harness_name env cg cfg =
let inhabit_trace tenv trace harness_name cg cfg = let inhabit_trace tenv trace harness_name cg cfg =
if IList.length trace > 0 then if IList.length trace > 0 then
let source_file = Cg.get_source cg in let source_file = Cg.get_source cg in
let harness_file = create_dummy_harness_file harness_name in let harness_filename = create_dummy_harness_filename harness_name in
let start_line = 1 in let start_line = 1 in
let empty_env = let empty_env =
let pc = { Location.line = start_line; col = 1; file = source_file; } in let pc = { Location.line = start_line; col = 1; file = source_file; } in
@ -279,5 +275,5 @@ let inhabit_trace tenv trace harness_name cg cfg =
let env'' = IList.fold_left (fun env to_call -> inhabit_call tenv to_call cfg env) empty_env trace in let env'' = IList.fold_left (fun env to_call -> inhabit_call tenv to_call cfg env) empty_env trace in
try try
setup_harness_cfg harness_name env'' cg cfg; setup_harness_cfg harness_name env'' cg cfg;
write_harness_to_file (IList.rev env''.instrs) harness_file write_harness_to_file (IList.rev env''.instrs) harness_filename
with Not_found -> () with Not_found -> ()

Loading…
Cancel
Save