7
8
import {BindingKind} from '@babel/traverse';
9
import * as t from '@babel/types';
10
-import {CompilerError} from '../CompilerError';
10
+import {
11
+ CompilerDiagnostic,
12
+ CompilerError,
13
+ ErrorCategory,
14
+} from '../CompilerError';
15
import {assertExhaustive} from '../Utils/utils';
16
import {Environment, ReactFunctionType} from './Environment';
17
import type {HookKind} from './ObjectShape';
58
*/
59
export type ReactiveFunction = {
60
loc: SourceLocation;
57
- id: string | null;
61
+ id: ValidIdentifierName | null;
62
+ nameHint: string | null;
63
params: Array<Place | SpreadPattern>;
64
generator: boolean;
65
async: boolean;
281
// A function lowered to HIR form, ie where its body is lowered to an HIR control-flow graph
282
export type HIRFunction = {
283
loc: SourceLocation;
279
- id: string | null;
284
+ id: ValidIdentifierName | null;
285
+ nameHint: string | null;
286
fnType: ReactFunctionType;
287
env: Environment;
288
params: Array<Place | SpreadPattern>;
1130
1131
export type FunctionExpression = {
1132
kind: 'FunctionExpression';
1127
- name: string | null;
1133
+ name: ValidIdentifierName | null;
1134
+ nameHint: string | null;
1135
loweredFunc: LoweredFunction;
1136
type:
1137
| 'ArrowFunctionExpression'
1308
1309
export function validateIdentifierName(
1310
name: string,
1304
-): Result<ValidIdentifierName, null> {
1305
- if (isReservedWord(name) || !t.isValidIdentifier(name)) {
1306
- return Err(null);
1311
+): Result<ValidatedIdentifier, CompilerError> {
1312
+ if (isReservedWord(name)) {
1313
+ const error = new CompilerError();
1314
+ error.pushDiagnostic(
1315
+ CompilerDiagnostic.create({
1316
+ category: ErrorCategory.Syntax,
1317
+ reason: 'Expected a non-reserved identifier name',
1318
+ description: `\`${name}\` is a reserved word in JavaScript and cannot be used as an identifier name`,
1319
+ suggestions: null,
1320
+ }).withDetails({
1321
+ kind: 'error',
1322
+ loc: GeneratedSource,
1323
+ message: 'reserved word',
1324
+ }),
1325
+ );
1326
+ return Err(error);
1327
+ } else if (!t.isValidIdentifier(name)) {
1328
+ const error = new CompilerError();
1329
+ error.pushDiagnostic(
1330
+ CompilerDiagnostic.create({
1331
+ category: ErrorCategory.Syntax,
1332
+ reason: `Expected a valid identifier name`,
1333
+ description: `\`${name}\` is not a valid JavaScript identifier`,
1334
+ suggestions: null,
1335
+ }).withDetails({
1336
+ kind: 'error',
1337
+ loc: GeneratedSource,
1338
+ message: 'reserved word',
1339
+ }),
1340
+ );
1341
}
1308
- return Ok(makeIdentifierName(name).value);
1342
+ return Ok({
1343
+ kind: 'named',
1344
+ value: name as ValidIdentifierName,
1345
+ });
1346
}
1347
1348
/**
1351
* original source code.
1352
*/
1353
export function makeIdentifierName(name: string): ValidatedIdentifier {
1317
- if (isReservedWord(name)) {
1318
- CompilerError.throwInvalidJS({
1319
- reason: 'Expected a non-reserved identifier name',
1320
- loc: GeneratedSource,
1321
- description: `\`${name}\` is a reserved word in JavaScript and cannot be used as an identifier name`,
1322
- suggestions: null,
1323
- });
1324
- } else {
1325
- CompilerError.invariant(t.isValidIdentifier(name), {
1326
- reason: `Expected a valid identifier name`,
1327
- description: `\`${name}\` is not a valid JavaScript identifier`,
1328
- details: [
1329
- {
1330
- kind: 'error',
1331
- loc: GeneratedSource,
1332
- message: null,
1333
- },
1334
- ],
1335
- suggestions: null,
1336
- });
1337
- }
1338
- return {
1339
- kind: 'named',
1340
- value: name as ValidIdentifierName,
1341
- };
1354
+ return validateIdentifierName(name).unwrap();
1355
}
1356
1357
/**