[linters] Improve linter developer mode

Reviewed By: jvillard

Differential Revision: D4844827

fbshipit-source-id: ed7da04
master
Dulma Churchill 8 years ago committed by Facebook Github Bot
parent b349fb147c
commit 07c9e71399

@ -714,12 +714,6 @@ and continue =
"Continue the capture for the reactive analysis, increasing the changed files/procedures. (If \ "Continue the capture for the reactive analysis, increasing the changed files/procedures. (If \
a procedure was changed beforehand, keep the changed marking.)" a procedure was changed beforehand, keep the changed marking.)"
and linters_ignore_clang_failures =
CLOpt.mk_bool ~long:"linters-ignore-clang-failures"
~parse_mode:CLOpt.(Infer [Clang])
~default:false
"Continue linting files even if some compilation fails."
and copy_propagation = and copy_propagation =
CLOpt.mk_bool ~deprecated:["copy-propagation"] ~long:"copy-propagation" CLOpt.mk_bool ~deprecated:["copy-propagation"] ~long:"copy-propagation"
"Perform copy-propagation on the IR" "Perform copy-propagation on the IR"
@ -734,9 +728,13 @@ and (
developer_mode, developer_mode,
debug, debug,
debug_exceptions, debug_exceptions,
default_linters,
failures_allowed,
filtering, filtering,
frontend_tests, frontend_tests,
linters_developer_mode,
print_buckets, print_buckets,
print_logs,
print_types, print_types,
reports_include_ml_loc, reports_include_ml_loc,
test, test,
@ -744,7 +742,11 @@ and (
write_html, write_html,
write_dotty write_dotty
) = ) =
let developer_mode = let failures_allowed =
CLOpt.mk_bool ~deprecated_no:["-no_failures_allowed"] ~long:"failures-allowed" ~default:true
"Fail if at least one of the translations fails (clang only)"
and developer_mode =
CLOpt.mk_bool ~long:"developer-mode" CLOpt.mk_bool ~long:"developer-mode"
~default:(equal_exe current_exe Print) ~default:(equal_exe current_exe Print)
"Show internal exceptions" "Show internal exceptions"
@ -801,19 +803,39 @@ and (
[developer_mode; print_buckets; reports_include_ml_loc] [developer_mode; print_buckets; reports_include_ml_loc]
[filtering] [filtering]
and default_linters =
CLOpt.mk_bool ~long:"default-linters" ~parse_mode:CLOpt.(Infer [Clang]) ~default:true
"Use the default linters for the analysis."
and frontend_tests = and frontend_tests =
CLOpt.mk_bool_group ~long:"frontend-tests" CLOpt.mk_bool_group ~long:"frontend-tests"
~parse_mode:CLOpt.(Infer [Clang]) ~parse_mode:CLOpt.(Infer [Clang])
"Save filename.ext.test.dot with the cfg in dotty format for frontend tests (also sets \ "Save filename.ext.test.dot with the cfg in dotty format for frontend tests (also sets \
--print-types)" --print-types)"
[print_types] [] [print_types] []
and print_logs =
CLOpt.mk_bool ~long:"print-logs" ~parse_mode:CLOpt.(Infer [Driver])
"Also log messages to stdout and stderr"
in
let linters_developer_mode =
CLOpt.mk_bool_group ~long:"linters-developer-mode" ~parse_mode:CLOpt.(Infer [Clang])
"Debug mode for developing new linters. (Sets the analyzer to \"linters\"; also sets \
--debug, --developer-mode, --print-logs, and \
unsets --allowed-failures and --default-linters."
[debug; developer_mode; print_logs] [failures_allowed; default_linters]
in ( in (
developer_mode, developer_mode,
debug, debug,
debug_exceptions, debug_exceptions,
default_linters,
failures_allowed,
filtering, filtering,
frontend_tests, frontend_tests,
linters_developer_mode,
print_buckets, print_buckets,
print_logs,
print_types, print_types,
reports_include_ml_loc, reports_include_ml_loc,
test, test,
@ -822,10 +844,6 @@ and (
write_dotty write_dotty
) )
and default_linters =
CLOpt.mk_bool ~long:"default-linters" ~parse_mode:CLOpt.(Infer [Clang]) ~default:true
"Use the default linters for the analysis."
and dependencies = and dependencies =
CLOpt.mk_bool ~deprecated:["dependencies"] ~long:"dependencies" CLOpt.mk_bool ~deprecated:["dependencies"] ~long:"dependencies"
~parse_mode:CLOpt.(Infer [Java]) ~parse_mode:CLOpt.(Infer [Java])
@ -900,10 +918,6 @@ and fail_on_bug =
(Printf.sprintf "Exit with error code %d if Infer found something to report" (Printf.sprintf "Exit with error code %d if Infer found something to report"
fail_on_issue_exit_code) fail_on_issue_exit_code)
and failures_allowed =
CLOpt.mk_bool ~deprecated_no:["-no_failures_allowed"] ~long:"failures-allowed" ~default:true
"Fail if at least one of the translations fails (clang only)"
and fcp_apple_clang = and fcp_apple_clang =
CLOpt.mk_path_opt ~long:"fcp-apple-clang" CLOpt.mk_path_opt ~long:"fcp-apple-clang"
~meta:"path" "Specify the path to Apple Clang" ~meta:"path" "Specify the path to Apple Clang"
@ -1013,15 +1027,21 @@ and latex =
~meta:"file" ~meta:"file"
"Write a latex report of the analysis results to a file" "Write a latex report of the analysis results to a file"
and linter =
CLOpt.mk_string_opt ~long:"linter" ~parse_mode:CLOpt.(Infer [Clang])
"From the linters available, only run this one linter. \
(Useful together with --linters-developer-mode)"
and linters_def_file = and linters_def_file =
CLOpt.mk_path_list ~default:[] CLOpt.mk_path_list ~default:[]
~long:"linters-def-file" ~parse_mode:CLOpt.(Infer [Clang]) ~long:"linters-def-file" ~parse_mode:CLOpt.(Infer [Clang])
~meta:"file" "Specify the file containing linters definition (e.g. 'linters.al')" ~meta:"file" "Specify the file containing linters definition (e.g. 'linters.al')"
and linters_developer_mode = and linters_ignore_clang_failures =
CLOpt.mk_bool ~long:"linters-developer-mode" ~parse_mode:CLOpt.(Infer [Clang]) CLOpt.mk_bool ~long:"linters-ignore-clang-failures"
"Debug mode for developing new linters. Sets the linters analyzer, disables other \ ~parse_mode:CLOpt.(Infer [Clang])
default linters and also sets --print-logs, --debug and --no-allowed-failures." ~default:false
"Continue linting files even if some compilation fails."
and load_average = and load_average =
CLOpt.mk_float_opt ~long:"load-average" ~short:'l' CLOpt.mk_float_opt ~long:"load-average" ~short:'l'
@ -1121,10 +1141,6 @@ and precondition_stats =
CLOpt.mk_bool ~deprecated:["precondition_stats"] ~long:"precondition-stats" CLOpt.mk_bool ~deprecated:["precondition_stats"] ~long:"precondition-stats"
"Print stats about preconditions to standard output" "Print stats about preconditions to standard output"
and print_logs =
CLOpt.mk_bool ~long:"print-logs" ~parse_mode:CLOpt.(Infer [Driver])
"Also log messages to stdout and stderr"
and print_builtins = and print_builtins =
CLOpt.mk_bool ~deprecated:["print_builtins"] ~long:"print-builtins" CLOpt.mk_bool ~deprecated:["print_builtins"] ~long:"print-builtins"
"Print the builtin functions and exit" "Print the builtin functions and exit"
@ -1536,13 +1552,9 @@ let post_parsing_initialization () =
List.rev_map ~f:(fun x -> `Raw x) !compilation_database List.rev_map ~f:(fun x -> `Raw x) !compilation_database
|> List.rev_map_append ~f:(fun x -> `Escaped x) !compilation_database_escaped; |> List.rev_map_append ~f:(fun x -> `Escaped x) !compilation_database_escaped;
(* set linters developer flags *) (* set analyzer mode to linters in linters developer mode *)
if !linters_developer_mode then ( if !linters_developer_mode then (
debug := true;
failures_allowed := false;
print_logs := true;
analyzer := Some Linters; analyzer := Some Linters;
default_linters := false
); );
if !default_linters then if !default_linters then
linters_def_file := linters_def_default_file :: !linters_def_file; linters_def_file := linters_def_default_file :: !linters_def_file;
@ -1615,6 +1627,7 @@ and classpath = !classpath
and cluster_cmdline = !cluster and cluster_cmdline = !cluster
and compute_analytics = !compute_analytics and compute_analytics = !compute_analytics
and continue_capture = !continue and continue_capture = !continue
and linter = !linter
and default_linters = !default_linters and default_linters = !default_linters
and linters_ignore_clang_failures = !linters_ignore_clang_failures and linters_ignore_clang_failures = !linters_ignore_clang_failures
and copy_propagation = !copy_propagation and copy_propagation = !copy_propagation
@ -1664,6 +1677,7 @@ and jobs = !jobs
and join_cond = !join_cond and join_cond = !join_cond
and latex = !latex and latex = !latex
and linters_def_file = !linters_def_file and linters_def_file = !linters_def_file
and linters_developer_mode = !linters_developer_mode
and load_average = match !load_average with and load_average = match !load_average with
| None when !buck -> | None when !buck ->
Some (float_of_int ncpu) Some (float_of_int ncpu)

@ -270,7 +270,9 @@ val javac_verbose_out : string
val jobs : int val jobs : int
val join_cond : int val join_cond : int
val latex : string option val latex : string option
val linter : string option
val linters_def_file : string list val linters_def_file : string list
val linters_developer_mode : bool
val load_analysis_results : string option val load_analysis_results : string option
val makefile_cmdline : string val makefile_cmdline : string
val maven : bool val maven : bool

@ -254,9 +254,12 @@ let store_issues source_file =
let do_frontend_checks trans_unit_ctx ast = let do_frontend_checks trans_unit_ctx ast =
try try
let parsed_linters = parse_ctl_files Config.linters_def_file in let parsed_linters = parse_ctl_files Config.linters_def_file in
CFrontend_errors.parsed_linters := parsed_linters; let filtered_parsed_linters = CFrontend_errors.filter_parsed_linters parsed_linters in
CFrontend_errors.parsed_linters := filtered_parsed_linters;
let source_file = trans_unit_ctx.CFrontend_config.source_file in let source_file = trans_unit_ctx.CFrontend_config.source_file in
Logging.out "Start linting file %a@\n" SourceFile.pp source_file; Logging.out "Start linting file %a with rules: @\n%s@\n"
SourceFile.pp source_file
(CFrontend_errors.linters_to_string filtered_parsed_linters);
match ast with match ast with
| Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) -> | Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) ->
let context = let context =

@ -17,6 +17,25 @@ type linter = {
def_file : string option; def_file : string option;
} }
(* If in linter developer mode and if current linter was passed, filter it out *)
let filter_parsed_linters parsed_linters =
if List.length parsed_linters > 1 && Config.linters_developer_mode then
match Config.linter with
| None ->
failwith ("ERROR: In linters developer mode you should debug only one linter at a time. \
This is important for debugging the rule. Pass the flag \
--linter <name> to specify the linter you want to debug.");
| Some lint ->
List.filter ~f:(
fun (rule : linter) -> String.equal rule.issue_desc.name lint
) parsed_linters
else parsed_linters
let linters_to_string linters =
let linter_to_string linters =
List.map ~f:(fun (rule : linter) -> rule.issue_desc.name) linters in
String.concat ~sep:"\n" (linter_to_string linters)
(* Map a formula id to a triple (visited, parameters, definition). (* Map a formula id to a triple (visited, parameters, definition).
Visited is used during the expansion phase to understand if the Visited is used during the expansion phase to understand if the
formula was already expanded and, if yes we have a cyclic definifion *) formula was already expanded and, if yes we have a cyclic definifion *)

@ -15,6 +15,10 @@ type linter = {
def_file : string option; def_file : string option;
} }
val filter_parsed_linters : linter list -> linter list
val linters_to_string : linter list -> string
(* map used to expand macro. It maps a formula id to a triple (* map used to expand macro. It maps a formula id to a triple
(visited, parameters, definition). (visited, parameters, definition).
Visited is used during the expansion phase to understand if the Visited is used during the expansion phase to understand if the

Loading…
Cancel
Save