Skip to content

Commit c969116

Browse files
SamChou19815meta-codesync[bot]
authored andcommitted
1 parent 8bad22f commit c969116

3 files changed

Lines changed: 47 additions & 37 deletions

File tree

src/typing/react_rules.ml

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ module ConditionalState : sig
226226

227227
val reset_label : t -> string -> saved_cond -> t
228228

229-
val enter_switch : t -> (t -> unit) -> saved_cond * saved_switch
229+
val enter_switch_or_loop : t -> (t -> unit) -> saved_cond * saved_switch
230230

231-
val reset_switch : t -> saved_cond -> saved_switch -> t
231+
val reset_switch_or_loop : t -> saved_cond -> saved_switch -> t
232232

233233
val break : t -> string option -> t
234234

@@ -250,7 +250,7 @@ end = struct
250250
broken: bool;
251251
return_seen: bool;
252252
label_scopes: bool SMap.t;
253-
switch_scope: bool;
253+
switch_or_loop_scope: bool;
254254
try_state: try_state;
255255
}
256256

@@ -276,7 +276,7 @@ end = struct
276276
broken = false;
277277
return_seen = false;
278278
label_scopes = SMap.empty;
279-
switch_scope = false;
279+
switch_or_loop_scope = false;
280280
try_state = NotInTry;
281281
}
282282

@@ -292,7 +292,7 @@ end = struct
292292
return_seen;
293293
try_state;
294294
label_scopes = _;
295-
switch_scope = _;
295+
switch_or_loop_scope = _;
296296
conditional_context = _;
297297
} as t
298298
)
@@ -308,8 +308,8 @@ end = struct
308308
setter { t with label_scopes = SMap.add s false label_scopes };
309309
conditional_context
310310

311-
let reset_broken ({ label_scopes; switch_scope; _ } as t) =
312-
{ t with broken = SMap.fold (fun _ -> ( || )) label_scopes switch_scope }
311+
let reset_broken ({ label_scopes; switch_or_loop_scope; _ } as t) =
312+
{ t with broken = SMap.fold (fun _ -> ( || )) label_scopes switch_or_loop_scope }
313313

314314
let reset_label ({ label_scopes; _ } as t) s conditional =
315315
let label_broken = SMap.find s label_scopes in
@@ -320,13 +320,13 @@ end = struct
320320
else
321321
t
322322

323-
let enter_switch ({ conditional_context; switch_scope; _ } as t) setter =
324-
setter { t with switch_scope = false };
325-
(conditional_context, switch_scope)
323+
let enter_switch_or_loop ({ conditional_context; switch_or_loop_scope; _ } as t) setter =
324+
setter { t with switch_or_loop_scope = false };
325+
(conditional_context, switch_or_loop_scope)
326326

327-
let reset_switch ({ switch_scope; _ } as t) conditional cur_switch =
328-
let t = { t with switch_scope = cur_switch } in
329-
if switch_scope then
327+
let reset_switch_or_loop ({ switch_or_loop_scope; _ } as t) conditional cur_switch_or_loop =
328+
let t = { t with switch_or_loop_scope = cur_switch_or_loop } in
329+
if switch_or_loop_scope then
330330
let t = reset_broken t in
331331
reset_conditional t conditional
332332
else
@@ -335,7 +335,7 @@ end = struct
335335
let break t s =
336336
let ({ label_scopes; _ } as t) = { t with broken = true; conditional_context = true } in
337337
match s with
338-
| None -> { t with switch_scope = true }
338+
| None -> { t with switch_or_loop_scope = true }
339339
| Some s -> { t with label_scopes = SMap.add s true label_scopes }
340340

341341
let enter_try ({ conditional_context; try_state; _ } as t) setter =
@@ -361,15 +361,15 @@ end = struct
361361
broken = b1;
362362
return_seen = r1;
363363
label_scopes = l1;
364-
switch_scope = s1;
364+
switch_or_loop_scope = s1;
365365
try_state = t1;
366366
}
367367
{
368368
conditional_context = c2;
369369
broken = b2;
370370
return_seen = r2;
371371
label_scopes = l2;
372-
switch_scope = s2;
372+
switch_or_loop_scope = s2;
373373
try_state = t2;
374374
} =
375375
{
@@ -386,7 +386,7 @@ end = struct
386386
| (None, None) -> None)
387387
l1
388388
l2;
389-
switch_scope = s1 || s2;
389+
switch_or_loop_scope = s1 || s2;
390390
try_state = max_try t1 t2;
391391
return_seen = r1 || r2;
392392
}
@@ -1243,9 +1243,10 @@ and component_ast_visitor tast cx rrid =
12431243

12441244
method! switch stmt =
12451245
let (cur, cur_switch) =
1246-
ConditionalState.enter_switch conditional_state (fun state -> conditional_state <- state)
1246+
ConditionalState.enter_switch_or_loop conditional_state (fun state ->
1247+
conditional_state <- state
1248+
)
12471249
in
1248-
12491250
let { Ast.Statement.Switch.discriminant; cases; comments = _; exhaustive_out = _ } = stmt in
12501251
let (_ : _ Ast.Expression.t) = this#expression discriminant in
12511252
let (_ : _ list) =
@@ -1254,7 +1255,7 @@ and component_ast_visitor tast cx rrid =
12541255
cases
12551256
in
12561257

1257-
conditional_state <- ConditionalState.reset_switch conditional_state cur cur_switch;
1258+
conditional_state <- ConditionalState.reset_switch_or_loop conditional_state cur cur_switch;
12581259
stmt
12591260

12601261
method visit_switch_case ~is_last ({ Ast.Statement.Switch.Case.test; _ } as case) =
@@ -1315,28 +1316,52 @@ and component_ast_visitor tast cx rrid =
13151316
let { Ast.Statement.ForIn.left; right; body; _ } = stmt in
13161317
let _left' : _ Ast.Statement.ForIn.left = this#for_in_statement_lhs left in
13171318
let _right' : _ Ast.Expression.t = this#expression right in
1319+
let (cur, cur_loop) =
1320+
ConditionalState.enter_switch_or_loop conditional_state (fun state ->
1321+
conditional_state <- state
1322+
)
1323+
in
13181324
let _body' : _ Ast.Statement.t = this#in_conditional this#statement body in
1325+
conditional_state <- ConditionalState.reset_switch_or_loop conditional_state cur cur_loop;
13191326
stmt
13201327

13211328
method! for_of_statement stmt =
13221329
let { Ast.Statement.ForOf.left; right; body; _ } = stmt in
13231330
let _left' : _ Ast.Statement.ForOf.left = this#for_of_statement_lhs left in
13241331
let _right' : _ Ast.Expression.t = this#expression right in
1332+
let (cur, cur_loop) =
1333+
ConditionalState.enter_switch_or_loop conditional_state (fun state ->
1334+
conditional_state <- state
1335+
)
1336+
in
13251337
let _body' : _ Ast.Statement.t = this#in_conditional this#statement body in
1338+
conditional_state <- ConditionalState.reset_switch_or_loop conditional_state cur cur_loop;
13261339
stmt
13271340

13281341
method! for_statement stmt =
13291342
let { Ast.Statement.For.init; test; update; body; _ } = stmt in
13301343
let _init' : _ option = Base.Option.map ~f:this#for_statement_init init in
1344+
let (cur, cur_loop) =
1345+
ConditionalState.enter_switch_or_loop conditional_state (fun state ->
1346+
conditional_state <- state
1347+
)
1348+
in
13311349
let _test' : _ option = Base.Option.map ~f:this#predicate_expression test in
13321350
let _update' : _ option = Base.Option.map ~f:(this#in_conditional this#expression) update in
13331351
let _body' : _ Ast.Statement.t = this#in_conditional this#statement body in
1352+
conditional_state <- ConditionalState.reset_switch_or_loop conditional_state cur cur_loop;
13341353
stmt
13351354

13361355
method! while_ stmt =
13371356
let { Ast.Statement.While.test; body; _ } = stmt in
1357+
let (cur, cur_loop) =
1358+
ConditionalState.enter_switch_or_loop conditional_state (fun state ->
1359+
conditional_state <- state
1360+
)
1361+
in
13381362
let _test' : _ Ast.Expression.t = this#predicate_expression test in
13391363
let _body' : _ Ast.Statement.t = this#in_conditional this#statement body in
1364+
conditional_state <- ConditionalState.reset_switch_or_loop conditional_state cur cur_loop;
13401365
stmt
13411366

13421367
method function_component_body = super#function_body_any

tests/hook_syntax/hook_syntax.exp

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1863,21 +1863,6 @@ References:
18631863
^^^^^^^ [1]
18641864

18651865

1866-
Error ------------------------------------------------------------------------------------------ rules_of_hooks.js:798:3
1867-
1868-
Cannot call hook [1] because React hooks cannot be called in conditional contexts.
1869-
(https://react.dev/reference/rules/rules-of-hooks) [react-rule-hook-conditional]
1870-
1871-
rules_of_hooks.js:798:3
1872-
798| useState(); // bad error. Not actually conditional
1873-
^^^^^^^^^^
1874-
1875-
References:
1876-
rules_of_hooks.js:798:3
1877-
798| useState(); // bad error. Not actually conditional
1878-
^^^^^^^^ [1]
1879-
1880-
18811866
Error ------------------------------------------------------------------------------------------ rules_of_hooks.js:807:3
18821867

18831868
Cannot call hook [1] because React hooks can only be called within components or hooks. This hook is definitely not
@@ -2660,4 +2645,4 @@ References:
26602645

26612646

26622647

2663-
Found 172 errors
2648+
Found 171 errors

tests/hook_syntax/rules_of_hooks.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -795,7 +795,7 @@ hook useBreakInUnlabeledForLoop() {
795795
for (let i = 0; i < 10; i++) {
796796
break;
797797
}
798-
useState(); // bad error. Not actually conditional
798+
useState(); // ok
799799
}
800800

801801
// Currently invalid.

0 commit comments

Comments
 (0)