Skip to content

Commit df64cc2

Browse files
mvitousekfacebook-github-bot
authored andcommitted
[flow] Compatibility mode exclusion
Summary: This diff makes a few changes to the hook compatibility mode: * It changes the name (internally to flow, and externally in the flowconfig) for the hook compatibility mode from `hooklike_functions` to `hook_compatibility` to better match how we refer to it. `hooklike_functions` still is available in the flowconfig for... compatibility (lol) * It introduces a new flowconfig option, `experimental.component_syntax.hook_compatibility.excludes`, to disable compatibility mode in a directory. The converse, `experimental.component_syntax.hook_compatibility.includes`, already existed. * It modifies the behavior of inclusion/exclusion so that files that are included in compatibility mode have their exports behave accordingly: a compatible module that has a function hook export will have that function hook be callable in excluded components. Reviewed By: alexmckenley Differential Revision: D55780714 fbshipit-source-id: 83a3a4a69bcaa4161251af39554ca9ff72b99b3e
1 parent 47f6599 commit df64cc2

33 files changed

+221
-94
lines changed

src/codemods/annotate_exports.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ module SignatureVerification = struct
7777
enable_relay_integration = Options.enable_relay_integration options;
7878
casting_syntax = Options.casting_syntax options;
7979
relay_integration_module_prefix = Options.relay_integration_module_prefix options;
80-
hooklike_functions = Options.hooklike_functions_in_file options file;
80+
hook_compatibility = Options.hook_compatibility_in_file options file;
8181
for_builtins = false;
8282
locs_to_dirtify = [];
8383
}

src/commands/commandUtils.ml

+7-3
Original file line numberDiff line numberDiff line change
@@ -1379,11 +1379,15 @@ let make_options
13791379
opt_as_const = Base.Option.value ~default:false (FlowConfig.enable_as_const flowconfig);
13801380
opt_component_syntax = FlowConfig.component_syntax flowconfig;
13811381
opt_react_rules = FlowConfig.react_rules flowconfig;
1382-
opt_hooklike_functions = FlowConfig.hooklike_functions flowconfig;
1383-
opt_hooklike_functions_includes =
1382+
opt_hook_compatibility = FlowConfig.hook_compatibility flowconfig;
1383+
opt_hook_compatibility_includes =
13841384
Base.List.map
13851385
~f:(Files.expand_project_root_token ~root)
1386-
(FlowConfig.hooklike_functions_includes flowconfig);
1386+
(FlowConfig.hook_compatibility_includes flowconfig);
1387+
opt_hook_compatibility_excludes =
1388+
Base.List.map
1389+
~f:(Files.expand_project_root_token ~root)
1390+
(FlowConfig.hook_compatibility_excludes flowconfig);
13871391
opt_enable_const_params =
13881392
Base.Option.value (FlowConfig.enable_const_params flowconfig) ~default:false;
13891393
opt_enable_relay_integration = FlowConfig.relay_integration flowconfig;

src/commands/config/flowConfig.ml

+33-12
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,9 @@ module Opts = struct
5555
casting_syntax: Options.CastingSyntax.t option;
5656
channel_mode: [ `pipe | `socket ] option;
5757
component_syntax: bool;
58-
hooklike_functions: bool;
59-
hooklike_functions_includes: string list;
58+
hook_compatibility: bool;
59+
hook_compatibility_includes: string list;
60+
hook_compatibility_excludes: string list;
6061
react_rules: Options.react_rules list;
6162
emoji: bool option;
6263
enable_as_const: bool option;
@@ -184,8 +185,9 @@ module Opts = struct
184185
channel_mode = None;
185186
casting_syntax = None;
186187
component_syntax = false;
187-
hooklike_functions = true;
188-
hooklike_functions_includes = [];
188+
hook_compatibility = true;
189+
hook_compatibility_includes = [];
190+
hook_compatibility_excludes = [];
189191
react_rules = [];
190192
emoji = None;
191193
enable_as_const = None;
@@ -556,14 +558,21 @@ module Opts = struct
556558
]
557559
(fun opts v -> Ok { opts with react_rules = v :: opts.react_rules })
558560

559-
let hooklike_functions_includes_parser =
561+
let hook_compatibility_includes_parser =
560562
string
561-
~init:(fun opts -> { opts with hooklike_functions_includes = [] })
563+
~init:(fun opts -> { opts with hook_compatibility_includes = [] })
562564
~multiple:true
563565
(fun opts v ->
564-
Ok { opts with hooklike_functions_includes = v :: opts.hooklike_functions_includes })
566+
Ok { opts with hook_compatibility_includes = v :: opts.hook_compatibility_includes })
565567

566-
let hooklike_functions_parser = boolean (fun opts v -> Ok { opts with hooklike_functions = v })
568+
let hook_compatibility_excludes_parser =
569+
string
570+
~init:(fun opts -> { opts with hook_compatibility_excludes = [] })
571+
~multiple:true
572+
(fun opts v ->
573+
Ok { opts with hook_compatibility_excludes = v :: opts.hook_compatibility_excludes })
574+
575+
let hook_compatibility_parser = boolean (fun opts v -> Ok { opts with hook_compatibility = v })
567576

568577
let automatic_require_default_parser =
569578
boolean (fun opts v -> Ok { opts with automatic_require_default = Some v })
@@ -896,9 +905,19 @@ module Opts = struct
896905
boolean (fun opts v -> Ok { opts with enable_const_params = Some v })
897906
);
898907
("experimental.component_syntax", component_syntax_parser);
899-
("experimental.component_syntax.hooklike_functions", hooklike_functions_parser);
908+
("experimental.component_syntax.hook_compatibility", hook_compatibility_parser);
909+
("experimental.component_syntax.hooklike_functions", hook_compatibility_parser);
910+
( "experimental.component_syntax.hook_compatibility.includes",
911+
hook_compatibility_includes_parser
912+
);
900913
( "experimental.component_syntax.hooklike_functions.includes",
901-
hooklike_functions_includes_parser
914+
hook_compatibility_includes_parser
915+
);
916+
( "experimental.component_syntax.hook_compatibility.excludes",
917+
hook_compatibility_excludes_parser
918+
);
919+
( "experimental.component_syntax.hooklike_functions.excludes",
920+
hook_compatibility_excludes_parser
902921
);
903922
("experimental.react_rule", react_rules_parser);
904923
("experimental.facebook_module_interop", facebook_module_interop_parser);
@@ -1552,9 +1571,11 @@ let channel_mode c = c.options.Opts.channel_mode
15521571

15531572
let component_syntax c = c.options.Opts.component_syntax
15541573

1555-
let hooklike_functions_includes c = c.options.Opts.hooklike_functions_includes
1574+
let hook_compatibility_includes c = c.options.Opts.hook_compatibility_includes
1575+
1576+
let hook_compatibility_excludes c = c.options.Opts.hook_compatibility_excludes
15561577

1557-
let hooklike_functions c = c.options.Opts.hooklike_functions
1578+
let hook_compatibility c = c.options.Opts.hook_compatibility
15581579

15591580
let react_rules c = c.options.Opts.react_rules
15601581

src/commands/config/flowConfig.mli

+4-2
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,11 @@ val channel_mode : config -> [ `pipe | `socket ] option
8888

8989
val component_syntax : config -> bool
9090

91-
val hooklike_functions_includes : config -> string list
91+
val hook_compatibility_excludes : config -> string list
9292

93-
val hooklike_functions : config -> bool
93+
val hook_compatibility_includes : config -> string list
94+
95+
val hook_compatibility : config -> bool
9496

9597
val react_rules : config -> Options.react_rules list
9698

src/common/options.ml

+30-16
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,9 @@ type t = {
8282
opt_casting_syntax: CastingSyntax.t;
8383
opt_channel_mode: [ `pipe | `socket ];
8484
opt_component_syntax: bool;
85-
opt_hooklike_functions_includes: string list;
86-
opt_hooklike_functions: bool;
85+
opt_hook_compatibility_includes: string list;
86+
opt_hook_compatibility_excludes: string list;
87+
opt_hook_compatibility: bool;
8788
opt_react_rules: react_rules list;
8889
opt_debug: bool;
8990
opt_enable_const_params: bool;
@@ -190,20 +191,33 @@ let channel_mode opts = opts.opt_channel_mode
190191

191192
let component_syntax opts = opts.opt_component_syntax
192193

193-
let hooklike_functions opts = opts.opt_hooklike_functions
194-
195-
let hooklike_functions_includes opts = opts.opt_hooklike_functions_includes
196-
197-
let hooklike_functions_in_file opts file =
198-
hooklike_functions opts
199-
|| begin
200-
match hooklike_functions_includes opts with
201-
| [] -> false
202-
| dirs ->
203-
let filename = File_key.to_string file in
204-
let normalized_filename = Sys_utils.normalize_filename_dir_sep filename in
205-
List.exists (fun str -> Base.String.is_prefix ~prefix:str normalized_filename) dirs
206-
end
194+
let hook_compatibility opts = opts.opt_hook_compatibility
195+
196+
let hook_compatibility_includes opts = opts.opt_hook_compatibility_includes
197+
198+
let hook_compatibility_excludes opts = opts.opt_hook_compatibility_excludes
199+
200+
let hook_compatibility_in_file opts file =
201+
let included =
202+
hook_compatibility opts
203+
|| begin
204+
match hook_compatibility_includes opts with
205+
| [] -> false
206+
| dirs ->
207+
let filename = File_key.to_string file in
208+
let normalized_filename = Sys_utils.normalize_filename_dir_sep filename in
209+
List.exists (fun str -> Base.String.is_prefix ~prefix:str normalized_filename) dirs
210+
end
211+
in
212+
let excluded =
213+
match hook_compatibility_excludes opts with
214+
| [] -> false
215+
| dirs ->
216+
let filename = File_key.to_string file in
217+
let normalized_filename = Sys_utils.normalize_filename_dir_sep filename in
218+
List.exists (fun str -> Base.String.is_prefix ~prefix:str normalized_filename) dirs
219+
in
220+
included && not excluded
207221

208222
let typecheck_component_syntax_in_file opts file =
209223
component_syntax opts || File_key.is_lib_file file

src/flow_dot_js.ml

+4-3
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ let load_lib_files files =
9494
enable_component_syntax = true;
9595
component_syntax_enabled_in_config = true;
9696
enable_ts_syntax = true;
97-
hooklike_functions = true;
97+
hook_compatibility = true;
9898
casting_syntax = Options.CastingSyntax.Both;
9999
for_builtins = true;
100100
locs_to_dirtify = [];
@@ -120,8 +120,9 @@ let stub_metadata ~root ~checked =
120120
babel_loose_array_spread = false;
121121
casting_syntax = Options.CastingSyntax.Both;
122122
component_syntax = true;
123-
hooklike_functions = true;
124-
hooklike_functions_includes = [];
123+
hook_compatibility = true;
124+
hook_compatibility_includes = [];
125+
hook_compatibility_excludes = [];
125126
react_rules =
126127
Options.
127128
[ValidateRefAccessDuringRender; DeepReadOnlyProps; DeepReadOnlyHookReturns; RulesOfHooks];

src/parser_utils/exports/__tests__/exports_tests.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ let sig_opts =
5959
enable_component_syntax = true;
6060
component_syntax_enabled_in_config = true;
6161
enable_ts_syntax = true;
62-
hooklike_functions = true;
62+
hook_compatibility = true;
6363
enable_relay_integration = false;
6464
casting_syntax = Options.CastingSyntax.Colon;
6565
relay_integration_module_prefix = None;

src/parser_utils/type_sig/__tests__/type_sig_tests.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ let sig_options
216216
?(enable_enums = true)
217217
?(enable_component_syntax = true)
218218
?(enable_ts_syntax = true)
219-
?(hooklike_functions = true)
219+
?(hook_compatibility = true)
220220
?(enable_relay_integration = false)
221221
?(casting_syntax = Options.CastingSyntax.Colon)
222222
?relay_integration_module_prefix
@@ -234,7 +234,7 @@ let sig_options
234234
enable_component_syntax;
235235
component_syntax_enabled_in_config = true;
236236
enable_ts_syntax;
237-
hooklike_functions;
237+
hook_compatibility;
238238
enable_relay_integration;
239239
casting_syntax;
240240
relay_integration_module_prefix;

src/parser_utils/type_sig/type_sig_options.ml

+3-3
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type t = {
1616
enable_component_syntax: bool;
1717
component_syntax_enabled_in_config: bool;
1818
enable_ts_syntax: bool;
19-
hooklike_functions: bool;
19+
hook_compatibility: bool;
2020
casting_syntax: Options.CastingSyntax.t;
2121
enable_relay_integration: bool;
2222
relay_integration_module_prefix: string option;
@@ -51,7 +51,7 @@ let of_options options docblock locs_to_dirtify file =
5151
enable_relay_integration;
5252
relay_integration_module_prefix;
5353
locs_to_dirtify;
54-
hooklike_functions = Options.hooklike_functions options;
54+
hook_compatibility = Options.hook_compatibility_in_file options file;
5555
suppress_types = Options.suppress_types options;
5656
facebook_fbt = Options.facebook_fbt options;
5757
max_literal_len = Options.max_literal_length options;
@@ -82,7 +82,7 @@ let builtin_options options =
8282
enable_component_syntax = true;
8383
component_syntax_enabled_in_config = Options.component_syntax options;
8484
enable_ts_syntax = false;
85-
hooklike_functions = Options.hooklike_functions options;
85+
hook_compatibility = Options.hook_compatibility options;
8686
casting_syntax = Options.casting_syntax options;
8787
for_builtins = true;
8888
locs_to_dirtify = [];

src/parser_utils/type_sig/type_sig_parse.ml

+2-2
Original file line numberDiff line numberDiff line change
@@ -3555,7 +3555,7 @@ and function_def_helper =
35553555
match id with
35563556
| _ when hook -> HookDecl fun_loc
35573557
| Some (_, { Ast.Identifier.name; _ })
3558-
when opts.hooklike_functions && Flow_ast_utils.hook_name name ->
3558+
when opts.hook_compatibility && Flow_ast_utils.hook_name name ->
35593559
AnyHook
35603560
| _ -> NonHook
35613561
in
@@ -4516,7 +4516,7 @@ let declare_function_decl opts scope tbls decl =
45164516
HookAnnot
45174517
else if
45184518
opts.component_syntax_enabled_in_config
4519-
&& opts.hooklike_functions
4519+
&& opts.hook_compatibility
45204520
&& Flow_ast_utils.hook_name name
45214521
then
45224522
AnyHook

src/services/code_action/__tests__/refactor_extract_utils_tests.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ let stub_metadata ~root ~checked =
3737
babel_loose_array_spread = false;
3838
casting_syntax = Options.CastingSyntax.Colon;
3939
component_syntax = false;
40-
hooklike_functions_includes = [];
41-
hooklike_functions = true;
40+
hook_compatibility_excludes = [];
41+
hook_compatibility_includes = [];
42+
hook_compatibility = true;
4243
react_rules = [];
4344
react_rules_always = false;
4445
enable_as_const = false;

src/typing/__tests__/type_hint_test.ml

+4-3
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ let metadata =
2929
babel_loose_array_spread = false;
3030
casting_syntax = Options.CastingSyntax.Colon;
3131
component_syntax = true;
32-
hooklike_functions_includes = [];
33-
hooklike_functions = true;
32+
hook_compatibility_excludes = [];
33+
hook_compatibility_includes = [];
34+
hook_compatibility = true;
3435
react_rules = [];
3536
react_rules_always = false;
3637
enable_as_const = false;
@@ -197,7 +198,7 @@ end = struct
197198
enable_component_syntax = true;
198199
component_syntax_enabled_in_config = true;
199200
enable_ts_syntax = true;
200-
hooklike_functions = true;
201+
hook_compatibility = true;
201202
casting_syntax = Options.CastingSyntax.Both;
202203
for_builtins = true;
203204
locs_to_dirtify = [];

src/typing/__tests__/typed_ast_test.ml

+3-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ let metadata =
2727
babel_loose_array_spread = false;
2828
casting_syntax = Options.CastingSyntax.Colon;
2929
component_syntax = true;
30-
hooklike_functions_includes = [];
31-
hooklike_functions = true;
30+
hook_compatibility_excludes = [];
31+
hook_compatibility_includes = [];
32+
hook_compatibility = true;
3233
react_rules = [];
3334
react_rules_always = false;
3435
enable_as_const = false;

src/typing/context.ml

+9-6
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ type metadata = {
3838
babel_loose_array_spread: bool;
3939
casting_syntax: Options.CastingSyntax.t;
4040
component_syntax: bool;
41-
hooklike_functions_includes: string list;
42-
hooklike_functions: bool;
41+
hook_compatibility_excludes: string list;
42+
hook_compatibility_includes: string list;
43+
hook_compatibility: bool;
4344
react_rules: Options.react_rules list;
4445
react_rules_always: bool;
4546
enable_as_const: bool;
@@ -254,8 +255,9 @@ let metadata_of_options options =
254255
babel_loose_array_spread = Options.babel_loose_array_spread options;
255256
casting_syntax = Options.casting_syntax options;
256257
component_syntax = Options.component_syntax options;
257-
hooklike_functions_includes = Options.hooklike_functions_includes options;
258-
hooklike_functions = Options.hooklike_functions options;
258+
hook_compatibility_excludes = Options.hook_compatibility_excludes options;
259+
hook_compatibility_includes = Options.hook_compatibility_includes options;
260+
hook_compatibility = Options.hook_compatibility options;
259261
react_rules = Options.react_rules options;
260262
react_rules_always = false;
261263
enable_as_const = Options.as_const options;
@@ -455,8 +457,9 @@ let casting_syntax cx = cx.metadata.casting_syntax
455457

456458
let component_syntax cx = cx.metadata.component_syntax || File_key.is_lib_file cx.file
457459

458-
let hooklike_functions cx =
459-
cx.metadata.hooklike_functions || in_dirlist cx cx.metadata.hooklike_functions_includes
460+
let hook_compatibility cx =
461+
(cx.metadata.hook_compatibility || in_dirlist cx cx.metadata.hook_compatibility_includes)
462+
&& not (in_dirlist cx cx.metadata.hook_compatibility_excludes)
460463

461464
let react_rules_always cx = cx.metadata.react_rules_always
462465

src/typing/context.mli

+4-3
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,9 @@ type metadata = {
7575
babel_loose_array_spread: bool;
7676
casting_syntax: Options.CastingSyntax.t;
7777
component_syntax: bool;
78-
hooklike_functions_includes: string list;
79-
hooklike_functions: bool;
78+
hook_compatibility_excludes: string list;
79+
hook_compatibility_includes: string list;
80+
hook_compatibility: bool;
8081
react_rules: Options.react_rules list;
8182
react_rules_always: bool;
8283
enable_as_const: bool;
@@ -160,7 +161,7 @@ val casting_syntax : t -> Options.CastingSyntax.t
160161

161162
val component_syntax : t -> bool
162163

163-
val hooklike_functions : t -> bool
164+
val hook_compatibility : t -> bool
164165

165166
val react_rule_enabled : t -> Options.react_rules -> bool
166167

src/typing/env_resolution.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ let expression cx ?cond exp =
5555
t
5656

5757
let make_hooklike cx t =
58-
if Context.hooklike_functions cx then
58+
if Context.hook_compatibility cx then
5959
Flow_js.mk_possibly_evaluated_destructor
6060
cx
6161
unknown_use

0 commit comments

Comments
 (0)