[linters] Introduce whitelist and blacklist path, also multiple paths

Reviewed By: ddino

Differential Revision: D5209648

fbshipit-source-id: dbb77c2
master
Dulma Churchill 8 years ago committed by Facebook Github Bot
parent 938425020d
commit dfca0cdcf7

@ -18,7 +18,8 @@ type linter = {
condition : CTL.t;
issue_desc : CIssue.issue_desc;
def_file : string option;
path : string option;
whitelist_paths : ALVar.t list;
blacklist_paths : ALVar.t list;
}
(* If in linter developer mode and if current linter was passed, filter it out *)
@ -37,9 +38,16 @@ let filter_parsed_linters_developer parsed_linters =
let filter_parsed_linters_by_path parsed_linters source_file =
let filter_parsed_linter_by_path linter =
match linter.path with
| Some path -> ALVar.str_match_regex (SourceFile.to_rel_path source_file) path
| None -> true in
let should_lint paths =
List.exists
~f:(fun path -> ALVar.compare_str_with_alexp (SourceFile.to_rel_path source_file) path)
paths in
let whitelist_ok =
List.is_empty linter.whitelist_paths || should_lint linter.whitelist_paths in
let blacklist_ok =
List.is_empty linter.blacklist_paths || not (should_lint linter.blacklist_paths) in
whitelist_ok && blacklist_ok
in
List.filter ~f:filter_parsed_linter_by_path parsed_linters
let filter_parsed_linters parsed_linters source_file =
@ -162,30 +170,32 @@ let create_parsed_linters linters_def_file checkers : linter list =
severity = Exceptions.Kwarning;
mode = CIssue.On;
} in
let issue_desc, condition, path =
let process_linter_definitions (issue, cond, path) description =
let issue_desc, condition, whitelist_paths, blacklist_paths =
let process_linter_definitions (issue, cond, wl_paths, bl_paths) description =
match description with
| CSet (av, phi) when ALVar.is_report_when_keyword av ->
issue, phi, path
issue, phi, wl_paths, bl_paths
| CDesc (av, msg) when ALVar.is_message_keyword av ->
{issue with description = msg}, cond, path
{issue with description = msg}, cond, wl_paths, bl_paths
| CDesc (av, sugg) when ALVar.is_suggestion_keyword av ->
{issue with suggestion = Some sugg}, cond, path
{issue with suggestion = Some sugg}, cond, wl_paths, bl_paths
| CDesc (av, sev) when ALVar.is_severity_keyword av ->
{issue with severity = string_to_err_kind sev}, cond, path
{issue with severity = string_to_err_kind sev}, cond, wl_paths, bl_paths
| CDesc (av, m) when ALVar.is_mode_keyword av ->
{issue with mode = string_to_issue_mode m }, cond, path
| CDesc (av, path') when ALVar.is_path_keyword av ->
issue, cond, string_to_path path'
| _ -> issue, cond, path in
{issue with mode = string_to_issue_mode m }, cond, wl_paths, bl_paths
| CPath (`WhitelistPath, paths) ->
issue, cond, paths, bl_paths
| CPath (`BlacklistPath, paths) ->
issue, cond, wl_paths, paths
| _ -> issue, cond, wl_paths, bl_paths in
List.fold
~f:process_linter_definitions
~init:(dummy_issue, CTL.False, None)
~init:(dummy_issue, CTL.False, [], [])
checker.definitions in
L.(debug Linters Medium) "@\nMaking condition and issue desc for checker '%s'@\n" checker.name;
L.(debug Linters Medium) "@\nCondition =@\n %a@\n" CTL.Debug.pp_formula condition;
L.(debug Linters Medium) "@\nIssue_desc = %a@\n" CIssue.pp_issue issue_desc;
{condition; issue_desc; def_file = Some linters_def_file; path;} in
{condition; issue_desc; def_file = Some linters_def_file; whitelist_paths; blacklist_paths;} in
List.map ~f:do_one_checker checkers
let rec apply_substitution f sub =

@ -13,7 +13,8 @@ type linter = {
condition : CTL.t;
issue_desc : CIssue.issue_desc;
def_file : string option;
path : string option;
whitelist_paths : ALVar.t list;
blacklist_paths : ALVar.t list;
}
val filter_parsed_linters : linter list -> SourceFile.t -> linter list

@ -77,10 +77,12 @@ let has_transition phi = match phi with
set message = "bla"
*)
type clause =
| CLet of ALVar.formula_id * ALVar.t list * t (* Let clause: let id = definifion; *)
| CSet of ALVar.keyword * t (* Set clause: set id = definition *)
| CDesc of ALVar.keyword * string (* Description clause eg: set message = "..." *)
| CPath of [ `WhitelistPath | `BlacklistPath ] * ALVar.t list
type ctl_checker = {
name : string; (* Checker's name *)
@ -441,7 +443,14 @@ let print_checker c =
cn_str Debug.pp_formula phi
| CDesc (keyword, s) ->
let cn_str = ALVar.keyword_to_string keyword in
L.(debug Linters Medium) " %s= @\n %s@\n@\n" cn_str s)
L.(debug Linters Medium) " %s= @\n %s@\n@\n" cn_str s
| CPath (paths_keyword, paths) ->
let keyword =
(match paths_keyword with
| `WhitelistPath -> "whitelist_path"
| _ -> "blacklist_path") in
let paths_str = String.concat ~sep:"," (List.map ~f:ALVar.alexp_to_string paths) in
L.(debug Linters Medium) " %s= @\n %s@\n@\n" keyword paths_str)
) c.definitions;
L.(debug Linters Medium) "@\n-------------------- @\n"

@ -80,6 +80,7 @@ type clause =
| CLet of ALVar.formula_id * ALVar.t list * t (* Let clause: let id = definifion; *)
| CSet of ALVar.keyword * t (* Set clause: set id = definition *)
| CDesc of ALVar.keyword * string (* Description clause eg: set message = "..." *)
| CPath of [ `WhitelistPath | `BlacklistPath ] * ALVar.t list
type ctl_checker = {
name : string; (* Checker's name *)

@ -54,6 +54,8 @@ rule token = parse
| "LET" { LET }
| "TRUE" { TRUE }
| "FALSE" { FALSE }
| "whitelist_path" { WHITELIST_PATH }
| "blacklist_path" { BLACKLIST_PATH }
| "{" { LEFT_BRACE }
| "}" { RIGHT_BRACE }
| "(" { LEFT_PAREN }

@ -67,6 +67,8 @@
%token <string> IDENTIFIER
%token <string> FILE_IDENTIFIER
%token <string> STRING
%token WHITELIST_PATH
%token BLACKLIST_PATH
%token EOF
/* associativity and priority (lower to higher) of operators */
@ -125,6 +127,11 @@ checker:
}
;
path_list:
| alexp { [$1] }
| alexp COMMA path_list { $1 :: $3 }
;
clause_list:
| clause SEMICOLON { [$1] }
| clause SEMICOLON clause_list { $1 :: $3 }
@ -143,6 +150,10 @@ clause:
| _ -> failwith "string '%s' cannot be set to a variable. \
Use the reserverd variable 'report_when'" in
CTL.CSet (alvar, $4) }
| SET WHITELIST_PATH ASSIGNMENT LEFT_BRACE path_list RIGHT_BRACE
{ CTL.CPath (`WhitelistPath, $5) }
| SET BLACKLIST_PATH ASSIGNMENT LEFT_BRACE path_list RIGHT_BRACE
{ CTL.CPath (`BlacklistPath, $5) }
| SET identifier ASSIGNMENT STRING
{ L.(debug Linters Verbose) "\tParsed SET clause@\n";
let alvar = match $2 with
@ -150,10 +161,9 @@ clause:
| "suggestion" -> ALVar.Suggestion
| "severity" -> ALVar.Severity
| "mode" -> ALVar.Mode
| "path" -> ALVar.Path
| _ -> failwithf "string '%s' cannot be set in a SET clause. \
Use either of: \
'message', 'mode', 'severity', 'suggestion' or 'path'" $2 in
'message', 'mode', 'severity' or 'suggestion'" $2 in
CTL.CDesc (alvar, $4) }
| let_clause { $1 }
;

@ -2,7 +2,9 @@ codetoanalyze/objc/linters-for-test-only/filter_by_path/include_file.m, main, 9,
codetoanalyze/objc/linters-for-test-only/filter_by_path/include_file.m, main, 9, FILTER_BY_ALL_PATH_EXAMPLE, []
codetoanalyze/objc/linters-for-test-only/filter_by_path/include_file.m, main, 9, FILTER_BY_PATH_EXAMPLE, []
codetoanalyze/objc/linters-for-test-only/implicit_cast.c, main, 9, ALL_PATH_NO_FILTER_EXAMPLE, []
codetoanalyze/objc/linters-for-test-only/implicit_cast.c, main, 9, BLACKLIST_PATH_EXAMPLE, []
codetoanalyze/objc/linters-for-test-only/implicit_cast.c, main, 9, FILTER_BY_ALL_PATH_EXAMPLE, []
codetoanalyze/objc/linters-for-test-only/implicit_cast.c, main, 9, WHITE_BLACKLIST_PATH_EXAMPLE, []
codetoanalyze/objc/linters-for-test-only/implicit_cast.c, main, 10, TEST_VAR_TYPE_CHECK, []
codetoanalyze/objc/linters-for-test-only/implicit_cast.c, main, 11, TEST_IMPLICIT_CAST_CHECK, []
codetoanalyze/objc/linters-for-test-only/implicit_cast.c, main, 11, TEST_VAR_TYPE_CHECK, []

@ -242,7 +242,7 @@ DEFINE-CHECKER FILTER_BY_PATH_EXAMPLE = {
WHEN declaration_has_name("main")
HOLDS-IN-NODE FunctionDecl;
SET message = "Found main method";
SET path = "codetoanalyze/objc/linters-for-test-only/filter_by_path/.*";
SET whitelist_path = { REGEXP("codetoanalyze/objc/linters-for-test-only/filter_by_path/.*"), "A.m" };
};
DEFINE-CHECKER ALL_PATH_NO_FILTER_EXAMPLE = {
@ -257,5 +257,22 @@ DEFINE-CHECKER FILTER_BY_ALL_PATH_EXAMPLE = {
WHEN declaration_has_name("main")
HOLDS-IN-NODE FunctionDecl;
SET message = "Found main method";
SET path = ".*";
SET whitelist_path = { REGEXP(".*") };
};
DEFINE-CHECKER BLACKLIST_PATH_EXAMPLE = {
SET report_when =
WHEN declaration_has_name("main")
HOLDS-IN-NODE FunctionDecl;
SET message = "Found main method";
SET blacklist_path = { REGEXP("codetoanalyze/objc/linters-for-test-only/filter_by_path/.*") };
};
DEFINE-CHECKER WHITE_BLACKLIST_PATH_EXAMPLE = {
SET report_when =
WHEN declaration_has_name("main")
HOLDS-IN-NODE FunctionDecl;
SET message = "Found main method";
SET whitelist_path = { REGEXP(".*") };
SET blacklist_path = { REGEXP("codetoanalyze/objc/linters-for-test-only/filter_by_path/.*") };
};

Loading…
Cancel
Save