Skip to content

Commit 366b632

Browse files
committed
#2940: switch to node-compat-table for node data
1 parent daf372d commit 366b632

File tree

2 files changed

+90
-22
lines changed

2 files changed

+90
-22
lines changed

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,11 @@ github/compat-table:
631631
mkdir -p github/compat-table
632632
git clone --depth 1 https://github.com/kangax/compat-table.git github/compat-table
633633

634-
compat-table: | github/compat-table
634+
github/node-compat-table:
635+
mkdir -p github/node-compat-table
636+
git clone --depth 1 https://github.com/williamkapke/node-compat-table.git github/node-compat-table
637+
638+
compat-table: | github/compat-table github/node-compat-table
635639
node scripts/compat-table.js
636640

637641
################################################################################

scripts/compat-table.js

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ function getValueOfTest(value) {
119119
return value === true
120120
}
121121

122-
function mergeVersions(target, res) {
122+
function mergeVersions(target, res, omit = []) {
123123
// The original data set will contain something like "chrome44: true" for a
124124
// given feature. And the interpolation script will expand this to something
125125
// like "chrome44: true, chrome45: true, chrome46: true, ..." so we want to
@@ -131,7 +131,7 @@ function mergeVersions(target, res) {
131131
const match = /^([a-z_]+)[0-9_]+$/.exec(key)
132132
if (match) {
133133
const engine = match[1]
134-
if (engines.indexOf(engine) >= 0) {
134+
if (engines.indexOf(engine) >= 0 && omit.indexOf(engine) < 0) {
135135
const version = parseEnvsVersions({ [key]: true })[engine][0].version
136136
if (!lowestVersionMap[engine] || compareVersions({ version }, { version: lowestVersionMap[engine] }) < 0) {
137137
lowestVersionMap[engine] = version
@@ -154,7 +154,10 @@ function mergeVersions(target, res) {
154154
}
155155

156156
// ES5 features
157-
mergeVersions('ObjectAccessors', { es5: true })
157+
mergeVersions('ObjectAccessors', {
158+
es5: true,
159+
node0_4: true, // "node-compat-table" doesn't appear to cover ES5 features...
160+
})
158161

159162
// ES6 features
160163
mergeVersions('ArraySpread', { es2015: true })
@@ -336,6 +339,8 @@ mergeVersions('RegexpMatchIndices', {
336339
safari15: true,
337340
})
338341

342+
const omitNode = ['node']
343+
339344
for (const test of [...es5.tests, ...es6.tests, ...stage4.tests, ...stage1to3.tests]) {
340345
const feature = features[test.name]
341346
if (feature) {
@@ -351,16 +356,90 @@ for (const test of [...es5.tests, ...es6.tests, ...stage4.tests, ...stage1to3.te
351356
for (const key in res)
352357
res[key] &&= getValueOfTest(subtest.res[key] ?? false)
353358

354-
mergeVersions(feature.target, res)
359+
mergeVersions(feature.target, res, omitNode)
355360
} else {
356-
mergeVersions(feature.target, test.res)
361+
mergeVersions(feature.target, test.res, omitNode)
357362
}
358363
} else if (test.subtests) {
359364
for (const subtest of test.subtests) {
360365
const feature = features[`${test.name}: ${subtest.name}`]
361366
if (feature) {
362367
feature.found = true
363-
mergeVersions(feature.target, subtest.res)
368+
mergeVersions(feature.target, subtest.res, omitNode)
369+
}
370+
}
371+
}
372+
}
373+
374+
// Node compatibility data is handled separately because the data source
375+
// https://github.com/williamkapke/node-compat-table is (for now at least)
376+
// more up to date than https://github.com/kangax/compat-table.
377+
{
378+
const nodeCompatTableDir = path.join(__dirname, '../github/node-compat-table/results/v8')
379+
const reformattedTestResults = {}
380+
381+
// Format the data like the kangax table
382+
for (const entry of fs.readdirSync(nodeCompatTableDir)) {
383+
// Note: this omits data for the "0.x.y" releases because the data isn't clean
384+
const match = /^([1-9]\d*\.\d+\.\d+)\.json$/.exec(entry)
385+
if (match) {
386+
const version = 'node' + match[1].replace(/\./g, '_')
387+
const jsonPath = path.join(nodeCompatTableDir, entry)
388+
const json = JSON.parse(fs.readFileSync(jsonPath, 'utf8'))
389+
390+
for (const key in json) {
391+
if (key.startsWith('ES')) {
392+
const object = json[key]
393+
394+
for (const key in object) {
395+
const testResult = object[key]
396+
const split = key.replace('<code>', '').replace('</code>', '').split('›')
397+
398+
if (split.length === 2) {
399+
const test = reformattedTestResults[split[1]] || (reformattedTestResults[split[1]] = { name: split[1] })
400+
const res = test.res || (test.res = {})
401+
res[version] = testResult
402+
}
403+
404+
else if (split.length === 3) {
405+
const test = reformattedTestResults[split[1]] || (reformattedTestResults[split[1]] = { name: split[1] })
406+
const subtests = test.subtests || (test.subtests = {})
407+
const subtest = subtests[split[2]] || (subtests[split[2]] = { name: split[2] })
408+
const res = subtest.res || (subtest.res = {})
409+
res[version] = testResult
410+
}
411+
}
412+
}
413+
}
414+
}
415+
}
416+
417+
for (const test of Object.values(reformattedTestResults)) {
418+
const feature = features[test.name]
419+
if (feature) {
420+
feature.found = true
421+
if (test.subtests) {
422+
const res = {}
423+
for (const subtest of Object.values(test.subtests))
424+
for (const key in subtest.res)
425+
res[key] = true
426+
for (const subtest of Object.values(test.subtests))
427+
for (const key in res)
428+
res[key] &&= getValueOfTest(subtest.res[key] ?? false)
429+
mergeVersions(feature.target, res)
430+
} else {
431+
mergeVersions(feature.target, test.res)
432+
}
433+
} else if (test.subtests) {
434+
for (const subtest of Object.values(test.subtests)) {
435+
const feature = features[`${test.name}: ${subtest.name}`]
436+
if (feature) {
437+
if (feature.target === 'ObjectAccessors') {
438+
console.log(test.name, res)
439+
}
440+
feature.found = true
441+
mergeVersions(feature.target, subtest.res)
442+
}
364443
}
365444
}
366445
}
@@ -372,21 +451,6 @@ for (const feature in features) {
372451
}
373452
}
374453

375-
// Apply some manual overrides from this thread: https://github.com/evanw/esbuild/issues/2940#issuecomment-1437818002
376-
// Each one has been manually checked using past node releases: https://nodejs.org/download/release/
377-
applyManualOverride('ClassPrivateBrandCheck', 'node', [{ start: [16, 9], end: null }], [{ start: [16, 4], end: null }])
378-
applyManualOverride('Hashbang', 'node', [{ start: [12, 0], end: null }], [{ start: [12, 5], end: null }])
379-
applyManualOverride('OptionalChain', 'node', [{ start: [16, 9], end: null }], [{ start: [16, 1], end: null }])
380-
applyManualOverride('TemplateLiteral', 'node', [{ start: [4], end: null }], [{ start: [10], end: null }])
381-
382-
function applyManualOverride(target, engine, expected, changed) {
383-
const observed = JSON.stringify(versions[target][engine])
384-
expected = JSON.stringify(expected)
385-
if (observed !== expected)
386-
throw new Error(`Mismatch for versions.${target}.${engine}: Expected ${observed} to be ${expected}`)
387-
versions[target][engine] = changed
388-
}
389-
390454
function upper(text) {
391455
if (text === 'es' || text === 'ios' || text === 'ie') return text.toUpperCase()
392456
return text[0].toUpperCase() + text.slice(1)

0 commit comments

Comments
 (0)