diff --git a/docs/rules/no-inline-comments.md b/docs/rules/no-inline-comments.md index cf6b7b01035..cde77e9e499 100644 --- a/docs/rules/no-inline-comments.md +++ b/docs/rules/no-inline-comments.md @@ -35,3 +35,55 @@ var foo = 5; var bar = 5; //This is a comment below a line of code ``` + +### JSX exception + +Comments inside the curly braces in JSX are allowed to be on the same line as the braces, but only if they are not on the same line with other code, and the braces do not enclose an actual expression. + +Examples of **incorrect** code for this rule: + +```js +/*eslint no-inline-comments: "error"*/ + +var foo =
{ /* On the same line with other code */ }

Some heading

; + +var bar = ( +
+ { // These braces are not just for the comment, so it can't be on the same line + baz + } +
+); +``` + +Examples of **correct** code for this rule: + +```js +/*eslint no-inline-comments: "error"*/ + +var foo = ( +
+ {/* These braces are just for this comment and there is nothing else on this line */} +

Some heading

+
+) + +var bar = ( +
+ { + // There is nothing else on this line + baz + } +
+); + +var quux = ( +
+ {/* + Multiline + comment + */} +

Some heading

+
+) +``` diff --git a/lib/rules/no-inline-comments.js b/lib/rules/no-inline-comments.js index b35db114100..bd226ecc35f 100644 --- a/lib/rules/no-inline-comments.js +++ b/lib/rules/no-inline-comments.js @@ -35,22 +35,36 @@ module.exports = { */ function testCodeAroundComment(node) { - // Get the whole line and cut it off at the start of the comment - const startLine = String(sourceCode.lines[node.loc.start.line - 1]); - const endLine = String(sourceCode.lines[node.loc.end.line - 1]); + const startLine = String(sourceCode.lines[node.loc.start.line - 1]), + endLine = String(sourceCode.lines[node.loc.end.line - 1]), + preamble = startLine.slice(0, node.loc.start.column).trim(), + postamble = endLine.slice(node.loc.end.column).trim(), + isPreambleEmpty = !preamble, + isPostambleEmpty = !postamble; - const preamble = startLine.slice(0, node.loc.start.column).trim(); + // Nothing on both sides + if (isPreambleEmpty && isPostambleEmpty) { + return; + } - // Also check after the comment - const postamble = endLine.slice(node.loc.end.column).trim(); + // JSX Exception + if ( + (isPreambleEmpty || preamble === "{") && + (isPostambleEmpty || postamble === "}") + ) { + const enclosingNode = sourceCode.getNodeByRangeIndex(node.range[0]); - // Check that this comment isn't an ESLint directive - const isDirective = astUtils.isDirectiveComment(node); + if (enclosingNode && enclosingNode.type === "JSXEmptyExpression") { + return; + } + } - // Should be empty if there was only whitespace around the comment - if (!isDirective && (preamble || postamble)) { - context.report({ node, message: "Unexpected comment inline with code." }); + // Don't report ESLint directive comments + if (astUtils.isDirectiveComment(node)) { + return; } + + context.report({ node, message: "Unexpected comment inline with code." }); } //-------------------------------------------------------------------------- diff --git a/tests/lib/rules/no-inline-comments.js b/tests/lib/rules/no-inline-comments.js index 6af30d12b94..6a6f5a8ef0a 100644 --- a/tests/lib/rules/no-inline-comments.js +++ b/tests/lib/rules/no-inline-comments.js @@ -15,7 +15,13 @@ const rule = require("../../../lib/rules/no-inline-comments"), // Tests //------------------------------------------------------------------------------ -const ruleTester = new RuleTester(), +const ruleTester = new RuleTester({ + parserOptions: { + ecmaFeatures: { + jsx: true + } + } + }), lineError = { message: "Unexpected comment inline with code.", type: "Line" @@ -32,7 +38,57 @@ ruleTester.run("no-inline-comments", rule, { "var a = 2;\n// A valid comment after code", "// A solitary comment", "var a = 1; // eslint-disable-line no-debugger", - "var a = 1; /* eslint-disable-line no-debugger */" + "var a = 1; /* eslint-disable-line no-debugger */", + + // JSX exception + `var a = ( +
+ {/*comment*/} +
+ )`, + `var a = ( +
+ { /* comment */ } +

Some heading

+
+ )`, + `var a = ( +
+ {// comment + } +
+ )`, + `var a = ( +
+ { // comment + } +
+ )`, + `var a = ( +
+ {/* comment 1 */ + /* comment 2 */} +
+ )`, + `var a = ( +
+ {/* + * comment 1 + */ + /* + * comment 2 + */} +
+ )`, + `var a = ( +
+ {/* + multi + line + comment + */} +
+ )` ], invalid: [ @@ -55,7 +111,240 @@ ruleTester.run("no-inline-comments", rule, { { code: "var a = 4;\n/**A\n * block\n * comment\n * inline\n * between\n * code*/ var foo = a;", errors: [blockError] + }, + { + code: "var a = \n{/**/}", + errors: [blockError] + }, + + // JSX + { + code: `var a = ( +
{/* comment */}
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
{// comment + } +
+ )`, + errors: [lineError] + }, + { + code: `var a = ( +
{/* comment */ + } +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
{/* + * comment + */ + } +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
{/* + * comment + */} +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
{/* + * comment + */}
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ {/* + * comment + */}
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { + /* + * comment + */}
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { + /* comment */}
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ {b/* comment */} +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ {/* comment */b} +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ {// comment + b + } +
+ )`, + errors: [lineError] + }, + { + code: `var a = ( +
+ {/* comment */ + b + } +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ {/* + * comment + */ + b + } +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { + b// comment + } +
+ )`, + errors: [lineError] + }, + { + code: `var a = ( +
+ { + /* comment */b + } +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { + b/* comment */ + } +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { + b + /* + * comment + */} +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { + b + /* comment */} +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { + { /* this is an empty object literal, not braces for js code! */ } + } +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { + {// comment + } + } +
+ )`, + errors: [lineError] + }, + { + code: `var a = ( +
+ { + { + /* comment */} + } +
+ )`, + errors: [blockError] + }, + { + code: `var a = ( +
+ { /* two comments on the same line... */ /* ...are not allowed, same as with a non-JSX code */} +
+ )`, + errors: [blockError, blockError] + }, + { + code: `var a = ( +
+ { + /* overlapping + */ /* + lines */ + } +
+ )`, + errors: [blockError, blockError] } ] - });