diff --git a/lib/rules/max-lines-per-function.js b/lib/rules/max-lines-per-function.js index 5985a739e4b..c1b945ca11a 100644 --- a/lib/rules/max-lines-per-function.js +++ b/lib/rules/max-lines-per-function.js @@ -80,7 +80,7 @@ module.exports = { OPTIONS_OR_INTEGER_SCHEMA ], messages: { - exceed: "{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}." + exceed: "{{name}} has exceeded the limit of lines allowed by {{linesExceed}}. Maximum allowed number of lines per function is {{maxLines}}." } }, @@ -170,18 +170,26 @@ module.exports = { return; } let lineCount = 0; + let comments = 0; + let blankLines = 0; for (let i = node.loc.start.line - 1; i < node.loc.end.line; ++i) { const line = lines[i]; if (skipComments) { if (commentLineNumbers.has(i + 1) && isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))) { + if (lineCount <= maxLines) { + comments++; + } continue; } } if (skipBlankLines) { if (line.match(/^\s*$/u)) { + if (lineCount <= maxLines) { + blankLines++; + } continue; } } @@ -191,11 +199,21 @@ module.exports = { if (lineCount > maxLines) { const name = upperCaseFirst(astUtils.getFunctionNameWithKind(funcNode)); + const linesExceed = lineCount - maxLines; + + const loc = { + start: { + line: node.loc.start.line + maxLines + (comments + blankLines), + column: 0 + }, + end: node.loc.end + }; context.report({ node, + loc, messageId: "exceed", - data: { name, lineCount, maxLines } + data: { name, linesExceed, maxLines } }); } } diff --git a/tests/lib/rules/max-lines-per-function.js b/tests/lib/rules/max-lines-per-function.js index ba01206f4a3..74acab2af2e 100644 --- a/tests/lib/rules/max-lines-per-function.js +++ b/tests/lib/rules/max-lines-per-function.js @@ -199,7 +199,14 @@ if ( x === y ) { code: "function name() {\n}", options: [1], errors: [ - { messageId: "exceed", data: { name: "Function 'name'", lineCount: 2, maxLines: 1 } } + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 1, maxLines: 1 }, + line: 2, + column: 1, + endLine: 2, + endColumn: 2 + } ] }, @@ -208,7 +215,14 @@ if ( x === y ) { code: "var func = function() {\n}", options: [1], errors: [ - { messageId: "exceed", data: { name: "Function", lineCount: 2, maxLines: 1 } } + { + messageId: "exceed", + data: { name: "Function", linesExceed: 1, maxLines: 1 }, + line: 2, + column: 1, + endLine: 2, + endColumn: 2 + } ] }, @@ -217,7 +231,14 @@ if ( x === y ) { code: "const bar = () => {\nconst x = 2 + 1;\nreturn x;\n}", options: [3], errors: [ - { messageId: "exceed", data: { name: "Arrow function", lineCount: 4, maxLines: 3 } } + { + messageId: "exceed", + data: { name: "Arrow function", linesExceed: 1, maxLines: 3 }, + line: 4, + column: 1, + endLine: 4, + endColumn: 2 + } ] }, @@ -226,7 +247,14 @@ if ( x === y ) { code: "const bar = () =>\n 2", options: [1], errors: [ - { messageId: "exceed", data: { name: "Arrow function", lineCount: 2, maxLines: 1 } } + { + messageId: "exceed", + data: { name: "Arrow function", linesExceed: 1, maxLines: 1 }, + line: 2, + column: 1, + endLine: 2, + endColumn: 3 + } ] }, @@ -235,7 +263,14 @@ if ( x === y ) { code: `() => {${"foo\n".repeat(60)}}`, options: [{}], errors: [ - { messageId: "exceed", data: { name: "Arrow function", lineCount: 61, maxLines: 50 } } + { + messageId: "exceed", + data: { name: "Arrow function", linesExceed: 11, maxLines: 50 }, + line: 51, + column: 1, + endLine: 61, + endColumn: 2 + } ] }, @@ -244,7 +279,14 @@ if ( x === y ) { code: "function name() {\nvar x = 5;\n\t\n \n\nvar x = 2;\n}", options: [{ max: 6, skipComments: false, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Function 'name'", lineCount: 7, maxLines: 6 } } + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 1, maxLines: 6 }, + line: 7, + column: 1, + endLine: 7, + endColumn: 2 + } ] }, @@ -253,7 +295,14 @@ if ( x === y ) { code: "function name() {\r\nvar x = 5;\r\n\t\r\n \r\n\r\nvar x = 2;\r\n}", options: [{ max: 6, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Function 'name'", lineCount: 7, maxLines: 6 } } + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 1, maxLines: 6 }, + line: 7, + column: 1, + endLine: 7, + endColumn: 2 + } ] }, @@ -262,7 +311,14 @@ if ( x === y ) { code: "function name() {\nvar x = 5;\n\t\n \n\nvar x = 2;\n}", options: [{ max: 2, skipComments: true, skipBlankLines: true }], errors: [ - { messageId: "exceed", data: { name: "Function 'name'", lineCount: 4, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 2, maxLines: 2 }, + line: 6, + column: 1, + endLine: 7, + endColumn: 2 + } ] }, @@ -271,7 +327,14 @@ if ( x === y ) { code: "function name() {\r\nvar x = 5;\r\n\t\r\n \r\n\r\nvar x = 2;\r\n}", options: [{ max: 2, skipComments: true, skipBlankLines: true }], errors: [ - { messageId: "exceed", data: { name: "Function 'name'", lineCount: 4, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 2, maxLines: 2 }, + line: 6, + column: 1, + endLine: 7, + endColumn: 2 + } ] }, @@ -280,7 +343,14 @@ if ( x === y ) { code: "function name() { // end of line comment\nvar x = 5; /* mid line comment */\n\t// single line comment taking up whole line\n\t\n \n\nvar x = 2;\n}", options: [{ max: 6, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Function 'name'", lineCount: 7, maxLines: 6 } } + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 1, maxLines: 6 }, + line: 8, + column: 1, + endLine: 8, + endColumn: 2 + } ] }, @@ -289,7 +359,14 @@ if ( x === y ) { code: "function name() { // end of line comment\nvar x = 5; /* mid line comment */\n\t// single line comment taking up whole line\n\t\n \n\nvar x = 2;\n}", options: [{ max: 1, skipComments: true, skipBlankLines: true }], errors: [ - { messageId: "exceed", data: { name: "Function 'name'", lineCount: 4, maxLines: 1 } } + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 3, maxLines: 1 }, + line: 2, + column: 1, + endLine: 8, + endColumn: 2 + } ] }, @@ -298,7 +375,14 @@ if ( x === y ) { code: "function name() { // end of line comment\nvar x = 5; /* mid line comment */\n\t// single line comment taking up whole line\n\t\n \n\nvar x = 2;\n}", options: [{ max: 1, skipComments: false, skipBlankLines: true }], errors: [ - { messageId: "exceed", data: { name: "Function 'name'", lineCount: 5, maxLines: 1 } } + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 4, maxLines: 1 }, + line: 2, + column: 1, + endLine: 8, + endColumn: 2 + } ] }, @@ -313,7 +397,14 @@ if ( x === y ) { }`, options: [{ max: 2, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Function 'foo'", lineCount: 7, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Function 'foo'", linesExceed: 5, maxLines: 2 }, + line: 3, + column: 1, + endLine: 7, + endColumn: 2 + } ] }, @@ -328,7 +419,14 @@ function ()`, options: [{ max: 2, skipComments: true, skipBlankLines: false, IIFEs: true }], errors: [ - { messageId: "exceed", data: { name: "Function", lineCount: 4, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Function", linesExceed: 2, maxLines: 2 }, + line: 4, + column: 1, + endLine: 5, + endColumn: 2 + } ] }, @@ -346,7 +444,14 @@ if ( x === y ) { }`, options: [{ max: 9, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Function 'parent'", lineCount: 10, maxLines: 9 } } + { + messageId: "exceed", + data: { name: "Function 'parent'", linesExceed: 1, maxLines: 9 }, + line: 10, + column: 1, + endLine: 10, + endColumn: 2 + } ] }, @@ -364,8 +469,22 @@ if ( x === y ) { }`, options: [{ max: 2, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Function 'parent'", lineCount: 10, maxLines: 2 } }, - { messageId: "exceed", data: { name: "Function 'nested'", lineCount: 4, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Function 'parent'", linesExceed: 8, maxLines: 2 }, + line: 3, + column: 1, + endLine: 10, + endColumn: 2 + }, + { + messageId: "exceed", + data: { name: "Function 'nested'", linesExceed: 2, maxLines: 2 }, + line: 5, + column: 1, + endLine: 6, + endColumn: 2 + } ] }, @@ -380,7 +499,14 @@ if ( x === y ) { }`, options: [{ max: 2, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Method 'method'", lineCount: 5, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Method 'method'", linesExceed: 3, maxLines: 2 }, + line: 4, + column: 1, + endLine: 6, + endColumn: 6 + } ] }, @@ -395,7 +521,14 @@ if ( x === y ) { }`, options: [{ max: 2, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Static method 'foo'", lineCount: 5, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Static method 'foo'", linesExceed: 3, maxLines: 2 }, + line: 4, + column: 1, + endLine: 6, + endColumn: 6 + } ] }, @@ -408,9 +541,16 @@ if ( x === y ) { return 1 } }`, - options: [{ max: 2, skipComments: true, skipBlankLines: false }], + options: [{ max: 4, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Getter 'foo'", lineCount: 5, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Getter 'foo'", linesExceed: 1, maxLines: 4 }, + line: 6, + column: 1, + endLine: 6, + endColumn: 6 + } ] }, @@ -425,7 +565,14 @@ if ( x === y ) { }`, options: [{ max: 2, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Setter 'foo'", lineCount: 5, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Setter 'foo'", linesExceed: 3, maxLines: 2 }, + line: 4, + column: 1, + endLine: 6, + endColumn: 6 + } ] }, @@ -443,7 +590,14 @@ if ( x === y ) { }`, options: [{ max: 2, skipComments: true, skipBlankLines: false }], errors: [ - { messageId: "exceed", data: { name: "Static method", lineCount: 8, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Static method", linesExceed: 6, maxLines: 2 }, + line: 4, + column: 1, + endLine: 9, + endColumn: 6 + } ] }, @@ -458,7 +612,14 @@ if ( x === y ) { }());`, options: [{ max: 2, skipComments: true, skipBlankLines: false, IIFEs: true }], errors: [ - { messageId: "exceed", data: { name: "Function", lineCount: 7, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Function", linesExceed: 5, maxLines: 2 }, + line: 3, + column: 1, + endLine: 7, + endColumn: 2 + } ] }, @@ -473,7 +634,28 @@ if ( x === y ) { })();`, options: [{ max: 2, skipComments: true, skipBlankLines: false, IIFEs: true }], errors: [ - { messageId: "exceed", data: { name: "Arrow function", lineCount: 7, maxLines: 2 } } + { + messageId: "exceed", + data: { name: "Arrow function", linesExceed: 5, maxLines: 2 }, + line: 3, + column: 1, + endLine: 7, + endColumn: 2 + } + ] + }, + { + code: "\nfoo();\nbar();\nbaz();\nfunction name() {\nvar x = 5;\n/* comment 1 */\n/* comment 2 */\n\t\n \n\nvar x = 2;\n}\nquz();", + options: [{ max: 2, skipComments: true, skipBlankLines: true }], + errors: [ + { + messageId: "exceed", + data: { name: "Function 'name'", linesExceed: 2, maxLines: 2 }, + line: 12, + column: 1, + endLine: 13, + endColumn: 2 + } ] } ]