mirror of
https://github.com/DavidAnson/markdownlint.git
synced 2025-12-17 06:20:12 +01:00
Refactor lintContent to do less processing of errors for each rule and instead handle all errors at the end.
This commit is contained in:
parent
e531bd6359
commit
d3c56d3ab8
2 changed files with 119 additions and 143 deletions
|
|
@ -1306,35 +1306,6 @@ function getEnabledRulesPerLineNumber(ruleList, lines, frontMatterLines, noInlin
|
||||||
enabledRulesPerLineNumber: enabledRulesPerLineNumber
|
enabledRulesPerLineNumber: enabledRulesPerLineNumber
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
* Compare function for Array.prototype.sort for ascending order of errors.
|
|
||||||
*
|
|
||||||
* @param {LintError} a First error.
|
|
||||||
* @param {LintError} b Second error.
|
|
||||||
* @returns {number} Positive value if a>b, negative value if b<a, 0 otherwise.
|
|
||||||
*/
|
|
||||||
function lineNumberComparison(a, b) {
|
|
||||||
return a.lineNumber - b.lineNumber;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Filter function to include everything.
|
|
||||||
*
|
|
||||||
* @returns {boolean} True.
|
|
||||||
*/
|
|
||||||
function filterAllValues() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Function to return unique values from a sorted errors array.
|
|
||||||
*
|
|
||||||
* @param {LintError} value Error instance.
|
|
||||||
* @param {number} index Index in array.
|
|
||||||
* @param {LintError[]} array Array of errors.
|
|
||||||
* @returns {boolean} Filter value.
|
|
||||||
*/
|
|
||||||
function uniqueFilterForSortedErrors(value, index, array) {
|
|
||||||
return (index === 0) || (value.lineNumber > array[index - 1].lineNumber);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* Lints a string containing Markdown content.
|
* Lints a string containing Markdown content.
|
||||||
*
|
*
|
||||||
|
|
@ -1375,7 +1346,7 @@ function lintContent(ruleList, name, content, md, config, frontMatter, handleRul
|
||||||
cache.flattenedLists(helpers.flattenLists(params.tokens));
|
cache.flattenedLists(helpers.flattenLists(params.tokens));
|
||||||
cache.codeBlockAndSpanRanges(helpers.codeBlockAndSpanRanges(params, cache.lineMetadata()));
|
cache.codeBlockAndSpanRanges(helpers.codeBlockAndSpanRanges(params, cache.lineMetadata()));
|
||||||
// Function to run for each rule
|
// Function to run for each rule
|
||||||
var result = (resultVersion === 0) ? {} : [];
|
var results = [];
|
||||||
// eslint-disable-next-line jsdoc/require-jsdoc
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
||||||
function forRule(rule) {
|
function forRule(rule) {
|
||||||
// Configure rule
|
// Configure rule
|
||||||
|
|
@ -1463,7 +1434,7 @@ function lintContent(ruleList, name, content, md, config, frontMatter, handleRul
|
||||||
"fixInfo": fixInfo ? cleanFixInfo : null
|
"fixInfo": fixInfo ? cleanFixInfo : null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Call (possibly external) rule function
|
// Call (possibly external) rule function to report errors
|
||||||
if (handleRuleFailures) {
|
if (handleRuleFailures) {
|
||||||
try {
|
try {
|
||||||
rule.function(params, onError);
|
rule.function(params, onError);
|
||||||
|
|
@ -1480,46 +1451,20 @@ function lintContent(ruleList, name, content, md, config, frontMatter, handleRul
|
||||||
}
|
}
|
||||||
// Record any errors (significant performance benefit from length check)
|
// Record any errors (significant performance benefit from length check)
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
errors.sort(lineNumberComparison);
|
|
||||||
var filteredErrors = errors
|
var filteredErrors = errors
|
||||||
.filter((resultVersion === 3) ?
|
.filter(function (error) { return (enabledRulesPerLineNumber[error.lineNumber][ruleName]); })
|
||||||
filterAllValues :
|
.map(function (error) { return ({
|
||||||
uniqueFilterForSortedErrors)
|
"lineNumber": error.lineNumber,
|
||||||
.filter(function removeDisabledRules(error) {
|
"ruleName": rule.names[0],
|
||||||
return enabledRulesPerLineNumber[error.lineNumber][ruleName];
|
"ruleNames": rule.names,
|
||||||
})
|
"ruleDescription": rule.description,
|
||||||
.map(function formatResults(error) {
|
"ruleInformation": rule.information ? rule.information.href : null,
|
||||||
if (resultVersion === 0) {
|
"errorDetail": error.detail,
|
||||||
return error.lineNumber;
|
"errorContext": error.context,
|
||||||
}
|
"errorRange": error.range,
|
||||||
var errorObject = {};
|
"fixInfo": error.fixInfo
|
||||||
errorObject.lineNumber = error.lineNumber;
|
}); });
|
||||||
if (resultVersion === 1) {
|
Array.prototype.push.apply(results, filteredErrors);
|
||||||
errorObject.ruleName = ruleNameFriendly;
|
|
||||||
errorObject.ruleAlias = rule.names[1] || rule.names[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
errorObject.ruleNames = rule.names;
|
|
||||||
}
|
|
||||||
errorObject.ruleDescription = rule.description;
|
|
||||||
errorObject.ruleInformation =
|
|
||||||
rule.information ? rule.information.href : null;
|
|
||||||
errorObject.errorDetail = error.detail;
|
|
||||||
errorObject.errorContext = error.context;
|
|
||||||
errorObject.errorRange = error.range;
|
|
||||||
if (resultVersion === 3) {
|
|
||||||
errorObject.fixInfo = error.fixInfo;
|
|
||||||
}
|
|
||||||
return errorObject;
|
|
||||||
});
|
|
||||||
if (filteredErrors.length > 0) {
|
|
||||||
if (resultVersion === 0) {
|
|
||||||
result[ruleNameFriendly] = filteredErrors;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Array.prototype.push.apply(result, filteredErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Run all rules
|
// Run all rules
|
||||||
|
|
@ -1531,7 +1476,50 @@ function lintContent(ruleList, name, content, md, config, frontMatter, handleRul
|
||||||
return callback(error);
|
return callback(error);
|
||||||
}
|
}
|
||||||
cache.clear();
|
cache.clear();
|
||||||
return callback(null, result);
|
// Sort results by rule name by line number
|
||||||
|
results.sort(function (a, b) { return (a.ruleName.localeCompare(b.ruleName) ||
|
||||||
|
a.lineNumber - b.lineNumber); });
|
||||||
|
if (resultVersion < 3) {
|
||||||
|
// Remove fixInfo and multiple errors for the same rule and line number
|
||||||
|
var noPrevious_1 = {
|
||||||
|
"ruleName": null,
|
||||||
|
"lineNumber": -1
|
||||||
|
};
|
||||||
|
results = results.filter(function (error, index, array) {
|
||||||
|
delete error.fixInfo;
|
||||||
|
var previous = array[index - 1] || noPrevious_1;
|
||||||
|
return ((error.ruleName !== previous.ruleName) ||
|
||||||
|
(error.lineNumber !== previous.lineNumber));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (resultVersion === 0) {
|
||||||
|
// Return a dictionary of rule->[line numbers]
|
||||||
|
var dictionary = {};
|
||||||
|
for (var _i = 0, results_1 = results; _i < results_1.length; _i++) {
|
||||||
|
var error = results_1[_i];
|
||||||
|
var ruleLines = dictionary[error.ruleName] || [];
|
||||||
|
ruleLines.push(error.lineNumber);
|
||||||
|
dictionary[error.ruleName] = ruleLines;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
results = dictionary;
|
||||||
|
}
|
||||||
|
else if (resultVersion === 1) {
|
||||||
|
// Use ruleAlias instead of ruleNames
|
||||||
|
for (var _b = 0, results_2 = results; _b < results_2.length; _b++) {
|
||||||
|
var error = results_2[_b];
|
||||||
|
error.ruleAlias = error.ruleNames[1] || error.ruleName;
|
||||||
|
delete error.ruleNames;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// resultVersion 2 or 3: Remove unwanted ruleName
|
||||||
|
for (var _c = 0, results_3 = results; _c < results_3.length; _c++) {
|
||||||
|
var error = results_3[_c];
|
||||||
|
delete error.ruleName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return callback(null, results);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Lints a file containing Markdown content.
|
* Lints a file containing Markdown content.
|
||||||
|
|
|
||||||
|
|
@ -416,38 +416,6 @@ function getEnabledRulesPerLineNumber(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Compare function for Array.prototype.sort for ascending order of errors.
|
|
||||||
*
|
|
||||||
* @param {LintError} a First error.
|
|
||||||
* @param {LintError} b Second error.
|
|
||||||
* @returns {number} Positive value if a>b, negative value if b<a, 0 otherwise.
|
|
||||||
*/
|
|
||||||
function lineNumberComparison(a, b) {
|
|
||||||
return a.lineNumber - b.lineNumber;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter function to include everything.
|
|
||||||
*
|
|
||||||
* @returns {boolean} True.
|
|
||||||
*/
|
|
||||||
function filterAllValues() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function to return unique values from a sorted errors array.
|
|
||||||
*
|
|
||||||
* @param {LintError} value Error instance.
|
|
||||||
* @param {number} index Index in array.
|
|
||||||
* @param {LintError[]} array Array of errors.
|
|
||||||
* @returns {boolean} Filter value.
|
|
||||||
*/
|
|
||||||
function uniqueFilterForSortedErrors(value, index, array) {
|
|
||||||
return (index === 0) || (value.lineNumber > array[index - 1].lineNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lints a string containing Markdown content.
|
* Lints a string containing Markdown content.
|
||||||
*
|
*
|
||||||
|
|
@ -508,7 +476,7 @@ function lintContent(
|
||||||
helpers.codeBlockAndSpanRanges(params, cache.lineMetadata())
|
helpers.codeBlockAndSpanRanges(params, cache.lineMetadata())
|
||||||
);
|
);
|
||||||
// Function to run for each rule
|
// Function to run for each rule
|
||||||
const result = (resultVersion === 0) ? {} : [];
|
let results = [];
|
||||||
// eslint-disable-next-line jsdoc/require-jsdoc
|
// eslint-disable-next-line jsdoc/require-jsdoc
|
||||||
function forRule(rule) {
|
function forRule(rule) {
|
||||||
// Configure rule
|
// Configure rule
|
||||||
|
|
@ -597,7 +565,7 @@ function lintContent(
|
||||||
"fixInfo": fixInfo ? cleanFixInfo : null
|
"fixInfo": fixInfo ? cleanFixInfo : null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// Call (possibly external) rule function
|
// Call (possibly external) rule function to report errors
|
||||||
if (handleRuleFailures) {
|
if (handleRuleFailures) {
|
||||||
try {
|
try {
|
||||||
rule.function(params, onError);
|
rule.function(params, onError);
|
||||||
|
|
@ -612,44 +580,22 @@ function lintContent(
|
||||||
}
|
}
|
||||||
// Record any errors (significant performance benefit from length check)
|
// Record any errors (significant performance benefit from length check)
|
||||||
if (errors.length > 0) {
|
if (errors.length > 0) {
|
||||||
errors.sort(lineNumberComparison);
|
|
||||||
const filteredErrors = errors
|
const filteredErrors = errors
|
||||||
.filter((resultVersion === 3) ?
|
.filter((error) => (
|
||||||
filterAllValues :
|
enabledRulesPerLineNumber[error.lineNumber][ruleName]
|
||||||
uniqueFilterForSortedErrors)
|
))
|
||||||
.filter(function removeDisabledRules(error) {
|
.map((error) => ({
|
||||||
return enabledRulesPerLineNumber[error.lineNumber][ruleName];
|
"lineNumber": error.lineNumber,
|
||||||
})
|
"ruleName": rule.names[0],
|
||||||
.map(function formatResults(error) {
|
"ruleNames": rule.names,
|
||||||
if (resultVersion === 0) {
|
"ruleDescription": rule.description,
|
||||||
return error.lineNumber;
|
"ruleInformation": rule.information ? rule.information.href : null,
|
||||||
}
|
"errorDetail": error.detail,
|
||||||
const errorObject = {};
|
"errorContext": error.context,
|
||||||
errorObject.lineNumber = error.lineNumber;
|
"errorRange": error.range,
|
||||||
if (resultVersion === 1) {
|
"fixInfo": error.fixInfo
|
||||||
errorObject.ruleName = ruleNameFriendly;
|
}));
|
||||||
errorObject.ruleAlias = rule.names[1] || rule.names[0];
|
Array.prototype.push.apply(results, filteredErrors);
|
||||||
} else {
|
|
||||||
errorObject.ruleNames = rule.names;
|
|
||||||
}
|
|
||||||
errorObject.ruleDescription = rule.description;
|
|
||||||
errorObject.ruleInformation =
|
|
||||||
rule.information ? rule.information.href : null;
|
|
||||||
errorObject.errorDetail = error.detail;
|
|
||||||
errorObject.errorContext = error.context;
|
|
||||||
errorObject.errorRange = error.range;
|
|
||||||
if (resultVersion === 3) {
|
|
||||||
errorObject.fixInfo = error.fixInfo;
|
|
||||||
}
|
|
||||||
return errorObject;
|
|
||||||
});
|
|
||||||
if (filteredErrors.length > 0) {
|
|
||||||
if (resultVersion === 0) {
|
|
||||||
result[ruleNameFriendly] = filteredErrors;
|
|
||||||
} else {
|
|
||||||
Array.prototype.push.apply(result, filteredErrors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Run all rules
|
// Run all rules
|
||||||
|
|
@ -660,7 +606,49 @@ function lintContent(
|
||||||
return callback(error);
|
return callback(error);
|
||||||
}
|
}
|
||||||
cache.clear();
|
cache.clear();
|
||||||
return callback(null, result);
|
// Sort results by rule name by line number
|
||||||
|
results.sort((a, b) => (
|
||||||
|
a.ruleName.localeCompare(b.ruleName) ||
|
||||||
|
a.lineNumber - b.lineNumber
|
||||||
|
));
|
||||||
|
if (resultVersion < 3) {
|
||||||
|
// Remove fixInfo and multiple errors for the same rule and line number
|
||||||
|
const noPrevious = {
|
||||||
|
"ruleName": null,
|
||||||
|
"lineNumber": -1
|
||||||
|
};
|
||||||
|
results = results.filter((error, index, array) => {
|
||||||
|
delete error.fixInfo;
|
||||||
|
const previous = array[index - 1] || noPrevious;
|
||||||
|
return (
|
||||||
|
(error.ruleName !== previous.ruleName) ||
|
||||||
|
(error.lineNumber !== previous.lineNumber)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (resultVersion === 0) {
|
||||||
|
// Return a dictionary of rule->[line numbers]
|
||||||
|
const dictionary = {};
|
||||||
|
for (const error of results) {
|
||||||
|
const ruleLines = dictionary[error.ruleName] || [];
|
||||||
|
ruleLines.push(error.lineNumber);
|
||||||
|
dictionary[error.ruleName] = ruleLines;
|
||||||
|
}
|
||||||
|
// @ts-ignore
|
||||||
|
results = dictionary;
|
||||||
|
} else if (resultVersion === 1) {
|
||||||
|
// Use ruleAlias instead of ruleNames
|
||||||
|
for (const error of results) {
|
||||||
|
error.ruleAlias = error.ruleNames[1] || error.ruleName;
|
||||||
|
delete error.ruleNames;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// resultVersion 2 or 3: Remove unwanted ruleName
|
||||||
|
for (const error of results) {
|
||||||
|
delete error.ruleName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return callback(null, results);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue