Skip to content

Commit

Permalink
feat: support eslint v8 (fixes #78)
Browse files Browse the repository at this point in the history
  • Loading branch information
aladdin-add committed Nov 1, 2021
1 parent 8437f12 commit 97acbc6
Show file tree
Hide file tree
Showing 6 changed files with 269 additions and 252 deletions.
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
"author": "薛定谔的猫 <weiran.zsd@outlook.com>",
"description": "some eslint plugins",
"devDependencies": {
"eslint": "^7.15.0",
"eslint-config-eslint": "^6.0.0",
"eslint-plugin-eslint-plugin": "^3.0.2",
"eslint-plugin-jsdoc": "^30.7.8",
"eslint": "^8.1.0",
"eslint-config-eslint": "^7.0.0",
"eslint-plugin-eslint-plugin": "^4.0.1",
"eslint-plugin-jsdoc": "^37.0.3",
"eslint-plugin-node": "^11.1.0"
},
"scripts": {
Expand Down
128 changes: 68 additions & 60 deletions packages/autofix/lib/rules.js
Original file line number Diff line number Diff line change
@@ -1,60 +1,68 @@
/**
* @fileoverview expored all rules in the plugin.
* @author 唯然<weiran.zsd@outlook.com>
*/

"use strict";

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const fs = require("fs");
const path = require("path");
const eslintVersion = require("eslint/package.json").version;


/**
* Loads a given rule from the filesystem and generates its documentation URL
* @param {string} ruleName The name of the rule
* @returns {Rule} The ESLint rule to export
*/
function loadRule(ruleName) {
const rule = require(path.join(__dirname, "rules", ruleName));

rule.meta.docs.url =
`https://eslint.org/docs/rules/${ruleName}`;

return rule;
}

const allRules = {};

// eslint v6 restructed its codebase
// TODO: this might be unreliable
if (eslintVersion >= "6.0.0") {
const builtin = require("eslint/lib/rules");

for (const [ruleId, rule] of builtin) {
if (rule.meta.fixable) {
allRules[ruleId] = rule;
}
}
} else {
const builtin = require("eslint/lib/built-in-rules-index"); // eslint-disable-line node/no-missing-require

Object.keys(builtin)
.filter(rule => builtin[rule].meta.fixable)
.reduce((acc, cur) => {
acc[cur] = builtin[cur];
return acc;
}, allRules);
}

// import all rules in lib/rules
fs.readdirSync(`${__dirname}/rules`)
.filter(fileName => fileName.endsWith(".js") && /^[^._]/u.test(fileName))
.map(fileName => fileName.replace(/\.js$/u, ""))
.reduce((rules, ruleName) => Object.assign(rules, { [ruleName]: loadRule(ruleName) }), allRules);

module.exports = allRules;
/**
* @fileoverview expored all rules in the plugin.
* @author 唯然<weiran.zsd@outlook.com>
*/

"use strict";

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const fs = require("fs");
const path = require("path");
const eslintVersion = Number.parseInt(require("eslint/package.json").version, 10);


/**
* Loads a given rule from the filesystem and generates its documentation URL
* @param {string} ruleName The name of the rule
* @returns {Rule} The ESLint rule to export
*/
function loadRule(ruleName) {
const rule = require(path.join(__dirname, "rules", ruleName));

rule.meta.docs.url =
`https://eslint.org/docs/rules/${ruleName}`;

return rule;
}

const allRules = {};

// eslint v6 restructed its codebase
// TODO: this might be unreliable
if (eslintVersion >= 8) {
const { builtinRules } = require("eslint/use-at-your-own-risk"); // eslint-disable-line node/no-missing-require

for (const [ruleId, rule] of builtinRules) {
if (rule.meta.fixable) {
allRules[ruleId] = rule;
}
}
} else if (eslintVersion >= 6) {
const builtin = require("eslint/lib/rules");

for (const [ruleId, rule] of builtin) {
if (rule.meta.fixable) {
allRules[ruleId] = rule;
}
}
} else {
const builtin = require("eslint/lib/built-in-rules-index"); // eslint-disable-line node/no-missing-require

Object.keys(builtin)
.filter(rule => builtin[rule].meta.fixable)
.reduce((acc, cur) => {
acc[cur] = builtin[cur];
return acc;
}, allRules);
}

// import all rules in lib/rules
fs.readdirSync(path.join(__dirname, "rules"))
.filter(fileName => fileName.endsWith(".js") && /^[^._]/u.test(fileName))
.map(fileName => fileName.replace(/\.js$/u, ""))
.reduce((rules, ruleName) => Object.assign(rules, { [ruleName]: loadRule(ruleName) }), allRules);

module.exports = allRules;
10 changes: 5 additions & 5 deletions packages/autofix/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
],
"dependencies": {
"eslint-rule-composer": "^0.3.0",
"espree": "^7.3.1",
"espree": "^9.0.0",
"esutils": "^2.0.2",
"lodash": "^4.17.20",
"string-similarity": "^4.0.3"
},
"devDependencies": {
"@not-an-aardvark/node-release-script": "^0.1.0",
"@types/eslint": "^7.2.6",
"execa": "^5.0.0",
"@types/eslint": "^7.28.2",
"execa": "^5.1.1",
"git-config": "0.0.7",
"husky": "^4.3.5",
"husky": "^7.0.4",
"minimist": "^1.2.0",
"mocha": "^8.2.1"
"mocha": "^9.1.3"
},
"peerDependencies": {
"eslint": ">= 5.12.1"
Expand Down
164 changes: 83 additions & 81 deletions packages/autofix/tools/eslint-rules/rule-def-format.js
Original file line number Diff line number Diff line change
@@ -1,81 +1,83 @@
/**
* @fileoverview Rule definition of "rule-def-format"
* @author Pig Fang <g-plane@hotmail.com>
*/
"use strict";

const path = require("path");

module.exports = {
meta: {
fixable: "code"
},
create: context => ({
CallExpression: node => {
if (node.callee.type !== "MemberExpression") {
return;
}

const { callee: { object: { name: objectName }, property: { name: propertyName } }, arguments: args } = node;
const sourceCode = context.getSourceCode();

if (objectName === "utils" && propertyName === "getFixableRule") {
const arg0 = args[0];
const ruleName = path.basename(context.getFilename(), ".js");

if (arg0.value !== ruleName) {
context.report({
node: arg0,
message: `Rule name should be '${ruleName}'`,
fix: fixer => fixer.replaceText(arg0, `"${ruleName}"`)
});
}
return;
}

if (objectName === "ruleComposer") {
if (propertyName === "mapReports") {
const [, predicate] = args;

if (predicate.type === "ArrowFunctionExpression" || predicate.type === "FunctionExpression") {
if (predicate.body.type !== "BlockStatement") {
context.report({
node: predicate.body,
message: "Body of predicate should be a block statement."
});
return;
}
const param0 = predicate.params[0].name;

const statements = predicate.body.body;

const returnStatement = statements.find(stmt => stmt.type === "ReturnStatement");

if (!returnStatement) {
context.report({
node: predicate,
message: "Should returning the problem object.",
fix: fixer => {
const lastToken = sourceCode.getLastToken(predicate);

return fixer.insertTextBefore(lastToken, `\nreturn ${param0};\n`);
}
});
} else if (returnStatement.argument.name !== param0) {
context.report({
node: predicate,
message: "Should returning the problem object.",
fix: fixer => fixer.replaceText(returnStatement, `return ${param0};`)
});
}
}
} else if (propertyName === "joinReports" && args[0].type !== "ArrayExpression") {
context.report({
node: args[0],
message: "The first argument of 'joinReports' should be an array."
});
}
}
}
})
};
/**
* @fileoverview Rule definition of "rule-def-format"
* @author Pig Fang <g-plane@hotmail.com>
*/
"use strict";

const path = require("path");

module.exports = {
meta: {
fixable: "code",
type: "problem",
schema: []
},
create: context => ({
CallExpression: node => {
if (node.callee.type !== "MemberExpression") {
return;
}

const { callee: { object: { name: objectName }, property: { name: propertyName } }, arguments: args } = node;
const sourceCode = context.getSourceCode();

if (objectName === "utils" && propertyName === "getFixableRule") {
const arg0 = args[0];
const ruleName = path.basename(context.getFilename(), ".js");

if (arg0.value !== ruleName) {
context.report({
node: arg0,
message: `Rule name should be '${ruleName}'`,
fix: fixer => fixer.replaceText(arg0, `"${ruleName}"`)
});
}
return;
}

if (objectName === "ruleComposer") {
if (propertyName === "mapReports") {
const [, predicate] = args;

if (predicate.type === "ArrowFunctionExpression" || predicate.type === "FunctionExpression") {
if (predicate.body.type !== "BlockStatement") {
context.report({
node: predicate.body,
message: "Body of predicate should be a block statement."
});
return;
}
const param0 = predicate.params[0].name;

const statements = predicate.body.body;

const returnStatement = statements.find(stmt => stmt.type === "ReturnStatement");

if (!returnStatement) {
context.report({
node: predicate,
message: "Should returning the problem object.",
fix: fixer => {
const lastToken = sourceCode.getLastToken(predicate);

return fixer.insertTextBefore(lastToken, `\nreturn ${param0};\n`);
}
});
} else if (returnStatement.argument.name !== param0) {
context.report({
node: predicate,
message: "Should returning the problem object.",
fix: fixer => fixer.replaceText(returnStatement, `return ${param0};`)
});
}
}
} else if (propertyName === "joinReports" && args[0].type !== "ArrayExpression") {
context.report({
node: args[0],
message: "The first argument of 'joinReports' should be an array."
});
}
}
}
})
};
Loading

0 comments on commit 97acbc6

Please sign in to comment.