[linters] Save the linters file in the linter definition

Reviewed By: ddino

Differential Revision: D4689093

fbshipit-source-id: bd4e706
master
Dulma Churchill 8 years ago committed by Facebook Github Bot
parent 06ac72c311
commit cdd58da8b1

@ -11,9 +11,7 @@ open! IStd
open Lexing
open Ctl_lexer
(* Parse the file with linters definitions, and it returns a list
of checkers in the form of pairs (condition, issue_desc) *)
let parse_ctl_file linters_files =
let parse_ctl_file linters_def_file channel : CFrontend_errors.linter list =
let print_position _ lexbuf =
let pos = lexbuf.lex_curr_p in
Logging.err "%s:%d:%d" pos.pos_fname
@ -29,21 +27,26 @@ let parse_ctl_file linters_files =
\n########################################################\n@."
print_position lexbuf;
exit (-1) in
List.iter ~f:(fun fn ->
Logging.out "Loading linters rules from %s\n" fn;
let inx = open_in fn in
let lexbuf = Lexing.from_channel inx in
lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = fn };
(match parse_with_error lexbuf with
| Some parsed_checkers ->
Logging.out "#### Start Expanding checkers #####\n";
let exp_checkers = CFrontend_errors.expand_checkers parsed_checkers in
Logging.out "#### Checkers Expanded #####\n";
if Config.debug_mode then List.iter ~f:CTL.print_checker exp_checkers;
CFrontend_errors.make_condition_issue_desc_pair exp_checkers;
| None -> Logging.out "No linters found.\n");
In_channel.close inx) linters_files
let lexbuf = Lexing.from_channel channel in
lexbuf.lex_curr_p <- { lexbuf.lex_curr_p with pos_fname = linters_def_file };
match parse_with_error lexbuf with
| Some parsed_checkers ->
Logging.out "#### Start Expanding checkers #####\n";
let exp_checkers = CFrontend_errors.expand_checkers parsed_checkers in
Logging.out "#### Checkers Expanded #####\n";
if Config.debug_mode then List.iter ~f:CTL.print_checker exp_checkers;
CFrontend_errors.create_parsed_linters linters_def_file exp_checkers
| None -> Logging.out "No linters found.\n";[]
(* Parse the files with linters definitions, and it returns a list of linters *)
let parse_ctl_files linters_def_files : CFrontend_errors.linter list =
let collect_parsed_linters linters_def_file linters =
Logging.out "Loading linters rules from %s\n" linters_def_file;
let in_channel = open_in linters_def_file in
let parsed_linters = parse_ctl_file linters_def_file in_channel in
In_channel.close in_channel;
List.append parsed_linters linters in
List.fold_right ~f:collect_parsed_linters ~init:[] linters_def_files
let rec get_responds_to_selector stmt =
let open Clang_ast_t in
@ -209,7 +212,8 @@ let store_issues source_file =
let do_frontend_checks trans_unit_ctx ast =
try
parse_ctl_file Config.linters_def_file;
let parsed_linters = parse_ctl_files Config.linters_def_file in
CFrontend_errors.parsed_linters := parsed_linters;
let source_file = trans_unit_ctx.CFrontend_config.source_file in
Logging.out "Start linting file %a@\n" SourceFile.pp source_file;
match ast with

@ -9,6 +9,12 @@
open! IStd
type linter = {
condition : CTL.t;
issue_desc : CIssue.issue_desc;
def_file : string option;
}
let single_to_multi checker =
fun ctx an ->
let condition, issue_desc_opt = checker ctx an in
@ -35,8 +41,9 @@ let stmt_single_checkers_list =
let stmt_checkers_list = List.map ~f:single_to_multi stmt_single_checkers_list
(* List of checkers that will be filled after parsing them from a file *)
let checkers_decl_stmt = ref []
(* List of checkers that will be filled after parsing them from
input the linter def files *)
let parsed_linters = ref []
let evaluate_place_holder ph an =
match ph with
@ -92,8 +99,8 @@ let string_to_issue_mode m =
(Logging.err "\n[ERROR] Mode %s does not exist. Please specify ON/OFF\n" s;
assert false)
(** Convert a parsed checker in a pair (condition, issue_desc) *)
let make_condition_issue_desc_pair checkers =
(** Convert a parsed checker in list of linters *)
let create_parsed_linters linters_def_file checkers : linter list =
let open CIssue in
let open CTL in
let open Ctl_parser_types in
@ -107,7 +114,7 @@ let make_condition_issue_desc_pair checkers =
severity = Exceptions.Kwarning;
mode = CIssue.On;
} in
let issue, condition = List.fold ~f:(fun (issue', cond') d ->
let issue_desc, condition = List.fold ~f:(fun (issue', cond') d ->
match d with
| CSet (s, phi) when String.equal s report_when_const ->
issue', phi
@ -124,9 +131,9 @@ let make_condition_issue_desc_pair checkers =
Logging.out "\nMaking condition and issue desc for checker '%s'\n"
c.name;
Logging.out "\nCondition =\n %a\n" CTL.Debug.pp_formula condition;
Logging.out "\nIssue_desc = %a\n" CIssue.pp_issue issue);
condition, issue in
checkers_decl_stmt := List.map ~f:do_one_checker checkers
Logging.out "\nIssue_desc = %a\n" CIssue.pp_issue issue_desc);
{condition; issue_desc; def_file = Some linters_def_file} in
List.map ~f:do_one_checker checkers
(* expands use of let defined formula id in checkers with their definition *)
@ -232,18 +239,18 @@ let invoke_set_of_hard_coded_checkers_an context (an : Ctl_parser_types.ast_node
) checkers
(* Calls the set of checkers parsed from files (if any) *)
let invoke_set_of_parsed_checkers_an context (an : Ctl_parser_types.ast_node) =
let invoke_set_of_parsed_checkers_an parsed_linters context (an : Ctl_parser_types.ast_node) =
let key = match an with
| Decl dec -> CAst_utils.generate_key_decl dec
| Stmt st -> CAst_utils.generate_key_stmt st in
List.iter ~f:(fun (condition, issue_desc) ->
if CIssue.should_run_check issue_desc.CIssue.mode &&
CTL.eval_formula condition an context then
List.iter ~f:(fun (linter : linter) ->
if CIssue.should_run_check linter.issue_desc.CIssue.mode &&
CTL.eval_formula linter.condition an context then
let loc = CFrontend_checkers.location_from_an context an in
fill_issue_desc_info_and_log context an key issue_desc loc
) !checkers_decl_stmt
fill_issue_desc_info_and_log context an key linter.issue_desc loc
) parsed_linters
(* We decouple the hardcoded checkers from the parsed ones *)
let invoke_set_of_checkers_on_node context an =
invoke_set_of_parsed_checkers_an context an;
invoke_set_of_parsed_checkers_an !parsed_linters context an;
invoke_set_of_hard_coded_checkers_an context an

@ -9,6 +9,14 @@
open! IStd
type linter = {
condition : CTL.t;
issue_desc : CIssue.issue_desc;
def_file : string option;
}
(* List of checkers that will be filled after parsing them from a file *)
val parsed_linters : linter list ref
(* Module for warnings detected at translation time by the frontend *)
@ -17,7 +25,6 @@ val invoke_set_of_checkers_on_node : CLintersContext.context -> Ctl_parser_types
val expand_checkers : CTL.ctl_checker list -> CTL.ctl_checker list
val make_condition_issue_desc_pair :
CTL.ctl_checker list -> unit
val create_parsed_linters : string -> CTL.ctl_checker list -> linter list
val remove_new_lines : string -> string

Loading…
Cancel
Save