Skip to content

Commit 81fc6a2

Browse files
authored
chore: refactor auto-generation scripts (#48)
* chore: refactor auto-generated scripts * refactor
1 parent 55e7b49 commit 81fc6a2

File tree

4 files changed

+116
-69
lines changed

4 files changed

+116
-69
lines changed

docs/rules/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,8 @@ There are multiple configs that enable all rules in this category: `plugin:es-x/
235235

236236
## Legacy
237237

238-
Rules in this category disallow the syntax contained in [Annex B](https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html) or Legacy.
239-
The rules are not included in any preset.
238+
Rules in this category disallow the syntax contained in [Annex B](https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html) or Legacy. \
239+
Rules in this category are not included in any preset.
240240

241241
| Rule ID | Description | |
242242
|:--------|:------------|:--:|

scripts/rules.js

Lines changed: 65 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,42 +18,86 @@ const libRoot = path.resolve(__dirname, "../lib/rules")
1818
/**
1919
* @typedef {Object} Category
2020
* @property {string} id The category name.
21-
* @property {number} revision The revision number.
22-
* @property {string} configName The config name.
23-
* @property {string} aboveConfigName The config name for disallowing features all above.
21+
* @property {string} title The category title.
22+
* @property {number} [edition] The edition number.
23+
* @property {string} [configName] The config name.
24+
* @property {string} [aboveConfigName] The config name for disallowing features all above.
2425
* @property {Rule[]} rules The rules in this category.
2526
* @property {boolean} [experimental] The flag to be belong to experimental configs.
27+
* @property {string} [comment] The category comment.
28+
* @property {"ecma262" | "ecma402"} specKind The specification kind.
2629
*/
2730

2831
/** @type {Record<string, Category>} */
29-
const categories = [14, 13, 12, 11, 10, 9, 8, 7, 6, 5].reduce(
30-
(map, revision, _, [latest]) => {
31-
const year = revision <= 5 ? 5 : 2009 + revision
32-
const id = `ES${year}`
33-
map[id] = {
34-
id,
35-
title: id,
36-
revision,
37-
rules: [],
38-
experimental: revision === latest,
32+
const categories = [
33+
2023,
34+
2022,
35+
2021,
36+
2020,
37+
2019,
38+
2018,
39+
2017,
40+
2016,
41+
2015,
42+
[5, 1],
43+
[3, null],
44+
]
45+
.map((esVersion) =>
46+
Array.isArray(esVersion) ? esVersion : [esVersion, esVersion],
47+
)
48+
.reduce((map, versions, index, list) => {
49+
const experimental = index === 0
50+
const [vFor262, _vFor402] = versions
51+
const [prevVFor262, _prevVFor402] = list[index + 1] || [null, null]
52+
const ecma262Id = `ES${vFor262}`
53+
if (prevVFor262) {
54+
map[ecma262Id] = {
55+
id: ecma262Id,
56+
title: `ES${vFor262}`,
57+
edition: vFor262 > 5 ? vFor262 - 2009 : vFor262,
58+
rules: [],
59+
experimental,
60+
specKind: "ecma262",
61+
configName: experimental
62+
? "no-new-in-esnext"
63+
: `no-new-in-es${vFor262}`,
64+
aboveConfigName: experimental
65+
? undefined
66+
: `restrict-to-es${prevVFor262}`,
67+
}
3968
}
69+
// TODO: https://github.com/eslint-community/eslint-plugin-es-x/issues/45
70+
// if (vFor402 && prevVFor402) {
71+
// const ecma402Id = `ES${vFor402}-Intl-API`
72+
// map[ecma402Id] = {
73+
// id: ecma402Id,
74+
// title: `ES${vFor402} Intl API`,
75+
// edition: vFor402 - 2013,
76+
// rules: [],
77+
// experimental,
78+
// specKind: "ecma402",
79+
// configName: experimental
80+
// ? "no-new-in-esnext-intl-api"
81+
// : `no-new-in-es${vFor402}-intl-api`,
82+
// aboveConfigName: experimental
83+
// ? undefined
84+
// : prevVFor402 === 1
85+
// ? "restrict-to-es-intl-api-1st-edition"
86+
// : `restrict-to-es${prevVFor402}-intl-api`,
87+
// }
88+
// }
4089
return map
41-
},
42-
{},
43-
)
90+
}, {})
4491
categories.legacy = {
4592
id: "legacy",
4693
title: "Legacy",
47-
ignorePreset: true,
48-
comment: `Rules in this category disallow the syntax contained in [Annex B](https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html) or Legacy.
49-
The rules are not included in any preset.`,
94+
comment:
95+
"Rules in this category disallow the syntax contained in [Annex B](https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html) or Legacy.",
5096
rules: [],
5197
}
5298
categories.uncategorized = {
5399
id: "uncategorized",
54100
title: "Uncategorized",
55-
ignorePreset: true,
56-
comment: "Rules in this category are not included in any preset.",
57101
rules: [],
58102
}
59103

scripts/update-docs-readme.js

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,13 @@ ${ruleSectionContent}
4545

4646
function extractCategoryId(filePath) {
4747
const basename = path.basename(filePath, ".js")
48-
const match = /no-new-in-(es\d+)/u.exec(basename)
49-
return match ? match[1].toUpperCase() : undefined
48+
const category = Object.values(categories).find(
49+
({ configName }) => configName === basename,
50+
)
51+
if (category) {
52+
return category.id
53+
}
54+
return undefined
5055
}
5156

5257
/**
@@ -57,17 +62,24 @@ function toSection(category) {
5762
if (!category.rules.length) {
5863
return undefined
5964
}
60-
const configIds = formatList(
61-
configs
62-
.filter((c) => c.categoryIds.includes(category.id))
63-
.map((c) => `\`${c.id}\``)
64-
.sort(collator.compare.bind(collator)),
65-
)
66-
const comment =
67-
category.comment ||
68-
(configIds
69-
? `There are multiple configs that enable all rules in this category: ${configIds}`
70-
: "There is a config that enables the rules in this category: `plugin:es-x/no-new-in-esnext`")
65+
const configIds = configs
66+
.filter((c) => c.categoryIds.includes(category.id))
67+
.map((c) => `\`${c.id}\``)
68+
.sort(collator.compare.bind(collator))
69+
70+
let comment = ""
71+
if (category.comment) {
72+
comment = `${category.comment} \\\n`
73+
}
74+
comment += !configIds.length
75+
? "Rules in this category are not included in any preset."
76+
: configIds.length > 1
77+
? `There are multiple configs that enable all rules in this category: ${formatList(
78+
configIds,
79+
)}`
80+
: `There is a config that enables the rules in this category: ${formatList(
81+
configIds,
82+
)}`
7183

7284
return `## ${category.title}
7385

scripts/update-lib-configs.js

Lines changed: 24 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,6 @@ const { ESLint } = require("eslint")
1010
const { categories } = require("./rules")
1111
const Root = path.resolve(__dirname, "../lib/configs")
1212

13-
function configNameToDisallowNewIn(revision) {
14-
const year = revision <= 5 ? revision : 2009 + revision
15-
return `no-new-in-es${year}`
16-
}
17-
18-
function configNameToRestrictToPreviousOf(revision) {
19-
const prevRev = revision === 5 ? 3 : revision - 1
20-
const year = prevRev <= 5 ? prevRev : 2009 + prevRev
21-
return `restrict-to-es${year}`
22-
}
23-
2413
function wrapCode(code) {
2514
return `/**
2615
* DON'T EDIT THIS FILE.
@@ -32,33 +21,35 @@ module.exports = ${code}
3221
`
3322
}
3423

35-
for (const { experimental, revision, rules, ignorePreset } of Object.values(
36-
categories,
37-
)) {
38-
if (ignorePreset) {
24+
for (const {
25+
edition,
26+
rules,
27+
configName,
28+
aboveConfigName,
29+
specKind,
30+
} of Object.values(categories)) {
31+
if (!configName) {
3932
continue
4033
}
4134
const ruleSetting = rules.map((r) => `"es-x/${r.ruleId}":"error"`).join(",")
42-
const extendSetting = Object.values(categories)
43-
.filter((c) => c.revision >= revision && !c.experimental)
44-
.map(
45-
(c) =>
46-
`require.resolve("./${configNameToDisallowNewIn(c.revision)}")`,
47-
)
48-
.join(",")
4935

50-
if (experimental) {
51-
fs.writeFileSync(
52-
path.join(Root, "no-new-in-esnext.js"),
53-
wrapCode(`{ plugins: ["es-x"], rules: { ${ruleSetting} } }`),
54-
)
55-
} else {
56-
fs.writeFileSync(
57-
path.join(Root, `${configNameToDisallowNewIn(revision)}.js`),
58-
wrapCode(`{ plugins: ["es-x"], rules: { ${ruleSetting} } }`),
59-
)
36+
fs.writeFileSync(
37+
path.join(Root, `${configName}.js`),
38+
wrapCode(`{ plugins: ["es-x"], rules: { ${ruleSetting} } }`),
39+
)
40+
if (aboveConfigName) {
41+
const extendSetting = Object.values(categories)
42+
.filter(
43+
(c) =>
44+
c.edition >= edition &&
45+
c.specKind === specKind &&
46+
!c.experimental &&
47+
c.configName,
48+
)
49+
.map((c) => `require.resolve("./${c.configName}")`)
50+
.join(",")
6051
fs.writeFileSync(
61-
path.join(Root, `${configNameToRestrictToPreviousOf(revision)}.js`),
52+
path.join(Root, `${aboveConfigName}.js`),
6253
wrapCode(`{ extends: [${extendSetting}] }`),
6354
)
6455
}

0 commit comments

Comments
 (0)