[cli] introduce `--linters` and `--capture`

Summary:
Linters are now considered a "checker", like backend checkers. This makes, eg,
`--racerd-only` disable the linters, which is more intuitive.

We can now express `-a linters` and `--clang-frontend-action` in terms of these
two new options. For instance, `-a linters --clang-frontend-action lint` is the
same as `--linters-only --no-capture`.

This is another step in the direction of getting rid of `--analyzers`.

Reviewed By: dulmarod

Differential Revision: D6147387

fbshipit-source-id: 53622b2
master
Jules Villard 7 years ago committed by Facebook Github Bot
parent e7907032bf
commit 71ed554c57

@ -277,14 +277,16 @@ let add parse_mode sections desc =
()
let deprecate_desc parse_mode ~long ~short ~deprecated desc =
let deprecate_desc parse_mode ~long ~short ~deprecated doc desc =
let warn () =
match parse_mode with
| Javac | NoParse ->
()
| InferCommand ->
| InferCommand when long <> "" ->
warnf "WARNING: '-%s' is deprecated. Use '--%s'%s instead.@." deprecated long
(if short = "" then "" else Printf.sprintf " or '-%s'" short)
| InferCommand ->
warnf "WARNING: '-%s' is deprecated. Here is its documentation:@\n%s@." deprecated doc
in
let warn_then_f f x = warn () ; f x in
let deprecated_spec =
@ -335,7 +337,7 @@ let mk ?(deprecated= []) ?(parse_mode= InferCommand) ?(in_help= []) ~long ?short
if short <> "" then add parse_mode [] {desc with long= ""; meta= ""; doc= ""} ;
(* add desc for deprecated options only for parsing, without documentation *)
List.iter deprecated ~f:(fun deprecated ->
deprecate_desc parse_mode ~long ~short ~deprecated desc |> add parse_mode [] ) ;
deprecate_desc parse_mode ~long ~short ~deprecated doc desc |> add parse_mode [] ) ;
variable

@ -713,6 +713,7 @@ and ( annotation_reachability
, eradicate
, fragment_retains_view
, immutable_cast
, linters
, liveness
, printf_args
, quandary
@ -750,6 +751,7 @@ and ( annotation_reachability
and immutable_cast =
mk_checker ~long:"immutable-cast" ~default:true
"the detection of object cast from immutable type to mutable type. For instance, it will detect cast from ImmutableList to List, ImmutableMap to Map, and ImmutableSet to Set."
and linters = mk_checker ~long:"linters" ~default:true "syntactic linters"
and liveness =
mk_checker ~long:"liveness" ~default:true "the detection of dead stores and unused variables"
and printf_args =
@ -812,6 +814,7 @@ and ( annotation_reachability
, eradicate
, fragment_retains_view
, immutable_cast
, linters
, liveness
, printf_args
, quandary
@ -898,6 +901,11 @@ and calls_csv =
~meta:"file" "Write individual calls in CSV format to $(i,file)"
and capture =
CLOpt.mk_bool ~long:"capture" ~default:true
"capture and translate source files into infer's intermediate language for analysis"
and changed_files_index =
CLOpt.mk_path_opt ~long:"changed-files-index"
~in_help:CLOpt.([(Analyze, manual_generic); (Diff, manual_generic)])
@ -914,10 +922,10 @@ and clang_biniou_file =
and clang_compilation_dbs = ref []
and clang_frontend_action =
CLOpt.mk_symbol_opt ~long:"clang-frontend-action"
CLOpt.mk_symbol_opt ~long:"" ~deprecated:["-clang-frontend-action"]
~in_help:CLOpt.([(Capture, manual_clang); (Run, manual_clang)])
"Specify whether the clang frontend should capture or lint or both."
~symbols:clang_frontend_action_symbols
(* doc only shows up in deprecation warnings *)
"use --capture and --linters instead" ~symbols:clang_frontend_action_symbols
and clang_include_to_override_regex =
@ -2161,7 +2169,7 @@ let post_parsing_initialization command_opt =
:= List.rev_map ~f:(fun x -> `Raw x) !compilation_database
|> List.rev_map_append ~f:(fun x -> `Escaped x) !compilation_database_escaped ;
(* set analyzer mode to linters in linters developer mode *)
if !linters_developer_mode then analyzer := Some Linters ;
if !linters_developer_mode then linters := true ;
if !default_linters then linters_def_file := linters_def_default_file :: !linters_def_file ;
( if Option.is_none !analyzer then
match (command_opt : CLOpt.command option) with
@ -2179,7 +2187,11 @@ let post_parsing_initialization command_opt =
| Some Crashcontext ->
disable_all_checkers () ;
crashcontext := true
| Some (CaptureOnly | Checkers | CompileOnly | Linters) | None ->
| Some Linters ->
disable_all_checkers () ;
capture := false ;
linters := true
| Some (CaptureOnly | Checkers | CompileOnly) | None ->
() ) ;
Option.value ~default:CLOpt.Run command_opt
@ -2294,6 +2306,17 @@ and bufferoverrun = !bufferoverrun
and calls_csv = !calls_csv
and capture =
(* take `--clang-frontend-action` as the source of truth as long as that option exists *)
match !clang_frontend_action with
| Some (`Capture | `Lint_and_capture) ->
true
| Some `Lint ->
false
| None ->
!capture
and changed_files_index = !changed_files_index
and check_nullable = !check_nullable
@ -2436,6 +2459,17 @@ and latex = !latex
and linter = !linter
and linters =
(* take `--clang-frontend-action` as the source of truth as long as that option exists *)
match !clang_frontend_action with
| Some (`Lint | `Lint_and_capture) ->
true
| Some `Capture ->
false
| None ->
!linters
and linters_def_file = !linters_def_file
and linters_def_folder = !linters_def_folder
@ -2670,30 +2704,11 @@ and analysis_suppress_errors analyzer =
let captured_dir = results_dir ^/ captured_dir_name
let clang_frontend_do_capture, clang_frontend_do_lint =
match !clang_frontend_action with
| Some `Lint ->
(false, true) (* no capture, lint *)
| Some `Capture ->
(true, false) (* capture, no lint *)
| Some `Lint_and_capture ->
(true, true) (* capture, lint *)
| None ->
match !analyzer with
| Some Linters ->
(false, true) (* no capture, lint *)
| Some BiAbduction | Some Checkers ->
(true, false) (* capture, no lint *)
| _ ->
(* capture, lint *) (true, true)
let analyzer = match !analyzer with Some a -> a | None -> Checkers
let clang_frontend_action_string =
String.concat ~sep:" and "
( (if clang_frontend_do_capture then ["translating"] else [])
@ if clang_frontend_do_lint then ["linting"] else [] )
((if capture then ["translating"] else []) @ if linters then ["linting"] else [])
let dynamic_dispatch =

@ -326,6 +326,8 @@ val bufferoverrun : bool
val calls_csv : string option
val capture : bool
val captured_dir : string
(** directory where the results of the capture phase are stored *)
@ -337,10 +339,6 @@ val clang_biniou_file : string option
val clang_frontend_action_string : string
val clang_frontend_do_capture : bool
val clang_frontend_do_lint : bool
val clang_ignore_regex : string option
val clang_include_to_override_regex : string option
@ -506,6 +504,8 @@ val latex : string option
val linter : string option
val linters : bool
val linters_def_file : string list
val linters_def_folder : string list

@ -35,7 +35,7 @@ let init_global_state_for_capture_and_linters source_file =
L.(debug Capture Medium) "Processing %s" (Filename.basename (SourceFile.to_abs_path source_file)) ;
if Config.developer_mode then register_perf_stats_report source_file ;
Config.curr_language := Config.Clang ;
if Config.clang_frontend_do_capture then DB.Results_dir.init source_file ;
if Config.capture then DB.Results_dir.init source_file ;
CFrontend_config.reset_global_state ()
@ -85,9 +85,8 @@ let run_clang_frontend ast_source =
L.(debug Capture Quiet) "Clang frontend action is %s@\n" Config.clang_frontend_action_string ;
L.(debug Capture Medium)
"Start %s of AST from %a@\n" Config.clang_frontend_action_string pp_ast_filename ast_source ;
if Config.clang_frontend_do_lint then
CFrontend_checkers_main.do_frontend_checks trans_unit_ctx ast_decl ;
if Config.clang_frontend_do_capture then CFrontend.do_source_file trans_unit_ctx ast_decl ;
if Config.linters then CFrontend_checkers_main.do_frontend_checks trans_unit_ctx ast_decl ;
if Config.capture then CFrontend.do_source_file trans_unit_ctx ast_decl ;
L.(debug Capture Medium)
"End %s of AST file %a... OK!@\n" Config.clang_frontend_action_string pp_ast_filename
ast_source ;

@ -63,18 +63,16 @@ let run_compilation_database compilation_database should_capture_file =
CompilationDatabase.filter_compilation_data compilation_database ~f:should_capture_file
in
let number_of_jobs = List.length compilation_data in
let capture_text =
if Config.equal_analyzer Config.analyzer Config.Linters then "linting" else "translating"
in
L.(debug Capture Quiet) "Starting %s %d files@\n%!" capture_text number_of_jobs ;
L.progress "Starting %s %d files@\n%!" capture_text number_of_jobs ;
L.(debug Capture Quiet)
"Starting %s %d files@\n%!" Config.clang_frontend_action_string number_of_jobs ;
L.progress "Starting %s %d files@\n%!" Config.clang_frontend_action_string number_of_jobs ;
let sequence = Parmap.L (List.map ~f:create_cmd compilation_data) in
let fail_sentinel_fname = Config.results_dir ^/ Config.linters_failed_sentinel_filename in
let fail_sentinel =
if Config.linters_ignore_clang_failures then None
else
match Config.buck_compilation_database with
| Some NoDeps when Config.clang_frontend_do_lint ->
| Some NoDeps when Config.linters ->
Some fail_sentinel_fname
| Some NoDeps | Some Deps _ | None ->
None

@ -127,7 +127,7 @@ let clean_results_dir () =
let check_captured_empty mode =
let clean_command_opt = clean_compilation_command mode in
if Config.clang_frontend_do_capture && Utils.directory_is_empty Config.captured_dir then (
if Config.capture && Utils.directory_is_empty Config.captured_dir then (
( match clean_command_opt with
| Some clean_command ->
L.user_warning "@\nNothing to compile. Try running `%s` first.@." clean_command

Loading…
Cancel
Save