2 * @fileoverview enforce a maximum file length
3 * @author Alberto RodrÃguez
7 //------------------------------------------------------------------------------
9 //------------------------------------------------------------------------------
11 const lodash = require("lodash");
12 const astUtils = require("./utils/ast-utils");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
23 description: "enforce a maximum number of lines per file",
24 category: "Stylistic Issues",
26 url: "https://eslint.org/docs/rules/max-lines"
50 additionalProperties: false
57 "File has too many lines ({{actual}}). Maximum allowed is {{max}}."
62 const option = context.options[0];
66 typeof option === "object" &&
67 Object.prototype.hasOwnProperty.call(option, "max")
70 } else if (typeof option === "number") {
74 const skipComments = option && option.skipComments;
75 const skipBlankLines = option && option.skipBlankLines;
77 const sourceCode = context.getSourceCode();
80 * Returns whether or not a token is a comment node type
81 * @param {Token} token The token to check
82 * @returns {boolean} True if the token is a comment node
84 function isCommentNodeType(token) {
85 return token && (token.type === "Block" || token.type === "Line");
89 * Returns the line numbers of a comment that don't have any code on the same line
90 * @param {Node} comment The comment node to check
91 * @returns {number[]} The line numbers
93 function getLinesWithoutCode(comment) {
94 let start = comment.loc.start.line;
95 let end = comment.loc.end.line;
101 token = sourceCode.getTokenBefore(token, {
102 includeComments: true
104 } while (isCommentNodeType(token));
106 if (token && astUtils.isTokenOnSameLine(token, comment)) {
112 token = sourceCode.getTokenAfter(token, {
113 includeComments: true
115 } while (isCommentNodeType(token));
117 if (token && astUtils.isTokenOnSameLine(comment, token)) {
122 return lodash.range(start, end + 1);
129 let lines = sourceCode.lines.map((text, i) => ({
135 * If file ends with a linebreak, `sourceCode.lines` will have one extra empty line at the end.
136 * That isn't a real line, so we shouldn't count it.
138 if (lines.length > 1 && lodash.last(lines).text === "") {
142 if (skipBlankLines) {
143 lines = lines.filter(l => l.text.trim() !== "");
147 const comments = sourceCode.getAllComments();
149 const commentLines = lodash.flatten(
150 comments.map(comment => getLinesWithoutCode(comment))
153 lines = lines.filter(
154 l => !commentLines.includes(l.lineNumber)
158 if (lines.length > max) {
161 line: lines[max].lineNumber,
165 line: sourceCode.lines.length,
166 column: lodash.last(sourceCode.lines).length