11
import {
12
CompilerDiagnostic,
13
CompilerError,
14
+ CompilerErrorDetail,
15
CompilerSuggestionOperation,
16
ErrorCategory,
17
} from '../CompilerError';
106
if (param.isIdentifier()) {
107
const binding = builder.resolveIdentifier(param);
108
if (binding.kind !== 'Identifier') {
108
- builder.errors.pushDiagnostic(
109
+ builder.recordError(
110
CompilerDiagnostic.create({
111
category: ErrorCategory.Invariant,
112
reason: 'Could not find binding',
170
'Assignment',
171
);
172
} else {
172
- builder.errors.pushDiagnostic(
173
+ builder.recordError(
174
CompilerDiagnostic.create({
175
category: ErrorCategory.Todo,
176
reason: `Handle ${param.node.type} parameters`,
201
lowerStatement(builder, body);
202
directives = body.get('directives').map(d => d.node.value.value);
203
} else {
203
- builder.errors.pushDiagnostic(
204
+ builder.recordError(
205
CompilerDiagnostic.create({
206
category: ErrorCategory.Syntax,
207
reason: `Unexpected function body kind`,
218
if (id != null) {
219
const idResult = validateIdentifierName(id);
220
if (idResult.isErr()) {
220
- builder.errors.merge(idResult.unwrapErr());
221
+ for (const detail of idResult.unwrapErr().details) {
222
+ builder.recordError(detail);
223
+ }
224
} else {
225
validatedId = idResult.unwrap().value;
226
}
244
245
const hirBody = builder.build();
246
244
- // Record all accumulated errors (including any from build()) on env
245
- if (builder.errors.hasAnyErrors()) {
246
- env.recordErrors(builder.errors);
247
- }
248
-
247
return {
248
id: validatedId,
249
nameHint: null,
280
* for control-flow and is generally considered an anti-pattern. we can likely
281
* just not support this pattern, unless it really becomes necessary for some reason.
282
*/
285
- builder.errors.push({
286
- reason:
287
- '(BuildHIR::lowerStatement) Support ThrowStatement inside of try/catch',
288
- category: ErrorCategory.Todo,
289
- loc: stmt.node.loc ?? null,
290
- suggestions: null,
291
- });
283
+ builder.recordError(
284
+ new CompilerErrorDetail({
285
+ reason:
286
+ '(BuildHIR::lowerStatement) Support ThrowStatement inside of try/catch',
287
+ category: ErrorCategory.Todo,
288
+ loc: stmt.node.loc ?? null,
289
+ suggestions: null,
290
+ }),
291
+ );
292
}
293
const terminal: ThrowTerminal = {
294
kind: 'throw',
470
} else if (binding.path.isFunctionDeclaration()) {
471
kind = InstructionKind.HoistedFunction;
472
} else if (!binding.path.isVariableDeclarator()) {
473
- builder.errors.push({
474
- category: ErrorCategory.Todo,
475
- reason: 'Unsupported declaration type for hoisting',
476
- description: `variable "${binding.identifier.name}" declared with ${binding.path.type}`,
477
- suggestions: null,
478
- loc: id.parentPath.node.loc ?? GeneratedSource,
479
- });
473
+ builder.recordError(
474
+ new CompilerErrorDetail({
475
+ category: ErrorCategory.Todo,
476
+ reason: 'Unsupported declaration type for hoisting',
477
+ description: `variable "${binding.identifier.name}" declared with ${binding.path.type}`,
478
+ suggestions: null,
479
+ loc: id.parentPath.node.loc ?? GeneratedSource,
480
+ }),
481
+ );
482
continue;
483
} else {
482
- builder.errors.push({
483
- category: ErrorCategory.Todo,
484
- reason: 'Handle non-const declarations for hoisting',
485
- description: `variable "${binding.identifier.name}" declared with ${binding.kind}`,
486
- suggestions: null,
487
- loc: id.parentPath.node.loc ?? GeneratedSource,
488
- });
484
+ builder.recordError(
485
+ new CompilerErrorDetail({
486
+ category: ErrorCategory.Todo,
487
+ reason: 'Handle non-const declarations for hoisting',
488
+ description: `variable "${binding.identifier.name}" declared with ${binding.kind}`,
489
+ suggestions: null,
490
+ loc: id.parentPath.node.loc ?? GeneratedSource,
491
+ }),
492
+ );
493
continue;
494
}
495
579
};
580
}
581
if (!init.isVariableDeclaration()) {
578
- builder.errors.push({
579
- reason:
580
- '(BuildHIR::lowerStatement) Handle non-variable initialization in ForStatement',
581
- category: ErrorCategory.Todo,
582
- loc: stmt.node.loc ?? null,
583
- suggestions: null,
584
- });
582
+ builder.recordError(
583
+ new CompilerErrorDetail({
584
+ reason:
585
+ '(BuildHIR::lowerStatement) Handle non-variable initialization in ForStatement',
586
+ category: ErrorCategory.Todo,
587
+ loc: stmt.node.loc ?? null,
588
+ suggestions: null,
589
+ }),
590
+ );
591
// Lower the init expression as best-effort and continue
592
if (init.isExpression()) {
593
lowerExpressionToTemporary(builder, init as NodePath<t.Expression>);
660
661
const test = stmt.get('test');
662
if (test.node == null) {
657
- builder.errors.push({
658
- reason: `(BuildHIR::lowerStatement) Handle empty test in ForStatement`,
659
- category: ErrorCategory.Todo,
660
- loc: stmt.node.loc ?? null,
661
- suggestions: null,
662
- });
663
+ builder.recordError(
664
+ new CompilerErrorDetail({
665
+ reason: `(BuildHIR::lowerStatement) Handle empty test in ForStatement`,
666
+ category: ErrorCategory.Todo,
667
+ loc: stmt.node.loc ?? null,
668
+ suggestions: null,
669
+ }),
670
+ );
671
// Treat `for(;;)` as `while(true)` to keep the builder state consistent
672
builder.terminateWithContinuation(
673
{
830
const testExpr = case_.get('test');
831
if (testExpr.node == null) {
832
if (hasDefault) {
825
- builder.errors.push({
826
- reason: `Expected at most one \`default\` branch in a switch statement, this code should have failed to parse`,
827
- category: ErrorCategory.Syntax,
828
- loc: case_.node.loc ?? null,
829
- suggestions: null,
830
- });
833
+ builder.recordError(
834
+ new CompilerErrorDetail({
835
+ reason: `Expected at most one \`default\` branch in a switch statement, this code should have failed to parse`,
836
+ category: ErrorCategory.Syntax,
837
+ loc: case_.node.loc ?? null,
838
+ suggestions: null,
839
+ }),
840
+ );
841
break;
842
}
843
hasDefault = true;
904
const stmt = stmtPath as NodePath<t.VariableDeclaration>;
905
const nodeKind: t.VariableDeclaration['kind'] = stmt.node.kind;
906
if (nodeKind === 'var') {
897
- builder.errors.push({
898
- reason: `(BuildHIR::lowerStatement) Handle ${nodeKind} kinds in VariableDeclaration`,
899
- category: ErrorCategory.Todo,
900
- loc: stmt.node.loc ?? null,
901
- suggestions: null,
902
- });
907
+ builder.recordError(
908
+ new CompilerErrorDetail({
909
+ reason: `(BuildHIR::lowerStatement) Handle ${nodeKind} kinds in VariableDeclaration`,
910
+ category: ErrorCategory.Todo,
911
+ loc: stmt.node.loc ?? null,
912
+ suggestions: null,
913
+ }),
914
+ );
915
// Treat `var` as `let` so references to the variable don't break
916
}
917
const kind =
936
} else if (id.isIdentifier()) {
937
const binding = builder.resolveIdentifier(id);
938
if (binding.kind !== 'Identifier') {
927
- builder.errors.push({
928
- reason: `(BuildHIR::lowerAssignment) Could not find binding for declaration.`,
929
- category: ErrorCategory.Invariant,
930
- loc: id.node.loc ?? null,
931
- suggestions: null,
932
- });
939
+ builder.recordError(
940
+ new CompilerErrorDetail({
941
+ reason: `(BuildHIR::lowerAssignment) Could not find binding for declaration.`,
942
+ category: ErrorCategory.Invariant,
943
+ loc: id.node.loc ?? null,
944
+ suggestions: null,
945
+ }),
946
+ );
947
} else {
948
const place: Place = {
949
effect: Effect.Unknown,
955
if (builder.isContextIdentifier(id)) {
956
if (kind === InstructionKind.Const) {
957
const declRangeStart = declaration.parentPath.node.start!;
944
- builder.errors.push({
945
- reason: `Expect \`const\` declaration not to be reassigned`,
946
- category: ErrorCategory.Syntax,
947
- loc: id.node.loc ?? null,
948
- suggestions: [
949
- {
950
- description: 'Change to a `let` declaration',
951
- op: CompilerSuggestionOperation.Replace,
952
- range: [declRangeStart, declRangeStart + 5], // "const".length
953
- text: 'let',
954
- },
955
- ],
956
- });
958
+ builder.recordError(
959
+ new CompilerErrorDetail({
960
+ reason: `Expect \`const\` declaration not to be reassigned`,
961
+ category: ErrorCategory.Syntax,
962
+ loc: id.node.loc ?? null,
963
+ suggestions: [
964
+ {
965
+ description: 'Change to a `let` declaration',
966
+ op: CompilerSuggestionOperation.Replace,
967
+ range: [declRangeStart, declRangeStart + 5], // "const".length
968
+ text: 'let',
969
+ },
970
+ ],
971
+ }),
972
+ );
973
}
974
lowerValueToTemporary(builder, {
975
kind: 'DeclareContext',
1003
}
1004
}
1005
} else {
990
- builder.errors.push({
991
- reason: `Expected variable declaration to be an identifier if no initializer was provided`,
992
- description: `Got a \`${id.type}\``,
993
- category: ErrorCategory.Syntax,
994
- loc: stmt.node.loc ?? null,
995
- suggestions: null,
996
- });
1006
+ builder.recordError(
1007
+ new CompilerErrorDetail({
1008
+ reason: `Expected variable declaration to be an identifier if no initializer was provided`,
1009
+ description: `Got a \`${id.type}\``,
1010
+ category: ErrorCategory.Syntax,
1011
+ loc: stmt.node.loc ?? null,
1012
+ suggestions: null,
1013
+ }),
1014
+ );
1015
}
1016
}
1017
return;
1112
const testBlock = builder.reserve('loop');
1113
1114
if (stmt.node.await) {
1097
- builder.errors.push({
1098
- reason: `(BuildHIR::lowerStatement) Handle for-await loops`,
1099
- category: ErrorCategory.Todo,
1100
- loc: stmt.node.loc ?? null,
1101
- suggestions: null,
1102
- });
1115
+ builder.recordError(
1116
+ new CompilerErrorDetail({
1117
+ reason: `(BuildHIR::lowerStatement) Handle for-await loops`,
1118
+ category: ErrorCategory.Todo,
1119
+ loc: stmt.node.loc ?? null,
1120
+ suggestions: null,
1121
+ }),
1122
+ );
1123
return;
1124
}
1125
1342
1343
const handlerPath = stmt.get('handler');
1344
if (!hasNode(handlerPath)) {
1325
- builder.errors.push({
1326
- reason: `(BuildHIR::lowerStatement) Handle TryStatement without a catch clause`,
1327
- category: ErrorCategory.Todo,
1328
- loc: stmt.node.loc ?? null,
1329
- suggestions: null,
1330
- });
1345
+ builder.recordError(
1346
+ new CompilerErrorDetail({
1347
+ reason: `(BuildHIR::lowerStatement) Handle TryStatement without a catch clause`,
1348
+ category: ErrorCategory.Todo,
1349
+ loc: stmt.node.loc ?? null,
1350
+ suggestions: null,
1351
+ }),
1352
+ );
1353
return;
1354
}
1355
if (hasNode(stmt.get('finalizer'))) {
1334
- builder.errors.push({
1335
- reason: `(BuildHIR::lowerStatement) Handle TryStatement with a finalizer ('finally') clause`,
1336
- category: ErrorCategory.Todo,
1337
- loc: stmt.node.loc ?? null,
1338
- suggestions: null,
1339
- });
1356
+ builder.recordError(
1357
+ new CompilerErrorDetail({
1358
+ reason: `(BuildHIR::lowerStatement) Handle TryStatement with a finalizer ('finally') clause`,
1359
+ category: ErrorCategory.Todo,
1360
+ loc: stmt.node.loc ?? null,
1361
+ suggestions: null,
1362
+ }),
1363
+ );
1364
}
1365
1366
const handlerBindingPath = handlerPath.get('param');
1447
return;
1448
}
1449
case 'WithStatement': {
1426
- builder.errors.push({
1427
- reason: `JavaScript 'with' syntax is not supported`,
1428
- description: `'with' syntax is considered deprecated and removed from JavaScript standards, consider alternatives`,
1429
- category: ErrorCategory.UnsupportedSyntax,
1430
- loc: stmtPath.node.loc ?? null,
1431
- suggestions: null,
1432
- });
1450
+ builder.recordError(
1451
+ new CompilerErrorDetail({
1452
+ reason: `JavaScript 'with' syntax is not supported`,
1453
+ description: `'with' syntax is considered deprecated and removed from JavaScript standards, consider alternatives`,
1454
+ category: ErrorCategory.UnsupportedSyntax,
1455
+ loc: stmtPath.node.loc ?? null,
1456
+ suggestions: null,
1457
+ }),
1458
+ );
1459
lowerValueToTemporary(builder, {
1460
kind: 'UnsupportedNode',
1461
loc: stmtPath.node.loc ?? GeneratedSource,
1469
* and complex enough to support that we don't anticipate supporting anytime soon. Developers
1470
* are encouraged to lift classes out of component/hook declarations.
1471
*/
1446
- builder.errors.push({
1447
- reason: 'Inline `class` declarations are not supported',
1448
- description: `Move class declarations outside of components/hooks`,
1449
- category: ErrorCategory.UnsupportedSyntax,
1450
- loc: stmtPath.node.loc ?? null,
1451
- suggestions: null,
1452
- });
1472
+ builder.recordError(
1473
+ new CompilerErrorDetail({
1474
+ reason: 'Inline `class` declarations are not supported',
1475
+ description: `Move class declarations outside of components/hooks`,
1476
+ category: ErrorCategory.UnsupportedSyntax,
1477
+ loc: stmtPath.node.loc ?? null,
1478
+ suggestions: null,
1479
+ }),
1480
+ );
1481
lowerValueToTemporary(builder, {
1482
kind: 'UnsupportedNode',
1483
loc: stmtPath.node.loc ?? GeneratedSource,
1500
case 'ImportDeclaration':
1501
case 'TSExportAssignment':
1502
case 'TSImportEqualsDeclaration': {
1475
- builder.errors.push({
1476
- reason:
1477
- 'JavaScript `import` and `export` statements may only appear at the top level of a module',
1478
- category: ErrorCategory.Syntax,
1479
- loc: stmtPath.node.loc ?? null,
1480
- suggestions: null,
1481
- });
1503
+ builder.recordError(
1504
+ new CompilerErrorDetail({
1505
+ reason:
1506
+ 'JavaScript `import` and `export` statements may only appear at the top level of a module',
1507
+ category: ErrorCategory.Syntax,
1508
+ loc: stmtPath.node.loc ?? null,
1509
+ suggestions: null,
1510
+ }),
1511
+ );
1512
lowerValueToTemporary(builder, {
1513
kind: 'UnsupportedNode',
1514
loc: stmtPath.node.loc ?? GeneratedSource,
1517
return;
1518
}
1519
case 'TSNamespaceExportDeclaration': {
1490
- builder.errors.push({
1491
- reason:
1492
- 'TypeScript `namespace` statements may only appear at the top level of a module',
1493
- category: ErrorCategory.Syntax,
1494
- loc: stmtPath.node.loc ?? null,
1495
- suggestions: null,
1496
- });
1520
+ builder.recordError(
1521
+ new CompilerErrorDetail({
1522
+ reason:
1523
+ 'TypeScript `namespace` statements may only appear at the top level of a module',
1524
+ category: ErrorCategory.Syntax,
1525
+ loc: stmtPath.node.loc ?? null,
1526
+ suggestions: null,
1527
+ }),
1528
+ );
1529
lowerValueToTemporary(builder, {
1530
kind: 'UnsupportedNode',
1531
loc: stmtPath.node.loc ?? GeneratedSource,
1606
};
1607
}
1608
1577
- builder.errors.push({
1578
- reason: `(BuildHIR::lowerExpression) Expected Identifier, got ${key.type} key in ObjectExpression`,
1579
- category: ErrorCategory.Todo,
1580
- loc: key.node.loc ?? null,
1581
- suggestions: null,
1582
- });
1609
+ builder.recordError(
1610
+ new CompilerErrorDetail({
1611
+ reason: `(BuildHIR::lowerExpression) Expected Identifier, got ${key.type} key in ObjectExpression`,
1612
+ category: ErrorCategory.Todo,
1613
+ loc: key.node.loc ?? null,
1614
+ suggestions: null,
1615
+ }),
1616
+ );
1617
return null;
1618
}
1619
1665
}
1666
const valuePath = propertyPath.get('value');
1667
if (!valuePath.isExpression()) {
1634
- builder.errors.push({
1635
- reason: `(BuildHIR::lowerExpression) Handle ${valuePath.type} values in ObjectExpression`,
1636
- category: ErrorCategory.Todo,
1637
- loc: valuePath.node.loc ?? null,
1638
- suggestions: null,
1639
- });
1668
+ builder.recordError(
1669
+ new CompilerErrorDetail({
1670
+ reason: `(BuildHIR::lowerExpression) Handle ${valuePath.type} values in ObjectExpression`,
1671
+ category: ErrorCategory.Todo,
1672
+ loc: valuePath.node.loc ?? null,
1673
+ suggestions: null,
1674
+ }),
1675
+ );
1676
continue;
1677
}
1678
const value = lowerExpressionToTemporary(builder, valuePath);
1693
});
1694
} else if (propertyPath.isObjectMethod()) {
1695
if (propertyPath.node.kind !== 'method') {
1660
- builder.errors.push({
1661
- reason: `(BuildHIR::lowerExpression) Handle ${propertyPath.node.kind} functions in ObjectExpression`,
1662
- category: ErrorCategory.Todo,
1663
- loc: propertyPath.node.loc ?? null,
1664
- suggestions: null,
1665
- });
1696
+ builder.recordError(
1697
+ new CompilerErrorDetail({
1698
+ reason: `(BuildHIR::lowerExpression) Handle ${propertyPath.node.kind} functions in ObjectExpression`,
1699
+ category: ErrorCategory.Todo,
1700
+ loc: propertyPath.node.loc ?? null,
1701
+ suggestions: null,
1702
+ }),
1703
+ );
1704
continue;
1705
}
1706
const method = lowerObjectMethod(builder, propertyPath);
1716
key: loweredKey,
1717
});
1718
} else {
1681
- builder.errors.push({
1682
- reason: `(BuildHIR::lowerExpression) Handle ${propertyPath.type} properties in ObjectExpression`,
1683
- category: ErrorCategory.Todo,
1684
- loc: propertyPath.node.loc ?? null,
1685
- suggestions: null,
1686
- });
1719
+ builder.recordError(
1720
+ new CompilerErrorDetail({
1721
+ reason: `(BuildHIR::lowerExpression) Handle ${propertyPath.type} properties in ObjectExpression`,
1722
+ category: ErrorCategory.Todo,
1723
+ loc: propertyPath.node.loc ?? null,
1724
+ suggestions: null,
1725
+ }),
1726
+ );
1727
continue;
1728
}
1729
}
1751
);
1752
elements.push({kind: 'Spread', place});
1753
} else {
1714
- builder.errors.push({
1715
- reason: `(BuildHIR::lowerExpression) Handle ${element.type} elements in ArrayExpression`,
1716
- category: ErrorCategory.Todo,
1717
- loc: element.node.loc ?? null,
1718
- suggestions: null,
1719
- });
1754
+ builder.recordError(
1755
+ new CompilerErrorDetail({
1756
+ reason: `(BuildHIR::lowerExpression) Handle ${element.type} elements in ArrayExpression`,
1757
+ category: ErrorCategory.Todo,
1758
+ loc: element.node.loc ?? null,
1759
+ suggestions: null,
1760
+ }),
1761
+ );
1762
continue;
1763
}
1764
}
1772
const expr = exprPath as NodePath<t.NewExpression>;
1773
const calleePath = expr.get('callee');
1774
if (!calleePath.isExpression()) {
1733
- builder.errors.push({
1734
- reason: `Expected an expression as the \`new\` expression receiver (v8 intrinsics are not supported)`,
1735
- description: `Got a \`${calleePath.node.type}\``,
1736
- category: ErrorCategory.Syntax,
1737
- loc: calleePath.node.loc ?? null,
1738
- suggestions: null,
1739
- });
1775
+ builder.recordError(
1776
+ new CompilerErrorDetail({
1777
+ reason: `Expected an expression as the \`new\` expression receiver (v8 intrinsics are not supported)`,
1778
+ description: `Got a \`${calleePath.node.type}\``,
1779
+ category: ErrorCategory.Syntax,
1780
+ loc: calleePath.node.loc ?? null,
1781
+ suggestions: null,
1782
+ }),
1783
+ );
1784
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
1785
}
1786
const callee = lowerExpressionToTemporary(builder, calleePath);
1801
const expr = exprPath as NodePath<t.CallExpression>;
1802
const calleePath = expr.get('callee');
1803
if (!calleePath.isExpression()) {
1760
- builder.errors.push({
1761
- reason: `Expected Expression, got ${calleePath.type} in CallExpression (v8 intrinsics not supported). This error is likely caused by a bug in React Compiler. Please file an issue`,
1762
- category: ErrorCategory.Todo,
1763
- loc: calleePath.node.loc ?? null,
1764
- suggestions: null,
1765
- });
1804
+ builder.recordError(
1805
+ new CompilerErrorDetail({
1806
+ reason: `Expected Expression, got ${calleePath.type} in CallExpression (v8 intrinsics not supported). This error is likely caused by a bug in React Compiler. Please file an issue`,
1807
+ category: ErrorCategory.Todo,
1808
+ loc: calleePath.node.loc ?? null,
1809
+ suggestions: null,
1810
+ }),
1811
+ );
1812
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
1813
}
1814
if (calleePath.isMemberExpression()) {
1837
const expr = exprPath as NodePath<t.BinaryExpression>;
1838
const leftPath = expr.get('left');
1839
if (!leftPath.isExpression()) {
1794
- builder.errors.push({
1795
- reason: `(BuildHIR::lowerExpression) Expected Expression, got ${leftPath.type} lval in BinaryExpression`,
1796
- category: ErrorCategory.Todo,
1797
- loc: leftPath.node.loc ?? null,
1798
- suggestions: null,
1799
- });
1840
+ builder.recordError(
1841
+ new CompilerErrorDetail({
1842
+ reason: `(BuildHIR::lowerExpression) Expected Expression, got ${leftPath.type} lval in BinaryExpression`,
1843
+ category: ErrorCategory.Todo,
1844
+ loc: leftPath.node.loc ?? null,
1845
+ suggestions: null,
1846
+ }),
1847
+ );
1848
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
1849
}
1850
const left = lowerExpressionToTemporary(builder, leftPath);
1851
const right = lowerExpressionToTemporary(builder, expr.get('right'));
1852
const operator = expr.node.operator;
1853
if (operator === '|>') {
1806
- builder.errors.push({
1807
- reason: `(BuildHIR::lowerExpression) Pipe operator not supported`,
1808
- category: ErrorCategory.Todo,
1809
- loc: leftPath.node.loc ?? null,
1810
- suggestions: null,
1811
- });
1854
+ builder.recordError(
1855
+ new CompilerErrorDetail({
1856
+ reason: `(BuildHIR::lowerExpression) Pipe operator not supported`,
1857
+ category: ErrorCategory.Todo,
1858
+ loc: leftPath.node.loc ?? null,
1859
+ suggestions: null,
1860
+ }),
1861
+ );
1862
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
1863
}
1864
return {
1882
last = lowerExpressionToTemporary(builder, item);
1883
}
1884
if (last === null) {
1835
- builder.errors.push({
1836
- reason: `Expected sequence expression to have at least one expression`,
1837
- category: ErrorCategory.Syntax,
1838
- loc: expr.node.loc ?? null,
1839
- suggestions: null,
1840
- });
1885
+ builder.recordError(
1886
+ new CompilerErrorDetail({
1887
+ reason: `Expected sequence expression to have at least one expression`,
1888
+ category: ErrorCategory.Syntax,
1889
+ loc: expr.node.loc ?? null,
1890
+ suggestions: null,
1891
+ }),
1892
+ );
1893
} else {
1894
lowerValueToTemporary(builder, {
1895
kind: 'StoreLocal',
2095
* OptionalMemberExpressions as the left side of an AssignmentExpression are Stage 1 and
2096
* not supported by React Compiler yet.
2097
*/
2046
- builder.errors.push({
2047
- reason: `(BuildHIR::lowerExpression) Unsupported syntax on the left side of an AssignmentExpression`,
2048
- description: `Expected an LVal, got: ${left.type}`,
2049
- category: ErrorCategory.Todo,
2050
- loc: left.node.loc ?? null,
2051
- suggestions: null,
2052
- });
2098
+ builder.recordError(
2099
+ new CompilerErrorDetail({
2100
+ reason: `(BuildHIR::lowerExpression) Unsupported syntax on the left side of an AssignmentExpression`,
2101
+ description: `Expected an LVal, got: ${left.type}`,
2102
+ category: ErrorCategory.Todo,
2103
+ loc: left.node.loc ?? null,
2104
+ suggestions: null,
2105
+ }),
2106
+ );
2107
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2108
}
2109
}
2126
};
2127
const binaryOperator = operators[operator];
2128
if (binaryOperator == null) {
2075
- builder.errors.push({
2076
- reason: `(BuildHIR::lowerExpression) Handle ${operator} operators in AssignmentExpression`,
2077
- category: ErrorCategory.Todo,
2078
- loc: expr.node.loc ?? null,
2079
- suggestions: null,
2080
- });
2129
+ builder.recordError(
2130
+ new CompilerErrorDetail({
2131
+ reason: `(BuildHIR::lowerExpression) Handle ${operator} operators in AssignmentExpression`,
2132
+ category: ErrorCategory.Todo,
2133
+ loc: expr.node.loc ?? null,
2134
+ suggestions: null,
2135
+ }),
2136
+ );
2137
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2138
}
2139
const left = expr.get('left');
2227
}
2228
}
2229
default: {
2174
- builder.errors.push({
2175
- reason: `(BuildHIR::lowerExpression) Expected Identifier or MemberExpression, got ${expr.type} lval in AssignmentExpression`,
2176
- category: ErrorCategory.Todo,
2177
- loc: expr.node.loc ?? null,
2178
- suggestions: null,
2179
- });
2230
+ builder.recordError(
2231
+ new CompilerErrorDetail({
2232
+ reason: `(BuildHIR::lowerExpression) Expected Identifier or MemberExpression, got ${expr.type} lval in AssignmentExpression`,
2233
+ category: ErrorCategory.Todo,
2234
+ loc: expr.node.loc ?? null,
2235
+ suggestions: null,
2236
+ }),
2237
+ );
2238
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2239
}
2240
}
2268
continue;
2269
}
2270
if (!attribute.isJSXAttribute()) {
2213
- builder.errors.push({
2214
- reason: `(BuildHIR::lowerExpression) Handle ${attribute.type} attributes in JSXElement`,
2215
- category: ErrorCategory.Todo,
2216
- loc: attribute.node.loc ?? null,
2217
- suggestions: null,
2218
- });
2271
+ builder.recordError(
2272
+ new CompilerErrorDetail({
2273
+ reason: `(BuildHIR::lowerExpression) Handle ${attribute.type} attributes in JSXElement`,
2274
+ category: ErrorCategory.Todo,
2275
+ loc: attribute.node.loc ?? null,
2276
+ suggestions: null,
2277
+ }),
2278
+ );
2279
continue;
2280
}
2281
const namePath = attribute.get('name');
2283
if (namePath.isJSXIdentifier()) {
2284
propName = namePath.node.name;
2285
if (propName.indexOf(':') !== -1) {
2226
- builder.errors.push({
2227
- reason: `(BuildHIR::lowerExpression) Unexpected colon in attribute name \`${propName}\``,
2228
- category: ErrorCategory.Todo,
2229
- loc: namePath.node.loc ?? null,
2230
- suggestions: null,
2231
- });
2286
+ builder.recordError(
2287
+ new CompilerErrorDetail({
2288
+ reason: `(BuildHIR::lowerExpression) Unexpected colon in attribute name \`${propName}\``,
2289
+ category: ErrorCategory.Todo,
2290
+ loc: namePath.node.loc ?? null,
2291
+ suggestions: null,
2292
+ }),
2293
+ );
2294
}
2295
} else {
2296
CompilerError.invariant(namePath.isJSXNamespacedName(), {
2313
});
2314
} else {
2315
if (!valueExpr.isJSXExpressionContainer()) {
2254
- builder.errors.push({
2255
- reason: `(BuildHIR::lowerExpression) Handle ${valueExpr.type} attribute values in JSXElement`,
2256
- category: ErrorCategory.Todo,
2257
- loc: valueExpr.node?.loc ?? null,
2258
- suggestions: null,
2259
- });
2316
+ builder.recordError(
2317
+ new CompilerErrorDetail({
2318
+ reason: `(BuildHIR::lowerExpression) Handle ${valueExpr.type} attribute values in JSXElement`,
2319
+ category: ErrorCategory.Todo,
2320
+ loc: valueExpr.node?.loc ?? null,
2321
+ suggestions: null,
2322
+ }),
2323
+ );
2324
continue;
2325
}
2326
const expression = valueExpr.get('expression');
2327
if (!expression.isExpression()) {
2264
- builder.errors.push({
2265
- reason: `(BuildHIR::lowerExpression) Handle ${expression.type} expressions in JSXExpressionContainer within JSXElement`,
2266
- category: ErrorCategory.Todo,
2267
- loc: valueExpr.node.loc ?? null,
2268
- suggestions: null,
2269
- });
2328
+ builder.recordError(
2329
+ new CompilerErrorDetail({
2330
+ reason: `(BuildHIR::lowerExpression) Handle ${expression.type} expressions in JSXExpressionContainer within JSXElement`,
2331
+ category: ErrorCategory.Todo,
2332
+ loc: valueExpr.node.loc ?? null,
2333
+ suggestions: null,
2334
+ }),
2335
+ );
2336
continue;
2337
}
2338
value = lowerExpressionToTemporary(builder, expression);
2383
});
2384
for (const [name, locations] of Object.entries(fbtLocations)) {
2385
if (locations.length > 1) {
2320
- builder.errors.pushDiagnostic(
2386
+ builder.recordError(
2387
new CompilerDiagnostic({
2388
category: ErrorCategory.Todo,
2389
reason: 'Support duplicate fbt tags',
2444
case 'TaggedTemplateExpression': {
2445
const expr = exprPath as NodePath<t.TaggedTemplateExpression>;
2446
if (expr.get('quasi').get('expressions').length !== 0) {
2381
- builder.errors.push({
2382
- reason:
2383
- '(BuildHIR::lowerExpression) Handle tagged template with interpolations',
2384
- category: ErrorCategory.Todo,
2385
- loc: exprPath.node.loc ?? null,
2386
- suggestions: null,
2387
- });
2447
+ builder.recordError(
2448
+ new CompilerErrorDetail({
2449
+ reason:
2450
+ '(BuildHIR::lowerExpression) Handle tagged template with interpolations',
2451
+ category: ErrorCategory.Todo,
2452
+ loc: exprPath.node.loc ?? null,
2453
+ suggestions: null,
2454
+ }),
2455
+ );
2456
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2457
}
2458
CompilerError.invariant(expr.get('quasi').get('quasis').length == 1, {
2462
});
2463
const value = expr.get('quasi').get('quasis').at(0)!.node.value;
2464
if (value.raw !== value.cooked) {
2397
- builder.errors.push({
2398
- reason:
2399
- '(BuildHIR::lowerExpression) Handle tagged template where cooked value is different from raw value',
2400
- category: ErrorCategory.Todo,
2401
- loc: exprPath.node.loc ?? null,
2402
- suggestions: null,
2403
- });
2465
+ builder.recordError(
2466
+ new CompilerErrorDetail({
2467
+ reason:
2468
+ '(BuildHIR::lowerExpression) Handle tagged template where cooked value is different from raw value',
2469
+ category: ErrorCategory.Todo,
2470
+ loc: exprPath.node.loc ?? null,
2471
+ suggestions: null,
2472
+ }),
2473
+ );
2474
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2475
}
2476
2487
const quasis = expr.get('quasis');
2488
2489
if (subexprs.length !== quasis.length - 1) {
2420
- builder.errors.push({
2421
- reason: `Unexpected quasi and subexpression lengths in template literal`,
2422
- category: ErrorCategory.Syntax,
2423
- loc: exprPath.node.loc ?? null,
2424
- suggestions: null,
2425
- });
2490
+ builder.recordError(
2491
+ new CompilerErrorDetail({
2492
+ reason: `Unexpected quasi and subexpression lengths in template literal`,
2493
+ category: ErrorCategory.Syntax,
2494
+ loc: exprPath.node.loc ?? null,
2495
+ suggestions: null,
2496
+ }),
2497
+ );
2498
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2499
}
2500
2501
if (subexprs.some(e => !e.isExpression())) {
2430
- builder.errors.push({
2431
- reason: `(BuildHIR::lowerAssignment) Handle TSType in TemplateLiteral.`,
2432
- category: ErrorCategory.Todo,
2433
- loc: exprPath.node.loc ?? null,
2434
- suggestions: null,
2435
- });
2502
+ builder.recordError(
2503
+ new CompilerErrorDetail({
2504
+ reason: `(BuildHIR::lowerAssignment) Handle TSType in TemplateLiteral.`,
2505
+ category: ErrorCategory.Todo,
2506
+ loc: exprPath.node.loc ?? null,
2507
+ suggestions: null,
2508
+ }),
2509
+ );
2510
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2511
}
2512
2543
};
2544
}
2545
} else {
2472
- builder.errors.push({
2473
- reason: `Only object properties can be deleted`,
2546
+ builder.recordError(
2547
+ new CompilerErrorDetail({
2548
+ reason: `Only object properties can be deleted`,
2549
+ category: ErrorCategory.Syntax,
2550
+ loc: expr.node.loc ?? null,
2551
+ suggestions: [
2552
+ {
2553
+ description: 'Remove this line',
2554
+ range: [expr.node.start!, expr.node.end!],
2555
+ op: CompilerSuggestionOperation.Remove,
2556
+ },
2557
+ ],
2558
+ }),
2559
+ );
2560
+ return {kind: 'UnsupportedNode', node: expr.node, loc: exprLoc};
2561
+ }
2562
+ } else if (expr.node.operator === 'throw') {
2563
+ builder.recordError(
2564
+ new CompilerErrorDetail({
2565
+ reason: `Throw expressions are not supported`,
2566
category: ErrorCategory.Syntax,
2567
loc: expr.node.loc ?? null,
2568
suggestions: [
2572
op: CompilerSuggestionOperation.Remove,
2573
},
2574
],
2483
- });
2484
- return {kind: 'UnsupportedNode', node: expr.node, loc: exprLoc};
2485
- }
2486
- } else if (expr.node.operator === 'throw') {
2487
- builder.errors.push({
2488
- reason: `Throw expressions are not supported`,
2489
- category: ErrorCategory.Syntax,
2490
- loc: expr.node.loc ?? null,
2491
- suggestions: [
2492
- {
2493
- description: 'Remove this line',
2494
- range: [expr.node.start!, expr.node.end!],
2495
- op: CompilerSuggestionOperation.Remove,
2496
- },
2497
- ],
2498
- });
2575
+ }),
2576
+ );
2577
return {kind: 'UnsupportedNode', node: expr.node, loc: exprLoc};
2578
} else {
2579
return {
2683
};
2684
}
2685
if (!argument.isIdentifier()) {
2608
- builder.errors.push({
2609
- reason: `(BuildHIR::lowerExpression) Handle UpdateExpression with ${argument.type} argument`,
2610
- category: ErrorCategory.Todo,
2611
- loc: exprPath.node.loc ?? null,
2612
- suggestions: null,
2613
- });
2686
+ builder.recordError(
2687
+ new CompilerErrorDetail({
2688
+ reason: `(BuildHIR::lowerExpression) Handle UpdateExpression with ${argument.type} argument`,
2689
+ category: ErrorCategory.Todo,
2690
+ loc: exprPath.node.loc ?? null,
2691
+ suggestions: null,
2692
+ }),
2693
+ );
2694
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2695
} else if (builder.isContextIdentifier(argument)) {
2616
- builder.errors.push({
2617
- reason: `(BuildHIR::lowerExpression) Handle UpdateExpression to variables captured within lambdas.`,
2618
- category: ErrorCategory.Todo,
2619
- loc: exprPath.node.loc ?? null,
2620
- suggestions: null,
2621
- });
2696
+ builder.recordError(
2697
+ new CompilerErrorDetail({
2698
+ reason: `(BuildHIR::lowerExpression) Handle UpdateExpression to variables captured within lambdas.`,
2699
+ category: ErrorCategory.Todo,
2700
+ loc: exprPath.node.loc ?? null,
2701
+ suggestions: null,
2702
+ }),
2703
+ );
2704
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2705
}
2706
const lvalue = lowerIdentifierForAssignment(
2714
* lowerIdentifierForAssignment should have already reported an error if it returned null,
2715
* we check here just in case
2716
*/
2635
- if (!builder.errors.hasAnyErrors()) {
2636
- builder.errors.push({
2637
- reason: `(BuildHIR::lowerExpression) Found an invalid UpdateExpression without a previously reported error`,
2638
- category: ErrorCategory.Invariant,
2639
- loc: exprLoc,
2640
- suggestions: null,
2641
- });
2717
+ if (!builder.environment.hasErrors()) {
2718
+ builder.recordError(
2719
+ new CompilerErrorDetail({
2720
+ reason: `(BuildHIR::lowerExpression) Found an invalid UpdateExpression without a previously reported error`,
2721
+ category: ErrorCategory.Invariant,
2722
+ loc: exprLoc,
2723
+ suggestions: null,
2724
+ }),
2725
+ );
2726
}
2727
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2728
} else if (lvalue.kind === 'Global') {
2645
- builder.errors.push({
2646
- reason: `(BuildHIR::lowerExpression) Support UpdateExpression where argument is a global`,
2647
- category: ErrorCategory.Todo,
2648
- loc: exprLoc,
2649
- suggestions: null,
2650
- });
2729
+ builder.recordError(
2730
+ new CompilerErrorDetail({
2731
+ reason: `(BuildHIR::lowerExpression) Support UpdateExpression where argument is a global`,
2732
+ category: ErrorCategory.Todo,
2733
+ loc: exprLoc,
2734
+ suggestions: null,
2735
+ }),
2736
+ );
2737
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2738
}
2739
const value = lowerIdentifier(builder, argument);
2783
};
2784
}
2785
2700
- builder.errors.push({
2701
- reason: `(BuildHIR::lowerExpression) Handle MetaProperty expressions other than import.meta`,
2702
- category: ErrorCategory.Todo,
2703
- loc: exprPath.node.loc ?? null,
2704
- suggestions: null,
2705
- });
2786
+ builder.recordError(
2787
+ new CompilerErrorDetail({
2788
+ reason: `(BuildHIR::lowerExpression) Handle MetaProperty expressions other than import.meta`,
2789
+ category: ErrorCategory.Todo,
2790
+ loc: exprPath.node.loc ?? null,
2791
+ suggestions: null,
2792
+ }),
2793
+ );
2794
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2795
}
2796
default: {
2709
- builder.errors.push({
2710
- reason: `(BuildHIR::lowerExpression) Handle ${exprPath.type} expressions`,
2711
- category: ErrorCategory.Todo,
2712
- loc: exprPath.node.loc ?? null,
2713
- suggestions: null,
2714
- });
2797
+ builder.recordError(
2798
+ new CompilerErrorDetail({
2799
+ reason: `(BuildHIR::lowerExpression) Handle ${exprPath.type} expressions`,
2800
+ category: ErrorCategory.Todo,
2801
+ loc: exprPath.node.loc ?? null,
2802
+ suggestions: null,
2803
+ }),
2804
+ );
2805
return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc};
2806
}
2807
}
3091
expr: NodePath<t.Expression>,
3092
): Place {
3093
if (!isReorderableExpression(builder, expr, true)) {
3004
- builder.errors.push({
3005
- reason: `(BuildHIR::node.lowerReorderableExpression) Expression type \`${expr.type}\` cannot be safely reordered`,
3006
- category: ErrorCategory.Todo,
3007
- loc: expr.node.loc ?? null,
3008
- suggestions: null,
3009
- });
3094
+ builder.recordError(
3095
+ new CompilerErrorDetail({
3096
+ reason: `(BuildHIR::node.lowerReorderableExpression) Expression type \`${expr.type}\` cannot be safely reordered`,
3097
+ category: ErrorCategory.Todo,
3098
+ loc: expr.node.loc ?? null,
3099
+ suggestions: null,
3100
+ }),
3101
+ );
3102
}
3103
return lowerExpressionToTemporary(builder, expr);
3104
}
3295
} else if (argPath.isExpression()) {
3296
args.push(lowerExpressionToTemporary(builder, argPath));
3297
} else {
3206
- builder.errors.push({
3207
- reason: `(BuildHIR::lowerExpression) Handle ${argPath.type} arguments in CallExpression`,
3208
- category: ErrorCategory.Todo,
3209
- loc: argPath.node.loc ?? null,
3210
- suggestions: null,
3211
- });
3298
+ builder.recordError(
3299
+ new CompilerErrorDetail({
3300
+ reason: `(BuildHIR::lowerExpression) Handle ${argPath.type} arguments in CallExpression`,
3301
+ category: ErrorCategory.Todo,
3302
+ loc: argPath.node.loc ?? null,
3303
+ suggestions: null,
3304
+ }),
3305
+ );
3306
}
3307
}
3308
return args;
3332
} else if (propertyNode.isNumericLiteral()) {
3333
property = makePropertyLiteral(propertyNode.node.value);
3334
} else {
3241
- builder.errors.push({
3242
- reason: `(BuildHIR::lowerMemberExpression) Handle ${propertyNode.type} property`,
3243
- category: ErrorCategory.Todo,
3244
- loc: propertyNode.node.loc ?? null,
3245
- suggestions: null,
3246
- });
3335
+ builder.recordError(
3336
+ new CompilerErrorDetail({
3337
+ reason: `(BuildHIR::lowerMemberExpression) Handle ${propertyNode.type} property`,
3338
+ category: ErrorCategory.Todo,
3339
+ loc: propertyNode.node.loc ?? null,
3340
+ suggestions: null,
3341
+ }),
3342
+ );
3343
return {
3344
object,
3345
property: propertyNode.toString(),
3355
return {object, property, value};
3356
} else {
3357
if (!propertyNode.isExpression()) {
3262
- builder.errors.push({
3263
- reason: `(BuildHIR::lowerMemberExpression) Expected Expression, got ${propertyNode.type} property`,
3264
- category: ErrorCategory.Todo,
3265
- loc: propertyNode.node.loc ?? null,
3266
- suggestions: null,
3267
- });
3358
+ builder.recordError(
3359
+ new CompilerErrorDetail({
3360
+ reason: `(BuildHIR::lowerMemberExpression) Expected Expression, got ${propertyNode.type} property`,
3361
+ category: ErrorCategory.Todo,
3362
+ loc: propertyNode.node.loc ?? null,
3363
+ suggestions: null,
3364
+ }),
3365
+ );
3366
return {
3367
object,
3368
property: propertyNode.toString(),
3415
const name = exprPath.node.name.name;
3416
const tag = `${namespace}:${name}`;
3417
if (namespace.indexOf(':') !== -1 || name.indexOf(':') !== -1) {
3320
- builder.errors.push({
3321
- reason: `Expected JSXNamespacedName to have no colons in the namespace or name`,
3322
- description: `Got \`${namespace}\` : \`${name}\``,
3323
- category: ErrorCategory.Syntax,
3324
- loc: exprPath.node.loc ?? null,
3325
- suggestions: null,
3326
- });
3418
+ builder.recordError(
3419
+ new CompilerErrorDetail({
3420
+ reason: `Expected JSXNamespacedName to have no colons in the namespace or name`,
3421
+ description: `Got \`${namespace}\` : \`${name}\``,
3422
+ category: ErrorCategory.Syntax,
3423
+ loc: exprPath.node.loc ?? null,
3424
+ suggestions: null,
3425
+ }),
3426
+ );
3427
}
3428
const place = lowerValueToTemporary(builder, {
3429
kind: 'Primitive',
3432
});
3433
return place;
3434
} else {
3335
- builder.errors.push({
3336
- reason: `(BuildHIR::lowerJsxElementName) Handle ${exprPath.type} tags`,
3337
- category: ErrorCategory.Todo,
3338
- loc: exprPath.node.loc ?? null,
3339
- suggestions: null,
3340
- });
3435
+ builder.recordError(
3436
+ new CompilerErrorDetail({
3437
+ reason: `(BuildHIR::lowerJsxElementName) Handle ${exprPath.type} tags`,
3438
+ category: ErrorCategory.Todo,
3439
+ loc: exprPath.node.loc ?? null,
3440
+ suggestions: null,
3441
+ }),
3442
+ );
3443
return lowerValueToTemporary(builder, {
3444
kind: 'UnsupportedNode',
3445
node: exprNode,
3528
});
3529
return place;
3530
} else {
3429
- builder.errors.push({
3430
- reason: `(BuildHIR::lowerJsxElement) Unhandled JsxElement, got: ${exprPath.type}`,
3431
- category: ErrorCategory.Todo,
3432
- loc: exprPath.node.loc ?? null,
3433
- suggestions: null,
3434
- });
3531
+ builder.recordError(
3532
+ new CompilerErrorDetail({
3533
+ reason: `(BuildHIR::lowerJsxElement) Unhandled JsxElement, got: ${exprPath.type}`,
3534
+ category: ErrorCategory.Todo,
3535
+ loc: exprPath.node.loc ?? null,
3536
+ suggestions: null,
3537
+ }),
3538
+ );
3539
const place = lowerValueToTemporary(builder, {
3540
kind: 'UnsupportedNode',
3541
node: exprNode,
3702
}
3703
default: {
3704
if (binding.kind === 'Global' && binding.name === 'eval') {
3601
- builder.errors.push({
3602
- reason: `The 'eval' function is not supported`,
3603
- description:
3604
- 'Eval is an anti-pattern in JavaScript, and the code executed cannot be evaluated by React Compiler',
3605
- category: ErrorCategory.UnsupportedSyntax,
3606
- loc: exprPath.node.loc ?? null,
3607
- suggestions: null,
3608
- });
3705
+ builder.recordError(
3706
+ new CompilerErrorDetail({
3707
+ reason: `The 'eval' function is not supported`,
3708
+ description:
3709
+ 'Eval is an anti-pattern in JavaScript, and the code executed cannot be evaluated by React Compiler',
3710
+ category: ErrorCategory.UnsupportedSyntax,
3711
+ loc: exprPath.node.loc ?? null,
3712
+ suggestions: null,
3713
+ }),
3714
+ );
3715
}
3716
return lowerValueToTemporary(builder, {
3717
kind: 'LoadGlobal',
3762
return {kind: 'Global', name: path.node.name};
3763
} else {
3764
// Else its an internal error bc we couldn't find the binding
3659
- builder.errors.push({
3660
- reason: `(BuildHIR::lowerAssignment) Could not find binding for declaration.`,
3661
- category: ErrorCategory.Invariant,
3662
- loc: path.node.loc ?? null,
3663
- suggestions: null,
3664
- });
3765
+ builder.recordError(
3766
+ new CompilerErrorDetail({
3767
+ reason: `(BuildHIR::lowerAssignment) Could not find binding for declaration.`,
3768
+ category: ErrorCategory.Invariant,
3769
+ loc: path.node.loc ?? null,
3770
+ suggestions: null,
3771
+ }),
3772
+ );
3773
return null;
3774
}
3775
} else if (
3776
binding.bindingKind === 'const' &&
3777
kind === InstructionKind.Reassign
3778
) {
3671
- builder.errors.push({
3672
- reason: `Cannot reassign a \`const\` variable`,
3673
- category: ErrorCategory.Syntax,
3674
- loc: path.node.loc ?? null,
3675
- description:
3676
- binding.identifier.name != null
3677
- ? `\`${binding.identifier.name.value}\` is declared as const`
3678
- : null,
3679
- });
3779
+ builder.recordError(
3780
+ new CompilerErrorDetail({
3781
+ reason: `Cannot reassign a \`const\` variable`,
3782
+ category: ErrorCategory.Syntax,
3783
+ loc: path.node.loc ?? null,
3784
+ description:
3785
+ binding.identifier.name != null
3786
+ ? `\`${binding.identifier.name.value}\` is declared as const`
3787
+ : null,
3788
+ }),
3789
+ );
3790
return null;
3791
}
3792
3835
let temporary;
3836
if (builder.isContextIdentifier(lvalue)) {
3837
if (kind === InstructionKind.Const && !isHoistedIdentifier) {
3728
- builder.errors.push({
3729
- reason: `Expected \`const\` declaration not to be reassigned`,
3730
- category: ErrorCategory.Syntax,
3731
- loc: lvalue.node.loc ?? null,
3732
- suggestions: null,
3733
- });
3838
+ builder.recordError(
3839
+ new CompilerErrorDetail({
3840
+ reason: `Expected \`const\` declaration not to be reassigned`,
3841
+ category: ErrorCategory.Syntax,
3842
+ loc: lvalue.node.loc ?? null,
3843
+ suggestions: null,
3844
+ }),
3845
+ );
3846
}
3847
3848
if (
3851
kind !== InstructionKind.Let &&
3852
kind !== InstructionKind.Function
3853
) {
3742
- builder.errors.push({
3743
- reason: `Unexpected context variable kind`,
3744
- category: ErrorCategory.Syntax,
3745
- loc: lvalue.node.loc ?? null,
3746
- suggestions: null,
3747
- });
3854
+ builder.recordError(
3855
+ new CompilerErrorDetail({
3856
+ reason: `Unexpected context variable kind`,
3857
+ category: ErrorCategory.Syntax,
3858
+ loc: lvalue.node.loc ?? null,
3859
+ suggestions: null,
3860
+ }),
3861
+ );
3862
temporary = lowerValueToTemporary(builder, {
3863
kind: 'UnsupportedNode',
3864
node: lvalueNode,
3922
loc,
3923
});
3924
} else {
3811
- builder.errors.push({
3812
- reason: `(BuildHIR::lowerAssignment) Handle ${property.type} properties in MemberExpression`,
3813
- category: ErrorCategory.Todo,
3814
- loc: property.node.loc ?? null,
3815
- suggestions: null,
3816
- });
3925
+ builder.recordError(
3926
+ new CompilerErrorDetail({
3927
+ reason: `(BuildHIR::lowerAssignment) Handle ${property.type} properties in MemberExpression`,
3928
+ category: ErrorCategory.Todo,
3929
+ loc: property.node.loc ?? null,
3930
+ suggestions: null,
3931
+ }),
3932
+ );
3933
return {kind: 'UnsupportedNode', node: lvalueNode, loc};
3934
}
3935
return {kind: 'LoadLocal', place: temporary, loc: temporary.loc};
3936
} else {
3937
if (!property.isExpression()) {
3822
- builder.errors.push({
3823
- reason:
3824
- '(BuildHIR::lowerAssignment) Expected private name to appear as a non-computed property',
3825
- category: ErrorCategory.Todo,
3826
- loc: property.node.loc ?? null,
3827
- suggestions: null,
3828
- });
3938
+ builder.recordError(
3939
+ new CompilerErrorDetail({
3940
+ reason:
3941
+ '(BuildHIR::lowerAssignment) Expected private name to appear as a non-computed property',
3942
+ category: ErrorCategory.Todo,
3943
+ loc: property.node.loc ?? null,
3944
+ suggestions: null,
3945
+ }),
3946
+ );
3947
return {kind: 'UnsupportedNode', node: lvalueNode, loc};
3948
}
3949
const propertyPlace = lowerExpressionToTemporary(builder, property);
4004
if (identifier === null) {
4005
continue;
4006
} else if (identifier.kind === 'Global') {
3889
- builder.errors.push({
3890
- category: ErrorCategory.Todo,
3891
- reason:
3892
- 'Expected reassignment of globals to enable forceTemporaries',
3893
- loc: element.node.loc ?? GeneratedSource,
3894
- });
4007
+ builder.recordError(
4008
+ new CompilerErrorDetail({
4009
+ category: ErrorCategory.Todo,
4010
+ reason:
4011
+ 'Expected reassignment of globals to enable forceTemporaries',
4012
+ loc: element.node.loc ?? GeneratedSource,
4013
+ }),
4014
+ );
4015
continue;
4016
}
4017
items.push({
4045
if (identifier === null) {
4046
continue;
4047
} else if (identifier.kind === 'Global') {
3928
- builder.errors.push({
3929
- category: ErrorCategory.Todo,
3930
- reason:
3931
- 'Expected reassignment of globals to enable forceTemporaries',
3932
- loc: element.node.loc ?? GeneratedSource,
3933
- });
4048
+ builder.recordError(
4049
+ new CompilerErrorDetail({
4050
+ category: ErrorCategory.Todo,
4051
+ reason:
4052
+ 'Expected reassignment of globals to enable forceTemporaries',
4053
+ loc: element.node.loc ?? GeneratedSource,
4054
+ }),
4055
+ );
4056
continue;
4057
}
4058
items.push(identifier);
4120
if (property.isRestElement()) {
4121
const argument = property.get('argument');
4122
if (!argument.isIdentifier()) {
4001
- builder.errors.push({
4002
- reason: `(BuildHIR::lowerAssignment) Handle ${argument.node.type} rest element in ObjectPattern`,
4003
- category: ErrorCategory.Todo,
4004
- loc: argument.node.loc ?? null,
4005
- suggestions: null,
4006
- });
4123
+ builder.recordError(
4124
+ new CompilerErrorDetail({
4125
+ reason: `(BuildHIR::lowerAssignment) Handle ${argument.node.type} rest element in ObjectPattern`,
4126
+ category: ErrorCategory.Todo,
4127
+ loc: argument.node.loc ?? null,
4128
+ suggestions: null,
4129
+ }),
4130
+ );
4131
continue;
4132
}
4133
if (
4154
if (identifier === null) {
4155
continue;
4156
} else if (identifier.kind === 'Global') {
4033
- builder.errors.push({
4034
- category: ErrorCategory.Todo,
4035
- reason:
4036
- 'Expected reassignment of globals to enable forceTemporaries',
4037
- loc: property.node.loc ?? GeneratedSource,
4038
- });
4157
+ builder.recordError(
4158
+ new CompilerErrorDetail({
4159
+ category: ErrorCategory.Todo,
4160
+ reason:
4161
+ 'Expected reassignment of globals to enable forceTemporaries',
4162
+ loc: property.node.loc ?? GeneratedSource,
4163
+ }),
4164
+ );
4165
continue;
4166
}
4167
properties.push({
4172
} else {
4173
// TODO: this should always be true given the if/else
4174
if (!property.isObjectProperty()) {
4049
- builder.errors.push({
4050
- reason: `(BuildHIR::lowerAssignment) Handle ${property.type} properties in ObjectPattern`,
4051
- category: ErrorCategory.Todo,
4052
- loc: property.node.loc ?? null,
4053
- suggestions: null,
4054
- });
4175
+ builder.recordError(
4176
+ new CompilerErrorDetail({
4177
+ reason: `(BuildHIR::lowerAssignment) Handle ${property.type} properties in ObjectPattern`,
4178
+ category: ErrorCategory.Todo,
4179
+ loc: property.node.loc ?? null,
4180
+ suggestions: null,
4181
+ }),
4182
+ );
4183
continue;
4184
}
4185
if (property.node.computed) {
4058
- builder.errors.push({
4059
- reason: `(BuildHIR::lowerAssignment) Handle computed properties in ObjectPattern`,
4060
- category: ErrorCategory.Todo,
4061
- loc: property.node.loc ?? null,
4062
- suggestions: null,
4063
- });
4186
+ builder.recordError(
4187
+ new CompilerErrorDetail({
4188
+ reason: `(BuildHIR::lowerAssignment) Handle computed properties in ObjectPattern`,
4189
+ category: ErrorCategory.Todo,
4190
+ loc: property.node.loc ?? null,
4191
+ suggestions: null,
4192
+ }),
4193
+ );
4194
continue;
4195
}
4196
const loweredKey = lowerObjectPropertyKey(builder, property);
4199
}
4200
const element = property.get('value');
4201
if (!element.isLVal()) {
4072
- builder.errors.push({
4073
- reason: `(BuildHIR::lowerAssignment) Expected object property value to be an LVal, got: ${element.type}`,
4074
- category: ErrorCategory.Todo,
4075
- loc: element.node.loc ?? null,
4076
- suggestions: null,
4077
- });
4202
+ builder.recordError(
4203
+ new CompilerErrorDetail({
4204
+ reason: `(BuildHIR::lowerAssignment) Expected object property value to be an LVal, got: ${element.type}`,
4205
+ category: ErrorCategory.Todo,
4206
+ loc: element.node.loc ?? null,
4207
+ suggestions: null,
4208
+ }),
4209
+ );
4210
continue;
4211
}
4212
if (
4224
if (identifier === null) {
4225
continue;
4226
} else if (identifier.kind === 'Global') {
4095
- builder.errors.push({
4096
- category: ErrorCategory.Todo,
4097
- reason:
4098
- 'Expected reassignment of globals to enable forceTemporaries',
4099
- loc: element.node.loc ?? GeneratedSource,
4100
- });
4227
+ builder.recordError(
4228
+ new CompilerErrorDetail({
4229
+ category: ErrorCategory.Todo,
4230
+ reason:
4231
+ 'Expected reassignment of globals to enable forceTemporaries',
4232
+ loc: element.node.loc ?? GeneratedSource,
4233
+ }),
4234
+ );
4235
continue;
4236
}
4237
properties.push({
4375
);
4376
}
4377
default: {
4244
- builder.errors.push({
4245
- reason: `(BuildHIR::lowerAssignment) Handle ${lvaluePath.type} assignments`,
4246
- category: ErrorCategory.Todo,
4247
- loc: lvaluePath.node.loc ?? null,
4248
- suggestions: null,
4249
- });
4378
+ builder.recordError(
4379
+ new CompilerErrorDetail({
4380
+ reason: `(BuildHIR::lowerAssignment) Handle ${lvaluePath.type} assignments`,
4381
+ category: ErrorCategory.Todo,
4382
+ loc: lvaluePath.node.loc ?? null,
4383
+ suggestions: null,
4384
+ }),
4385
+ );
4386
return {kind: 'UnsupportedNode', node: lvalueNode, loc};
4387
}
4388
}