[nullsafe] Slightly more functional style for ThirdPartyAnnotationInfo storage

Summary:
Let the functions return the modified storage, not unit.

It will play nicely with the next diff, which will add more data to
storage which will be non-mutable.

Reviewed By: artempyanykh

Differential Revision: D18569768

fbshipit-source-id: ade5685be
master
Mitya Lyubarskiy 5 years ago committed by Facebook Github Bot
parent 108473e97b
commit 71fd925d7f

@ -20,23 +20,27 @@ let pp_parsing_error fmt {line_number; unparsable_method; parsing_error} =
(* Consequtively evaluates results for all elements in a list,
returns Ok () if all succeeded or the first error.
returns Ok (folded results) if all succeeded, or the first error.
The evaluator function [f] has access to element's index.
*)
let bind_list_with_index list ~f =
List.foldi list ~init:(Ok ()) ~f:(fun index acc elem -> Result.bind acc ~f:(fun _ -> f index elem))
let bind_list_with_index ~init list ~f =
List.foldi list ~init:(Ok init) ~f:(fun index acc elem ->
Result.bind acc ~f:(fun acc -> f acc index elem) )
let parse_line_and_add_to_storage storage line =
let parse_line_and_add_to_storage storage _line_index line =
let open Result in
ThirdPartyMethod.parse line
>>= fun (signature, nullability) -> Ok (Hashtbl.add storage signature nullability)
>>= fun (signature, nullability) ->
Ok
( Hashtbl.add storage signature nullability ;
storage )
let add_from_signature_file storage ~lines =
(* each line in a file should represent a method signature *)
bind_list_with_index lines ~f:(fun index method_as_str ->
parse_line_and_add_to_storage storage method_as_str
bind_list_with_index lines ~init:storage ~f:(fun storage index method_as_str ->
parse_line_and_add_to_storage storage index method_as_str
|> Result.map_error ~f:(fun parsing_error ->
{line_number= index + 1; unparsable_method= method_as_str; parsing_error} ) )

@ -17,7 +17,7 @@ type file_parsing_error =
val pp_parsing_error : Format.formatter -> file_parsing_error -> unit
val add_from_signature_file : storage -> lines:string list -> (unit, file_parsing_error) result
val add_from_signature_file : storage -> lines:string list -> (storage, file_parsing_error) result
(** Parse the information from the signature file, and add it to the storage *)
val find_nullability_info :

@ -34,16 +34,18 @@ let assert_no_info storage unique_repr =
let add_from_annot_file_and_check_success storage ~lines =
ThirdPartyAnnotationInfo.add_from_signature_file storage ~lines
|> Result.iter_error ~f:(fun parsing_error ->
assert_failure
(F.asprintf "Expected to parse the file, but it was unparsable: %a"
ThirdPartyAnnotationInfo.pp_parsing_error parsing_error) )
match ThirdPartyAnnotationInfo.add_from_signature_file storage ~lines with
| Ok storage ->
storage
| Error parsing_error ->
assert_failure
(F.asprintf "Expected to parse the file, but it was unparsable: %a"
ThirdPartyAnnotationInfo.pp_parsing_error parsing_error)
let add_from_annot_file_and_check_failure storage ~lines ~expected_error_line_number =
match ThirdPartyAnnotationInfo.add_from_signature_file storage ~lines with
| Ok () ->
| Ok _ ->
assert_failure
"Expected to not be able to parse the file, but it was successfully parsed instead"
| Error {line_number} ->
@ -55,10 +57,11 @@ let basic_find =
let open ThirdPartyMethod in
"basic_find"
>:: fun _ ->
let storage = ThirdPartyAnnotationInfo.create_storage () in
let lines = ["a.A#foo(b.B)"; "b.B#bar(c.C, @Nullable d.D) @Nullable"] in
(* Load some functions from the file *)
add_from_annot_file_and_check_success storage ~lines ;
let storage =
add_from_annot_file_and_check_success (ThirdPartyAnnotationInfo.create_storage ()) ~lines
in
(* Make sure we can find what we just stored *)
assert_has_nullability_info storage
{class_name= "a.A"; method_name= Method "foo"; param_types= ["b.B"]}
@ -83,7 +86,6 @@ let overload_resolution =
let open ThirdPartyMethod in
"overload_resolution"
>:: fun _ ->
let storage = ThirdPartyAnnotationInfo.create_storage () in
let lines =
[ "a.b.SomeClass#foo(@Nullable a.b.C1) @Nullable"
; "a.b.SomeClass#<init>(a.b.C1)"
@ -94,7 +96,9 @@ let overload_resolution =
; "a.b.SomeClass#foo(@Nullable a.b.C2)" ]
in
(* Load some functions from the file *)
add_from_annot_file_and_check_success storage ~lines ;
let storage =
add_from_annot_file_and_check_success (ThirdPartyAnnotationInfo.create_storage ()) ~lines
in
(* Make sure we can find what we just stored *)
(* a.b.SomeClass.foo with 1 param *)
assert_has_nullability_info storage
@ -146,16 +150,17 @@ let can_add_several_files =
"can_add_several_files"
>:: fun _ ->
let open ThirdPartyMethod in
let storage = ThirdPartyAnnotationInfo.create_storage () in
(* 1. Add file and check if we added info *)
let file1 = ["a.A#foo(b.B)"; "b.B#bar(c.C, @Nullable d.D) @Nullable"] in
add_from_annot_file_and_check_success storage ~lines:file1 ;
let storage =
add_from_annot_file_and_check_success (ThirdPartyAnnotationInfo.create_storage ()) ~lines:file1
in
assert_has_nullability_info storage
{class_name= "a.A"; method_name= Method "foo"; param_types= ["b.B"]}
~expected_nullability:{ret_nullability= Nonnull; param_nullability= [Nonnull]} ;
(* 2. Add another file and check if we added info *)
let file2 = ["e.E#baz(f.F)"; "g.G#<init>(h.H, @Nullable i.I) @Nullable"] in
add_from_annot_file_and_check_success storage ~lines:file2 ;
let storage = add_from_annot_file_and_check_success storage ~lines:file2 in
assert_has_nullability_info storage
{class_name= "e.E"; method_name= Method "baz"; param_types= ["f.F"]}
~expected_nullability:{ret_nullability= Nonnull; param_nullability= [Nonnull]} ;
@ -176,7 +181,8 @@ let should_not_forgive_unparsable_strings =
let file_ok = [line1; line2_ok; line3] in
let file_bad = [line1; line2_bad; line3] in
(* Ensure we can add the good file, but can not add the bad one *)
add_from_annot_file_and_check_success (ThirdPartyAnnotationInfo.create_storage ()) ~lines:file_ok ;
add_from_annot_file_and_check_success (ThirdPartyAnnotationInfo.create_storage ()) ~lines:file_ok
|> ignore ;
add_from_annot_file_and_check_failure
(ThirdPartyAnnotationInfo.create_storage ())
~lines:file_bad ~expected_error_line_number:2

Loading…
Cancel
Save