@ -68,42 +68,67 @@ let nullability_for_return ~proc_name ~is_callee_in_trust_list ~nullsafe_mode ~i
final_nullability
final_nullability
let nullability_for_param ~ proc_name ~ param_num ~ is_callee_in_trust_list ~ nullsafe_mode
~ is_third_party ~ is_provisional_annotation_mode param_type param_annotations =
let nullability =
AnnotatedNullability . of_type_and_annotation ~ is_callee_in_trust_list ~ nullsafe_mode
~ is_third_party param_type param_annotations
in
if
is_provisional_annotation_mode
&& AnnotatedNullability . can_be_considered_for_provisional_annotation nullability
then
AnnotatedNullability . ProvisionallyNullable
( ProvisionalAnnotation . Param { method_info = proc_name ; num = param_num } )
else nullability
(* Given annotations for method signature, extract nullability information
(* Given annotations for method signature, extract nullability information
for return type and params * )
for return type and params * )
let extract_nullability ~ proc_name ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party
let extract_for_ret ~ proc_name ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party
~ is_provisional_annotation_mode ret_type ret_annotations param_annotated_types =
~ is_provisional_annotation_mode ret_type ret_annotations param_info =
let params_nullability =
List . mapi param_annotated_types ~ f : ( fun param_num ( param_type , param_annotations ) ->
nullability_for_param ~ proc_name ~ param_num ~ is_callee_in_trust_list ~ nullsafe_mode
~ is_third_party ~ is_provisional_annotation_mode param_type param_annotations )
in
let has_propagates_nullable_in_param =
let has_propagates_nullable_in_param =
List . exists params_nullability ~ f : ( function
List . exists param_info ~ f : ( fun { param_annotated_type = { nullability } } ->
| AnnotatedNullability . Nullable AnnotatedNullability . AnnotatedPropagatesNullable ->
match nullability with
true
| AnnotatedNullability . Nullable AnnotatedNullability . AnnotatedPropagatesNullable ->
| _ ->
true
false )
| _ ->
false )
in
in
let return_nullability =
let return_nullability =
nullability_for_return ~ proc_name ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party
nullability_for_return ~ proc_name ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party
ret_type ~ is_provisional_annotation_mode ret_annotations ~ has_propagates_nullable_in_param
ret_type ~ is_provisional_annotation_mode ret_annotations ~ has_propagates_nullable_in_param
in
in
( return_nullability , params_nullability )
{ ret_annotation_deprecated = ret_annotations
; ret_annotated_type = AnnotatedType . { nullability = return_nullability ; typ = ret_type } }
let get_param_nullability ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party param_name
param_type param_annotations =
if Mangled . is_this param_name then AnnotatedNullability . StrictNonnull ImplicitThis
else
AnnotatedNullability . of_type_and_annotation ~ is_callee_in_trust_list ~ nullsafe_mode
~ is_third_party param_type param_annotations
(* When getting param indices, we might need to offset to account for synthetic virtual params *)
let get_param_index_offset param_nullabilities =
match param_nullabilities with
| AnnotatedNullability . StrictNonnull ImplicitThis :: _ ->
1
| _ ->
0
let correct_by_provisional_annotations ~ proc_name param_nullabilities =
let index_offset = get_param_index_offset param_nullabilities in
List . mapi param_nullabilities ~ f : ( fun param_index nullability ->
if AnnotatedNullability . can_be_considered_for_provisional_annotation nullability then
AnnotatedNullability . ProvisionallyNullable
( ProvisionalAnnotation . Param { method_info = proc_name ; num = param_index - index_offset } )
else nullability )
let extract_for_params ~ proc_name ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party
~ is_provisional_annotation_mode param_info =
let param_nullability =
List . map param_info ~ f : ( fun ( param_name , typ , annotations ) ->
get_param_nullability ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party param_name typ
annotations )
in
let corrected_nullability =
if is_provisional_annotation_mode then
correct_by_provisional_annotations ~ proc_name param_nullability
else param_nullability
in
List . map2_exn param_info corrected_nullability
~ f : ( fun ( mangled , typ , param_annotation_deprecated ) nullability ->
{ param_annotation_deprecated ; mangled ; param_annotated_type = AnnotatedType . { nullability ; typ } } )
let get_impl ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_provisional_annotation_mode
let get_impl ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_provisional_annotation_mode
@ -118,24 +143,17 @@ let get_impl ~is_callee_in_trust_list ~nullsafe_mode ~is_provisional_annotation_
( ThirdPartyAnnotationGlobalRepo . get_repo () )
( ThirdPartyAnnotationGlobalRepo . get_repo () )
proc_name
proc_name
in
in
let param s_with_annotations = ProcAttributes . get_annotated_formals proc_attributes in
let param _info =
let param_annotated_types =
ProcAttributes . get_annotated_formals proc_attributes
List . map params_with_annotations ~ f : ( fun ( ( _ , typ ) , annotations ) -> ( typ , annotations ) )
| > List . map ~ f : ( fun ( ( a , b ) , c ) -> ( a , b , c ) )
in
in
let return_nullability, params_nullability =
let params =
extract_ nullability ~ proc_name ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party
extract_ for_params ~ proc_name ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party
~ is_provisional_annotation_mode ret_type ret_annotation param_annotated_types
~ is_provisional_annotation_mode param_info
in
in
let ret =
let ret =
{ ret_annotation_deprecated = ret_annotation
extract_for_ret ~ proc_name ~ is_callee_in_trust_list ~ nullsafe_mode ~ is_third_party
; ret_annotated_type = AnnotatedType . { nullability = return_nullability ; typ = ret_type } }
~ is_provisional_annotation_mode ret_type ret_annotation params
in
let params =
List . map2_exn params_with_annotations params_nullability
~ f : ( fun ( ( mangled , typ ) , param_annotation_deprecated ) nullability ->
{ param_annotation_deprecated
; mangled
; param_annotated_type = AnnotatedType . { nullability ; typ } } )
in
in
let kind = if is_third_party then ThirdParty Unregistered else FirstParty in
let kind = if is_third_party then ThirdParty Unregistered else FirstParty in
{ nullsafe_mode ; kind ; ret ; params }
{ nullsafe_mode ; kind ; ret ; params }