• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
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",
19            category: "Stylistic Issues",
20            recommended: false,
21            url: "https://eslint.org/docs/rules/no-inline-comments"
22        },
23
24        schema: [
25            {
26                type: "object",
27                properties: {
28                    ignorePattern: {
29                        type: "string"
30                    }
31                },
32                additionalProperties: false
33            }
34        ],
35
36        messages: {
37            unexpectedInlineComment: "Unexpected comment inline with code."
38        }
39    },
40
41    create(context) {
42        const sourceCode = context.getSourceCode();
43        const options = context.options[0];
44        let customIgnoreRegExp;
45
46        if (options && options.ignorePattern) {
47            customIgnoreRegExp = new RegExp(options.ignorePattern, "u");
48        }
49
50        /**
51         * Will check that comments are not on lines starting with or ending with code
52         * @param {ASTNode} node The comment node to check
53         * @private
54         * @returns {void}
55         */
56        function testCodeAroundComment(node) {
57
58            const startLine = String(sourceCode.lines[node.loc.start.line - 1]),
59                endLine = String(sourceCode.lines[node.loc.end.line - 1]),
60                preamble = startLine.slice(0, node.loc.start.column).trim(),
61                postamble = endLine.slice(node.loc.end.column).trim(),
62                isPreambleEmpty = !preamble,
63                isPostambleEmpty = !postamble;
64
65            // Nothing on both sides
66            if (isPreambleEmpty && isPostambleEmpty) {
67                return;
68            }
69
70            // Matches the ignore pattern
71            if (customIgnoreRegExp && customIgnoreRegExp.test(node.value)) {
72                return;
73            }
74
75            // JSX Exception
76            if (
77                (isPreambleEmpty || preamble === "{") &&
78                (isPostambleEmpty || postamble === "}")
79            ) {
80                const enclosingNode = sourceCode.getNodeByRangeIndex(node.range[0]);
81
82                if (enclosingNode && enclosingNode.type === "JSXEmptyExpression") {
83                    return;
84                }
85            }
86
87            // Don't report ESLint directive comments
88            if (astUtils.isDirectiveComment(node)) {
89                return;
90            }
91
92            context.report({
93                node,
94                messageId: "unexpectedInlineComment"
95            });
96        }
97
98        //--------------------------------------------------------------------------
99        // Public
100        //--------------------------------------------------------------------------
101
102        return {
103            Program() {
104                sourceCode.getAllComments()
105                    .filter(token => token.type !== "Shebang")
106                    .forEach(testCodeAroundComment);
107            }
108        };
109    }
110};
111