[buck][java] remove genrule integration and combined mode

Summary:
Now that the buck java flavour is fully deployed, the genrule-based integrations for java can be removed. We also remove the combined (clang+java) integration as this will be reimplemented using flavours in the future.

Also, remove a bunch of deprecated arguments linked to these integrations.

Reviewed By: jvillard

Differential Revision: D26104384

fbshipit-source-id: 6b0059407
master
Nikos Gorogiannis 4 years ago committed by Facebook GitHub Bot
parent e04f0a0ffa
commit 7e4dc9477e

@ -183,7 +183,7 @@ endif
ifneq ($(BUCK),no) ifneq ($(BUCK),no)
BUILD_SYSTEMS_TESTS += genrulecapture buck_java_flavor BUILD_SYSTEMS_TESTS += buck_java_flavor
endif endif
ifneq ($(MVN),no) ifneq ($(MVN),no)
BUILD_SYSTEMS_TESTS += mvn BUILD_SYSTEMS_TESTS += mvn

@ -133,10 +133,6 @@ BUCK OPTIONS
Activates: Buck integration for clang-based targets Activates: Buck integration for clang-based targets
(C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang) (C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang)
--buck-combined
Activates: Buck integration for clang-based and Java targets.
(Conversely: --no-buck-combined)
--buck-compilation-database { no-deps | deps } --buck-compilation-database { no-deps | deps }
Buck integration using the compilation database, with or without Buck integration using the compilation database, with or without
dependencies. Only includes clang targets, as per Buck's dependencies. Only includes clang targets, as per Buck's
@ -146,10 +142,6 @@ BUCK OPTIONS
Depth of dependencies used by the --buck-compilation-database deps Depth of dependencies used by the --buck-compilation-database deps
option. By default, all recursive dependencies are captured. option. By default, all recursive dependencies are captured.
--buck-java
Activates: Buck integration for Java targets. (Conversely:
--no-buck-java)
--buck-java-flavor --buck-java-flavor
Activates: Buck integration for Java which uses the buck flavor Activates: Buck integration for Java which uses the buck flavor
#infer-java-capture instead of genrules like buck-java. #infer-java-capture instead of genrules like buck-java.

@ -140,10 +140,6 @@ OPTIONS
(C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang) (C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang)
See also infer-capture(1). See also infer-capture(1).
--buck-combined
Activates: Buck integration for clang-based and Java targets.
(Conversely: --no-buck-combined) See also infer-capture(1).
--buck-compilation-database { no-deps | deps } --buck-compilation-database { no-deps | deps }
Buck integration using the compilation database, with or without Buck integration using the compilation database, with or without
dependencies. Only includes clang targets, as per Buck's dependencies. Only includes clang targets, as per Buck's
@ -154,10 +150,6 @@ OPTIONS
option. By default, all recursive dependencies are captured. option. By default, all recursive dependencies are captured.
See also infer-capture(1). See also infer-capture(1).
--buck-java
Activates: Buck integration for Java targets. (Conversely:
--no-buck-java) See also infer-capture(1).
--buck-java-flavor --buck-java-flavor
Activates: Buck integration for Java which uses the buck flavor Activates: Buck integration for Java which uses the buck flavor
#infer-java-capture instead of genrules like buck-java. #infer-java-capture instead of genrules like buck-java.

@ -140,10 +140,6 @@ OPTIONS
(C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang) (C/C++/Objective-C/Objective-C++). (Conversely: --no-buck-clang)
See also infer-capture(1). See also infer-capture(1).
--buck-combined
Activates: Buck integration for clang-based and Java targets.
(Conversely: --no-buck-combined) See also infer-capture(1).
--buck-compilation-database { no-deps | deps } --buck-compilation-database { no-deps | deps }
Buck integration using the compilation database, with or without Buck integration using the compilation database, with or without
dependencies. Only includes clang targets, as per Buck's dependencies. Only includes clang targets, as per Buck's
@ -154,10 +150,6 @@ OPTIONS
option. By default, all recursive dependencies are captured. option. By default, all recursive dependencies are captured.
See also infer-capture(1). See also infer-capture(1).
--buck-java
Activates: Buck integration for Java targets. (Conversely:
--no-buck-java) See also infer-capture(1).
--buck-java-flavor --buck-java-flavor
Activates: Buck integration for Java which uses the buck flavor Activates: Buck integration for Java which uses the buck flavor
#infer-java-capture instead of genrules like buck-java. #infer-java-capture instead of genrules like buck-java.

@ -20,29 +20,13 @@ let pp_clang_compilation_db_deps fmt = function
F.pp_print_string fmt "DepsAllDepths" F.pp_print_string fmt "DepsAllDepths"
type t = type t = ClangFlavors | ClangCompilationDB of clang_compilation_db_deps | JavaFlavor
| CombinedGenrule
| ClangFlavors
| ClangCompilationDB of clang_compilation_db_deps
| JavaFlavor
| JavaGenruleMaster
let is_java_genrule_master_or_combined = function
| JavaGenruleMaster | CombinedGenrule ->
true
| ClangFlavors | ClangCompilationDB _ | JavaFlavor ->
false
let is_clang_compilation_db = function let is_clang_compilation_db = function
| ClangCompilationDB _ -> | ClangCompilationDB _ ->
true true
| ClangFlavors | JavaGenruleMaster | CombinedGenrule | JavaFlavor -> | ClangFlavors | JavaFlavor ->
false false
let is_clang_flavors = function let is_clang_flavors = function ClangFlavors -> true | ClangCompilationDB _ | JavaFlavor -> false
| ClangFlavors ->
true
| ClangCompilationDB _ | JavaGenruleMaster | CombinedGenrule | JavaFlavor ->
false

@ -13,14 +13,7 @@ type clang_compilation_db_deps = NoDependencies | DepsUpToDepth of int | DepsAll
val pp_clang_compilation_db_deps : F.formatter -> clang_compilation_db_deps -> unit val pp_clang_compilation_db_deps : F.formatter -> clang_compilation_db_deps -> unit
type t = type t = ClangFlavors | ClangCompilationDB of clang_compilation_db_deps | JavaFlavor
| CombinedGenrule
| ClangFlavors
| ClangCompilationDB of clang_compilation_db_deps
| JavaFlavor
| JavaGenruleMaster
val is_java_genrule_master_or_combined : t -> bool
val is_clang_compilation_db : t -> bool val is_clang_compilation_db : t -> bool

@ -730,20 +730,6 @@ and buck_mode =
~f:(set_mode `ClangFlavors) ~f:(set_mode `ClangFlavors)
"Buck integration for clang-based targets (C/C++/Objective-C/Objective-C++)." "Buck integration for clang-based targets (C/C++/Objective-C/Objective-C++)."
|> ignore ; |> ignore ;
CLOpt.mk_bool ~long:"buck-java"
~deprecated:
[ "-genrule-master-mode"
; "-no-genrule-master-mode"
(* --no-genrule-master-mode was used in the past to enable a now-defunct Java integration,
so both --genrule-master-mode and --no-genrule-master-mode enable the Java
integration... sorry about that. *)
; "-no-flavors"
(* --no-flavors was used in the past to enable the Java integration in some cases, let's
keep it that way for compatibility for now *) ]
~in_help:InferCommand.[(Capture, manual_buck)]
~f:(set_mode `Java)
"Buck integration for Java targets."
|> ignore ;
CLOpt.mk_symbol_opt ~long:"buck-compilation-database" ~deprecated:["-use-compilation-database"] CLOpt.mk_symbol_opt ~long:"buck-compilation-database" ~deprecated:["-use-compilation-database"]
~in_help:InferCommand.[(Capture, manual_buck)] ~in_help:InferCommand.[(Capture, manual_buck)]
~f:(fun s -> ~f:(fun s ->
@ -753,11 +739,6 @@ and buck_mode =
clang targets, as per Buck's $(i,#compilation-database) flavor." clang targets, as per Buck's $(i,#compilation-database) flavor."
~symbols:[("no-deps", `NoDeps); ("deps", `DepsTmp)] ~symbols:[("no-deps", `NoDeps); ("deps", `DepsTmp)]
|> ignore ; |> ignore ;
CLOpt.mk_bool ~long:"buck-combined"
~in_help:InferCommand.[(Capture, manual_buck)]
~f:(set_mode `CombinedGenrule)
"Buck integration for clang-based and Java targets."
|> ignore ;
CLOpt.mk_bool ~long:"buck-java-flavor" CLOpt.mk_bool ~long:"buck-java-flavor"
~in_help:InferCommand.[(Capture, manual_buck)] ~in_help:InferCommand.[(Capture, manual_buck)]
~f:(set_mode `JavaFlavor) ~f:(set_mode `JavaFlavor)
@ -2776,16 +2757,12 @@ and buck_mode : BuckMode.t option =
None None
| `ClangFlavors, _ -> | `ClangFlavors, _ ->
Some ClangFlavors Some ClangFlavors
| `Java, _ ->
Some JavaGenruleMaster
| `ClangCompilationDB `NoDeps, _ -> | `ClangCompilationDB `NoDeps, _ ->
Some (ClangCompilationDB NoDependencies) Some (ClangCompilationDB NoDependencies)
| `ClangCompilationDB `DepsTmp, None -> | `ClangCompilationDB `DepsTmp, None ->
Some (ClangCompilationDB DepsAllDepths) Some (ClangCompilationDB DepsAllDepths)
| `ClangCompilationDB `DepsTmp, Some depth -> | `ClangCompilationDB `DepsTmp, Some depth ->
Some (ClangCompilationDB (DepsUpToDepth depth)) Some (ClangCompilationDB (DepsUpToDepth depth))
| `CombinedGenrule, _ ->
Some CombinedGenrule
| `JavaFlavor, _ -> | `JavaFlavor, _ ->
Some JavaFlavor Some JavaFlavor

@ -114,7 +114,7 @@ module Target = struct
match (mode, command) with match (mode, command) with
| ClangCompilationDB _, _ -> | ClangCompilationDB _, _ ->
add_flavor_internal target "compilation-database" add_flavor_internal target "compilation-database"
| ClangFlavors, Compile | JavaGenruleMaster, _ | CombinedGenrule, _ -> | ClangFlavors, Compile ->
target target
| JavaFlavor, _ -> | JavaFlavor, _ ->
add_flavor_internal target "infer-java-capture" add_flavor_internal target "infer-java-capture"
@ -126,9 +126,6 @@ let config =
let clang_path = let clang_path =
List.fold ["clang"; "install"; "bin"; "clang"] ~init:Config.fcp_dir ~f:Filename.concat List.fold ["clang"; "install"; "bin"; "clang"] ~init:Config.fcp_dir ~f:Filename.concat
in in
let get_java_genrule_config () =
["infer.version=" ^ Version.versionString; "infer.mode=capture"]
in
let get_java_flavor_config () = let get_java_flavor_config () =
if Config.buck_java_flavor_suppress_config then [] if Config.buck_java_flavor_suppress_config then []
else else
@ -158,14 +155,10 @@ let config =
fun buck_mode -> fun buck_mode ->
let args = let args =
match (buck_mode : BuckMode.t) with match (buck_mode : BuckMode.t) with
| JavaGenruleMaster ->
get_java_genrule_config ()
| JavaFlavor -> | JavaFlavor ->
get_java_flavor_config () get_java_flavor_config ()
| ClangFlavors -> | ClangFlavors ->
get_flavors_config () get_flavors_config ()
| CombinedGenrule ->
get_java_genrule_config () @ get_flavors_config ()
| ClangCompilationDB _ -> | ClangCompilationDB _ ->
[] []
in in
@ -201,7 +194,6 @@ module Query = struct
| Set of string list | Set of string list
| Target of string | Target of string
| Union of expr list | Union of expr list
| Labelfilter of {label: string; expr: expr}
exception NotATarget exception NotATarget
@ -226,8 +218,6 @@ module Query = struct
Union exprs Union exprs
let label_filter ~label expr = Labelfilter {label; expr}
let rec pp fmt = function let rec pp fmt = function
| Target s -> | Target s ->
F.pp_print_string fmt s F.pp_print_string fmt s
@ -241,8 +231,6 @@ module Query = struct
F.fprintf fmt "set(%a)" (Pp.seq F.pp_print_string) sl F.fprintf fmt "set(%a)" (Pp.seq F.pp_print_string) sl
| Union exprs -> | Union exprs ->
Pp.seq ~sep:" + " pp fmt exprs Pp.seq ~sep:" + " pp fmt exprs
| Labelfilter {label; expr} ->
F.fprintf fmt "attrfilter(labels, %s, %a)" label pp expr
(* example query json output (* example query json output
@ -335,90 +323,25 @@ let parameters_with_argument =
let get_accepted_buck_kinds_pattern (mode : BuckMode.t) = let get_accepted_buck_kinds_pattern (mode : BuckMode.t) =
match mode with match mode with
| CombinedGenrule ->
"^(android|apple|cxx|java)_(binary|library)$"
| ClangCompilationDB _ -> | ClangCompilationDB _ ->
"^(apple|cxx)_(binary|library|test)$" "^(apple|cxx)_(binary|library|test)$"
| ClangFlavors -> | ClangFlavors ->
"^(apple|cxx)_(binary|library)$" "^(apple|cxx)_(binary|library)$"
| JavaGenruleMaster | JavaFlavor -> | JavaFlavor ->
"^(java|android)_library$" "^(java|android)_library$"
(** for genrule_master_mode, this is the label expected on the capture genrules *)
let infer_enabled_label = "infer_enabled"
(** for genrule_master_mode, this is the target name suffix for the capture genrules *)
let genrule_suffix = "_infer"
let config =
let clang_path =
List.fold ["clang"; "install"; "bin"; "clang"] ~init:Config.fcp_dir ~f:Filename.concat
in
let get_java_genrule_config () =
["infer.version=" ^ Version.versionString; "infer.mode=capture"]
in
let get_java_flavor_config () =
if Config.buck_java_flavor_suppress_config then []
else
[ "infer_java.version=" ^ Version.versionString
; Printf.sprintf "infer_java.binary=%s/infer" Config.bin_dir ]
in
let get_flavors_config () =
[ "client.id=infer.clang"
; Printf.sprintf "*//infer.infer_bin=%s" Config.bin_dir
; Printf.sprintf "*//infer.clang_compiler=%s" clang_path
; Printf.sprintf "*//infer.clang_plugin=%s" Config.clang_plugin_path
; "*//cxx.pch_enabled=false"
; (* Infer doesn't support C++ modules yet (T35656509) *)
"*//cxx.modules_default=false"
; "*//cxx.modules=false" ]
@ ( match Config.xcode_developer_dir with
| Some d ->
[Printf.sprintf "apple.xcode_developer_dir=%s" d]
| None ->
[] )
@
if List.is_empty Config.buck_blacklist then []
else
[ Printf.sprintf "*//infer.blacklist_regex=(%s)"
(String.concat ~sep:")|(" Config.buck_blacklist) ]
in
fun buck_mode ->
let args =
match (buck_mode : BuckMode.t) with
| JavaGenruleMaster ->
get_java_genrule_config ()
| JavaFlavor ->
get_java_flavor_config ()
| ClangFlavors ->
get_flavors_config ()
| CombinedGenrule ->
get_java_genrule_config () @ get_flavors_config ()
| ClangCompilationDB _ ->
[]
in
List.fold args ~init:[] ~f:(fun acc f -> "--config" :: f :: acc)
let resolve_pattern_targets (buck_mode : BuckMode.t) targets = let resolve_pattern_targets (buck_mode : BuckMode.t) targets =
targets |> List.rev_map ~f:Query.target |> Query.set targets |> List.rev_map ~f:Query.target |> Query.set
|> ( match buck_mode with |> ( match buck_mode with
| ClangFlavors | ClangCompilationDB NoDependencies -> | ClangFlavors | ClangCompilationDB NoDependencies ->
Fn.id Fn.id
| CombinedGenrule | ClangCompilationDB DepsAllDepths | JavaGenruleMaster | JavaFlavor -> | ClangCompilationDB DepsAllDepths | JavaFlavor ->
Query.deps None Query.deps None
| ClangCompilationDB (DepsUpToDepth depth) -> | ClangCompilationDB (DepsUpToDepth depth) ->
Query.deps (Some depth) ) Query.deps (Some depth) )
|> Query.kind ~pattern:(get_accepted_buck_kinds_pattern buck_mode) |> Query.kind ~pattern:(get_accepted_buck_kinds_pattern buck_mode)
|> ( if BuckMode.is_java_genrule_master_or_combined buck_mode then
Query.label_filter ~label:infer_enabled_label
else Fn.id )
|> Query.exec ~buck_mode |> Query.exec ~buck_mode
|>
if BuckMode.is_java_genrule_master_or_combined buck_mode then
List.rev_map ~f:(fun s -> s ^ genrule_suffix)
else Fn.id
type parsed_args = type parsed_args =
@ -497,7 +420,7 @@ let parse_command_and_targets (buck_mode : BuckMode.t) original_buck_args =
match (buck_mode, parsed_args) with match (buck_mode, parsed_args) with
| ClangFlavors, {pattern_targets= []; alias_targets= []; normal_targets} -> | ClangFlavors, {pattern_targets= []; alias_targets= []; normal_targets} ->
normal_targets normal_targets
| ( (ClangFlavors | CombinedGenrule | JavaGenruleMaster | ClangCompilationDB _ | JavaFlavor) | ( (ClangFlavors | ClangCompilationDB _ | JavaFlavor)
, {pattern_targets; alias_targets; normal_targets} ) -> , {pattern_targets; alias_targets; normal_targets} ) ->
pattern_targets |> List.rev_append alias_targets |> List.rev_append normal_targets pattern_targets |> List.rev_append alias_targets |> List.rev_append normal_targets
|> resolve_pattern_targets buck_mode |> resolve_pattern_targets buck_mode

@ -1,185 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
module F = Format
module L = Logging
(* example build report json output
[
{
"success" : true,
"results" : {
"//annotations:annotations_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/annotations/annotations_infer/infer_out"
},
"//module2:module2_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/module2/module2_infer/infer_out"
},
"//module1:module1_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/module1/module1_infer/infer_out"
},
"//module3:module1_infer" : {
"success" : "SUCCESS",
"type" : "BUILT_LOCALLY",
"outputs" : {
"DEFAULT" : [ "buck-out/gen/module1/module3_infer/infer_out" ]
}
}
},
"failures" : { }
}%
]
*)
(** Read the build report json file buck produced, and parse into a list of pairs
[(target, output-path)]. NB contrary to what buck documentation says, the output path is always
present even when the target is locally cached. *)
let read_and_parse_report build_report =
let get_json_field fieldname = function
| `Assoc fields ->
List.Assoc.find fields ~equal:String.equal fieldname
| _ ->
None
in
let parse_target (target, json) =
let path_opt =
match get_json_field "output" json with
| Some (`String str) ->
Some str
| _ -> (
match get_json_field "outputs" json |> Option.bind ~f:(get_json_field "DEFAULT") with
| Some (`List [`String str]) ->
Some str
| _ ->
None )
in
match path_opt with
| None ->
L.internal_error "Could not parse target json: %s@." (Yojson.Basic.to_string json) ;
None
| Some path ->
Some (target, path)
in
let parse_results = function
| `Assoc results ->
(* NB this will simply skip unparseable targets *)
List.filter_map results ~f:parse_target |> Option.some
| _ ->
None
in
Yojson.Basic.from_file build_report |> get_json_field "results" |> Option.bind ~f:parse_results
(** Function for processing paths in a buck build report and generating an [infer-deps.txt] file.
Given a pair [(buck_target, output_path)],
- if [output_path] contains a capture DB, then generate the appropriate deps line;
- if [output_path] contains an [infer-deps.txt] file, expand and inline it;
- if [output_path] is a dummy target used in the combined genrule integration for clang targets,
read its contents, parse them as an output directory path and apply the above two tests to
that *)
let expand_target acc (target, target_path) =
let expand_dir acc (target, target_path) =
(* invariant: [target_path] is absolute *)
let db_file = ResultsDirEntryName.get_path ~results_dir:target_path CaptureDB in
match Sys.file_exists db_file with
| `Yes ->
(* there is a capture DB at this path, so terminate expansion and generate deps line *)
let line = Printf.sprintf "%s\t-\t%s" target target_path in
line :: acc
| `No | `Unknown -> (
(* no capture DB was found, so look for, and inline, an [infer-deps.txt] file *)
let infer_deps =
ResultsDirEntryName.get_path ~results_dir:target_path CaptureDependencies
in
match Sys.file_exists infer_deps with
| `Yes ->
Utils.with_file_in infer_deps
~f:(In_channel.fold_lines ~init:acc ~f:(fun acc line -> line :: acc))
| `No | `Unknown ->
L.internal_error "No capture DB or infer-deps file in %s@." target_path ;
acc )
in
let target_path =
if Filename.is_absolute target_path then target_path else Config.project_root ^/ target_path
in
match Sys.is_directory target_path with
| `Yes ->
(* output path is directory, so should contain either a capture DB or an [infer-deps.txt] file *)
expand_dir acc (target, target_path)
| `No | `Unknown -> (
(* output path is not a directory, so assume it's an intermediate genrule output containing the
output path of the underlying capture target *)
match Utils.read_file target_path with
| Ok [new_target_path] ->
expand_dir acc (target, new_target_path)
| Ok _ ->
L.internal_error "Couldn't parse intermediate deps file %s@." target_path ;
acc
| Error error ->
L.internal_error "Error %s@\nCouldn't read intermediate deps file %s@." error target_path ;
acc )
let infer_deps_of_build_report build_report =
match read_and_parse_report build_report with
| None ->
L.die InternalError "Couldn't parse buck build report: %s@." build_report
| Some target_path_list ->
let infer_deps_lines =
List.fold target_path_list ~init:[] ~f:expand_target
|> List.dedup_and_sort ~compare:String.compare
in
let infer_deps = ResultsDir.get_path CaptureDependencies in
Utils.with_file_out infer_deps ~f:(fun out_channel ->
Out_channel.output_lines out_channel infer_deps_lines )
let run_buck_capture cmd =
let path_var = "PATH" in
let new_path =
Sys.getenv path_var
|> Option.value_map ~default:Config.bin_dir ~f:(fun old_path -> Config.bin_dir ^ ":" ^ old_path)
in
let extend_env = [(path_var, new_path)] in
Buck.wrap_buck_call ~extend_env ~label:"build" cmd |> ignore
let capture buck_mode build_cmd =
let prog, buck_cmd = (List.hd_exn build_cmd, List.tl_exn build_cmd) in
L.progress "Querying buck for genrule capture targets...@." ;
let time0 = Mtime_clock.counter () in
let command, args, targets = Buck.parse_command_and_targets buck_mode buck_cmd in
L.progress "Found %d genrule capture targets in %a.@." (List.length targets) Mtime.Span.pp
(Mtime_clock.count time0) ;
let all_args = List.rev_append args targets in
let build_report_file =
Filename.temp_file ~in_dir:(ResultsDir.get_path Temporary) "buck_build_report" ".json"
in
let updated_buck_cmd =
(* make buck tell us where in buck-out are the capture directories for merging *)
(prog :: command :: "--build-report" :: build_report_file :: Buck.config buck_mode)
@ Config.buck_build_args_no_inline
@ Buck.store_args_in_file ~identifier:"genrule_build" all_args
in
L.(debug Capture Quiet)
"Processed buck command '%a'@." (Pp.seq F.pp_print_string) updated_buck_cmd ;
if List.is_empty targets then L.external_warning "WARNING: found no buck targets to analyze.@."
else
let time0 = Mtime_clock.counter () in
run_buck_capture updated_buck_cmd ;
infer_deps_of_build_report build_report_file ;
L.progress "Genrule capture took %a.@." Mtime.Span.pp (Mtime_clock.count time0) ;
ResultsDir.RunState.set_merge_capture true ;
()

@ -1,14 +0,0 @@
(*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)
open! IStd
val infer_deps_of_build_report : string -> unit
(** parse a buck build report and construct resulting [infer-deps.txt] *)
val capture : BuckMode.t -> string list -> unit
(** do genrule capture with the given buck command line *)

@ -9,6 +9,143 @@ open! IStd
module F = Format module F = Format
module L = Logging module L = Logging
(* example build report json output
[
{
"success" : true,
"results" : {
"//annotations:annotations_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/annotations/annotations_infer/infer_out"
},
"//module2:module2_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/module2/module2_infer/infer_out"
},
"//module1:module1_infer" : {
"success" : true,
"type" : "BUILT_LOCALLY",
"output" : "buck-out/gen/module1/module1_infer/infer_out"
},
"//module3:module1_infer" : {
"success" : "SUCCESS",
"type" : "BUILT_LOCALLY",
"outputs" : {
"DEFAULT" : [ "buck-out/gen/module1/module3_infer/infer_out" ]
}
}
},
"failures" : { }
}%
]
*)
(** Read the build report json file buck produced, and parse into a list of pairs
[(target, output-path)]. NB contrary to what buck documentation says, the output path is always
present even when the target is locally cached. *)
let read_and_parse_report build_report =
let get_json_field fieldname = function
| `Assoc fields ->
List.Assoc.find fields ~equal:String.equal fieldname
| _ ->
None
in
let parse_target (target, json) =
let path_opt =
match get_json_field "output" json with
| Some (`String str) ->
Some str
| _ -> (
match get_json_field "outputs" json |> Option.bind ~f:(get_json_field "DEFAULT") with
| Some (`List [`String str]) ->
Some str
| _ ->
None )
in
match path_opt with
| None ->
L.internal_error "Could not parse target json: %s@." (Yojson.Basic.to_string json) ;
None
| Some path ->
Some (target, path)
in
let parse_results = function
| `Assoc results ->
(* NB this will simply skip unparseable targets *)
List.filter_map results ~f:parse_target |> Option.some
| _ ->
None
in
Yojson.Basic.from_file build_report |> get_json_field "results" |> Option.bind ~f:parse_results
(** Function for processing paths in a buck build report and generating an [infer-deps.txt] file.
Given a pair [(buck_target, output_path)],
- if [output_path] contains a capture DB, then generate the appropriate deps line;
- if [output_path] contains an [infer-deps.txt] file, expand and inline it;
- if [output_path] is a dummy target used in the combined genrule integration for clang targets,
read its contents, parse them as an output directory path and apply the above two tests to
that *)
let expand_target acc (target, target_path) =
let expand_dir acc (target, target_path) =
(* invariant: [target_path] is absolute *)
let db_file = ResultsDirEntryName.get_path ~results_dir:target_path CaptureDB in
match Sys.file_exists db_file with
| `Yes ->
(* there is a capture DB at this path, so terminate expansion and generate deps line *)
let line = Printf.sprintf "%s\t-\t%s" target target_path in
line :: acc
| `No | `Unknown -> (
(* no capture DB was found, so look for, and inline, an [infer-deps.txt] file *)
let infer_deps =
ResultsDirEntryName.get_path ~results_dir:target_path CaptureDependencies
in
match Sys.file_exists infer_deps with
| `Yes ->
Utils.with_file_in infer_deps
~f:(In_channel.fold_lines ~init:acc ~f:(fun acc line -> line :: acc))
| `No | `Unknown ->
L.internal_error "No capture DB or infer-deps file in %s@." target_path ;
acc )
in
let target_path =
if Filename.is_absolute target_path then target_path else Config.project_root ^/ target_path
in
match Sys.is_directory target_path with
| `Yes ->
(* output path is directory, so should contain either a capture DB or an [infer-deps.txt] file *)
expand_dir acc (target, target_path)
| `No | `Unknown -> (
(* output path is not a directory, so assume it's an intermediate genrule output containing the
output path of the underlying capture target *)
match Utils.read_file target_path with
| Ok [new_target_path] ->
expand_dir acc (target, new_target_path)
| Ok _ ->
L.internal_error "Couldn't parse intermediate deps file %s@." target_path ;
acc
| Error error ->
L.internal_error "Error %s@\nCouldn't read intermediate deps file %s@." error target_path ;
acc )
let infer_deps_of_build_report build_report =
match read_and_parse_report build_report with
| None ->
L.die InternalError "Couldn't parse buck build report: %s@." build_report
| Some target_path_list ->
let infer_deps_lines =
List.fold target_path_list ~init:[] ~f:expand_target
|> List.dedup_and_sort ~compare:String.compare
in
let infer_deps = ResultsDir.get_path CaptureDependencies in
Utils.with_file_out infer_deps ~f:(fun out_channel ->
Out_channel.output_lines out_channel infer_deps_lines )
let capture build_cmd = let capture build_cmd =
let prog, buck_cmd = (List.hd_exn build_cmd, List.tl_exn build_cmd) in let prog, buck_cmd = (List.hd_exn build_cmd, List.tl_exn build_cmd) in
L.progress "Querying buck for java flavor capture targets...@." ; L.progress "Querying buck for java flavor capture targets...@." ;
@ -34,7 +171,7 @@ let capture build_cmd =
else else
let time0 = Mtime_clock.counter () in let time0 = Mtime_clock.counter () in
Buck.wrap_buck_call ~label:"build" updated_buck_cmd |> ignore ; Buck.wrap_buck_call ~label:"build" updated_buck_cmd |> ignore ;
BuckGenrule.infer_deps_of_build_report build_report_file ; infer_deps_of_build_report build_report_file ;
L.progress "Java flavor capture took %a.@." Mtime.Span.pp (Mtime_clock.count time0) ; L.progress "Java flavor capture took %a.@." Mtime.Span.pp (Mtime_clock.count time0) ;
ResultsDir.RunState.set_merge_capture true ; ResultsDir.RunState.set_merge_capture true ;
() ()

@ -18,10 +18,8 @@ type mode =
| Analyze | Analyze
| Ant of {prog: string; args: string list} | Ant of {prog: string; args: string list}
| BuckClangFlavor of {build_cmd: string list} | BuckClangFlavor of {build_cmd: string list}
| BuckCombinedGenrule of {build_cmd: string list}
| BuckCompilationDB of {deps: BuckMode.clang_compilation_db_deps; prog: string; args: string list} | BuckCompilationDB of {deps: BuckMode.clang_compilation_db_deps; prog: string; args: string list}
| BuckGenrule of {prog: string} | BuckGenrule of {prog: string}
| BuckGenruleMaster of {build_cmd: string list}
| BuckJavaFlavor of {build_cmd: string list} | BuckJavaFlavor of {build_cmd: string list}
| Clang of {compiler: Clang.compiler; prog: string; args: string list} | Clang of {compiler: Clang.compiler; prog: string; args: string list}
| ClangCompilationDB of {db_files: [`Escaped of string | `Raw of string] list} | ClangCompilationDB of {db_files: [`Escaped of string | `Raw of string] list}
@ -41,15 +39,11 @@ let pp_mode fmt = function
F.fprintf fmt "Ant driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args F.fprintf fmt "Ant driver mode:@\nprog = '%s'@\nargs = %a" prog Pp.cli_args args
| BuckClangFlavor {build_cmd} -> | BuckClangFlavor {build_cmd} ->
F.fprintf fmt "BuckClangFlavor driver mode: build_cmd = %a" Pp.cli_args build_cmd F.fprintf fmt "BuckClangFlavor driver mode: build_cmd = %a" Pp.cli_args build_cmd
| BuckCombinedGenrule {build_cmd} ->
F.fprintf fmt "BuckCombinedGenrule driver mode: build_cmd = %a" Pp.cli_args build_cmd
| BuckCompilationDB {deps; prog; args} -> | BuckCompilationDB {deps; prog; args} ->
F.fprintf fmt "BuckCompilationDB driver mode:@\nprog = '%s'@\nargs = %a@\ndeps = %a" prog F.fprintf fmt "BuckCompilationDB driver mode:@\nprog = '%s'@\nargs = %a@\ndeps = %a" prog
Pp.cli_args args BuckMode.pp_clang_compilation_db_deps deps Pp.cli_args args BuckMode.pp_clang_compilation_db_deps deps
| BuckGenrule {prog} -> | BuckGenrule {prog} ->
F.fprintf fmt "BuckGenRule driver mode:@\nprog = '%s'" prog F.fprintf fmt "BuckGenRule driver mode:@\nprog = '%s'" prog
| BuckGenruleMaster {build_cmd} ->
F.fprintf fmt "BuckGenrule driver mode:@\nbuild command = %a" Pp.cli_args build_cmd
| BuckJavaFlavor {build_cmd} -> | BuckJavaFlavor {build_cmd} ->
F.fprintf fmt "BuckJavaFlavor driver mode:@\nbuild command = %a" Pp.cli_args build_cmd F.fprintf fmt "BuckJavaFlavor driver mode:@\nbuild command = %a" Pp.cli_args build_cmd
| Clang {prog; args} -> | Clang {prog; args} ->
@ -113,9 +107,6 @@ let capture ~changed_files = function
| BuckClangFlavor {build_cmd} -> | BuckClangFlavor {build_cmd} ->
L.progress "Capturing in buck mode...@." ; L.progress "Capturing in buck mode...@." ;
BuckFlavors.capture build_cmd BuckFlavors.capture build_cmd
| BuckCombinedGenrule {build_cmd} ->
L.progress "Capturing in buck combined genrule mode...@." ;
BuckGenrule.capture CombinedGenrule build_cmd
| BuckCompilationDB {deps; prog; args} -> | BuckCompilationDB {deps; prog; args} ->
L.progress "Capturing using Buck's compilation database...@." ; L.progress "Capturing using Buck's compilation database...@." ;
let db_files = let db_files =
@ -125,9 +116,6 @@ let capture ~changed_files = function
| BuckGenrule {prog} -> | BuckGenrule {prog} ->
L.progress "Capturing for Buck genrule compatibility...@." ; L.progress "Capturing for Buck genrule compatibility...@." ;
JMain.from_arguments prog JMain.from_arguments prog
| BuckGenruleMaster {build_cmd} ->
L.progress "Capturing for BuckGenruleMaster integration...@." ;
BuckGenrule.capture JavaGenruleMaster build_cmd
| BuckJavaFlavor {build_cmd} -> | BuckJavaFlavor {build_cmd} ->
L.progress "Capturing for BuckJavaFlavor integration...@." ; L.progress "Capturing for BuckJavaFlavor integration...@." ;
BuckJavaFlavor.capture build_cmd BuckJavaFlavor.capture build_cmd
@ -252,7 +240,7 @@ let analyze_and_report ?suppress_console_report ~changed_files mode =
&& InferCommand.equal Run Config.command -> && InferCommand.equal Run Config.command ->
(* if doing capture + analysis of buck with flavors, we always need to merge targets before the analysis phase *) (* if doing capture + analysis of buck with flavors, we always need to merge targets before the analysis phase *)
true true
| Analyze | BuckGenruleMaster _ | BuckCombinedGenrule _ | BuckJavaFlavor _ | Gradle _ -> | Analyze | BuckJavaFlavor _ | Gradle _ ->
ResultsDir.RunState.get_merge_capture () ResultsDir.RunState.get_merge_capture ()
| _ -> | _ ->
false false
@ -336,13 +324,11 @@ let assert_supported_build_system build_system =
match Config.buck_mode with match Config.buck_mode with
| None -> | None ->
error_no_buck_mode_specified () error_no_buck_mode_specified ()
| Some CombinedGenrule ->
(`ClangJava, "buck combined genrule")
| Some ClangFlavors -> | Some ClangFlavors ->
(`Clang, "buck with flavors") (`Clang, "buck with flavors")
| Some (ClangCompilationDB _) -> | Some (ClangCompilationDB _) ->
(`Clang, "buck compilation database") (`Clang, "buck compilation database")
| Some (JavaGenruleMaster | JavaFlavor) -> | Some JavaFlavor ->
(`Java, Config.string_of_build_system build_system) (`Java, Config.string_of_build_system build_system)
in in
assert_supported_mode analyzer build_string assert_supported_mode analyzer build_string
@ -369,8 +355,6 @@ let mode_of_build_command build_cmd (buck_mode : BuckMode.t option) =
Ant {prog; args} Ant {prog; args}
| BBuck, None -> | BBuck, None ->
error_no_buck_mode_specified () error_no_buck_mode_specified ()
| BBuck, Some CombinedGenrule ->
BuckCombinedGenrule {build_cmd}
| BBuck, Some (ClangCompilationDB deps) -> | BBuck, Some (ClangCompilationDB deps) ->
BuckCompilationDB {deps; prog; args= List.append args Config.buck_build_args} BuckCompilationDB {deps; prog; args= List.append args Config.buck_build_args}
| BBuck, Some ClangFlavors when Config.is_checker_enabled Linters -> | BBuck, Some ClangFlavors when Config.is_checker_enabled Linters ->
@ -378,8 +362,6 @@ let mode_of_build_command build_cmd (buck_mode : BuckMode.t option) =
"WARNING: the linters require --buck-compilation-database to be set.@ Alternatively, \ "WARNING: the linters require --buck-compilation-database to be set.@ Alternatively, \
set --no-linters to disable them and this warning.@." ; set --no-linters to disable them and this warning.@." ;
BuckClangFlavor {build_cmd} BuckClangFlavor {build_cmd}
| BBuck, Some JavaGenruleMaster ->
BuckGenruleMaster {build_cmd}
| BBuck, Some JavaFlavor -> | BBuck, Some JavaFlavor ->
BuckJavaFlavor {build_cmd} BuckJavaFlavor {build_cmd}
| BBuck, Some ClangFlavors -> | BBuck, Some ClangFlavors ->

@ -15,10 +15,8 @@ type mode =
| Analyze | Analyze
| Ant of {prog: string; args: string list} | Ant of {prog: string; args: string list}
| BuckClangFlavor of {build_cmd: string list} | BuckClangFlavor of {build_cmd: string list}
| BuckCombinedGenrule of {build_cmd: string list}
| BuckCompilationDB of {deps: BuckMode.clang_compilation_db_deps; prog: string; args: string list} | BuckCompilationDB of {deps: BuckMode.clang_compilation_db_deps; prog: string; args: string list}
| BuckGenrule of {prog: string} | BuckGenrule of {prog: string}
| BuckGenruleMaster of {build_cmd: string list}
| BuckJavaFlavor of {build_cmd: string list} | BuckJavaFlavor of {build_cmd: string list}
| Clang of {compiler: Clang.compiler; prog: string; args: string list} | Clang of {compiler: Clang.compiler; prog: string; args: string list}
| ClangCompilationDB of {db_files: [`Escaped of string | `Raw of string] list} | ClangCompilationDB of {db_files: [`Escaped of string | `Raw of string] list}

@ -1,2 +0,0 @@
[buildfile]
includes = //DEFS

@ -1,91 +0,0 @@
import os
original_cxx_library = cxx_library
original_java_library = java_library
infer_clang_flavor = "infer-capture-all"
def _cxx_infer_capture_genrule(name):
cmd = "echo $(location :{}#{}) > $OUT".format(name, infer_clang_flavor)
genrule(
name = name + "_infer",
out = "dummy_out",
cmd = cmd,
)
def cxx_library(name, **kwargs):
_cxx_infer_capture_genrule(name)
new_kwargs = dict(kwargs, labels=kwargs.get("labels", []) + ["infer_enabled"])
original_cxx_library(
name=name,
**new_kwargs
)
def _get_project_root():
return "\$(git rev-parse --show-toplevel)/infer/tests/build_systems/buck_combined"
def _infer_capture_genrule(
name,
srcs
):
args = [
"--jobs",
"1",
"--genrule-mode",
"--quiet",
"--no-progress-bar",
"--results-dir",
"$OUT",
"--sourcepath",
"$SRCDIR",
"--project-root",
_get_project_root(),
"--classpath",
"$(classpath :{})".format(name),
"--generated-classes",
"$(location :{})".format(name),
"capture",
]
args_file = os.path.join("$TMP", "args.txt")
subcommands = [
"echo {} >> {}".format(arg, args_file)
for arg in args
] + [
"infer @" + args_file
]
genrule(
name = name + "_infer",
srcs = srcs,
cmd = " && ".join(subcommands),
out = "infer_out",
labels = ["infer_genrule"],
)
def _make_infer_capture_genrule(name, kwargs):
java_sources = [
f
for f in kwargs.get("srcs", [])
if f.endswith(".java")
]
if java_sources != []:
_infer_capture_genrule(name, java_sources)
kwargs["labels"] = kwargs.get("labels", []) + ["infer_enabled"]
return kwargs
def java_library(name, **kwargs):
new_kwargs = _make_infer_capture_genrule(name, kwargs)
original_java_library(
name=name,
**new_kwargs
)

@ -1,26 +0,0 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
TESTS_DIR = ../..
ROOT_DIR = $(TESTS_DIR)/../..
BUCK_TARGET = //clang:hello //java:hello
SOURCES = clang/hello.c clang/hello2.c
OBJECTS = buck-out/gen/clang/hello\#compile-hello.c.o1f717d69,default/hello.c.o
INFER_OPTIONS = --report-custom-error --developer-mode --no-linters --buck-combined
INFERPRINT_OPTIONS = --issues-tests
CLEAN_EXTRA = buck-out
include $(TESTS_DIR)/infer.make
$(OBJECTS): $(SOURCES)
$(QUIET)$(call silent_on_success,Compiling Buck flavors tests,\
$(BUCK) build --no-cache $(BUCK_TARGET))
infer-out/report.json: $(CLANG_DEPS) $(SOURCES) $(MAKEFILE_LIST)
$(QUIET)$(BUCK) clean
$(call silent_on_success,Testing infer-run Buck combined genrule integration,\
$(INFER_BIN) $(INFER_OPTIONS) run --results-dir $(CURDIR)/infer-out -- \
$(BUCK) build --no-cache $(BUCK_TARGET))

@ -1,6 +0,0 @@
cxx_library(
name = 'hello',
srcs = [
'hello.c', 'hello2.c',
],
)

@ -1,13 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <stdlib.h>
void test() {
int* s = NULL;
*s = 42;
}

@ -1,13 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <stdlib.h>
void test2() {
int* s = NULL;
*s = 42;
}

@ -1,3 +0,0 @@
clang/hello.c, test, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test()]
clang/hello2.c, test2, 2, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure test2()]
java/NullDeref.java, NullDeref.callToStringWithNullBad():java.lang.String, 1, NULL_DEREFERENCE, no_bucket, ERROR, [start of procedure callToStringWithNullBad(),start of procedure myToString(...),Skipping toString(): unknown method]

@ -1,6 +0,0 @@
java_library(
name='hello',
srcs=glob(["*.java"]),
deps=[],
visibility=['PUBLIC'],
)

@ -1,16 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
public class NullDeref {
private static String myToString(Object foo) {
return foo.toString();
}
public String callToStringWithNullBad() {
return myToString(null);
}
}

@ -4,6 +4,6 @@
* This source code is licensed under the MIT license found in the * This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package genrulecapture.annotations; package buck_java_flavor.annotations;
public @interface ThreadSafe {} public @interface ThreadSafe {}

@ -1,2 +1,2 @@
module2/Class2.java, genrulecapture.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`] module2/Class2.java, buck_java_flavor.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
module2/Class2.java, genrulecapture.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`] module2/Class2.java, buck_java_flavor.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package genrulecapture.module1; package buck_java_flavor.module1;
public class Class1 { public class Class1 {
int x; int x;

@ -5,10 +5,10 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
package genrulecapture.module2; package buck_java_flavor.module2;
import genrulecapture.annotations.ThreadSafe; import buck_java_flavor.annotations.ThreadSafe;
import genrulecapture.module1.Class1; import buck_java_flavor.module1.Class1;
@ThreadSafe @ThreadSafe
public class Class2 { public class Class2 {

@ -1,9 +0,0 @@
[buildfile]
includes = //DEFS
[project]
ignore = .git, .ml, .mli
[java]
source_level = 8
target_level = 8

@ -1,78 +0,0 @@
import os
original_java_library = java_library
original_android_library = android_library
def _get_project_root():
return "\$(git rev-parse --show-toplevel)/infer/tests/build_systems/genrulecapture"
def _infer_capture_genrule(
name,
srcs
):
args = [
"--jobs",
"1",
"--genrule-mode",
"--quiet",
"--no-progress-bar",
"--results-dir",
"$OUT",
"--sourcepath",
"$SRCDIR",
"--project-root",
_get_project_root(),
"--classpath",
"$(classpath :{})".format(name),
"--generated-classes",
"$(location :{})".format(name),
"capture",
]
args_file = os.path.join("$TMP", "args.txt")
subcommands = [
"echo {} >> {}".format(arg, args_file)
for arg in args
] + [
"infer @" + args_file
]
genrule(
name = name + "_infer",
srcs = srcs,
cmd = " && ".join(subcommands),
out = "infer_out",
labels = ["infer_genrule"],
)
def _make_infer_capture_genrule(name, kwargs):
java_sources = [
f
for f in kwargs.get("srcs", [])
if f.endswith(".java")
]
if java_sources != []:
_infer_capture_genrule(name, java_sources)
kwargs["labels"] = kwargs.get("labels", []) + ["infer_enabled"]
return kwargs
def java_library(name, **kwargs):
new_kwargs = _make_infer_capture_genrule(name, kwargs)
original_java_library(
name=name,
**new_kwargs
)
def android_library(name, **kwargs):
new_kwargs = _make_infer_capture_genrule(name, kwargs)
original_android_library(
name=name,
**new_kwargs
)

@ -1,21 +0,0 @@
# Copyright (c) Facebook, Inc. and its affiliates.
#
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
TESTS_DIR = ../..
BUCK_TARGET = //module2:module2
CLEAN_EXTRA = buck-out
SOURCES = $(shell find . -name '*.java')
INFERPRINT_OPTIONS = --issues-tests
INFER_OPTIONS = --buck-java --debug-exceptions
include $(TESTS_DIR)/infer.make
$(INFER_OUT)/report.json: $(MAKEFILE_LIST) $(SOURCES)
$(QUIET)$(BUCK) clean
$(call silent_on_success,Testing genrule capture integration in $(TEST_REL_DIR),\
$(INFER_BIN) --results-dir $(@D) $(INFER_OPTIONS) -- \
$(BUCK) build --no-cache $(BUCK_TARGET))

@ -1,7 +0,0 @@
java_library(
name='annotations',
srcs=['ThreadSafe.java'],
visibility=[
'PUBLIC'
],
)

@ -1,9 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.annotations;
public @interface ThreadSafe {}

@ -1,2 +0,0 @@
module2/Class2.java, genrulecapture.module2.Class2.get():int, 22, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [<Read trace>,call to int Class1.get(),access to `this.c.x`,<Write trace>,call to void Class1.set(int),access to `this.c.x`]
module2/Class2.java, genrulecapture.module2.Class2.set(int):void, 18, THREAD_SAFETY_VIOLATION, no_bucket, WARNING, [call to void Class1.set(int),access to `this.c.x`]

@ -1,10 +0,0 @@
java_library(
name='module1',
srcs=glob(["*.java"]),
deps=[
'//annotations:annotations',
],
visibility=[
'PUBLIC'
],
)

@ -1,20 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.module1;
public class Class1 {
int x;
public void set(int d) {
x = d;
}
public int get() {
return x;
}
}

@ -1,9 +0,0 @@
java_library(
name='module2',
srcs=glob(["*.java"]),
deps=[
'//module1:module1',
'//annotations:annotations',
'//module3:module3',
]
)

@ -1,24 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
package genrulecapture.module2;
import genrulecapture.annotations.ThreadSafe;
import genrulecapture.module1.Class1;
@ThreadSafe
public class Class2 {
Class1 c;
void set(int x) {
c.set(x);
}
int get() {
return c.get();
}
}

@ -1,9 +0,0 @@
cxx_library(
name = 'module3',
visibility = [
'PUBLIC',
],
srcs = [
'some_c_code.c',
],
)

@ -1,13 +0,0 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include <stdlib.h>
void some_c_func() {
int* s = NULL;
*s = 42;
}
Loading…
Cancel
Save