@ -43,7 +43,7 @@ module ReportableViolation = struct
and function_info =
{ param_signature : AnnotatedSignature . param_signature
; actual_param_expression : string
; param_ posit io n: int
; param_ index : int
; annotated_signature : AnnotatedSignature . t
; procname : Procname . Java . t }
@ -106,7 +106,7 @@ module ReportableViolation = struct
let mk_issue_for_bad_param_passed
{ annotated_signature ; param_signature ; actual_param_expression ; param_ posit io n; procname }
{ annotated_signature ; param_signature ; actual_param_expression ; param_ index ; procname }
~ param_nullability_kind ~ nullability_evidence
~ ( make_issue_factory : description : string -> issue_type : IssueType . t -> NullsafeIssue . t ) =
let nullability_evidence_as_suffix =
@ -127,68 +127,73 @@ module ReportableViolation = struct
Format . asprintf " %a is %s " MF . pp_monospaced actual_param_expression nullability_descr
in
let issue_type = IssueType . eradicate_parameter_not_nullable in
match AnnotatedNullability . get_nullability annotated_param_nullability with
| Nullability . Null ->
Logging . die Logging . InternalError " Unexpected param nullability: Null "
| Nullability . Nullable ->
Logging . die Logging . InternalError " Passing anything to a nullable param should be allowed "
| Nullability . ThirdPartyNonnull ->
(* This is a special case. While for FB codebase we can assume "not annotated hence not nullable" rule for all_whitelisted signatures,
This is not the case for third party functions , which can have different conventions ,
So we can not just say " param is declared as non-nullable " like we say for FB - internal or modelled case :
param can be nullable according to API but it was just not annotated .
So we phrase it differently to remain truthful , but as specific as possible .
* )
let suggested_third_party_sig_file =
ThirdPartyAnnotationInfo . lookup_related_sig_file_for_proc
( ThirdPartyAnnotationGlobalRepo . get_repo () )
procname
in
let where_to_add_signature =
Option . value_map suggested_third_party_sig_file
~ f : ( fun sig_file_name ->
ThirdPartyAnnotationGlobalRepo . get_user_friendly_third_party_sig_file_name
~ filename : sig_file_name )
(* this can happen when third party is registered in a deprecated way ( not in third party repository ) *)
~ default : " the third party signature storage "
in
let procname_str = Procname . Java . to_simplified_string ~ withclass : true procname in
let description =
Format . asprintf
" Third-party %a is missing a signature that would allow passing a nullable to param \
# % d % a . Actual argument % s % s . Consider adding the correct signature of % a to % s . "
MF . pp_monospaced procname_str param_position pp_param_name param_signature . mangled
argument_description nullability_evidence_as_suffix MF . pp_monospaced procname_str
where_to_add_signature
in
make_issue_factory ~ description ~ issue_type
| > NullsafeIssue . with_third_party_dependent_methods [ ( procname , annotated_signature ) ]
(* Equivalent to non-null from user point of view *)
| Nullability . ProvisionallyNullable
| Nullability . LocallyCheckedNonnull
| Nullability . LocallyTrustedNonnull
| Nullability . UncheckedNonnull
| Nullability . StrictNonnull ->
let nonnull_evidence =
match annotated_signature . kind with
| FirstParty | ThirdParty Unregistered ->
" "
| ThirdParty ModelledInternally ->
" (according to nullsafe internal models) "
| ThirdParty ( InThirdPartyRepo { filename ; line_number } ) ->
Format . sprintf " (see %s at line %d) "
( ThirdPartyAnnotationGlobalRepo . get_user_friendly_third_party_sig_file_name
~ filename )
line_number
in
let description =
Format . asprintf " %a: parameter #%d%a is declared non-nullable%s but the argument %s%s. "
MF . pp_monospaced
( Procname . Java . to_simplified_string ~ withclass : true procname )
param_position pp_param_name param_signature . mangled nonnull_evidence
argument_description nullability_evidence_as_suffix
in
make_issue_factory ~ description ~ issue_type
let issue =
match AnnotatedNullability . get_nullability annotated_param_nullability with
| Nullability . Null ->
Logging . die Logging . InternalError " Unexpected param nullability: Null "
| Nullability . Nullable ->
Logging . die Logging . InternalError " Passing anything to a nullable param should be allowed "
| Nullability . ThirdPartyNonnull ->
(* This is a special case. While for FB codebase we can assume "not annotated hence not nullable" rule for all_whitelisted signatures,
This is not the case for third party functions , which can have different conventions ,
So we can not just say " param is declared as non-nullable " like we say for FB - internal or modelled case :
param can be nullable according to API but it was just not annotated .
So we phrase it differently to remain truthful , but as specific as possible .
* )
let suggested_third_party_sig_file =
ThirdPartyAnnotationInfo . lookup_related_sig_file_for_proc
( ThirdPartyAnnotationGlobalRepo . get_repo () )
procname
in
let where_to_add_signature =
Option . value_map suggested_third_party_sig_file
~ f : ( fun sig_file_name ->
ThirdPartyAnnotationGlobalRepo . get_user_friendly_third_party_sig_file_name
~ filename : sig_file_name )
(* this can happen when third party is registered in a deprecated way ( not in third party repository ) *)
~ default : " the third party signature storage "
in
let procname_str = Procname . Java . to_simplified_string ~ withclass : true procname in
let description =
Format . asprintf
" Third-party %a is missing a signature that would allow passing a nullable to param \
# % d % a . Actual argument % s % s . Consider adding the correct signature of % a to % s . "
MF . pp_monospaced procname_str
( param_index + 1 ) (* human-readable param number is indexed from 1 *)
pp_param_name param_signature . mangled argument_description
nullability_evidence_as_suffix MF . pp_monospaced procname_str where_to_add_signature
in
make_issue_factory ~ description ~ issue_type
| > NullsafeIssue . with_third_party_dependent_methods [ ( procname , annotated_signature ) ]
(* Equivalent to non-null from user point of view *)
| Nullability . ProvisionallyNullable
| Nullability . LocallyCheckedNonnull
| Nullability . LocallyTrustedNonnull
| Nullability . UncheckedNonnull
| Nullability . StrictNonnull ->
let nonnull_evidence =
match annotated_signature . kind with
| FirstParty | ThirdParty Unregistered ->
" "
| ThirdParty ModelledInternally ->
" (according to nullsafe internal models) "
| ThirdParty ( InThirdPartyRepo { filename ; line_number } ) ->
Format . sprintf " (see %s at line %d) "
( ThirdPartyAnnotationGlobalRepo . get_user_friendly_third_party_sig_file_name
~ filename )
line_number
in
let description =
Format . asprintf " %a: parameter #%d%a is declared non-nullable%s but the argument %s%s. "
MF . pp_monospaced
( Procname . Java . to_simplified_string ~ withclass : true procname )
( param_index + 1 ) (* human-readable param number is indexed from 1 *)
pp_param_name param_signature . mangled nonnull_evidence argument_description
nullability_evidence_as_suffix
in
make_issue_factory ~ description ~ issue_type
in
issue | > NullsafeIssue . with_parameter_not_nullable_info ~ param_index ~ proc_name : procname
let field_name_of_assignment_type = function