aboutsummaryrefslogtreecommitdiff
path: root/tools/eslint/lib/rules/no-warning-comments.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/eslint/lib/rules/no-warning-comments.js')
-rw-r--r--tools/eslint/lib/rules/no-warning-comments.js84
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
+ };
+};