diff options
Diffstat (limited to 'tools/eslint/lib/rules/no-warning-comments.js')
-rw-r--r-- | tools/eslint/lib/rules/no-warning-comments.js | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/tools/eslint/lib/rules/no-warning-comments.js b/tools/eslint/lib/rules/no-warning-comments.js new file mode 100644 index 0000000000..58b6764ff1 --- /dev/null +++ b/tools/eslint/lib/rules/no-warning-comments.js @@ -0,0 +1,84 @@ +/** + * @fileoverview Rule that warns about used warning comments + * @author Alexander Schmidt <https://github.com/lxanders> + */ + +"use strict"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = function (context) { + + var configuration = context.options[0] || {}, + warningTerms = configuration.terms || ["todo", "fixme", "xxx"], + location = configuration.location || "start", + warningRegExps; + + /** + * Convert a warning term into a RegExp which will match a comment containing that whole word in the specified + * location ("start" or "anywhere"). If the term starts or ends with non word characters, then the match will not + * require word boundaries on that side. + * + * @param {String} term A term to convert to a RegExp + * @returns {RegExp} The term converted to a RegExp + */ + function convertToRegExp(term) { + var escaped = term.replace(/[-\/\\$\^*+?.()|\[\]{}]/g, "\\$&"), + // If the term ends in a word character (a-z0-9_), ensure a word boundary at the end, so that substrings do + // not get falsely matched. eg "todo" in a string such as "mastodon". + // If the term ends in a non-word character, then \b won't match on the boundary to the next non-word + // character, which would likely be a space. For example `/\bFIX!\b/.test('FIX! blah') === false`. + // In these cases, use no bounding match. Same applies for the prefix, handled below. + suffix = /\w$/.test(term) ? "\\b" : "", + prefix; + + if (location === "start") { + // When matching at the start, ignore leading whitespace, and there's no need to worry about word boundaries + prefix = "^\\s*"; + } else if (/^\w/.test(term)) { + prefix = "\\b"; + } else { + prefix = ""; + } + + return new RegExp(prefix + escaped + suffix, "i"); + } + + /** + * Checks the specified comment for matches of the configured warning terms and returns the matches. + * @param {String} comment The comment which is checked. + * @returns {Array} All matched warning terms for this comment. + */ + function commentContainsWarningTerm(comment) { + var matches = []; + + warningRegExps.forEach(function (regex, index) { + if (regex.test(comment)) { + matches.push(warningTerms[index]); + } + }); + + return matches; + } + + /** + * Checks the specified node for matching warning comments and reports them. + * @param {ASTNode} node The AST node being checked. + * @returns {void} undefined. + */ + function checkComment(node) { + var matches = commentContainsWarningTerm(node.value); + + matches.forEach(function (matchedTerm) { + context.report(node, "Unexpected " + matchedTerm + " comment."); + }); + } + + warningRegExps = warningTerms.map(convertToRegExp); + return { + "BlockComment": checkComment, + "LineComment": checkComment + }; +}; |