[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, (* 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. The evaluator function [f] has access to element's index.
*) *)
let bind_list_with_index list ~f = let bind_list_with_index ~init list ~f =
List.foldi list ~init:(Ok ()) ~f:(fun index acc elem -> Result.bind acc ~f:(fun _ -> f index elem)) 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 let open Result in
ThirdPartyMethod.parse line 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 = let add_from_signature_file storage ~lines =
(* each line in a file should represent a method signature *) (* each line in a file should represent a method signature *)
bind_list_with_index lines ~f:(fun index method_as_str -> bind_list_with_index lines ~init:storage ~f:(fun storage index method_as_str ->
parse_line_and_add_to_storage storage method_as_str parse_line_and_add_to_storage storage index method_as_str
|> Result.map_error ~f:(fun parsing_error -> |> Result.map_error ~f:(fun parsing_error ->
{line_number= index + 1; unparsable_method= method_as_str; 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 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 *) (** Parse the information from the signature file, and add it to the storage *)
val find_nullability_info : 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 = let add_from_annot_file_and_check_success storage ~lines =
ThirdPartyAnnotationInfo.add_from_signature_file storage ~lines match ThirdPartyAnnotationInfo.add_from_signature_file storage ~lines with
|> Result.iter_error ~f:(fun parsing_error -> | Ok storage ->
assert_failure storage
(F.asprintf "Expected to parse the file, but it was unparsable: %a" | Error parsing_error ->
ThirdPartyAnnotationInfo.pp_parsing_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 = let add_from_annot_file_and_check_failure storage ~lines ~expected_error_line_number =
match ThirdPartyAnnotationInfo.add_from_signature_file storage ~lines with match ThirdPartyAnnotationInfo.add_from_signature_file storage ~lines with
| Ok () -> | Ok _ ->
assert_failure assert_failure
"Expected to not be able to parse the file, but it was successfully parsed instead" "Expected to not be able to parse the file, but it was successfully parsed instead"
| Error {line_number} -> | Error {line_number} ->
@ -55,10 +57,11 @@ let basic_find =
let open ThirdPartyMethod in let open ThirdPartyMethod in
"basic_find" "basic_find"
>:: fun _ -> >:: fun _ ->
let storage = ThirdPartyAnnotationInfo.create_storage () in
let lines = ["a.A#foo(b.B)"; "b.B#bar(c.C, @Nullable d.D) @Nullable"] in let lines = ["a.A#foo(b.B)"; "b.B#bar(c.C, @Nullable d.D) @Nullable"] in
(* Load some functions from the file *) (* 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 *) (* Make sure we can find what we just stored *)
assert_has_nullability_info storage assert_has_nullability_info storage
{class_name= "a.A"; method_name= Method "foo"; param_types= ["b.B"]} {class_name= "a.A"; method_name= Method "foo"; param_types= ["b.B"]}
@ -83,7 +86,6 @@ let overload_resolution =
let open ThirdPartyMethod in let open ThirdPartyMethod in
"overload_resolution" "overload_resolution"
>:: fun _ -> >:: fun _ ->
let storage = ThirdPartyAnnotationInfo.create_storage () in
let lines = let lines =
[ "a.b.SomeClass#foo(@Nullable a.b.C1) @Nullable" [ "a.b.SomeClass#foo(@Nullable a.b.C1) @Nullable"
; "a.b.SomeClass#<init>(a.b.C1)" ; "a.b.SomeClass#<init>(a.b.C1)"
@ -94,7 +96,9 @@ let overload_resolution =
; "a.b.SomeClass#foo(@Nullable a.b.C2)" ] ; "a.b.SomeClass#foo(@Nullable a.b.C2)" ]
in in
(* Load some functions from the file *) (* 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 *) (* Make sure we can find what we just stored *)
(* a.b.SomeClass.foo with 1 param *) (* a.b.SomeClass.foo with 1 param *)
assert_has_nullability_info storage assert_has_nullability_info storage
@ -146,16 +150,17 @@ let can_add_several_files =
"can_add_several_files" "can_add_several_files"
>:: fun _ -> >:: fun _ ->
let open ThirdPartyMethod in let open ThirdPartyMethod in
let storage = ThirdPartyAnnotationInfo.create_storage () in
(* 1. Add file and check if we added info *) (* 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 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 assert_has_nullability_info storage
{class_name= "a.A"; method_name= Method "foo"; param_types= ["b.B"]} {class_name= "a.A"; method_name= Method "foo"; param_types= ["b.B"]}
~expected_nullability:{ret_nullability= Nonnull; param_nullability= [Nonnull]} ; ~expected_nullability:{ret_nullability= Nonnull; param_nullability= [Nonnull]} ;
(* 2. Add another file and check if we added info *) (* 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 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 assert_has_nullability_info storage
{class_name= "e.E"; method_name= Method "baz"; param_types= ["f.F"]} {class_name= "e.E"; method_name= Method "baz"; param_types= ["f.F"]}
~expected_nullability:{ret_nullability= Nonnull; param_nullability= [Nonnull]} ; ~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_ok = [line1; line2_ok; line3] in
let file_bad = [line1; line2_bad; line3] in let file_bad = [line1; line2_bad; line3] in
(* Ensure we can add the good file, but can not add the bad one *) (* 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 add_from_annot_file_and_check_failure
(ThirdPartyAnnotationInfo.create_storage ()) (ThirdPartyAnnotationInfo.create_storage ())
~lines:file_bad ~expected_error_line_number:2 ~lines:file_bad ~expected_error_line_number:2

Loading…
Cancel
Save