main
ts 35 lines 1.08 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 import {CompilerError} from '..';
9 import {BlockId, ReactiveFunction, ReactiveTerminalStatement} from '../HIR';
10 import {ReactiveFunctionVisitor, visitReactiveFunction} from './visitors';
11
12 /**
13 * Assert that all break/continue targets reference existent labels.
14 */
15 export function assertWellFormedBreakTargets(fn: ReactiveFunction): void {
16 visitReactiveFunction(fn, new Visitor(), new Set());
17 }
18
19 class Visitor extends ReactiveFunctionVisitor<Set<BlockId>> {
20 override visitTerminal(
21 stmt: ReactiveTerminalStatement,
22 seenLabels: Set<BlockId>,
23 ): void {
24 if (stmt.label != null) {
25 seenLabels.add(stmt.label.id);
26 }
27 const terminal = stmt.terminal;
28 if (terminal.kind === 'break' || terminal.kind === 'continue') {
29 CompilerError.invariant(seenLabels.has(terminal.target), {
30 reason: 'Unexpected break to invalid label',
31 loc: stmt.terminal.loc,
32 });
33 }
34 }
35 }