import {CompilerDiagnostic, CompilerError} from '..';
import {ErrorCategory} from '../CompilerError';
import {BlockId, HIRFunction} from '../HIR';
import {Result} from '../Utils/Result';
import {retainWhere} from '../Utils/utils';
export function validateNoJSXInTryStatement(
fn: HIRFunction,
): Result<void, CompilerError> {
const activeTryBlocks: Array<BlockId> = [];
const errors = new CompilerError();
for (const [, block] of fn.body.blocks) {
retainWhere(activeTryBlocks, id => id !== block.id);
if (activeTryBlocks.length !== 0) {
for (const instr of block.instructions) {
const {value} = instr;
switch (value.kind) {
case 'JsxExpression':
case 'JsxFragment': {
errors.pushDiagnostic(
CompilerDiagnostic.create({
category: ErrorCategory.ErrorBoundaries,
reason: 'Avoid constructing JSX within try/catch',
description: `React does not immediately render components when JSX is rendered, so any errors from this component will not be caught by the try/catch. To catch errors in rendering a given component, wrap that component in an error boundary. (https://react.dev/reference/react/Component#catching-rendering-errors-with-an-error-boundary)`,
}).withDetails({
kind: 'error',
loc: value.loc,
message: 'Avoid constructing JSX within try/catch',
}),
);
break;
}
}
}
}
if (block.terminal.kind === 'try') {
activeTryBlocks.push(block.terminal.handler);
}
}
return errors.asResult();
}