Summary: In this diff, we just load the info from the storage. Next diff will be actually using this information to infer nullability. `ThirdPartyAnnotationGlobalRepo.get_repo` will be used in the next diff, hence #skipdeadcode Reviewed By: artempyanykh Differential Revision: D18347647 fbshipit-source-id: 82a9223c6master
parent
7ea42938fe
commit
3d2df4cc3c
@ -0,0 +1,45 @@
|
||||
(*
|
||||
* 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
|
||||
|
||||
let load_third_party_repo ~absolute_path_to_repo_dir =
|
||||
match Sys.is_directory absolute_path_to_repo_dir with
|
||||
| `Yes -> (
|
||||
match ThirdPartyAnnotationInfoLoader.load ~path_to_repo_dir:absolute_path_to_repo_dir with
|
||||
| Ok storage ->
|
||||
storage
|
||||
| Error error ->
|
||||
Logging.die Logging.InternalError "Error while reading 3rd party annotation repo: %a"
|
||||
ThirdPartyAnnotationInfoLoader.pp_load_error error )
|
||||
| _ ->
|
||||
Logging.die Logging.InternalError
|
||||
"Could not locate 3rd party annotation repository: expected location %s"
|
||||
absolute_path_to_repo_dir
|
||||
|
||||
|
||||
let get_absolute_path_to_repo_dir relative_path_to_repo_dir =
|
||||
match Config.inferconfig_dir with
|
||||
| None ->
|
||||
Logging.die Logging.InternalError
|
||||
"Could not locate .inferconfig directory, which is required for resolving the path to \
|
||||
third party annotation repository"
|
||||
| Some inferconfig_dir ->
|
||||
inferconfig_dir ^/ relative_path_to_repo_dir
|
||||
|
||||
|
||||
let create_global_storage () =
|
||||
match Config.nullsafe_third_party_signatures with
|
||||
| Some dir ->
|
||||
load_third_party_repo ~absolute_path_to_repo_dir:(get_absolute_path_to_repo_dir dir)
|
||||
(* Create empty *)
|
||||
| None ->
|
||||
ThirdPartyAnnotationInfo.create_storage ()
|
||||
|
||||
|
||||
let init () =
|
||||
let global_storage = create_global_storage () in
|
||||
ThirdPartyAnnotationGlobalRepo.initialize global_storage
|
@ -0,0 +1,10 @@
|
||||
(*
|
||||
* 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 init : unit -> unit
|
||||
(** This function should be called once before nullsafe checker is called *)
|
@ -0,0 +1,25 @@
|
||||
(*
|
||||
* 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
|
||||
|
||||
let repo = ref None
|
||||
|
||||
let initialize storage =
|
||||
match !repo with
|
||||
| None ->
|
||||
repo := Some storage
|
||||
| Some _ ->
|
||||
Logging.die Logging.InternalError "Attempt to initialize global 3rd party repository twice"
|
||||
|
||||
|
||||
let get_repo () =
|
||||
match !repo with
|
||||
| None ->
|
||||
Logging.die Logging.InternalError "Attempt to access not initialized 3rd party repository"
|
||||
| Some repo ->
|
||||
repo
|
@ -0,0 +1,16 @@
|
||||
(*
|
||||
* 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
|
||||
|
||||
(** A singleton. Should be initialized once prior to start of nullsafe. *)
|
||||
|
||||
val initialize : ThirdPartyAnnotationInfo.storage -> unit
|
||||
(** Should be initialized exactly once before access. *)
|
||||
|
||||
val get_repo : unit -> ThirdPartyAnnotationInfo.storage
|
||||
(** Can be accessed only when initialization was done *)
|
@ -0,0 +1,29 @@
|
||||
(*
|
||||
* 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
|
||||
|
||||
type load_error = {filename: string; parsing_error: ThirdPartyAnnotationInfo.file_parsing_error}
|
||||
|
||||
let pp_load_error fmt {filename; parsing_error} =
|
||||
Format.fprintf fmt "Could not parse %s: %a" filename ThirdPartyAnnotationInfo.pp_parsing_error
|
||||
parsing_error
|
||||
|
||||
|
||||
let add_from_file storage ~path_to_repo_dir ~sig_file =
|
||||
let lines = In_channel.read_lines (path_to_repo_dir ^ "/" ^ sig_file) in
|
||||
ThirdPartyAnnotationInfo.add_from_signature_file storage ~lines
|
||||
|> Result.map_error ~f:(fun parsing_error -> {filename= sig_file; parsing_error})
|
||||
|> Result.bind ~f:(fun _ -> Ok storage)
|
||||
|
||||
|
||||
let load ~path_to_repo_dir =
|
||||
(* Sequentally load information from all .sig files *)
|
||||
Sys.ls_dir path_to_repo_dir
|
||||
|> List.filter ~f:(String.is_suffix ~suffix:".sig")
|
||||
|> List.fold_result ~init:(ThirdPartyAnnotationInfo.create_storage ())
|
||||
~f:(fun accumulated_storage sig_file ->
|
||||
add_from_file accumulated_storage ~path_to_repo_dir ~sig_file )
|
@ -0,0 +1,17 @@
|
||||
(*
|
||||
* 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
|
||||
|
||||
type load_error
|
||||
|
||||
val pp_load_error : Format.formatter -> load_error -> unit
|
||||
|
||||
val load : path_to_repo_dir:string -> (ThirdPartyAnnotationInfo.storage, load_error) result
|
||||
(** Given a path to a repo with 3rd annotation info, loads it from a disk to
|
||||
in-memory representation.
|
||||
After this is done, information can be requested via [ThirdPartyAnnotationInfo].
|
||||
*)
|
@ -0,0 +1,2 @@
|
||||
some.test.pckg.SomeClass#getNullable() @Nullable
|
||||
some.test.pckg.SomeClass#getNonnull()
|
Loading…
Reference in new issue