[compiler] More precise errors for invalid import/export/namespace statements (#33748)
import, export, and TS namespace statements can only be used at the top-level of a module, which is enforced by parsers already. Here we add a backup validation of that. As of this PR, we now have only major statement type (class declarations) listed as a todo. --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/33748). * #33753 * #33752 * #33751 * #33750 * __->__ #33748
Joseph Savona committed
Jul 9, 2025 at 22:24 UTC
0bfa404bacbad78af5b39c080ba67535f2e53044
1 file changed
+36
-21
compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts
+36
-21
@@ -1397,6 +1397,41 @@ function lowerStatement(
1397
});
1398
return;
1399
}
1400
+ case 'ExportAllDeclaration':
1401
+ case 'ExportDefaultDeclaration':
1402
+ case 'ExportNamedDeclaration':
1403
+ case 'ImportDeclaration':
1404
+ case 'TSExportAssignment':
1405
+ case 'TSImportEqualsDeclaration': {
1406
+ builder.errors.push({
1407
+ reason:
1408
+ 'JavaScript `import` and `export` statements may only appear at the top level of a module',
1409
+ severity: ErrorSeverity.InvalidJS,
1410
+ loc: stmtPath.node.loc ?? null,
1411
+ suggestions: null,
1412
+ });
1413
+ lowerValueToTemporary(builder, {
1414
+ kind: 'UnsupportedNode',
1415
+ loc: stmtPath.node.loc ?? GeneratedSource,
1416
+ node: stmtPath.node,
1417
+ });
1418
+ return;
1419
+ }
1420
+ case 'TSNamespaceExportDeclaration': {
1421
+ builder.errors.push({
1422
+ reason:
1423
+ 'TypeScript `namespace` statements may only appear at the top level of a module',
1424
+ severity: ErrorSeverity.InvalidJS,
1425
+ loc: stmtPath.node.loc ?? null,
1426
+ suggestions: null,
1427
+ });
1428
+ lowerValueToTemporary(builder, {
1429
+ kind: 'UnsupportedNode',
1430
+ loc: stmtPath.node.loc ?? GeneratedSource,
1431
+ node: stmtPath.node,
1432
+ });
1433
+ return;
1434
+ }
1435
case 'DeclareClass':
1436
case 'DeclareExportAllDeclaration':
1437
case 'DeclareExportDeclaration':
@@ -1411,32 +1446,12 @@ function lowerStatement(
1446
case 'OpaqueType':
1447
case 'TSDeclareFunction':
1448
case 'TSInterfaceDeclaration':
1449
+ case 'TSModuleDeclaration':
1450
case 'TSTypeAliasDeclaration':
1451
case 'TypeAlias': {
1452
// We do not preserve type annotations/syntax through transformation
1453
return;
1454
}
1419
- case 'ExportAllDeclaration':
1420
- case 'ExportDefaultDeclaration':
1421
- case 'ExportNamedDeclaration':
1422
- case 'ImportDeclaration':
1423
- case 'TSExportAssignment':
1424
- case 'TSImportEqualsDeclaration':
1425
- case 'TSModuleDeclaration':
1426
- case 'TSNamespaceExportDeclaration': {
1427
- builder.errors.push({
1428
- reason: `(BuildHIR::lowerStatement) Handle ${stmtPath.type} statements`,
1429
- severity: ErrorSeverity.Todo,
1430
- loc: stmtPath.node.loc ?? null,
1431
- suggestions: null,
1432
- });
1433
- lowerValueToTemporary(builder, {
1434
- kind: 'UnsupportedNode',
1435
- loc: stmtPath.node.loc ?? GeneratedSource,
1436
- node: stmtPath.node,
1437
- });
1438
- return;
1439
- }
1455
default: {
1456
return assertExhaustive(
1457
stmtNode,