Adding new mode linters

Summary:
Adding a new mode linters. Now if the analyzer is linters, we do the linters and don't translate,
then, if the analyzer is Infer, we do the translation and the backend and not the linters checks, and the
default is that we do capture, backend and lint checks.

Made the tests separated, which saves time and also shows that the linters mode works.

Reviewed By: jvillard

Differential Revision: D3723472

fbshipit-source-id: 9d828d8
master
Dulma Churchill 8 years ago committed by Facebook Github Bot 6
parent 3d39fba622
commit b7ec110ea3

@ -73,6 +73,7 @@ ANALYZER_CAPTURE = 'capture'
ANALYZER_COMPILE = 'compile'
ANALYZER_TRACING = 'tracing'
ANALYZER_CRASHCONTEXT = 'crashcontext'
ANALYZER_LINTERS = 'linters'
ANALYZERS = [
ANALYZER_CAPTURE,
@ -81,5 +82,6 @@ ANALYZERS = [
ANALYZER_CRASHCONTEXT,
ANALYZER_ERADICATE,
ANALYZER_INFER,
ANALYZER_LINTERS,
ANALYZER_TRACING,
]

@ -18,12 +18,12 @@ module F = Format
type analyzer = Capture | Compile | Infer | Eradicate | Checkers | Tracing
| Crashcontext
| Crashcontext | Linters
let string_to_analyzer =
[("capture", Capture); ("compile", Compile);
("infer", Infer); ("eradicate", Eradicate); ("checkers", Checkers);
("tracing", Tracing); ("crashcontext", Crashcontext)]
("tracing", Tracing); ("crashcontext", Crashcontext); ("linters", Linters)]
type clang_lang = C | CPP | OBJC | OBJCPP
@ -130,7 +130,6 @@ let inferconfig_file = ".inferconfig"
let ivar_attributes = "ivar_attributes"
let lint_issues_dir_name = "lint_issues"
let linters_mode_enabled = false
(** letters used in the analysis output *)
let log_analysis_file = "F"
@ -517,14 +516,15 @@ and analyzer =
let () = match Infer with
(* NOTE: if compilation fails here, it means you have added a new analyzer without updating the
documentation of this option *)
| Capture | Compile | Infer | Eradicate | Checkers | Tracing | Crashcontext -> () in
| Capture | Compile | Infer | Eradicate | Checkers | Tracing | Crashcontext | Linters -> () in
CLOpt.mk_symbol_opt ~deprecated:["analyzer"] ~long:"analyzer" ~short:"a"
~exes:CLOpt.[Toplevel]
"Specify which analyzer to run (only one at a time is supported):\n\
- infer, eradicate, checkers: run the specified analysis\n\
- capture: run capture phase only (no analysis)\n\
- compile: run compilation command without interfering (Java only)\n\
- crashcontext, tracing: experimental (see --crashcontext and --tracing)"
- crashcontext, tracing: experimental (see --crashcontext and --tracing)\n\
- linters: run linters based on the ast only (Objective-C and Objective-C++ only)"
~symbols:string_to_analyzer
and android_harness =

@ -16,7 +16,7 @@ open! Utils
(** Various kind of analyzers *)
type analyzer = Capture | Compile | Infer | Eradicate | Checkers | Tracing
| Crashcontext
| Crashcontext | Linters
(** Association list of analyzers and their names *)
val string_to_analyzer : (string * analyzer) list
@ -81,7 +81,6 @@ val incremental_procs : bool
val initial_analysis_time : float
val ivar_attributes : string
val lint_issues_dir_name : string
val linters_mode_enabled : bool
val load_average : float option
val log_analysis_crash : string
val log_analysis_file : string

@ -27,7 +27,7 @@ let compute_icfg tenv ast =
Printing.log_out "\n Start creating icfg\n";
let cg = Cg.create () in
let cfg = Cfg.Node.create_cfg () in
if not Config.linters_mode_enabled then
if Config.analyzer <> Some Config.Linters then
IList.iter (CFrontend_declImpl.translate_one_declaration tenv cg cfg `DeclTraversal)
decl_list;
Printing.log_out "\n Finished creating icfg\n";
@ -61,7 +61,9 @@ let do_source_file source_file ast =
let call_graph, cfg = compute_icfg tenv ast in
Printing.log_out "\n End building call/cfg graph for '%s'.\n"
(DB.source_file_to_string source_file);
CFrontend_checkers_main.do_frontend_checks cfg call_graph source_file ast;
(* TODO (t12740727): Move this call to cMain once the transition to linters mode is finished *)
if Config.analyzer <> Some Config.Infer then
CFrontend_checkers_main.do_frontend_checks cfg call_graph source_file ast;
(* This part below is a boilerplate in every frontends. *)
(* This could be moved in the cfg_infer module *)
let source_dir = DB.source_dir_from_source_file !DB.current_source in

@ -17,6 +17,7 @@ let rec do_frontend_checks_stmt (context:CLintersContext.context) cfg cg method_
| _ -> ());
do_frontend_checks_stmt context' cfg cg method_decl stmt in
IList.iter (do_all_checks_on_stmts) stmts
and do_frontend_checks_decl context cfg cg decl =
let open Clang_ast_t in
let info = Clang_ast_proj.get_decl_tuple decl in
@ -61,5 +62,6 @@ let do_frontend_checks cfg cg source_file ast =
| Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) ->
let context = context_with_ck_set CLintersContext.empty decl_list in
IList.iter (do_frontend_checks_decl context cfg cg) decl_list;
if Config.linters_mode_enabled then store_issues source_file
(* TODO (t12740727): Remove condition once the transition to linters mode is finished *)
if Config.analyzer = Some Config.Linters then store_issues source_file
| _ -> assert false (* NOTE: Assumes that an AST alsways starts with a TranslationUnitDecl *)

@ -80,9 +80,9 @@ let get_err_log cfg cg method_decl_opt loc =
let procname = match method_decl_opt with
| Some method_decl -> General_utils.procname_of_decl method_decl
| None -> General_utils.get_procname_for_frontend_checks loc in
if Config.linters_mode_enabled then
if Config.analyzer = Some Config.Linters then
LintIssues.get_err_log procname
else
else (* TODO (t12740727): Remove this branch once the transition to linters mode is finished *)
let pdesc = CMethod_trans.get_method_for_frontend_checks cfg cg loc in
Cfg.Procdesc.get_err_log pdesc

@ -1,12 +1,5 @@
/* @generated */
digraph iCFG {
37 [label="37: Exit frontend_checks_260aba1187e75a8c3340e4b361681569 \n " color=yellow style=filled]
36 [label="36: Start frontend_checks_260aba1187e75a8c3340e4b361681569\nFormals: \nLocals: \n " color=yellow style=filled]
36 -> 37 ;
35 [label="35: DeclStmt \n n$4=_fun___objc_alloc_no_fail(sizeof(class NSAutoreleasePool ):unsigned long ) [line 60]\n n$5=_fun_NSObject_init(n$4:class NSAutoreleasePool *) virtual [line 60]\n *&pool:class NSAutoreleasePool *=n$5 [line 60]\n " shape="box"]

@ -40,12 +40,9 @@ public class AssignPointerTest {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createiOSInferCommandWithMLBuckets(
inferCmd = InferRunner.createObjCLintersCommand(
folder,
FILE,
"cf",
true);
FILE);
}
@Test

@ -40,7 +40,7 @@ public class AtomicPropertyTest {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommand(
inferCmd = InferRunner.createObjCLintersCommand(
folder,
FILE);
}

@ -39,7 +39,7 @@ public class NSNumber2Test {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommand(
inferCmd = InferRunner.createObjCLintersCommand(
folder,
NSNUMBER_FILE);
}

@ -39,7 +39,7 @@ public class NSNumberTest {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommand(
inferCmd = InferRunner.createObjCLintersCommand(
folder,
NSNUMBER_FILE);
}

@ -39,10 +39,9 @@ public class RegisteredObserver {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommandSimple(
inferCmd = InferRunner.createObjCLintersCommandSimple(
folder,
VCFile,
"cf");
VCFile);
}
@Test

@ -39,10 +39,9 @@ public class RegisteredObserver2 {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommandSimple(
inferCmd = InferRunner.createObjCLintersCommandSimple(
folder,
VCFile2,
"cf");
VCFile2);
}
@Test

@ -40,10 +40,9 @@ public class RegisteredObserver3 {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommandSimple(
inferCmd = InferRunner.createObjCLintersCommandSimple(
folder,
VCFile3,
"cf");
VCFile3);
}
@Test

@ -39,10 +39,9 @@ public class RegisteredObserver4 {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCInferCommandSimple(
inferCmd = InferRunner.createObjCLintersCommandSimple(
folder,
VCFile,
"cf");
VCFile);
}
@Test

@ -40,7 +40,7 @@ public class StrongDelegateTest {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmdFraction = InferRunner.createObjCInferCommand(
inferCmdFraction = InferRunner.createObjCLintersCommand(
folder,
FILE);
}

@ -35,7 +35,7 @@ package endtoend.objcpp.componentkit;
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCPPInferCommand(
inferCmd = InferRunner.createObjCPPLintersCommand(
folder,
FILE);
}

@ -38,7 +38,7 @@ public class MutableLocalVariableTest {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCPPInferCommand(
inferCmd = InferRunner.createObjCPPLintersCommand(
folder,
FILE);
}

@ -40,7 +40,7 @@ public class BlockCaptureCXXRefTest {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmd = InferRunner.createObjCPPInferCommand(folder, FILE);
inferCmd = InferRunner.createObjCPPLintersCommand(folder, FILE);
}
@Test

@ -41,7 +41,7 @@ public class GlobalVarTest {
@BeforeClass
public static void runInfer() throws InterruptedException, IOException {
inferCmdFraction = InferRunner.createObjCPPInferCommand(
inferCmdFraction = InferRunner.createObjCPPLintersCommand(
folder,
FILE);
}

@ -278,17 +278,14 @@ public class InferRunner {
TemporaryFolder folder,
String sourceFile,
Language lang,
boolean analyze,
String analyzer,
@Nullable String isysroot,
@Nullable String ml_buckets,
boolean arc,
ImmutableList<String> extraInferOptions) {
ImmutableList.Builder<String> inferOptionsBuilder = new ImmutableList.Builder<String>()
.addAll(extraInferOptions);
if (!analyze) {
inferOptionsBuilder.add("--analyzer").add("capture");
}
inferOptionsBuilder.add("--analyzer").add(analyzer);
inferOptionsBuilder
.add("--ml_buckets")
@ -311,7 +308,7 @@ public class InferRunner {
folder,
sourceFile,
Language.C,
false,
"capture",
null,
null,
false,
@ -332,7 +329,7 @@ public class InferRunner {
folder,
sourceFile,
Language.CPP,
false,
"capture",
null,
null,
false,
@ -353,7 +350,7 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjC,
false,
"capture",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
null,
false,
@ -374,7 +371,7 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjC,
false,
"capture",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
null,
true,
@ -395,7 +392,7 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjCPP,
false,
"capture",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
null,
false,
@ -416,7 +413,7 @@ public class InferRunner {
folder,
sourceFile,
Language.C,
true,
"infer",
null,
null,
false,
@ -441,7 +438,7 @@ public class InferRunner {
folder,
sourceFile,
Language.CPP,
true,
"infer",
null,
null,
false,
@ -471,7 +468,7 @@ public class InferRunner {
folder,
sourceFile,
Language.CPP,
true,
"infer",
null,
ml_bucket,
false,
@ -485,28 +482,13 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjC,
true,
"infer",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
null,
false,
ImmutableList.<String>of());
}
public static ImmutableList<String> createObjCInferCommandSimple(
TemporaryFolder folder,
String sourceFile,
String ml_bucket) throws IOException, InterruptedException {
return createClangInferCommand(
folder,
sourceFile,
Language.ObjC,
true,
null,
ml_bucket,
false,
ImmutableList.<String>of());
}
public static ImmutableList<String> createObjCInferCommandWithMLBuckets(
TemporaryFolder folder,
String sourceFile,
@ -516,7 +498,7 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjC,
true,
"infer",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
ml_bucket,
arc,
@ -530,7 +512,7 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjCPP,
true,
"infer",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
null,
false,
@ -544,7 +526,7 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjC,
false,
"infer",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
null,
false,
@ -558,7 +540,7 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjC,
true,
"infer",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
null,
false,
@ -574,13 +556,55 @@ public class InferRunner {
folder,
sourceFile,
Language.ObjC,
true,
"infer",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
bucket,
arc,
ImmutableList.<String>of());
}
public static ImmutableList<String> createLintersCommand(
TemporaryFolder folder,
String sourceFile,
Language lang) throws IOException, InterruptedException {
return createClangInferCommand(
folder,
sourceFile,
lang,
"linters",
getXcodeRoot() + IPHONESIMULATOR_ISYSROOT_SUFFIX,
null,
true,
ImmutableList.<String>of());
}
public static ImmutableList<String> createObjCLintersCommand(
TemporaryFolder folder,
String sourceFile) throws IOException, InterruptedException {
return createLintersCommand(folder, sourceFile, Language.ObjC);
}
public static ImmutableList<String> createObjCLintersCommandSimple(
TemporaryFolder folder,
String sourceFile) throws IOException, InterruptedException {
return createClangInferCommand(
folder,
sourceFile,
Language.ObjC,
"linters",
null,
null,
true,
ImmutableList.<String>of());
}
public static ImmutableList<String> createObjCPPLintersCommand(
TemporaryFolder folder,
String sourceFile) throws IOException, InterruptedException {
return createLintersCommand(folder, sourceFile, Language.ObjCPP);
}
@Nullable
public static File runInferFrontend(ImmutableList<String> inferCmd)
throws IOException, InterruptedException, InferException {

Loading…
Cancel
Save