1
2const MAX_UNICODE_CODEPOINT = 0x10FFFF;
3/** @type {(c: string) => boolean} */
4const isStart = c => /[\p{ID_Start}\u{2118}\u{212E}\u{309B}\u{309C}]/u.test(c); // Other_ID_Start explicitly included for back compat - see http://www.unicode.org/reports/tr31/#Introduction
5/** @type {(c: string) => boolean} */
6const isPart = c => /[\p{ID_Continue}\u{00B7}\u{0387}\u{19DA}\u{1369}\u{136A}\u{136B}\u{136C}\u{136D}\u{136E}\u{136F}\u{1370}\u{1371}]/u.test(c) || isStart(c); // Likewise for Other_ID_Continue
7const parts = [];
8let partsActive = false;
9let startsActive = false;
10const starts = [];
11
12for (let i = 0; i < MAX_UNICODE_CODEPOINT; i++) {
13    if (isStart(String.fromCodePoint(i)) !== startsActive) {
14        starts.push(i - +startsActive);
15        startsActive = !startsActive;
16    }
17    if (isPart(String.fromCodePoint(i)) !== partsActive) {
18        parts.push(i - +partsActive);
19        partsActive = !partsActive;
20    }
21}
22
23console.log(`/**
24* Generated by scripts/regenerate-unicode-identifier-parts.js on node ${process.version} with unicode ${process.versions.unicode}
25* based on http://www.unicode.org/reports/tr31/ and https://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords
26* unicodeESNextIdentifierStart corresponds to the ID_Start and Other_ID_Start property, and
27* unicodeESNextIdentifierPart corresponds to ID_Continue, Other_ID_Continue, plus ID_Start and Other_ID_Start
28*/`);
29console.log(`const unicodeESNextIdentifierStart = [${starts.join(", ")}];`);
30console.log(`const unicodeESNextIdentifierPart = [${parts.join(", ")}];`);
31