]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/no-warning-comments.js
2 * @fileoverview Rule that warns about used warning comments
3 * @author Alexander Schmidt <https://github.com/lxanders>
8 const escapeRegExp
= require("escape-string-regexp");
9 const astUtils
= require("./utils/ast-utils");
11 const CHAR_LIMIT
= 40;
13 //------------------------------------------------------------------------------
15 //------------------------------------------------------------------------------
17 /** @type {import('../shared/types').Rule} */
23 description
: "Disallow specified warning terms in comments",
25 url
: "https://eslint.org/docs/rules/no-warning-comments"
39 enum: ["start", "anywhere"]
51 additionalProperties
: false
56 unexpectedComment
: "Unexpected '{{matchedTerm}}' comment: '{{comment}}'."
61 const sourceCode
= context
.getSourceCode(),
62 configuration
= context
.options
[0] || {},
63 warningTerms
= configuration
.terms
|| ["todo", "fixme", "xxx"],
64 location
= configuration
.location
|| "start",
65 decoration
= [...configuration
.decoration
|| []].join(""),
66 selfConfigRegEx
= /\bno-warning-comments\b/u;
69 * Convert a warning term into a RegExp which will match a comment containing that whole word in the specified
70 * location ("start" or "anywhere"). If the term starts or ends with non word characters, then the match will not
71 * require word boundaries on that side.
72 * @param {string} term A term to convert to a RegExp
73 * @returns {RegExp} The term converted to a RegExp
75 function convertToRegExp(term
) {
76 const escaped
= escapeRegExp(term
);
77 const escapedDecoration
= escapeRegExp(decoration
);
80 * When matching at the start, ignore leading whitespace, and
81 * there's no need to worry about word boundaries.
83 * These expressions for the prefix and suffix are designed as follows:
84 * ^ handles any terms at the beginning of a comment.
85 * e.g. terms ["TODO"] matches `//TODO something`
86 * $ handles any terms at the end of a comment
87 * e.g. terms ["TODO"] matches `// something TODO`
88 * \b handles terms preceded/followed by word boundary
89 * e.g. terms: ["!FIX", "FIX!"] matches `// FIX!something` or `// something!FIX`
90 * terms: ["FIX"] matches `// FIX!` or `// !FIX`, but not `// fixed or affix`
93 * [\s]* handles optional leading spaces
94 * e.g. terms ["TODO"] matches `// TODO something`
95 * [\s\*]* (where "\*" is the escaped string of decoration)
96 * handles optional leading spaces or decoration characters (for "start" location only)
97 * e.g. terms ["TODO"] matches `/**** TODO something ... `
99 const wordBoundary
= "\\b";
103 if (location
=== "start") {
104 prefix
= `^[\\s${escapedDecoration}]*`;
105 } else if (/^\w/u.test(term
)) {
106 prefix
= wordBoundary
;
109 const suffix
= /\w$/u.test(term
) ? wordBoundary
: "";
110 const flags
= "iu"; // Case-insensitive with Unicode case folding.
113 * For location "start", the typical regex is:
114 * /^[\s]*ESCAPED_TERM\b/iu.
115 * Or if decoration characters are specified (e.g. "*"), then any of
116 * those characters may appear in any order at the start:
117 * /^[\s\*]*ESCAPED_TERM\b/iu.
119 * For location "anywhere" the typical regex is
120 * /\bESCAPED_TERM\b/iu
122 * If it starts or ends with non-word character, the prefix and suffix are empty, respectively.
124 return new RegExp(`${prefix}${escaped}${suffix}`, flags
);
127 const warningRegExps
= warningTerms
.map(convertToRegExp
);
130 * Checks the specified comment for matches of the configured warning terms and returns the matches.
131 * @param {string} comment The comment which is checked.
132 * @returns {Array} All matched warning terms for this comment.
134 function commentContainsWarningTerm(comment
) {
137 warningRegExps
.forEach((regex
, index
) => {
138 if (regex
.test(comment
)) {
139 matches
.push(warningTerms
[index
]);
147 * Checks the specified node for matching warning comments and reports them.
148 * @param {ASTNode} node The AST node being checked.
149 * @returns {void} undefined.
151 function checkComment(node
) {
152 const comment
= node
.value
;
155 astUtils
.isDirectiveComment(node
) &&
156 selfConfigRegEx
.test(comment
)
161 const matches
= commentContainsWarningTerm(comment
);
163 matches
.forEach(matchedTerm
=> {
164 let commentToDisplay
= "";
165 let truncated
= false;
167 for (const c
of comment
.trim().split(/\s+/u)) {
168 const tmp
= commentToDisplay
? `${commentToDisplay} ${c}` : c
;
170 if (tmp
.length
<= CHAR_LIMIT
) {
171 commentToDisplay
= tmp
;
180 messageId
: "unexpectedComment",
183 comment
: `${commentToDisplay}${
184 truncated ? "..." : ""
193 const comments
= sourceCode
.getAllComments();
196 .filter(token
=> token
.type
!== "Shebang")
197 .forEach(checkComment
);