Add is_objc_method_exposed predicate

Reviewed By: dulmarod

Differential Revision: D7862233

fbshipit-source-id: da2ee1b
master
Brandon Kieft 7 years ago committed by Facebook Github Bot
parent 96e5a976c4
commit 7d4bd403df

@ -26,6 +26,8 @@ type context =
(** If inside an objc class, contains the objc class (impl or interface) decl. *)
; current_objc_category: Clang_ast_t.decl option
(** If inside an objc category, contains the objc category (impl or interface) decl. *)
; current_objc_protocol: Clang_ast_t.decl option
(** If inside an objc protocol, contains the objc protocol decl. *)
; et_evaluation_node: string option
; if_context: if_context option
; in_for_loop_declaration: bool }
@ -38,6 +40,7 @@ let empty translation_unit_context =
; is_ck_translation_unit= false
; current_objc_class= None
; current_objc_category= None
; current_objc_protocol= None
; et_evaluation_node= None
; if_context= None
; in_for_loop_declaration= false }

@ -26,6 +26,8 @@ type context =
(** If inside an objc class, contains the objc class (impl or interface) decl. *)
; current_objc_category: Clang_ast_t.decl option
(** If inside an objc category, contains the objc category (impl or interface) decl. *)
; current_objc_protocol: Clang_ast_t.decl option
(** If inside an objc protocol, contains the objc protocol decl. *)
; et_evaluation_node: string option
; if_context: if_context option
; in_for_loop_declaration: bool }

@ -343,6 +343,11 @@ and do_frontend_checks_decl (context: CLintersContext.context)
let context' = {context with current_objc_category= Some decl} in
List.iter ~f:(do_frontend_checks_decl context' map_active) decls ;
call_tableaux context' an map_active
| ObjCProtocolDecl (_, _, decls, _, _) ->
CFrontend_errors.invoke_set_of_checkers_on_node context an ;
let context' = {context with current_objc_protocol= Some decl} in
List.iter ~f:(do_frontend_checks_decl context' map_active) decls ;
call_tableaux context' an map_active
| _ ->
CFrontend_errors.invoke_set_of_checkers_on_node context an ;
( match Clang_ast_proj.get_decl_context_tuple decl with

@ -297,6 +297,66 @@ let is_objc_method_overriding an =
false
let decl_list_has_objc_method decl_list method_name is_instance_method =
List.exists
~f:(fun decl ->
match decl with
| Clang_ast_t.ObjCMethodDecl (_, ni, omdi) ->
Bool.equal omdi.omdi_is_instance_method is_instance_method
&& String.equal ni.ni_name method_name
| _ ->
false )
decl_list
let current_objc_container context =
let open CLintersContext in
let current_objc_class = context.current_objc_class in
let current_objc_category = context.current_objc_category in
let current_objc_protocol = context.current_objc_protocol in
if not (Option.is_none current_objc_class) then current_objc_class
else if not (Option.is_none current_objc_category) then current_objc_category
else if not (Option.is_none current_objc_protocol) then current_objc_protocol
else None
let is_objc_method_exposed context an =
let open Clang_ast_t in
if is_objc_method_overriding an then true
else
match an with
| Ctl_parser_types.Decl (ObjCMethodDecl (_, ndi, mdi))
-> (
let method_name = ndi.ni_name in
let is_instance_method = mdi.omdi_is_instance_method in
match current_objc_container context with
| Some (ObjCImplementationDecl (_, _, _, _, oidi)) -> (
match CAst_utils.get_decl_opt_with_decl_ref oidi.oidi_class_interface with
| Some (ObjCInterfaceDecl (_, _, decl_list, _, otdi)) ->
decl_list_has_objc_method decl_list method_name is_instance_method
|| List.exists
~f:(fun decl_ref ->
match CAst_utils.get_decl decl_ref.dr_decl_pointer with
| Some (ObjCCategoryDecl (_, ni, decl_list, _, _)) ->
String.equal ni.ni_name ""
&& decl_list_has_objc_method decl_list method_name is_instance_method
| _ ->
false )
otdi.otdi_known_categories
| _ ->
false )
| Some (ObjCCategoryImplDecl (_, _, _, _, ocidi)) -> (
match CAst_utils.get_decl_opt_with_decl_ref ocidi.ocidi_category_decl with
| Some (ObjCCategoryDecl (_, _, decl_list, _, _)) ->
decl_list_has_objc_method decl_list method_name is_instance_method
| _ ->
false )
| _ ->
false )
| _ ->
false
(* checks whether an object is of a certain class *)
let is_object_of_class_named receiver cname =
let open Clang_ast_t in

@ -248,6 +248,18 @@ val is_objc_method_overriding : Ctl_parser_types.ast_node -> bool
* is not considered as overriding the same method in the interface or its categories.
*)
val is_objc_method_exposed : CLintersContext.context -> Ctl_parser_types.ast_node -> bool
(**
* Checks if the current node is an ObjCMethodDecl node and is exposed in an interface.
*
* A method is said to be exposed if it's overriding a method or it's declared
* in a matching interface. For example, a method defined in a class's
* implementation is exposed if it's declared in the class's interface or
* interface extension, but not if it's declared in a category on the class.
* If the current node is a subnode of an ObjCInterfaceDecl, ObjCCategoryDecl,
* or ObjCProtocolDecl, this predicate returns false.
*)
val captures_cxx_references : Ctl_parser_types.ast_node -> bool
(** 'captures_cxx_references an' is true iff the node an captures some CXX references *)

@ -1068,6 +1068,8 @@ let rec eval_Atomic pred_name_ args an lcxt =
CPredicates.is_objc_method_named an name
| "is_objc_method_overriding", [], an ->
CPredicates.is_objc_method_overriding an
| "is_objc_method_exposed", [], an ->
CPredicates.is_objc_method_exposed lcxt an
| "is_property_pointer_type", [], an ->
CPredicates.is_property_pointer_type an
| "is_strong_property", [], an ->

@ -594,3 +594,12 @@ DEFINE-CHECKER TEST_IS_OVERRIDING_METHOD = {
SET message = "Method %name% is overriding a method in a superclass.";
};
DEFINE-CHECKER TEST_IS_METHOD_EXPOSED = {
SET report_when =
is_objc_method_exposed;
SET message = "Method %name% is exposed in an interface.";
};

@ -1,6 +1,10 @@
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelfBase_testView, 16, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelfBase_testView, 17, TEST_VAR_TYPE_CHECK, WARNING, []
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallComplain, 40, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_methodThatShallComplain, 41, TEST_IF_VIEW_METHOD_IS_NOT_CALLED_WITH_SUPER, WARNING, []
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 27, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 27, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 44, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 44, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/CallingAMethodWithSelf.m, CallingAMethodWithSelf_testView, 45, TEST_VAR_TYPE_CHECK, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, Linters_dummy_method, 14, TEST_IF_IS_CLASS_NAMED, WARNING, []
@ -24,28 +28,50 @@ codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseC
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassCategoryMethod, 47, TEST_IF_METHOD_IS_IN_CATEGORY_ON_CLASS_NAMED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassCategoryMethod, 53, TEST_IF_METHOD_IS_IN_CATEGORY_NAMED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassCategoryMethod, 53, TEST_IF_METHOD_IS_IN_CATEGORY_ON_CLASS_NAMED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassCategoryMethod, 53, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassInterfaceExtensionMethod, 23, TEST_IF_METHOD_IS_IN_CATEGORY_ON_CLASS_NAMED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassInterfaceExtensionMethod, 31, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassMethod, 29, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProperty, 37, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProperty, 37, TEST_RETURN_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProtocolOptionalMethod, 35, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProtocolOptionalMethod, 35, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProtocolRequiredMethod, 33, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_myBaseClassProtocolRequiredMethod, 33, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_setMyBaseClassProperty, 40, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MyBaseClass_setMyBaseClassProperty, 40, TEST_PARAM_TYPE_CHECK2, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassCategoryMethod, 113, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassCategoryMethod, 113, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassInterfaceExtensionMethod, 93, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassInterfaceExtensionMethod, 93, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassMethod, 89, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassMethod, 89, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProperty, 105, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProperty, 105, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProperty, 105, TEST_RETURN_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProtocolOptionalMethod, 101, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProtocolOptionalMethod, 101, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProtocolRequiredMethod, 97, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_myBaseClassProtocolRequiredMethod, 97, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassCategoryMethod, 136, TEST_IF_METHOD_IS_IN_CATEGORY_ON_SUBCLASS_OF, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassCategoryMethod, 142, TEST_IF_METHOD_IS_IN_CATEGORY_ON_SUBCLASS_OF, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassCategoryMethod, 142, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassMethod, 83, TEST_IF_IS_METHOD_NAMED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassMethod, 117, TEST_IF_IS_METHOD_NAMED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassMethod, 117, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocol2OptionalMethod, 125, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocol2OptionalMethod, 125, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocol2RequiredMethod, 123, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocol2RequiredMethod, 123, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocolOptionalMethod, 121, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocolOptionalMethod, 121, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocolRequiredMethod, 119, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassProtocolRequiredMethod, 119, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassSubprotocol2OptionalMethod, 129, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassSubprotocol2OptionalMethod, 129, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassSubprotocol2RequiredMethod, 127, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_mySubclassSubprotocol2RequiredMethod, 127, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_setMyBaseClassProperty, 109, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_setMyBaseClassProperty, 109, TEST_IS_OVERRIDING_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/GenericTestClass.m, MySubclass_setMyBaseClassProperty, 109, TEST_PARAM_TYPE_CHECK2, WARNING, []
codetoanalyze/objc/linters-for-test-only/InContextOfMethodsTest.m, InContextOfMethodsTest_method, 16, TEST_IN_METHOD_CONTEXT, WARNING, []
@ -89,9 +115,11 @@ codetoanalyze/objc/linters-for-test-only/sel.m, fooButtonComponent_newWithAction
codetoanalyze/objc/linters-for-test-only/sel.m, fooButtonComponent_newWithAction, 12, TEST_PARAMETER_SEL_TYPE, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A_foo, 13, TEST_PARAM_TYPE_CHECK2, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A_foo, 13, TEST_RETURN_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A_foo, 19, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A_foo, 19, TEST_PARAM_TYPE_CHECK2, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, A_foo, 19, TEST_RETURN_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, B_bar, 28, TEST_RETURN_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, B_bar, 34, TEST_IS_METHOD_EXPOSED, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, B_bar, 34, TEST_RETURN_METHOD, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, B_bar, 35, TEST_ALL_METHODS, WARNING, []
codetoanalyze/objc/linters-for-test-only/subclassing.m, B_bar, 36, MACRO_TEST1, WARNING, []

Loading…
Cancel
Save