diff --git a/lib/rules/max-len.js b/lib/rules/max-len.js
index b29099ed4c4..82229c3be48 100644
--- a/lib/rules/max-len.js
+++ b/lib/rules/max-len.js
@@ -183,6 +183,21 @@ module.exports = {
(end.line > lineNumber || (end.line === lineNumber && end.column === line.length));
}
+ /**
+ * Check if a node is a JSXEmptyExpression contained in a single line JSXExpressionContainer.
+ * @param {ASTNode} node A node to check.
+ * @returns {boolean} True if the node is a JSXEmptyExpression contained in a single line JSXExpressionContainer.
+ */
+ function isJSXEmptyExpressionInSingleLineContainer(node) {
+ if (!node || !node.parent || node.type !== "JSXEmptyExpression" || node.parent.type !== "JSXExpressionContainer") {
+ return false;
+ }
+
+ const parent = node.parent;
+
+ return parent.loc.start.line === parent.loc.end.line;
+ }
+
/**
* Gets the line after the comment and any remaining trailing whitespace is
* stripped.
@@ -252,6 +267,33 @@ module.exports = {
return acc;
}
+ /**
+ * Returns an array of all comments in the source code.
+ * If the element in the array is a JSXEmptyExpression contained with a single line JSXExpressionContainer,
+ * the element is changed with JSXExpressionContainer node.
+ * @returns {ASTNode[]} An array of comment nodes
+ */
+ function getAllComments() {
+ const comments = [];
+
+ sourceCode.getAllComments()
+ .forEach(commentNode => {
+ const containingNode = sourceCode.getNodeByRangeIndex(commentNode.range[0]);
+
+ if (isJSXEmptyExpressionInSingleLineContainer(containingNode)) {
+
+ // push a unique node only
+ if (comments[comments.length - 1] !== containingNode.parent) {
+ comments.push(containingNode.parent);
+ }
+ } else {
+ comments.push(commentNode);
+ }
+ });
+
+ return comments;
+ }
+
/**
* Check the program for max length
* @param {ASTNode} node Node to examine
@@ -264,7 +306,7 @@ module.exports = {
const lines = sourceCode.lines,
// list of comments to ignore
- comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? sourceCode.getAllComments() : [];
+ comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? getAllComments() : [];
// we iterate over comments in parallel with the lines
let commentsIndex = 0;
diff --git a/tests/lib/rules/max-len.js b/tests/lib/rules/max-len.js
index 99822ccaef0..f6296b636b9 100644
--- a/tests/lib/rules/max-len.js
+++ b/tests/lib/rules/max-len.js
@@ -195,6 +195,140 @@ ruleTester.run("max-len", rule, {
{
code: "\tfoo",
options: [4, { tabWidth: 0 }]
+ },
+
+ // https://github.com/eslint/eslint/issues/12213
+ {
+ code: "var jsx = (<>\n" +
+ " { /* this line has 38 characters */}\n" +
+ ">)",
+ options: [15, { comments: 38 }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ "\t\t{ /* this line has 40 characters */}\n" +
+ ">)",
+ options: [15, 4, { comments: 44 }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " <> text >{ /* this line has 49 characters */}\n" +
+ ">)",
+ options: [13, { ignoreComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line has 44 characters */}\n" +
+ ">)",
+ options: [44, { comments: 37 }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line has 44 characters */}\n" +
+ ">)",
+ options: [37, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = ;",
+ options: [57],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = ;",
+ options: [57],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = ;",
+ options: [50],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " <> > {/* this line with two separate comments */} {/* have 80 characters */}\n" +
+ ">)",
+ options: [80],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line with two separate comments */} {/* have 80 characters */}\n" +
+ ">)",
+ options: [37, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line with two separate comments */} {/* have 80 characters */}\n" +
+ ">)",
+ options: [37, { ignoreComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line with two separate comments */} {/* have > 80 characters */ /* another comment in same braces */}\n" +
+ ">)",
+ options: [37, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line with two separate comments */} {/* have > 80 characters */ /* another comment in same braces */}\n" +
+ ">)",
+ options: [37, { ignoreComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/*\n" +
+ " this line has 34 characters\n" +
+ " */}\n" +
+ ">)",
+ options: [33, { comments: 34 }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/*\n" +
+ " this line has 34 characters\n" +
+ " */}\n" +
+ ">)",
+ options: [33, { ignoreComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {a & b /* this line has 34 characters\n" +
+ " */}\n" +
+ ">)",
+ options: [33, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {a & b /* this line has 34 characters\n" +
+ " */}\n" +
+ ">)",
+ options: [33, { ignoreComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } }
}
],
@@ -650,6 +784,321 @@ ruleTester.run("max-len", rule, {
column: 1
}
]
+ },
+
+ // https://github.com/eslint/eslint/issues/12213
+ {
+ code: "var jsx = (<>\n" +
+ " { /* this line has 38 characters */}\n" +
+ ">)",
+ options: [15, { comments: 37 }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "maxComment",
+ data: { lineLength: 38, maxCommentLength: 37 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ "\t\t{ /* this line has 40 characters */}\n" +
+ ">)",
+ options: [15, 4, { comments: 40 }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "maxComment",
+ data: { lineLength: 44, maxCommentLength: 40 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ "{ 38/* this line has 38 characters */}\n" +
+ ">)",
+ options: [15, { comments: 38 }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 38, maxLength: 15 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ "{ 38/* this line has 38 characters */}\n" +
+ ">)",
+ options: [37, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 38, maxLength: 37 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ "{ 38/* this line has 38 characters */}\n" +
+ ">)",
+ options: [37, { ignoreComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 38, maxLength: 37 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " <> 50 >{ 50/* this line has 50 characters */}\n" +
+ ">)",
+ options: [49, { comments: 100 }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 50, maxLength: 49 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 44 characters */}\n" +
+ " <> > {/* this line has 44 characters */}\n" +
+ ">)",
+ options: [37, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 44, maxLength: 37 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = ;",
+ options: [56],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 57, maxLength: 56 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = ;",
+ options: [56],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 57, maxLength: 56 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = ;",
+ options: [55, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 56, maxLength: 55 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = ;",
+ options: [30, { comments: 44 }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 51, maxLength: 30 },
+ type: "Program",
+ line: 3,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line with two separate comments */} {/* have 80 characters */}\n" +
+ ">)",
+ options: [79],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 80, maxLength: 79 },
+ type: "Program",
+ line: 3,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " <> > {/* this line with two separate comments */} {/* have 87 characters */} <> >\n" +
+ ">)",
+ options: [85, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 87, maxLength: 85 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line with two separate comments */} {/* have 87 characters */} <> >\n" +
+ ">)",
+ options: [37, { ignoreComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 87, maxLength: 37 },
+ type: "Program",
+ line: 3,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this line with two separate comments */} {/* have > 80 characters */ /* another comment in same braces */}\n" +
+ ">)",
+ options: [37],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 119, maxLength: 37 },
+ type: "Program",
+ line: 3,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this is not treated as a comment */ a & b} {/* trailing */ /* comments */}\n" +
+ ">)",
+ options: [37, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 55, maxLength: 37 },
+ type: "Program",
+ line: 3,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ " {/* this line has 37 characters */}\n" +
+ " <> > {/* this is not treated as a comment */ a & b} {/* trailing */ /* comments */}\n" +
+ ">)",
+ options: [37, { ignoreComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 55, maxLength: 37 },
+ type: "Program",
+ line: 3,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ "12345678901234{/*\n" +
+ "*/}\n" +
+ ">)",
+ options: [14, { ignoreTrailingComments: true }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 15, maxLength: 14 },
+ type: "Program",
+ line: 2,
+ column: 1
+ }
+ ]
+ },
+ {
+ code: "var jsx = (<>\n" +
+ "{/*\n" +
+ "this line has 31 characters */}\n" +
+ ">)",
+ options: [30, { comments: 100 }],
+ parserOptions: { ecmaFeatures: { jsx: true } },
+ errors: [
+ {
+ messageId: "max",
+ data: { lineLength: 31, maxLength: 30 },
+ type: "Program",
+ line: 3,
+ column: 1
+ }
+ ]
}
]
});