|  |  |  | @ -11,7 +11,7 @@ open! Utils | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | module L = Logging | 
			
		
	
		
			
				
					|  |  |  |  | module F = Format | 
			
		
	
		
			
				
					|  |  |  |  | module TypSet = Sil.TypSet | 
			
		
	
		
			
				
					|  |  |  |  | module TypSet = Sil.StructTypSet | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** Android lifecycle types and their lifecycle methods that are called by the framework *) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | @ -56,56 +56,31 @@ let android_lifecycles = | 
			
		
	
		
			
				
					|  |  |  |  |      fragment_lifecycle); | 
			
		
	
		
			
				
					|  |  |  |  |   ] | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** return the complete set of superclasses of [typ *) | 
			
		
	
		
			
				
					|  |  |  |  | (* TODO (t4644852): factor out subtyping functions into some sort of JavaUtil module *) | 
			
		
	
		
			
				
					|  |  |  |  | let get_all_supertypes typ tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   let get_direct_supers = function | 
			
		
	
		
			
				
					|  |  |  |  |     | Sil.Tstruct { Sil.csu = Csu.Class _; superclasses } -> | 
			
		
	
		
			
				
					|  |  |  |  |         superclasses | 
			
		
	
		
			
				
					|  |  |  |  |     | _ -> [] in | 
			
		
	
		
			
				
					|  |  |  |  |   let rec add_typ class_name typs = | 
			
		
	
		
			
				
					|  |  |  |  |     match Tenv.lookup tenv class_name with | 
			
		
	
		
			
				
					|  |  |  |  |     | Some struct_typ -> | 
			
		
	
		
			
				
					|  |  |  |  |         let typ' = Sil.Tstruct struct_typ in | 
			
		
	
		
			
				
					|  |  |  |  |         get_supers_rec typ' (TypSet.add typ' typs) | 
			
		
	
		
			
				
					|  |  |  |  |     | None -> typs | 
			
		
	
		
			
				
					|  |  |  |  |   and get_supers_rec typ all_supers = | 
			
		
	
		
			
				
					|  |  |  |  |     let direct_supers = get_direct_supers typ in | 
			
		
	
		
			
				
					|  |  |  |  |     IList.fold_left | 
			
		
	
		
			
				
					|  |  |  |  |       (fun typs class_name -> add_typ class_name typs) | 
			
		
	
		
			
				
					|  |  |  |  |       all_supers direct_supers in | 
			
		
	
		
			
				
					|  |  |  |  |   get_supers_rec typ (TypSet.add typ TypSet.empty) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** return true if [typ0] <: [typ1] *) | 
			
		
	
		
			
				
					|  |  |  |  | let is_subtype (typ0 : Sil.typ) (typ1 : Sil.typ) tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   TypSet.mem typ1 (get_all_supertypes typ0 tenv) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let is_subtype_package_class typ package classname tenv = | 
			
		
	
		
			
				
					|  |  |  |  | let is_subtype_package_class tenv struct_typ package classname = | 
			
		
	
		
			
				
					|  |  |  |  |   let classname = Mangled.from_package_class package classname in | 
			
		
	
		
			
				
					|  |  |  |  |   match Tenv.lookup tenv (Typename.TN_csu (Csu.Class Csu.Java, classname)) with | 
			
		
	
		
			
				
					|  |  |  |  |   | Some found_struct_typ -> is_subtype typ (Sil.Tstruct found_struct_typ) tenv | 
			
		
	
		
			
				
					|  |  |  |  |   | Some found_struct_typ -> PatternMatch.is_subtype tenv struct_typ found_struct_typ | 
			
		
	
		
			
				
					|  |  |  |  |   | _ -> false | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let is_context typ tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class typ "android.content" "Context" tenv | 
			
		
	
		
			
				
					|  |  |  |  | let is_context tenv typ = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class tenv typ "android.content" "Context" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let is_application typ tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class typ "android.app" "Application" tenv | 
			
		
	
		
			
				
					|  |  |  |  | let is_application tenv typ = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class tenv typ "android.app" "Application" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let is_activity typ tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class typ "android.app" "Activity" tenv | 
			
		
	
		
			
				
					|  |  |  |  | let is_activity tenv typ = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class tenv typ "android.app" "Activity" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let is_view typ tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class typ "android.view" "View" tenv | 
			
		
	
		
			
				
					|  |  |  |  | let is_view tenv typ = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class tenv typ "android.view" "View" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let is_fragment typ tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class typ "android.app" "Fragment" tenv || | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class typ "android.support.v4.app" "Fragment" tenv | 
			
		
	
		
			
				
					|  |  |  |  | let is_fragment tenv typ = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class tenv typ "android.app" "Fragment" || | 
			
		
	
		
			
				
					|  |  |  |  |   is_subtype_package_class tenv typ "android.support.v4.app" "Fragment" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** return true if [typ] is a subclass of [lifecycle_typ] *) | 
			
		
	
		
			
				
					|  |  |  |  | let typ_is_lifecycle_typ typ lifecycle_typ tenv = | 
			
		
	
		
			
				
					|  |  |  |  |   let supers = get_all_supertypes typ tenv in | 
			
		
	
		
			
				
					|  |  |  |  |   TypSet.mem lifecycle_typ supers | 
			
		
	
		
			
				
					|  |  |  |  | (** return true if [struct_typ] is a subclass of [lifecycle_struct_typ] *) | 
			
		
	
		
			
				
					|  |  |  |  | let typ_is_lifecycle_typ tenv struct_typ lifecycle_struct_typ = | 
			
		
	
		
			
				
					|  |  |  |  |   TypSet.mem lifecycle_struct_typ (PatternMatch.get_strict_supertypes tenv struct_typ) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** return true if [class_name] is the name of a class that belong to the Android framework *) | 
			
		
	
		
			
				
					|  |  |  |  | let is_android_lib_class class_name = | 
			
		
	
	
		
			
				
					|  |  |  | @ -114,7 +89,7 @@ let is_android_lib_class class_name = | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** given an Android framework type mangled string [lifecycle_typ] (e.g., android.app.Activity) and | 
			
		
	
		
			
				
					|  |  |  |  |     a list of method names [lifecycle_procs_strs], get the appropriate typ and procnames *) | 
			
		
	
		
			
				
					|  |  |  |  | let get_lifecycle_for_framework_typ_opt lifecycle_typ lifecycle_proc_strs tenv = | 
			
		
	
		
			
				
					|  |  |  |  | let get_lifecycle_for_framework_typ_opt tenv lifecycle_typ lifecycle_proc_strs = | 
			
		
	
		
			
				
					|  |  |  |  |   match Tenv.lookup tenv (Typename.TN_csu (Csu.Class Csu.Java, lifecycle_typ)) with | 
			
		
	
		
			
				
					|  |  |  |  |   | Some ({ Sil.csu = Csu.Class _; struct_name = Some _; def_methods } as lifecycle_typ) -> | 
			
		
	
		
			
				
					|  |  |  |  |       (* TODO (t4645631): collect the procedures for which is_java is returning false *) | 
			
		
	
	
		
			
				
					|  |  |  | @ -132,38 +107,12 @@ let get_lifecycle_for_framework_typ_opt lifecycle_typ lifecycle_proc_strs tenv = | 
			
		
	
		
			
				
					|  |  |  |  |             try (lookup_proc lifecycle_proc_str) :: lifecycle_procs | 
			
		
	
		
			
				
					|  |  |  |  |             with Not_found -> lifecycle_procs) | 
			
		
	
		
			
				
					|  |  |  |  |           [] lifecycle_proc_strs in | 
			
		
	
		
			
				
					|  |  |  |  |       Some (Sil.Tstruct lifecycle_typ, lifecycle_procs) | 
			
		
	
		
			
				
					|  |  |  |  |       Some (lifecycle_typ, lifecycle_procs) | 
			
		
	
		
			
				
					|  |  |  |  |   | _ -> None | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** return the complete list of (package, lifecycle_classname, lifecycle_methods) trios *) | 
			
		
	
		
			
				
					|  |  |  |  | let get_lifecycles = android_lifecycles | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let is_subclass tenv cn1 classname_str = | 
			
		
	
		
			
				
					|  |  |  |  |   let typename = | 
			
		
	
		
			
				
					|  |  |  |  |     Typename.Java.from_string classname_str in | 
			
		
	
		
			
				
					|  |  |  |  |   let lookup = Tenv.lookup tenv in | 
			
		
	
		
			
				
					|  |  |  |  |   match lookup cn1, lookup typename with | 
			
		
	
		
			
				
					|  |  |  |  |   | Some typ1, Some typ2 -> | 
			
		
	
		
			
				
					|  |  |  |  |       is_subtype (Sil.Tstruct typ1) (Sil.Tstruct typ2) tenv | 
			
		
	
		
			
				
					|  |  |  |  |   | _ -> false | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** Checks if the exception is an uncheched exception *) | 
			
		
	
		
			
				
					|  |  |  |  | let is_runtime_exception tenv typename = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subclass tenv typename "java.lang.RuntimeException" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** Checks if the class name is a Java exception *) | 
			
		
	
		
			
				
					|  |  |  |  | let is_exception tenv typename = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subclass tenv typename "java.lang.Exception" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | (** Checks if the class name is a Java exception *) | 
			
		
	
		
			
				
					|  |  |  |  | let is_throwable tenv typename = | 
			
		
	
		
			
				
					|  |  |  |  |   is_subclass tenv typename "java.lang.Throwable" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | let non_stub_android_jar () = | 
			
		
	
		
			
				
					|  |  |  |  |   let root_dir = Filename.dirname (Filename.dirname Sys.executable_name) in | 
			
		
	
		
			
				
					|  |  |  |  |   IList.fold_left Filename.concat root_dir ["lib"; "java"; "android"; "android-19.jar"] | 
			
		
	
	
		
			
				
					|  |  |  | 
 |