[componentkit] Initializer rule should return multiple issues

Reviewed By: jvillard

Differential Revision: D4359088

fbshipit-source-id: cd6d075
master
Ryan Rhee 8 years ago committed by Facebook Github Bot
parent 4e37677eeb
commit b557b49921

@ -219,7 +219,10 @@ let component_with_unconventional_superclass_advice context an =
additional factory methods are implementation-only, the rule doesn't catch additional factory methods are implementation-only, the rule doesn't catch
it. While its existence is probably not good, I can't think of any reason it. While its existence is probably not good, I can't think of any reason
there would be factory methods that aren't exposed outside of a class is there would be factory methods that aren't exposed outside of a class is
not useful if there's only one public factory method. *) not useful if there's only one public factory method.
Given n factory methods, the rule should emit n-1 issues. Each issue's
location should point to the method declaration. *)
let component_with_multiple_factory_methods_advice context an = let component_with_multiple_factory_methods_advice context an =
let is_unavailable_attr attr = match attr with let is_unavailable_attr attr = match attr with
| Clang_ast_t.UnavailableAttr _ -> true | Clang_ast_t.UnavailableAttr _ -> true
@ -234,21 +237,18 @@ let component_with_multiple_factory_methods_advice context an =
let check_interface if_decl = let check_interface if_decl =
match if_decl with match if_decl with
| Clang_ast_t.ObjCInterfaceDecl (decl_info, _, decls, _, _) -> | Clang_ast_t.ObjCInterfaceDecl (_, _, decls, _, _) ->
let factory_methods = IList.filter (is_available_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 CTL.True, IList.map (fun meth_decl -> {
CTL.True, Some { CIssue.name = "COMPONENT_WITH_MULTIPLE_FACTORY_METHODS";
CIssue.name = "COMPONENT_WITH_MULTIPLE_FACTORY_METHODS"; severity = Exceptions.Kadvice;
severity = Exceptions.Kadvice; mode = CIssue.On;
mode = CIssue.On; description = "Avoid Overrides";
description = "Avoid Overrides"; suggestion =
suggestion = Some "Instead, always expose all parameters in a single \
Some "Instead, always expose all parameters in a single \ designated initializer and document which are optional.";
designated initializer and document which are optional."; loc = CFrontend_checkers.location_from_decl context meth_decl
loc = CFrontend_checkers.location_from_dinfo context decl_info }) (IList.drop_first 1 factory_methods)
}
else
CTL.False, None
| _ -> assert false in | _ -> assert false in
match an with match an with
| CTL.Decl (Clang_ast_t.ObjCImplementationDecl (_, _, _, _, impl_decl_info)) -> | CTL.Decl (Clang_ast_t.ObjCImplementationDecl (_, _, _, _, impl_decl_info)) ->
@ -256,8 +256,8 @@ let component_with_multiple_factory_methods_advice context an =
Ast_utils.get_decl_opt_with_decl_ref impl_decl_info.oidi_class_interface in Ast_utils.get_decl_opt_with_decl_ref impl_decl_info.oidi_class_interface in
(match if_decl_opt with (match if_decl_opt with
| Some d when is_ck_context context an -> check_interface d | Some d when is_ck_context context an -> check_interface d
| _ -> CTL.False, None) | _ -> CTL.False, [])
| _ -> CTL.False, None | _ -> CTL.False, []
let in_ck_class (context: CLintersContext.context) = let in_ck_class (context: CLintersContext.context) =
Option.value_map ~f:is_component_or_controller_descendant_impl ~default:false Option.value_map ~f:is_component_or_controller_descendant_impl ~default:false

@ -26,7 +26,7 @@ val component_with_unconventional_superclass_advice :
CLintersContext.context -> CTL.ast_node -> CTL.t * CIssue.issue_desc option CLintersContext.context -> CTL.ast_node -> CTL.t * CIssue.issue_desc option
val component_with_multiple_factory_methods_advice : val component_with_multiple_factory_methods_advice :
CLintersContext.context -> CTL.ast_node -> CTL.t * CIssue.issue_desc option CLintersContext.context -> CTL.ast_node -> CTL.t * CIssue.issue_desc list
val component_initializer_with_side_effects_advice : val component_initializer_with_side_effects_advice :
CLintersContext.context -> CTL.ast_node -> CTL.t * CIssue.issue_desc option CLintersContext.context -> CTL.ast_node -> CTL.t * CIssue.issue_desc option

@ -24,11 +24,12 @@ let decl_single_checkers_list = [CFrontend_checkers.ctl_strong_delegate_warning;
ComponentKit.component_with_unconventional_superclass_advice; ComponentKit.component_with_unconventional_superclass_advice;
ComponentKit.mutable_local_vars_advice; ComponentKit.mutable_local_vars_advice;
ComponentKit.component_factory_function_advice; ComponentKit.component_factory_function_advice;
ComponentKit.component_file_cyclomatic_complexity_info; ComponentKit.component_file_cyclomatic_complexity_info;]
ComponentKit.component_with_multiple_factory_methods_advice;]
(* List of checkers on decls *) (* List of checkers on decls *)
let decl_checkers_list = IList.map single_to_multi decl_single_checkers_list let decl_checkers_list =
ComponentKit.component_with_multiple_factory_methods_advice::
(IList.map single_to_multi decl_single_checkers_list)
(* List of checkers on stmts *that return 0 or 1 issue* *) (* List of checkers on stmts *that return 0 or 1 issue* *)
let stmt_single_checkers_list = [CFrontend_checkers.ctl_direct_atomic_property_access_warning; let stmt_single_checkers_list = [CFrontend_checkers.ctl_direct_atomic_property_access_warning;

@ -51,3 +51,11 @@
+ (instancetype)newWithObject1:(NSObject*)obj; + (instancetype)newWithObject1:(NSObject*)obj;
+ (instancetype)newWithObject2:(NSObject*)obj; + (instancetype)newWithObject2:(NSObject*)obj;
@end @end
// 4 initializers -> should output 3 issues
@interface LotsOfInitializers : CKCompositeComponent
+ (instancetype)newWithObject1:(NSObject*)obj;
+ (instancetype)newWithObject2:(NSObject*)obj;
+ (instancetype)newWithObject3:(NSObject*)obj;
+ (instancetype)newWithObject4:(NSObject*)obj;
@end

@ -31,3 +31,6 @@
@implementation UnavailableInitializer2 @implementation UnavailableInitializer2
@end @end
@implementation LotsOfInitializers
@end

@ -6,9 +6,12 @@ codetoanalyze/objcpp/linters/componentkit/InitializerWithSideEffectTest.mm, FooC
codetoanalyze/objcpp/linters/componentkit/InitializerWithSideEffectTest.mm, FooComponent_newDerp, 29, COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS, [] codetoanalyze/objcpp/linters/componentkit/InitializerWithSideEffectTest.mm, FooComponent_newDerp, 29, COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS, []
codetoanalyze/objcpp/linters/componentkit/InitializerWithSideEffectTest.mm, __objc_anonymous_block_______1, 37, COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS, [] codetoanalyze/objcpp/linters/componentkit/InitializerWithSideEffectTest.mm, __objc_anonymous_block_______1, 37, COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS, []
codetoanalyze/objcpp/linters/componentkit/InitializerWithSideEffectTest.mm, __objc_anonymous_block_______2, 41, COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS, [] codetoanalyze/objcpp/linters/componentkit/InitializerWithSideEffectTest.mm, __objc_anonymous_block_______2, 41, COMPONENT_INITIALIZER_WITH_SIDE_EFFECTS, []
codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 18, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, [] codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 20, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, []
codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 27, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, [] codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 29, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, []
codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 48, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, [] codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 52, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, []
codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 58, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, []
codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 59, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, []
codetoanalyze/objcpp/linters/componentkit/MultipleFactoryMethodsTest.h, Linters_dummy_method, 60, COMPONENT_WITH_MULTIPLE_FACTORY_METHODS, []
codetoanalyze/objcpp/linters/componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 89, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE, [] codetoanalyze/objcpp/linters/componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 89, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE, []
codetoanalyze/objcpp/linters/componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 91, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE, [] codetoanalyze/objcpp/linters/componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 91, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE, []
codetoanalyze/objcpp/linters/componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 110, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE, [] codetoanalyze/objcpp/linters/componentkit/MutableLocalVariablesTest.mm, BarComponent_new, 110, MUTABLE_LOCAL_VARIABLE_IN_COMPONENT_FILE, []

Loading…
Cancel
Save