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