diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index ed59e34d3..1ed4280a3 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -416,6 +416,14 @@ let declaration_has_name an name = | _ -> false +(* an is an expression @selector with whose name in the language of re *) +let is_at_selector_with_name an re = + match an with + | Ctl_parser_types.Stmt ObjCSelectorExpr (_, _, _, s) + -> ALVar.compare_str_with_alexp s re + | _ + -> false + let is_class an re = match an with | Ctl_parser_types.Decl Clang_ast_t.ObjCInterfaceDecl _ diff --git a/infer/src/clang/cPredicates.mli b/infer/src/clang/cPredicates.mli index e747aa28e..294e97380 100644 --- a/infer/src/clang/cPredicates.mli +++ b/infer/src/clang/cPredicates.mli @@ -94,3 +94,6 @@ val objc_method_has_nth_parameter_of_type : val using_namespace : Ctl_parser_types.ast_node -> ALVar.alexp -> bool val receiver_method_call : Ctl_parser_types.ast_node -> Clang_ast_t.decl option + +val is_at_selector_with_name : Ctl_parser_types.ast_node -> ALVar.alexp -> bool +(** an is an expression @selector with whose name in the language of re *) diff --git a/infer/src/clang/cTL.ml b/infer/src/clang/cTL.ml index e82661f2f..02a1870c2 100644 --- a/infer/src/clang/cTL.ml +++ b/infer/src/clang/cTL.ml @@ -792,6 +792,8 @@ let rec eval_Atomic _pred_name args an lcxt = -> CPredicates.objc_method_has_nth_parameter_of_type an num typ | "using_namespace", [namespace], an -> CPredicates.using_namespace an namespace + | "is_at_selector_with_name", [name], an + -> CPredicates.is_at_selector_with_name an name | "has_type_subprotocol_of", [protname], an -> CPredicates.has_type_subprotocol_of an protname | _ diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m b/infer/tests/codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m new file mode 100644 index 000000000..87d6a6631 --- /dev/null +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2017 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ +#import "Foundation/NSObject.h" + +@interface TestView : NSObject +@end + +@implementation TestView + +- (void)methodd { + [self respondsToSelector:@selector(actionBla:)]; +} + +- (void)methoddd { + [self respondsToSelector:@selector(actionButtonTapped:)]; +} + +@end diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp index 3b53bad2d..9657aceda 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/issues.exp @@ -1,3 +1,6 @@ +codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m, TestView_methodd, 9, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m, TestView_methoddd, 14, TEST_BUILTIN_TYPE, [] +codetoanalyze/objc/linters-for-test-only/PrivateAPIChecker.m, TestView_methoddd, 16, TEST_SELECTOR, [] codetoanalyze/objc/linters-for-test-only/enums.m, test, 16, ENUM_CONSTANTS, [] codetoanalyze/objc/linters-for-test-only/enums.m, test_c_style_enum, 20, ENUM_CONSTANTS, [] codetoanalyze/objc/linters-for-test-only/filter_by_path/include_file.m, main, 9, ALL_PATH_NO_FILTER_EXAMPLE, [] diff --git a/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al b/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al index a985ca077..9d2ba5501 100644 --- a/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al +++ b/infer/tests/codetoanalyze/objc/linters-for-test-only/linters_example.al @@ -343,3 +343,8 @@ DEFINE-CHECKER ENUM_CONSTANTS = { SET report_when = is_enum_constant(REGEXP("MyName.*")) OR is_enum_constant("IMMEDIATE"); SET message = "Do not use the enum MyName or strategy"; }; + + DEFINE-CHECKER TEST_SELECTOR = { + SET report_when = is_at_selector_with_name("actionButtonTapped:"); + SET message = "Found @selector(actionButtonTapped:)"; + };