299377bc2dddfca2ae75ebcee5b0020ad1df4a64
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / max-lines.js
1 /**
2  * @fileoverview enforce a maximum file length
3  * @author Alberto Rodríguez
4  */
5 "use strict";
6
7 //------------------------------------------------------------------------------
8 // Requirements
9 //------------------------------------------------------------------------------
10
11 const lodash = require("lodash");
12 const astUtils = require("./utils/ast-utils");
13
14 //------------------------------------------------------------------------------
15 // Rule Definition
16 //------------------------------------------------------------------------------
17
18 module.exports = {
19     meta: {
20         type: "suggestion",
21
22         docs: {
23             description: "enforce a maximum number of lines per file",
24             category: "Stylistic Issues",
25             recommended: false,
26             url: "https://eslint.org/docs/rules/max-lines"
27         },
28
29         schema: [
30             {
31                 oneOf: [
32                     {
33                         type: "integer",
34                         minimum: 0
35                     },
36                     {
37                         type: "object",
38                         properties: {
39                             max: {
40                                 type: "integer",
41                                 minimum: 0
42                             },
43                             skipComments: {
44                                 type: "boolean"
45                             },
46                             skipBlankLines: {
47                                 type: "boolean"
48                             }
49                         },
50                         additionalProperties: false
51                     }
52                 ]
53             }
54         ],
55         messages: {
56             exceed: "File has too many lines ({{actual}}). Maximum allowed is {{max}}."
57         }
58     },
59
60     create(context) {
61         const option = context.options[0];
62         let max = 300;
63
64         if (typeof option === "object" && Object.prototype.hasOwnProperty.call(option, "max")) {
65             max = option.max;
66         } else if (typeof option === "number") {
67             max = option;
68         }
69
70         const skipComments = option && option.skipComments;
71         const skipBlankLines = option && option.skipBlankLines;
72
73         const sourceCode = context.getSourceCode();
74
75         /**
76          * Returns whether or not a token is a comment node type
77          * @param {Token} token The token to check
78          * @returns {boolean} True if the token is a comment node
79          */
80         function isCommentNodeType(token) {
81             return token && (token.type === "Block" || token.type === "Line");
82         }
83
84         /**
85          * Returns the line numbers of a comment that don't have any code on the same line
86          * @param {Node} comment The comment node to check
87          * @returns {number[]} The line numbers
88          */
89         function getLinesWithoutCode(comment) {
90             let start = comment.loc.start.line;
91             let end = comment.loc.end.line;
92
93             let token;
94
95             token = comment;
96             do {
97                 token = sourceCode.getTokenBefore(token, { includeComments: true });
98             } while (isCommentNodeType(token));
99
100             if (token && astUtils.isTokenOnSameLine(token, comment)) {
101                 start += 1;
102             }
103
104             token = comment;
105             do {
106                 token = sourceCode.getTokenAfter(token, { includeComments: true });
107             } while (isCommentNodeType(token));
108
109             if (token && astUtils.isTokenOnSameLine(comment, token)) {
110                 end -= 1;
111             }
112
113             if (start <= end) {
114                 return lodash.range(start, end + 1);
115             }
116             return [];
117         }
118
119         return {
120             "Program:exit"() {
121                 let lines = sourceCode.lines.map((text, i) => ({ lineNumber: i + 1, text }));
122
123                 if (skipBlankLines) {
124                     lines = lines.filter(l => l.text.trim() !== "");
125                 }
126
127                 if (skipComments) {
128                     const comments = sourceCode.getAllComments();
129
130                     const commentLines = lodash.flatten(comments.map(comment => getLinesWithoutCode(comment)));
131
132                     lines = lines.filter(l => !lodash.includes(commentLines, l.lineNumber));
133                 }
134
135                 if (lines.length > max) {
136                     context.report({
137                         loc: { line: 1, column: 0 },
138                         messageId: "exceed",
139                         data: {
140                             max,
141                             actual: lines.length
142                         }
143                     });
144                 }
145             }
146         };
147     }
148 };