diff --git a/infer/src/clang/ComponentKit.ml b/infer/src/clang/ComponentKit.ml index 3a80cb26c..fb8f7afe0 100644 --- a/infer/src/clang/ComponentKit.ml +++ b/infer/src/clang/ComponentKit.ml @@ -184,35 +184,6 @@ let component_with_unconventional_superclass_advice context decl = None | _ -> assert false -let if_decl_to_di_pointer_opt if_decl = - match if_decl with - | Clang_ast_t.ObjCInterfaceDecl (if_decl_info, _, _, _, _) -> - Some if_decl_info.di_pointer - | _ -> None - -let is_instance_type type_ptr = - match Ast_utils.name_opt_of_typedef_type_ptr type_ptr with - | Some name -> name = "instancetype" - | None -> false - -let return_type_matches_class_type rtp type_decl_pointer = - if is_instance_type rtp then - true - else - let return_type_decl_opt = Ast_utils.type_ptr_to_objc_interface rtp in - let return_type_decl_pointer_opt = - Option.map if_decl_to_di_pointer_opt return_type_decl_opt in - (Some type_decl_pointer) = return_type_decl_pointer_opt - -(** A class method that returns an instance of the class is a factory method. *) -let is_factory_method if_decl meth_decl = - let if_type_decl_pointer = if_decl_to_di_pointer_opt if_decl in - match meth_decl with - | Clang_ast_t.ObjCMethodDecl (_, _, omdi) -> - (not omdi.omdi_is_instance_method) && - (return_type_matches_class_type omdi.omdi_result_type if_type_decl_pointer) - | _ -> false - (** Components should only have one factory method. (They could technically have none if they re-use the parent class's factory @@ -227,7 +198,7 @@ let component_with_multiple_factory_methods_advice context decl = let check_interface if_decl = match if_decl with | Clang_ast_t.ObjCInterfaceDecl (decl_info, _, decls, _, _) -> - let factory_methods = IList.filter (is_factory_method if_decl) decls in + let factory_methods = IList.filter (Ast_utils.is_objc_factory_method if_decl) decls in if (IList.length factory_methods) > 1 then Some { CIssue.issue = CIssue.Component_with_multiple_factory_methods; diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index c3ffa94f6..e2687502c 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -476,6 +476,35 @@ struct type_ptr_to_objc_interface function_type_info.Clang_ast_t.fti_return_type | _ -> None + + let if_decl_to_di_pointer_opt if_decl = + match if_decl with + | Clang_ast_t.ObjCInterfaceDecl (if_decl_info, _, _, _, _) -> + Some if_decl_info.di_pointer + | _ -> None + + let is_instance_type type_ptr = + match name_opt_of_typedef_type_ptr type_ptr with + | Some name -> name = "instancetype" + | None -> false + + let return_type_matches_class_type rtp type_decl_pointer = + if is_instance_type rtp then + true + else + let return_type_decl_opt = type_ptr_to_objc_interface rtp in + let return_type_decl_pointer_opt = + Option.map if_decl_to_di_pointer_opt return_type_decl_opt in + (Some type_decl_pointer) = return_type_decl_pointer_opt + + let is_objc_factory_method if_decl meth_decl = + let if_type_decl_pointer = if_decl_to_di_pointer_opt if_decl in + match meth_decl with + | Clang_ast_t.ObjCMethodDecl (_, _, omdi) -> + (not omdi.omdi_is_instance_method) && + (return_type_matches_class_type omdi.omdi_result_type if_type_decl_pointer) + | _ -> false + (* let rec getter_attribute_opt attributes = match attributes with diff --git a/infer/src/clang/cFrontend_utils.mli b/infer/src/clang/cFrontend_utils.mli index 175e79a54..7c10cc539 100644 --- a/infer/src/clang/cFrontend_utils.mli +++ b/infer/src/clang/cFrontend_utils.mli @@ -172,6 +172,9 @@ sig ?blacklist:string list -> Clang_ast_t.decl option -> string list -> bool val type_ptr_to_objc_interface : Clang_ast_types.t_ptr -> Clang_ast_t.decl option + + (** A class method that returns an instance of the class is a factory method. *) + val is_objc_factory_method : Clang_ast_t.decl -> Clang_ast_t.decl -> bool end module General_utils :