mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-17 06:20:12 +01:00
Enable ESLint rule unicorn/no-array-for-each, auto-fix all violations, manually address new issues for ~4% time reduction measured via profile-fixture.mjs on Apple Silicon M1.
This commit is contained in:
parent
15efcb4282
commit
b6471fba31
34 changed files with 414 additions and 389 deletions
|
|
@ -29,32 +29,32 @@ function validateRuleList(ruleList, synchronous) {
|
|||
return result;
|
||||
}
|
||||
const allIds = {};
|
||||
ruleList.forEach(function forRule(rule, index) {
|
||||
for (const [ index, rule ] of ruleList.entries()) {
|
||||
const customIndex = index - rules.length;
|
||||
// eslint-disable-next-line jsdoc/require-jsdoc
|
||||
// eslint-disable-next-line no-inner-declarations, jsdoc/require-jsdoc
|
||||
function newError(property) {
|
||||
return new Error(
|
||||
"Property '" + property + "' of custom rule at index " +
|
||||
customIndex + " is incorrect.");
|
||||
}
|
||||
[ "names", "tags" ].forEach(function forProperty(property) {
|
||||
for (const property of [ "names", "tags" ]) {
|
||||
const value = rule[property];
|
||||
if (!result &&
|
||||
(!value || !Array.isArray(value) || (value.length === 0) ||
|
||||
!value.every(helpers.isString) || value.some(helpers.isEmptyString))) {
|
||||
result = newError(property);
|
||||
}
|
||||
});
|
||||
[
|
||||
}
|
||||
for (const propertyInfo of [
|
||||
[ "description", "string" ],
|
||||
[ "function", "function" ]
|
||||
].forEach(function forProperty(propertyInfo) {
|
||||
]) {
|
||||
const property = propertyInfo[0];
|
||||
const value = rule[property];
|
||||
if (!result && (!value || (typeof value !== propertyInfo[1]))) {
|
||||
result = newError(property);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (
|
||||
!result &&
|
||||
rule.information &&
|
||||
|
|
@ -76,24 +76,25 @@ function validateRuleList(ruleList, synchronous) {
|
|||
);
|
||||
}
|
||||
if (!result) {
|
||||
rule.names.forEach(function forName(name) {
|
||||
for (const name of rule.names) {
|
||||
const nameUpper = name.toUpperCase();
|
||||
if (!result && (allIds[nameUpper] !== undefined)) {
|
||||
result = new Error("Name '" + name + "' of custom rule at index " +
|
||||
customIndex + " is already used as a name or tag.");
|
||||
}
|
||||
allIds[nameUpper] = true;
|
||||
});
|
||||
rule.tags.forEach(function forTag(tag) {
|
||||
}
|
||||
for (const tag of rule.tags) {
|
||||
const tagUpper = tag.toUpperCase();
|
||||
if (!result && allIds[tagUpper]) {
|
||||
result = new Error("Tag '" + tag + "' of custom rule at index " +
|
||||
customIndex + " is already used as a name.");
|
||||
}
|
||||
allIds[tagUpper] = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// @ts-ignore
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -111,10 +112,10 @@ function newResults(ruleList) {
|
|||
const results = [];
|
||||
const keys = Object.keys(lintResults);
|
||||
keys.sort();
|
||||
keys.forEach(function forFile(file) {
|
||||
for (const file of keys) {
|
||||
const fileResults = lintResults[file];
|
||||
if (Array.isArray(fileResults)) {
|
||||
fileResults.forEach(function forResult(result) {
|
||||
for (const result of fileResults) {
|
||||
const ruleMoniker = result.ruleNames ?
|
||||
result.ruleNames.join("/") :
|
||||
(result.ruleName + "/" + result.ruleAlias);
|
||||
|
|
@ -129,30 +130,32 @@ function newResults(ruleList) {
|
|||
(result.errorContext ?
|
||||
" [Context: \"" + result.errorContext + "\"]" :
|
||||
""));
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (!ruleNameToRule) {
|
||||
ruleNameToRule = {};
|
||||
ruleList.forEach(function forRule(rule) {
|
||||
for (const rule of ruleList) {
|
||||
const ruleName = rule.names[0].toUpperCase();
|
||||
ruleNameToRule[ruleName] = rule;
|
||||
});
|
||||
}
|
||||
}
|
||||
Object.keys(fileResults).forEach(function forRule(ruleName) {
|
||||
for (const [ ruleName, ruleResults ] of Object.entries(fileResults)) {
|
||||
const rule = ruleNameToRule[ruleName.toUpperCase()];
|
||||
const ruleResults = fileResults[ruleName];
|
||||
ruleResults.forEach(function forLine(lineNumber) {
|
||||
for (const lineNumber of ruleResults) {
|
||||
// @ts-ignore
|
||||
const nameIndex = Math.min(useAlias ? 1 : 0, rule.names.length - 1);
|
||||
const result =
|
||||
file + ": " +
|
||||
lineNumber + ": " +
|
||||
// @ts-ignore
|
||||
rule.names[nameIndex] + " " +
|
||||
// @ts-ignore
|
||||
rule.description;
|
||||
results.push(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return results.join("\n");
|
||||
}
|
||||
Object.defineProperty(lintResults, "toString", { "value": toString });
|
||||
|
|
@ -196,7 +199,7 @@ function removeFrontMatter(content, frontMatter) {
|
|||
*/
|
||||
function annotateTokens(tokens, lines) {
|
||||
let trMap = null;
|
||||
tokens.forEach(function forToken(token) {
|
||||
for (const token of tokens) {
|
||||
// Provide missing maps for table content
|
||||
if (token.type === "tr_open") {
|
||||
trMap = token.map;
|
||||
|
|
@ -228,7 +231,7 @@ function annotateTokens(tokens, lines) {
|
|||
codeSpanExtraLines.push(code.split(helpers.newLineRe).length - 1);
|
||||
}
|
||||
);
|
||||
(token.children || []).forEach(function forChild(child) {
|
||||
for (const child of (token.children || [])) {
|
||||
child.lineNumber = lineNumber;
|
||||
child.line = lines[lineNumber - 1];
|
||||
if ((child.type === "softbreak") || (child.type === "hardbreak")) {
|
||||
|
|
@ -236,9 +239,9 @@ function annotateTokens(tokens, lines) {
|
|||
} else if (child.type === "code_inline") {
|
||||
lineNumber += codeSpanExtraLines.shift();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -250,24 +253,24 @@ function annotateTokens(tokens, lines) {
|
|||
function mapAliasToRuleNames(ruleList) {
|
||||
const aliasToRuleNames = {};
|
||||
// const tagToRuleNames = {};
|
||||
ruleList.forEach(function forRule(rule) {
|
||||
for (const rule of ruleList) {
|
||||
const ruleName = rule.names[0].toUpperCase();
|
||||
// The following is useful for updating README.md:
|
||||
// console.log(
|
||||
// "* **[" + ruleName + "](doc/Rules.md#" + ruleName.toLowerCase() +
|
||||
// ")** *" + rule.names.slice(1).join("/") + "* - " + rule.description);
|
||||
rule.names.forEach(function forName(name) {
|
||||
for (const name of rule.names) {
|
||||
const nameUpper = name.toUpperCase();
|
||||
aliasToRuleNames[nameUpper] = [ ruleName ];
|
||||
});
|
||||
rule.tags.forEach(function forTag(tag) {
|
||||
}
|
||||
for (const tag of rule.tags) {
|
||||
const tagUpper = tag.toUpperCase();
|
||||
const ruleNames = aliasToRuleNames[tagUpper] || [];
|
||||
ruleNames.push(ruleName);
|
||||
aliasToRuleNames[tagUpper] = ruleNames;
|
||||
// tagToRuleNames[tag] = ruleName;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
// The following is useful for updating README.md:
|
||||
// Object.keys(tagToRuleNames).sort().forEach(function forTag(tag) {
|
||||
// console.log("* **" + tag + "** - " +
|
||||
|
|
@ -292,14 +295,14 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
|
|||
);
|
||||
const ruleDefault = (defaultKey.length === 0) || !!config[defaultKey[0]];
|
||||
const effectiveConfig = {};
|
||||
ruleList.forEach((rule) => {
|
||||
for (const rule of ruleList) {
|
||||
const ruleName = rule.names[0].toUpperCase();
|
||||
effectiveConfig[ruleName] = ruleDefault;
|
||||
});
|
||||
deprecatedRuleNames.forEach((ruleName) => {
|
||||
}
|
||||
for (const ruleName of deprecatedRuleNames) {
|
||||
effectiveConfig[ruleName] = false;
|
||||
});
|
||||
Object.keys(config).forEach((key) => {
|
||||
}
|
||||
for (const key of Object.keys(config)) {
|
||||
let value = config[key];
|
||||
if (value) {
|
||||
if (!(value instanceof Object)) {
|
||||
|
|
@ -309,10 +312,10 @@ function getEffectiveConfig(ruleList, config, aliasToRuleNames) {
|
|||
value = false;
|
||||
}
|
||||
const keyUpper = key.toUpperCase();
|
||||
(aliasToRuleNames[keyUpper] || []).forEach((ruleName) => {
|
||||
for (const ruleName of (aliasToRuleNames[keyUpper] || [])) {
|
||||
effectiveConfig[ruleName] = value;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
return effectiveConfig;
|
||||
}
|
||||
|
||||
|
|
@ -378,7 +381,7 @@ function getEnabledRulesPerLineNumber(
|
|||
// Helper functions
|
||||
// eslint-disable-next-line jsdoc/require-jsdoc
|
||||
function handleInlineConfig(input, forEachMatch, forEachLine) {
|
||||
input.forEach((line, lineIndex) => {
|
||||
for (const [ lineIndex, line ] of input.entries()) {
|
||||
if (!noInlineConfig) {
|
||||
let match = null;
|
||||
while ((match = helpers.inlineCommentStartRe.exec(line))) {
|
||||
|
|
@ -395,7 +398,7 @@ function getEnabledRulesPerLineNumber(
|
|||
if (forEachLine) {
|
||||
forEachLine();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// eslint-disable-next-line jsdoc/require-jsdoc
|
||||
function configureFile(action, parameter) {
|
||||
|
|
@ -417,11 +420,11 @@ function getEnabledRulesPerLineNumber(
|
|||
const enabled = (action.startsWith("ENABLE"));
|
||||
const trimmed = parameter && parameter.trim();
|
||||
const items = trimmed ? trimmed.toUpperCase().split(/\s+/) : allRuleNames;
|
||||
items.forEach((nameUpper) => {
|
||||
(aliasToRuleNames[nameUpper] || []).forEach((ruleName) => {
|
||||
for (const nameUpper of items) {
|
||||
for (const ruleName of (aliasToRuleNames[nameUpper] || [])) {
|
||||
state[ruleName] = enabled;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
return state;
|
||||
}
|
||||
// eslint-disable-next-line jsdoc/require-jsdoc
|
||||
|
|
@ -463,11 +466,11 @@ function getEnabledRulesPerLineNumber(
|
|||
handleInlineConfig([ lines.join("\n") ], configureFile);
|
||||
const effectiveConfig = getEffectiveConfig(
|
||||
ruleList, config, aliasToRuleNames);
|
||||
ruleList.forEach((rule) => {
|
||||
for (const rule of ruleList) {
|
||||
const ruleName = rule.names[0].toUpperCase();
|
||||
allRuleNames.push(ruleName);
|
||||
enabledRules[ruleName] = !!effectiveConfig[ruleName];
|
||||
});
|
||||
}
|
||||
capturedRules = enabledRules;
|
||||
handleInlineConfig(lines, enableDisableFile);
|
||||
handleInlineConfig(lines, captureRestoreEnableDisable, updateLineState);
|
||||
|
|
@ -844,10 +847,10 @@ function lintInput(options, synchronous, callback) {
|
|||
3 : options.resultVersion;
|
||||
const md = markdownIt({ "html": true });
|
||||
const markdownItPlugins = options.markdownItPlugins || [];
|
||||
markdownItPlugins.forEach(function forPlugin(plugin) {
|
||||
for (const plugin of markdownItPlugins) {
|
||||
// @ts-ignore
|
||||
md.use(...plugin);
|
||||
});
|
||||
}
|
||||
const fs = options.fs || require("fs");
|
||||
const results = newResults(ruleList);
|
||||
let done = false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue