blob: 8a955a6130e298b6dfc2115bae0ff444dbc508d4 [file] [log] [blame]
Yang Guo4fd355c2019-09-19 10:59:03 +02001/**
2 * @fileoverview Enforces or disallows inline comments.
3 * @author Greg Cochard
4 */
5"use strict";
6
7const astUtils = require("./utils/ast-utils");
8
9//------------------------------------------------------------------------------
10// Rule Definition
11//------------------------------------------------------------------------------
12
13module.exports = {
14 meta: {
15 type: "suggestion",
16
17 docs: {
18 description: "disallow inline comments after code",
Yang Guo4fd355c2019-09-19 10:59:03 +020019 recommended: false,
20 url: "https://eslint.org/docs/rules/no-inline-comments"
21 },
22
Tim van der Lippe16aca392020-11-13 11:37:13 +000023 schema: [
24 {
25 type: "object",
26 properties: {
27 ignorePattern: {
28 type: "string"
29 }
30 },
31 additionalProperties: false
32 }
33 ],
34
35 messages: {
36 unexpectedInlineComment: "Unexpected comment inline with code."
37 }
Yang Guo4fd355c2019-09-19 10:59:03 +020038 },
39
40 create(context) {
41 const sourceCode = context.getSourceCode();
Tim van der Lippe16aca392020-11-13 11:37:13 +000042 const options = context.options[0];
43 let customIgnoreRegExp;
44
45 if (options && options.ignorePattern) {
46 customIgnoreRegExp = new RegExp(options.ignorePattern, "u");
47 }
Yang Guo4fd355c2019-09-19 10:59:03 +020048
49 /**
50 * Will check that comments are not on lines starting with or ending with code
51 * @param {ASTNode} node The comment node to check
52 * @private
53 * @returns {void}
54 */
55 function testCodeAroundComment(node) {
56
Tim van der Lippec8f6ffd2020-04-06 13:42:00 +010057 const startLine = String(sourceCode.lines[node.loc.start.line - 1]),
58 endLine = String(sourceCode.lines[node.loc.end.line - 1]),
59 preamble = startLine.slice(0, node.loc.start.column).trim(),
60 postamble = endLine.slice(node.loc.end.column).trim(),
61 isPreambleEmpty = !preamble,
62 isPostambleEmpty = !postamble;
Yang Guo4fd355c2019-09-19 10:59:03 +020063
Tim van der Lippec8f6ffd2020-04-06 13:42:00 +010064 // Nothing on both sides
65 if (isPreambleEmpty && isPostambleEmpty) {
66 return;
Yang Guo4fd355c2019-09-19 10:59:03 +020067 }
Tim van der Lippec8f6ffd2020-04-06 13:42:00 +010068
Tim van der Lippe16aca392020-11-13 11:37:13 +000069 // Matches the ignore pattern
70 if (customIgnoreRegExp && customIgnoreRegExp.test(node.value)) {
71 return;
72 }
73
Tim van der Lippec8f6ffd2020-04-06 13:42:00 +010074 // JSX Exception
75 if (
76 (isPreambleEmpty || preamble === "{") &&
77 (isPostambleEmpty || postamble === "}")
78 ) {
79 const enclosingNode = sourceCode.getNodeByRangeIndex(node.range[0]);
80
81 if (enclosingNode && enclosingNode.type === "JSXEmptyExpression") {
82 return;
83 }
84 }
85
86 // Don't report ESLint directive comments
87 if (astUtils.isDirectiveComment(node)) {
88 return;
89 }
90
Tim van der Lippe16aca392020-11-13 11:37:13 +000091 context.report({
92 node,
93 messageId: "unexpectedInlineComment"
94 });
Yang Guo4fd355c2019-09-19 10:59:03 +020095 }
96
97 //--------------------------------------------------------------------------
98 // Public
99 //--------------------------------------------------------------------------
100
101 return {
102 Program() {
Tim van der Lippe16aca392020-11-13 11:37:13 +0000103 sourceCode.getAllComments()
104 .filter(token => token.type !== "Shebang")
105 .forEach(testCodeAroundComment);
Yang Guo4fd355c2019-09-19 10:59:03 +0200106 }
107 };
108 }
109};