@ -8,6 +8,28 @@
 
			
		
	
		
		
			
				
					
					open !  IStd open !  IStd  
			
		
	
		
		
			
				
					
					module  F  =  Format module  F  =  Format  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					module  UserFriendlyNullable  =  struct  
			
		
	
		
		
			
				
					
					  type  t  =  ExplainablyNullable  of  explainably_nullable_kind  |  UntrustedNonnull  of  untrusted_kind 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  and  explainably_nullable_kind  =  Nullable  |  Null 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  and  untrusted_kind  =  ThirdPartyNonnull  |  UncheckedNonnull  |  LocallyCheckedNonnull 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					  let  from_nullability  =  function 
 
			
		
	
		
		
			
				
					
					    |  Nullability . Nullable  -> 
 
			
		
	
		
		
			
				
					
					        Some  ( ExplainablyNullable  Nullable ) 
 
			
		
	
		
		
			
				
					
					    |  Nullability . Null  -> 
 
			
		
	
		
		
			
				
					
					        Some  ( ExplainablyNullable  Null ) 
 
			
		
	
		
		
			
				
					
					    |  Nullability . UncheckedNonnull  -> 
 
			
		
	
		
		
			
				
					
					        Some  ( UntrustedNonnull  UncheckedNonnull ) 
 
			
		
	
		
		
			
				
					
					    |  Nullability . LocallyCheckedNonnull  -> 
 
			
		
	
		
		
			
				
					
					        Some  ( UntrustedNonnull  LocallyCheckedNonnull ) 
 
			
		
	
		
		
			
				
					
					    |  Nullability . ThirdPartyNonnull  -> 
 
			
		
	
		
		
			
				
					
					        Some  ( UntrustedNonnull  ThirdPartyNonnull ) 
 
			
		
	
		
		
			
				
					
					    |  Nullability . StrictNonnull  -> 
 
			
		
	
		
		
			
				
					
					        None 
 
			
		
	
		
		
			
				
					
					end  
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  is_object_nullability_self_explanatory  ~ object_expression  ( object_origin  :  TypeOrigin . t )  = let  is_object_nullability_self_explanatory  ~ object_expression  ( object_origin  :  TypeOrigin . t )  =  
			
		
	
		
		
			
				
					
					  (*  Fundamentally, object can be of two kinds: 
  (*  Fundamentally, object can be of two kinds: 
 
			
		
	
		
		
			
				
					
					     1 .  Indirect :  local  variable  that  was  instantiated  before . 
     1 .  Indirect :  local  variable  that  was  instantiated  before . 
 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -83,28 +105,40 @@ let get_field_class_name field_name =
 
			
		
	
		
		
			
				
					
					  | >  Option . value_map  ~ f : ( fun  ( classname ,  _ )  ->  classname )  ~ default : " the field class " 
  | >  Option . value_map  ~ f : ( fun  ( classname ,  _ )  ->  classname )  ~ default : " the field class " 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  mk_coming_from_unchecked_or_locally_checked_case_only  nullsafe_mode  nullability  = let  mk_coming_from_unchecked_or_locally_checked_case_only  nullsafe_mode  untrusted_kind  =  
			
				
				
			
		
	
		
		
			
				
					
					  match  ( nullsafe_mode ,  nullability )  with 
  match  ( nullsafe_mode ,  untrusted_kind )  with 
 
			
				
				
			
		
	
		
		
			
				
					
					  |  NullsafeMode . Strict ,  Nullability . UncheckedNonnull  -> 
  |  NullsafeMode . Strict ,  UserFriendlyNullable . UncheckedNonnull  -> 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					      " non-strict classes " 
      " non-strict classes " 
 
			
		
	
		
		
			
				
					
					  |  NullsafeMode . Strict ,  Nullability . LocallyCheckedNonnull  -> 
  |  NullsafeMode . Strict ,  UserFriendlyNullable . LocallyCheckedNonnull  -> 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					      " nullsafe-local classes " 
      " nullsafe-local classes " 
 
			
		
	
		
		
			
				
					
					  |  NullsafeMode . Local  _ ,  Nullability . UncheckedNonnull -> 
  |  NullsafeMode . Local  _ ,  _ -> 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					      " non-nullsafe classes " 
      " non-nullsafe classes " 
 
			
		
	
		
		
			
				
					
					  |  _  -> 
  |  NullsafeMode . Default ,  _  -> 
 
			
				
				
			
		
	
		
		
			
				
					
					      Logging . die  Logging . InternalError 
      Logging . die  InternalError 
 
			
				
				
			
		
	
		
		
			
				
					
					        " Should be called only for locally checked or unchecked nonnull cases " 
        " mk_coming_from_unchecked_or_locally_checked_case_only:: not applicable to default mode " 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					  |  _ ,  UserFriendlyNullable . ThirdPartyNonnull  -> 
 
			
		
	
		
		
			
				
					
					      Logging . die  InternalError 
 
			
		
	
		
		
			
				
					
					        " mk_coming_from_unchecked_or_locally_checked_case_only:: not applicable to  \ 
 
			
		
	
		
		
			
				
					
					         ThirdPartyNonnull  case " 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  mk_recommendation  nullsafe_mode  nullability  what  = let  mk_strictification_advice_unchecked_or_locally_checked_case_only  nullsafe_mode  untrusted_kind  
			
				
				
			
		
	
		
		
			
				
					
					  match  ( nullsafe_mode ,  nullability )  with 
    ~ what_to_strictify  = 
 
			
				
				
			
		
	
		
		
			
				
					
					  |  NullsafeMode . Strict ,  Nullability . UncheckedNonnull 
  match  untrusted_kind  with 
 
			
				
				
			
		
	
		
		
			
				
					
					  |  NullsafeMode . Strict ,  Nullability . LocallyCheckedNonnull  -> 
  |  UserFriendlyNullable . UncheckedNonnull  |  UserFriendlyNullable . LocallyCheckedNonnull  ->  ( 
 
			
				
				
			
		
	
		
		
			
				
					
					      Some  ( F . sprintf  " make %s nullsafe strict "  what ) 
    match  nullsafe_mode  with 
 
			
				
				
			
		
	
		
		
			
				
					
					  |  NullsafeMode . Local  _ ,  Nullability . UncheckedNonnull  -> 
    |  NullsafeMode . Strict  -> 
 
			
				
				
			
		
	
		
		
			
				
					
					      Some  ( F . sprintf  " make %s nullsafe "  what ) 
        F . sprintf  " make %s nullsafe strict "  what_to_strictify 
 
			
				
				
			
		
	
		
		
			
				
					
					  |  _  -> 
    |  NullsafeMode . Local  _  -> 
 
			
				
				
			
		
	
		
		
			
				
					
					      None 
        F . sprintf  " make %s nullsafe "  what_to_strictify 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					    |  NullsafeMode . Default  -> 
 
			
		
	
		
		
			
				
					
					        Logging . die  InternalError 
 
			
		
	
		
		
			
				
					
					          " mk_recommendation_unchecked_or_locally_checked_case_only:: should not be called for  \ 
 
			
		
	
		
		
			
				
					
					           default  mode "  ) 
 
			
		
	
		
		
			
				
					
					  |  UserFriendlyNullable . ThirdPartyNonnull  -> 
 
			
		
	
		
		
			
				
					
					      Logging . die  InternalError 
 
			
		
	
		
		
			
				
					
					        " mk_recommendation_unchecked_or_locally_checked_case_only:: not applicable to  \ 
 
			
		
	
		
		
			
				
					
					         ThirdPartyNonnull  case " 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  mk_recommendation_for_third_party_field  nullsafe_mode  field  = let  mk_recommendation_for_third_party_field  nullsafe_mode  field  =  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -114,12 +148,12 @@ let mk_recommendation_for_third_party_field nullsafe_mode field =
 
			
		
	
		
		
			
				
					
					  |  NullsafeMode . Local  _  -> 
  |  NullsafeMode . Local  _  -> 
 
			
		
	
		
		
			
				
					
					      F . sprintf  " access %s via a nullsafe getter "  field 
      F . sprintf  " access %s via a nullsafe getter "  field 
 
			
		
	
		
		
			
				
					
					  |  NullsafeMode . Default  -> 
  |  NullsafeMode . Default  -> 
 
			
		
	
		
		
			
				
					
					      Logging . die  Logging . InternalError 
      Logging . die  InternalError 
 
			
				
				
			
		
	
		
		
			
				
					
					        " Should not happen: we should tolerate third party in default mode " 
        " mk_recommendation_for_third_party_field:: Should not happen: we should tolerate third  \ 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					         party  in  default  mode " 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  get_info  object_origin  nullsafe_mode  bad_nullability  = let  get_info  object_origin  nullsafe_mode  untrusted_kind  =  
			
				
				
			
		
	
		
		
			
				
					
					  let  open  IOption . Let_syntax  in 
 
			
		
	
		
		
	
		
		
			
				
					
					  match  object_origin  with 
  match  object_origin  with 
 
			
		
	
		
		
			
				
					
					  |  TypeOrigin . MethodCall  { pname ;  call_loc }  -> 
  |  TypeOrigin . MethodCall  { pname ;  call_loc }  -> 
 
			
		
	
		
		
			
				
					
					      let  offending_object  = 
      let  offending_object  = 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -128,14 +162,9 @@ let get_info object_origin nullsafe_mode bad_nullability =
 
			
		
	
		
		
			
				
					
					      in 
      in 
 
			
		
	
		
		
			
				
					
					      let  object_loc  =  call_loc  in 
      let  object_loc  =  call_loc  in 
 
			
		
	
		
		
			
				
					
					      let  what_is_used  =  " Result of this call "  in 
      let  what_is_used  =  " Result of this call "  in 
 
			
		
	
		
		
			
				
					
					      let +  coming_from_explanation ,  recommendation ,  issue_type  = 
      let  coming_from_explanation ,  recommendation ,  issue_type  = 
 
			
				
				
			
		
	
		
		
			
				
					
					        match  bad_nullability  with 
        match  untrusted_kind  with 
 
			
				
				
			
		
	
		
		
			
				
					
					        |  Nullability . Null  |  Nullability . Nullable  -> 
        |  UserFriendlyNullable . ThirdPartyNonnull  -> 
 
			
				
				
			
		
	
		
		
			
				
					
					            (*  This method makes sense only for non-nullable violations  *) 
 
			
		
	
		
		
			
				
					
					            None 
 
			
		
	
		
		
			
				
					
					        |  Nullability . StrictNonnull  -> 
 
			
		
	
		
		
			
				
					
					            Logging . die  InternalError  " There should not be type violations involving StrictNonnull " 
 
			
		
	
		
		
			
				
					
					        |  Nullability . ThirdPartyNonnull  -> 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					            let  suggested_third_party_sig_file  = 
            let  suggested_third_party_sig_file  = 
 
			
		
	
		
		
			
				
					
					              ThirdPartyAnnotationInfo . lookup_related_sig_file_for_proc 
              ThirdPartyAnnotationInfo . lookup_related_sig_file_for_proc 
 
			
		
	
		
		
			
				
					
					                ( ThirdPartyAnnotationGlobalRepo . get_repo  () ) 
                ( ThirdPartyAnnotationGlobalRepo . get_repo  () ) 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -149,19 +178,19 @@ let get_info object_origin nullsafe_mode bad_nullability =
 
			
		
	
		
		
			
				
					
					                  (*  this can happen when third party is registered in a deprecated way  ( not in third party repository )   *) 
                  (*  this can happen when third party is registered in a deprecated way  ( not in third party repository )   *) 
 
			
		
	
		
		
			
				
					
					                ~ default : " the third party signature storage " 
                ~ default : " the third party signature storage " 
 
			
		
	
		
		
			
				
					
					            in 
            in 
 
			
		
	
		
		
			
				
					
					            return 
 
			
		
	
		
		
			
				
					
					            (  " not vetted third party methods " 
            (  " not vetted third party methods " 
 
			
		
	
		
		
			
				
					
					            ,  F . sprintf  " add the correct signature to %s "  where_to_add_signature 
            ,  F . sprintf  " add the correct signature to %s "  where_to_add_signature 
 
			
		
	
		
		
			
				
					
					            ,  IssueType . eradicate_unvetted_third_party_in_nullsafe  ) 
            ,  IssueType . eradicate_unvetted_third_party_in_nullsafe  ) 
 
			
		
	
		
		
			
				
					
					        |  Nullability. UncheckedNonnull  |  Nullability  . LocallyCheckedNonnull  -> 
        |  UserFriendlyNullable. UncheckedNonnull  |  UserFriendlyNullable  . LocallyCheckedNonnull  -> 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					            let  from  = 
            let  from  = 
 
			
		
	
		
		
			
				
					
					              mk_coming_from_unchecked_or_locally_checked_case_only  nullsafe_mode  bad_nullability 
              mk_coming_from_unchecked_or_locally_checked_case_only  nullsafe_mode  untrusted_kind 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					            in 
            in 
 
			
		
	
		
		
			
				
					
					            let + recommendation  = 
            let  recommendation  = 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					              let  what_to_strictify  = 
              let  what_to_strictify  = 
 
			
		
	
		
		
			
				
					
					                Option . value  ( get_method_class_name  pname )  ~ default : offending_object 
                Option . value  ( get_method_class_name  pname )  ~ default : offending_object 
 
			
		
	
		
		
			
				
					
					              in 
              in 
 
			
		
	
		
		
			
				
					
					              mk_recommendation  nullsafe_mode  bad_nullability  what_to_strictify 
              mk_strictification_advice_unchecked_or_locally_checked_case_only  nullsafe_mode 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					                untrusted_kind  ~ what_to_strictify 
 
			
		
	
		
		
			
				
					
					            in 
            in 
 
			
		
	
		
		
			
				
					
					            let  issue_type  =  IssueType . eradicate_unchecked_usage_in_nullsafe  in 
            let  issue_type  =  IssueType . eradicate_unchecked_usage_in_nullsafe  in 
 
			
		
	
		
		
			
				
					
					            ( from ,  recommendation ,  issue_type ) 
            ( from ,  recommendation ,  issue_type ) 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -183,24 +212,19 @@ let get_info object_origin nullsafe_mode bad_nullability =
 
			
		
	
		
		
			
				
					
					      (*  TODO: currently we do not support third-party annotations for fields. Because of this, 
      (*  TODO: currently we do not support third-party annotations for fields. Because of this, 
 
			
		
	
		
		
			
				
					
					         render  error  like  it  is  a  non - stict  class .  * ) 
         render  error  like  it  is  a  non - stict  class .  * ) 
 
			
		
	
		
		
			
				
					
					      let  what_is_used  =  " This field "  in 
      let  what_is_used  =  " This field "  in 
 
			
		
	
		
		
			
				
					
					      let +  coming_from_explanation ,  recommendation ,  issue_type  = 
      let  coming_from_explanation ,  recommendation ,  issue_type  = 
 
			
				
				
			
		
	
		
		
			
				
					
					        match  bad_nullability  with 
        match  untrusted_kind  with 
 
			
				
				
			
		
	
		
		
			
				
					
					        |  Nullability . Null  |  Nullability . Nullable  -> 
        |  UserFriendlyNullable . ThirdPartyNonnull  -> 
 
			
				
				
			
		
	
		
		
			
				
					
					            (*  This method makes sense only for non-nullable violations  *) 
 
			
		
	
		
		
			
				
					
					            None 
 
			
		
	
		
		
			
				
					
					        |  Nullability . StrictNonnull  -> 
 
			
		
	
		
		
			
				
					
					            Logging . die  InternalError  " There should not be type violations involving StrictNonnull " 
 
			
		
	
		
		
			
				
					
					        |  Nullability . ThirdPartyNonnull  -> 
 
			
		
	
		
		
			
				
					
					            return 
 
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					            (  " third-party classes " 
            (  " third-party classes " 
 
			
		
	
		
		
			
				
					
					            ,  mk_recommendation_for_third_party_field  nullsafe_mode  unqualified_name 
            ,  mk_recommendation_for_third_party_field  nullsafe_mode  unqualified_name 
 
			
		
	
		
		
			
				
					
					            ,  IssueType . eradicate_unvetted_third_party_in_nullsafe  ) 
            ,  IssueType . eradicate_unvetted_third_party_in_nullsafe  ) 
 
			
		
	
		
		
			
				
					
					        |  Nullability. UncheckedNonnull  |  Nullability  . LocallyCheckedNonnull  -> 
        |  UserFriendlyNullable . UncheckedNonnull  |  UserFriendlyNullable . LocallyCheckedNonnull  -> 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					            let  from  = 
            let  from  = 
 
			
		
	
		
		
			
				
					
					              mk_coming_from_unchecked_or_locally_checked_case_only  nullsafe_mode  bad_nullability 
              mk_coming_from_unchecked_or_locally_checked_case_only  nullsafe_mode  untrusted_kind 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					            in 
            in 
 
			
		
	
		
		
			
				
					
					            let +  recommendation  = 
            let  recommendation  = 
 
			
				
				
			
		
	
		
		
			
				
					
					              mk_recommendation  nullsafe_mode  bad_nullability  ( get_field_class_name  field_name ) 
              mk_strictification_advice_unchecked_or_locally_checked_case_only  nullsafe_mode 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					                untrusted_kind  ~ what_to_strictify : ( get_field_class_name  field_name ) 
 
			
		
	
		
		
			
				
					
					            in 
            in 
 
			
		
	
		
		
			
				
					
					            ( from ,  recommendation ,  IssueType . eradicate_unchecked_usage_in_nullsafe ) 
            ( from ,  recommendation ,  IssueType . eradicate_unchecked_usage_in_nullsafe ) 
 
			
		
	
		
		
			
				
					
					      in 
      in 
 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -210,19 +234,22 @@ let get_info object_origin nullsafe_mode bad_nullability =
 
			
		
	
		
		
			
				
					
					      ;  what_is_used 
      ;  what_is_used 
 
			
		
	
		
		
			
				
					
					      ;  recommendation 
      ;  recommendation 
 
			
		
	
		
		
			
				
					
					      ;  issue_type  } 
      ;  issue_type  } 
 
			
		
	
		
		
			
				
					
					  |  _  -> 
  |  other  -> 
 
			
				
				
			
		
	
		
		
			
				
					
					      None 
      Logging . die  InternalError 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					        " get_info:: untrusted_kind is possible only for MethodCall and Field origins, got %s  \ 
 
			
		
	
		
		
			
				
					
					         instead " 
 
			
		
	
		
		
			
				
					
					        ( TypeOrigin . to_string  other ) 
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					
 
			
		
	
		
		
			
				
					
					let  mk_special_nullsafe_issue  ~ nullsafe_mode  ~ bad_nullability  ~ bad_usage_location  object_origin  = let  mk_ nullsafe_issue_for_untrusted_values ~ nullsafe_mode  ~ untrusted_kind  ~ bad_usage_location   
			
				
				
			
		
	
		
		
			
				
					
					  let  open  IOption . Let_syntax  in 
    object_origin  =  
 
			
				
				
			
		
	
		
		
			
				
					
					  let + {  offending_object 
  let  {  offending_object 
 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					      ;  object_loc 
      ;  object_loc 
 
			
		
	
		
		
			
				
					
					      ;  coming_from_explanation 
      ;  coming_from_explanation 
 
			
		
	
		
		
			
				
					
					      ;  what_is_used 
      ;  what_is_used 
 
			
		
	
		
		
			
				
					
					      ;  recommendation 
      ;  recommendation 
 
			
		
	
		
		
			
				
					
					      ;  issue_type  }  = 
      ;  issue_type  }  = 
 
			
		
	
		
		
			
				
					
					    get_info  object_origin  nullsafe_mode  bad_nullability 
    get_info  object_origin  nullsafe_mode  untrusted_kind 
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					  in 
  in 
 
			
		
	
		
		
			
				
					
					  let  description  = 
  let  description  = 
 
			
		
	
		
		
			
				
					
					    F . asprintf 
    F . asprintf