Skip to content

Commit abd92bb

Browse files
authored
Improve builtin globals creation (#303)
1 parent 3ad88b6 commit abd92bb

File tree

7 files changed

+217
-195
lines changed

7 files changed

+217
-195
lines changed

.github/workflows/es-yearly-globals.yml

Lines changed: 0 additions & 28 deletions
This file was deleted.

package.json

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
"test": "npm run build && xo && ava && tsd",
1919
"prepare": "npm run build",
2020
"update": "node scripts/update.mjs",
21-
"update:browser": "node scripts/update.mjs --environment=browser",
22-
"update:builtin": "node scripts/update.mjs --environment=builtin",
23-
"update:nodeBuiltin": "node scripts/update.mjs --environment=nodeBuiltin",
24-
"update:worker": "node scripts/update.mjs --environment=worker",
25-
"update:serviceworker": "node scripts/update.mjs --environment=serviceworker",
26-
"update:shelljs": "node scripts/update.mjs --environment=shelljs",
27-
"update:jest": "node scripts/update.mjs --environment=jest",
28-
"update:vitest": "node scripts/update.mjs --environment=vitest",
21+
"update:browser": "node scripts/update.mjs --job=browser",
22+
"update:builtin": "node scripts/update.mjs --job=builtin",
23+
"update:builtin-yearly": "node scripts/update.mjs --job=builtin-yearly",
24+
"update:nodeBuiltin": "node scripts/update.mjs --job=nodeBuiltin",
25+
"update:worker": "node scripts/update.mjs --job=worker",
26+
"update:serviceworker": "node scripts/update.mjs --job=serviceworker",
27+
"update:shelljs": "node scripts/update.mjs --job=shelljs",
28+
"update:jest": "node scripts/update.mjs --job=jest",
29+
"update:vitest": "node scripts/update.mjs --job=vitest",
2930
"build": "run-s build:data build:types",
3031
"build:data": "node scripts/generate-data.mjs",
3132
"build:types": "node scripts/generate-types.mjs"

scripts/create-yearly-es-globals.mjs

Lines changed: 0 additions & 21 deletions
This file was deleted.

scripts/es-builtin.mjs

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import fs from 'node:fs/promises';
2+
import * as cheerio from 'cheerio';
3+
import {outdent} from 'outdent';
4+
import {
5+
DATA_DIRECTORY,
6+
readGlobals,
7+
} from '../utilities.mjs';
8+
import {getDataDiff} from './utilities.mjs';
9+
10+
// https://tc39.es/ecma262/
11+
const SPECIFICATION_URLS = [
12+
'https://raw.githubusercontent.com/tc39/ecma262/HEAD/spec.html',
13+
'https://cdn.jsdelivr.net/gh/tc39/ecma262/spec.html',
14+
];
15+
const CACHE_FILE = new URL('../.cache/spec.html', import.meta.url);
16+
17+
const additionalGlobals = [
18+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects#internationalization
19+
// https://www.ecma-international.org/publications-and-standards/standards/ecma-402/
20+
'Intl',
21+
22+
// Annex B
23+
// https://tc39.es/ecma262/#sec-additional-built-in-properties
24+
'escape',
25+
'unescape',
26+
];
27+
28+
const getText = async url => {
29+
const response = await fetch(url);
30+
const text = await response.text();
31+
return text;
32+
};
33+
34+
const getSpecification = async () => {
35+
let stat;
36+
37+
try {
38+
stat = await fs.stat(CACHE_FILE);
39+
} catch {}
40+
41+
if (stat) {
42+
if (Date.now() - stat.ctimeMs < /* 10 hours */ 10 * 60 * 60 * 1000) {
43+
return fs.readFile(CACHE_FILE, 'utf8');
44+
}
45+
46+
await fs.rm(CACHE_FILE);
47+
}
48+
49+
const text = await Promise.any(SPECIFICATION_URLS.map(url => getText(url)));
50+
51+
await fs.mkdir(new URL('./', CACHE_FILE), {recursive: true});
52+
await fs.writeFile(CACHE_FILE, text);
53+
54+
return text;
55+
};
56+
57+
function * getGlobalObjects($) {
58+
for (const element of $('emu-clause#sec-global-object emu-clause:not([type]) > h1')) {
59+
let text = $(element).text().trim();
60+
61+
// Function shape `Array ( . . . )`
62+
text = text.match(/^(?<functionName>\w+?)\s*\(.*?\)$/)?.groups.functionName ?? text;
63+
64+
if (!/^\w+$/.test(text)) {
65+
continue;
66+
}
67+
68+
yield text;
69+
}
70+
}
71+
72+
async function parseSpecification() {
73+
const specification = await getSpecification();
74+
const $ = cheerio.load(specification);
75+
const meta = $('pre.metadata').text();
76+
const {year} = meta.match(/title: ECMAScript® (?<year>\d{4})/).groups;
77+
78+
return {
79+
year,
80+
data: Object.fromEntries([...getGlobalObjects($), ...additionalGlobals].map(name => [name, false])),
81+
};
82+
}
83+
84+
async function buildYearlyBuiltinGlobals(job, options) {
85+
const {year, data} = await parseSpecification();
86+
const environment = `es${year}`;
87+
const original = await readGlobals(environment, {ignoreNonExits: true});
88+
const previousYear = Number(year) - 1;
89+
const previousYearData = await readGlobals(`es${previousYear}`);
90+
const previousYearProperties = new Set(Object.keys(previousYearData));
91+
const addedEntries = Object.entries(data).filter(([name]) => !previousYearProperties.has(name));
92+
93+
const content = addedEntries.length === 0
94+
? `export {default} from './es${previousYear}.mjs';`
95+
: outdent`
96+
import {mergeGlobals} from '../utilities.mjs';
97+
import es${previousYear}Globals from './es${previousYear}.mjs';
98+
99+
export default mergeGlobals(es${previousYear}Globals, {
100+
${addedEntries.map(([name, value]) => `\t${name}: ${value},`).join('\n')}
101+
});
102+
`;
103+
104+
const file = new URL(`${environment}.mjs`, DATA_DIRECTORY);
105+
106+
const code = outdent`
107+
// This file is autogenerated by scripts
108+
// Do NOT modify this file manually
109+
110+
${content};
111+
`;
112+
113+
if (!options.dryRun) {
114+
await fs.writeFile(file, code + '\n');
115+
}
116+
117+
return {
118+
environment,
119+
...getDataDiff(original, data),
120+
};
121+
}
122+
123+
async function getBuiltinGlobals() {
124+
const {data} = await parseSpecification();
125+
return data;
126+
}
127+
128+
export {getBuiltinGlobals, buildYearlyBuiltinGlobals};

scripts/get-builtin-globals.mjs

Lines changed: 0 additions & 71 deletions
This file was deleted.

0 commit comments

Comments
 (0)