From a45d59e4783f143b0a1635b69cdea47536cf00d6 Mon Sep 17 00:00:00 2001 From: Ryan Rhee Date: Thu, 27 Oct 2016 14:41:33 -0700 Subject: [PATCH] [componentkit] Don't count unavailable initializers Reviewed By: tks2103 Differential Revision: D4090154 fbshipit-source-id: e0626e6 --- infer/src/clang/ComponentKit.ml | 13 ++++++++++++- .../componentkit/MultipleFactoryMethodsTest.h | 15 +++++++++++++++ .../componentkit/MultipleFactoryMethodsTest.mm | 6 ++++++ .../tests/codetoanalyze/objcpp/linters/issues.exp | 1 + 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/infer/src/clang/ComponentKit.ml b/infer/src/clang/ComponentKit.ml index 7ceabd169..e50ecfaa2 100644 --- a/infer/src/clang/ComponentKit.ml +++ b/infer/src/clang/ComponentKit.ml @@ -197,10 +197,21 @@ let component_with_unconventional_superclass_advice context decl = there would be factory methods that aren't exposed outside of a class is not useful if there's only one public factory method. *) let component_with_multiple_factory_methods_advice context decl = + let is_unavailable_attr attr = match attr with + | Clang_ast_t.UnavailableAttr _ -> true + | _ -> false in + let is_available_factory_method if_decl (decl: Clang_ast_t.decl) = + let attrs = match decl with + | ObjCMethodDecl (decl_info, _, _) -> decl_info.Clang_ast_t.di_attributes + | _ -> assert false in + let unavailable_attrs = (IList.filter is_unavailable_attr attrs) in + let is_available = IList.length unavailable_attrs = 0 in + (Ast_utils.is_objc_factory_method if_decl decl) && is_available in + let check_interface if_decl = match if_decl with | Clang_ast_t.ObjCInterfaceDecl (decl_info, _, decls, _, _) -> - let factory_methods = IList.filter (Ast_utils.is_objc_factory_method if_decl) decls in + let factory_methods = IList.filter (is_available_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/tests/codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h b/infer/tests/codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h index 749be8150..bde7b5641 100644 --- a/infer/tests/codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h +++ b/infer/tests/codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h @@ -36,3 +36,18 @@ + (int)somethingElse; - (NSString*)blah:(int)lol; @end + +// OK - unavailable initializers shouldn't count +@interface UnavailableInitializer1 : CKCompositeComponent ++ (instancetype) new // shouldn't count since it's unavailable + __attribute__((unavailable("Must use designated initializer"))); ++ (instancetype)newWithObject:(NSObject*)obj; +@end + +// Not OK - there are 2 static initialzers, even w/out the unavailable one +@interface UnavailableInitializer2 : CKCompositeComponent ++ (instancetype) new // shouldn't count since it's unavailable + __attribute__((unavailable("Must use designated initializer"))); ++ (instancetype)newWithObject1:(NSObject*)obj; ++ (instancetype)newWithObject2:(NSObject*)obj; +@end diff --git a/infer/tests/codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.mm b/infer/tests/codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.mm index 4e51690bb..c4deff165 100644 --- a/infer/tests/codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.mm +++ b/infer/tests/codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.mm @@ -25,3 +25,9 @@ @implementation OKComponent @end + +@implementation UnavailableInitializer1 +@end + +@implementation UnavailableInitializer2 +@end diff --git a/infer/tests/codetoanalyze/objcpp/linters/issues.exp b/infer/tests/codetoanalyze/objcpp/linters/issues.exp index d440fa9ce..d8ee09ebd 100644 --- a/infer/tests/codetoanalyze/objcpp/linters/issues.exp +++ b/infer/tests/codetoanalyze/objcpp/linters/issues.exp @@ -8,6 +8,7 @@ componentkit/InitializerWithSideEffectTest.mm, __objc_anonymous_block_______1, 3 componentkit/InitializerWithSideEffectTest.mm, __objc_anonymous_block_______2, 41, COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 18, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 27, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS +componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 48, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 89, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 91, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 110, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE