Skip to content

Commit

Permalink
import the kangax compat-table data (#121, #231)
Browse files Browse the repository at this point in the history
  • Loading branch information
evanw committed Jul 7, 2020
1 parent ece931d commit bb54f56
Show file tree
Hide file tree
Showing 3 changed files with 295 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,16 @@ parcel2/node_modules:
scripts/node_modules:
cd scripts && npm ci

################################################################################
# This downloads the kangax compat-table and generates browser support mappings

github/compat-table:
mkdir -p github/compat-table
git clone --depth 1 https://github.com/kangax/compat-table.git github/compat-table

compat-table: | github/compat-table
node scripts/compat-table.js

################################################################################
# This runs the test262 official JavaScript test suite through esbuild

Expand Down
153 changes: 153 additions & 0 deletions internal/compat/table.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// This file was automatically generated by "compat-table.js"

package compat

type Engine uint8

const (
Android Engine = iota
Chrome
Edge
Firefox
Ios
Node
Safari
)

type Feature uint8

const (
Async Feature = iota
AsyncIter
BigInt
ClassField
ClassPrivateField
ClassPrivateMethod
ClassPrivateStaticField
ClassPrivateStaticMethod
ClassStaticField
ExponentOperator
Hashbang
LogicalAssignment
NestedRestBinding
NullishCoalescing
ObjectRestSpread
OptionalCatchBinding
OptionalChain
)

var Table = map[Feature]map[Engine]float32{
Async: map[Engine]float32{
Chrome: 55,
Edge: 15,
Firefox: 52,
Ios: 10.3,
Node: 7.6,
Safari: 10.1,
},
AsyncIter: map[Engine]float32{
Chrome: 63,
Edge: 79,
Firefox: 57,
Ios: 12,
Node: 10,
Safari: 12,
},
BigInt: map[Engine]float32{
Chrome: 67,
Edge: 79,
Firefox: 68,
Node: 10.4,
Safari: 14,
},
ClassField: map[Engine]float32{
Chrome: 72,
Edge: 79,
Firefox: 69,
Node: 12,
Safari: 14,
},
ClassPrivateField: map[Engine]float32{
Chrome: 74,
Edge: 79,
Node: 12,
},
ClassPrivateMethod: map[Engine]float32{
Chrome: 84,
},
ClassPrivateStaticField: map[Engine]float32{
Chrome: 74,
Edge: 79,
Node: 12,
},
ClassPrivateStaticMethod: map[Engine]float32{
Chrome: 84,
},
ClassStaticField: map[Engine]float32{
Chrome: 72,
Edge: 79,
Firefox: 75,
Node: 12,
},
ExponentOperator: map[Engine]float32{
Chrome: 52,
Edge: 14,
Firefox: 52,
Ios: 10.3,
Node: 7,
Safari: 10.1,
},
Hashbang: map[Engine]float32{
Chrome: 74,
Edge: 79,
Firefox: 67,
Ios: 13.4,
Node: 12,
Safari: 13.1,
},
LogicalAssignment: map[Engine]float32{
Chrome: 85,
Firefox: 79,
Safari: 14,
},
NestedRestBinding: map[Engine]float32{
Chrome: 49,
Edge: 14,
Firefox: 47,
Ios: 10.3,
Node: 6,
Safari: 10.1,
},
NullishCoalescing: map[Engine]float32{
Chrome: 80,
Edge: 80,
Firefox: 72,
Ios: 13.4,
Node: 14,
Safari: 13.1,
},
ObjectRestSpread: map[Engine]float32{
Chrome: 60,
Edge: 79,
Firefox: 55,
Ios: 11.3,
Node: 8.1,
Safari: 11.1,
},
OptionalCatchBinding: map[Engine]float32{
Chrome: 66,
Edge: 79,
Firefox: 58,
Ios: 11.3,
Node: 10,
Safari: 11.1,
},
OptionalChain: map[Engine]float32{
Chrome: 80,
Edge: 80,
Firefox: 74,
Ios: 13.4,
Node: 14,
Safari: 13.1,
},
}
132 changes: 132 additions & 0 deletions scripts/compat-table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Run this using "make compat-table"
const fs = require('fs')
const path = require('path')
const stage1to3 = require('../github/compat-table/data-esnext')
const stage4 = require('../github/compat-table/data-es2016plus')
const environments = require('../github/compat-table/environments.json')
const interpolateAllResults = require('../github/compat-table/build-utils/interpolate-all-results')

interpolateAllResults(stage1to3.tests, environments)
interpolateAllResults(stage4.tests, environments)

const features = {
'exponentiation (**) operator': { target: 'ExponentOperator' },
'nested rest destructuring, declarations': { target: 'NestedRestBinding' },
'nested rest destructuring, parameters': { target: 'NestedRestBinding' },
'async functions': { target: 'Async' },
'object rest/spread properties': { target: 'ObjectRestSpread' },
'Asynchronous Iterators': { target: 'AsyncIter' },
'optional catch binding': { target: 'OptionalCatchBinding' },
'BigInt: basic functionality': { target: 'BigInt' },
'optional chaining operator (?.)': { target: 'OptionalChain' },
'nullish coalescing operator (??)': { target: 'NullishCoalescing' },
'Logical Assignment': { target: 'LogicalAssignment' },
'Hashbang Grammar': { target: 'Hashbang' },

// Public fields
'instance class fields: public instance class fields': { target: 'ClassField' },
'instance class fields: computed instance class fields': { target: 'ClassField' },
'static class fields: public static class fields': { target: 'ClassStaticField' },
'static class fields: computed static class fields': { target: 'ClassStaticField' },

// Private fields
'instance class fields: private instance class fields basic support': { target: 'ClassPrivateField' },
'instance class fields: private instance class fields initializers': { target: 'ClassPrivateField' },
'instance class fields: optional private instance class fields access': { target: 'ClassPrivateField' },
'instance class fields: optional deep private instance class fields access': { target: 'ClassPrivateField' },
'static class fields: private static class fields': { target: 'ClassPrivateStaticField' },

// Private methods
'private class methods: private instance methods': { target: 'ClassPrivateMethod' },
'private class methods: private accessor properties': { target: 'ClassPrivateMethod' },
'private class methods: private static methods': { target: 'ClassPrivateStaticMethod' },
'private class methods: private static accessor properties': { target: 'ClassPrivateStaticMethod' },
}

const versions = {}
const engines = [
'android',
'chrome',
'edge',
'firefox',
'ios',
'node',
'safari',
]

function mergeVersions(target, res) {
const map = versions[target] || (versions[target] = {})
for (const key in res) {
if (res[key] === true) {
const engine = /^[a-z]*/.exec(key)[0]
if (engines.indexOf(engine) >= 0) {
const version = +key.slice(engine.length).replace('_', '.')
map[engine] = Math.min(version, map[engine] || Infinity)
}
}
}
}

for (const test of stage4.tests.concat(stage1to3.tests)) {
const feature = features[test.name]
if (feature) {
feature.found = true
if (test.subtests) {
for (const subtest of test.subtests) {
mergeVersions(feature.target, subtest.res)
}
} else {
mergeVersions(feature.target, test.res)
}
} else if (test.subtests) {
for (const subtest of test.subtests) {
const feature = features[`${test.name}: ${subtest.name}`]
if (feature) {
feature.found = true
mergeVersions(feature.target, subtest.res)
}
}
}
}

for (const feature in features) {
if (!features[feature].found) {
throw new Error(`Did not find ${feature}`)
}
}

function upperFirstLetter(text) {
return text[0].toUpperCase() + text.slice(1)
}

function writeInnerMap(obj) {
const keys = Object.keys(obj).sort()
const maxLength = keys.reduce((a, b) => Math.max(a, b.length + 1), 0)
return keys.map(x => `\t\t${(upperFirstLetter(x) + ':').padEnd(maxLength)} ${obj[x]},`).join('\n')
}

fs.writeFileSync(__dirname + '/../internal/compat/table.go',
`// This file was automatically generated by "${path.basename(__filename)}"
package compat
type Engine uint8
const (
${engines.map((x, i) => `\t${upperFirstLetter(x)}${i ? '' : ' Engine = iota'}`).join('\n')}
)
type Feature uint8
const (
${Object.keys(versions).sort().map((x, i) => `\t${x}${i ? '' : ' Feature = iota'}`).join('\n')}
)
var Table = map[Feature]map[Engine]float32{
${Object.keys(versions).sort().map(x => `\t${x}: map[Engine]float32{
${writeInnerMap(versions[x])}
\t},`).join('\n')}
}
`)

// console.log(versions)

0 comments on commit bb54f56

Please sign in to comment.