source: imaps-frontend/node_modules/eslint/lib/rules/padded-blocks.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/**
2 * @fileoverview A rule to ensure blank lines within blocks.
3 * @author Mathias Schreck <https://github.com/lo1tuma>
4 * @deprecated in ESLint v8.53.0
5 */
6
7"use strict";
8
9//------------------------------------------------------------------------------
10// Requirements
11//------------------------------------------------------------------------------
12
13const astUtils = require("./utils/ast-utils");
14
15//------------------------------------------------------------------------------
16// Rule Definition
17//------------------------------------------------------------------------------
18
19/** @type {import('../shared/types').Rule} */
20module.exports = {
21 meta: {
22 deprecated: true,
23 replacedBy: [],
24 type: "layout",
25
26 docs: {
27 description: "Require or disallow padding within blocks",
28 recommended: false,
29 url: "https://eslint.org/docs/latest/rules/padded-blocks"
30 },
31
32 fixable: "whitespace",
33
34 schema: [
35 {
36 oneOf: [
37 {
38 enum: ["always", "never"]
39 },
40 {
41 type: "object",
42 properties: {
43 blocks: {
44 enum: ["always", "never"]
45 },
46 switches: {
47 enum: ["always", "never"]
48 },
49 classes: {
50 enum: ["always", "never"]
51 }
52 },
53 additionalProperties: false,
54 minProperties: 1
55 }
56 ]
57 },
58 {
59 type: "object",
60 properties: {
61 allowSingleLineBlocks: {
62 type: "boolean"
63 }
64 },
65 additionalProperties: false
66 }
67 ],
68
69 messages: {
70 alwaysPadBlock: "Block must be padded by blank lines.",
71 neverPadBlock: "Block must not be padded by blank lines."
72 }
73 },
74
75 create(context) {
76 const options = {};
77 const typeOptions = context.options[0] || "always";
78 const exceptOptions = context.options[1] || {};
79
80 if (typeof typeOptions === "string") {
81 const shouldHavePadding = typeOptions === "always";
82
83 options.blocks = shouldHavePadding;
84 options.switches = shouldHavePadding;
85 options.classes = shouldHavePadding;
86 } else {
87 if (Object.prototype.hasOwnProperty.call(typeOptions, "blocks")) {
88 options.blocks = typeOptions.blocks === "always";
89 }
90 if (Object.prototype.hasOwnProperty.call(typeOptions, "switches")) {
91 options.switches = typeOptions.switches === "always";
92 }
93 if (Object.prototype.hasOwnProperty.call(typeOptions, "classes")) {
94 options.classes = typeOptions.classes === "always";
95 }
96 }
97
98 if (Object.prototype.hasOwnProperty.call(exceptOptions, "allowSingleLineBlocks")) {
99 options.allowSingleLineBlocks = exceptOptions.allowSingleLineBlocks === true;
100 }
101
102 const sourceCode = context.sourceCode;
103
104 /**
105 * Gets the open brace token from a given node.
106 * @param {ASTNode} node A BlockStatement or SwitchStatement node from which to get the open brace.
107 * @returns {Token} The token of the open brace.
108 */
109 function getOpenBrace(node) {
110 if (node.type === "SwitchStatement") {
111 return sourceCode.getTokenBefore(node.cases[0]);
112 }
113
114 if (node.type === "StaticBlock") {
115 return sourceCode.getFirstToken(node, { skip: 1 }); // skip the `static` token
116 }
117
118 // `BlockStatement` or `ClassBody`
119 return sourceCode.getFirstToken(node);
120 }
121
122 /**
123 * Checks if the given parameter is a comment node
124 * @param {ASTNode|Token} node An AST node or token
125 * @returns {boolean} True if node is a comment
126 */
127 function isComment(node) {
128 return node.type === "Line" || node.type === "Block";
129 }
130
131 /**
132 * Checks if there is padding between two tokens
133 * @param {Token} first The first token
134 * @param {Token} second The second token
135 * @returns {boolean} True if there is at least a line between the tokens
136 */
137 function isPaddingBetweenTokens(first, second) {
138 return second.loc.start.line - first.loc.end.line >= 2;
139 }
140
141
142 /**
143 * Checks if the given token has a blank line after it.
144 * @param {Token} token The token to check.
145 * @returns {boolean} Whether or not the token is followed by a blank line.
146 */
147 function getFirstBlockToken(token) {
148 let prev,
149 first = token;
150
151 do {
152 prev = first;
153 first = sourceCode.getTokenAfter(first, { includeComments: true });
154 } while (isComment(first) && first.loc.start.line === prev.loc.end.line);
155
156 return first;
157 }
158
159 /**
160 * Checks if the given token is preceded by a blank line.
161 * @param {Token} token The token to check
162 * @returns {boolean} Whether or not the token is preceded by a blank line
163 */
164 function getLastBlockToken(token) {
165 let last = token,
166 next;
167
168 do {
169 next = last;
170 last = sourceCode.getTokenBefore(last, { includeComments: true });
171 } while (isComment(last) && last.loc.end.line === next.loc.start.line);
172
173 return last;
174 }
175
176 /**
177 * Checks if a node should be padded, according to the rule config.
178 * @param {ASTNode} node The AST node to check.
179 * @throws {Error} (Unreachable)
180 * @returns {boolean} True if the node should be padded, false otherwise.
181 */
182 function requirePaddingFor(node) {
183 switch (node.type) {
184 case "BlockStatement":
185 case "StaticBlock":
186 return options.blocks;
187 case "SwitchStatement":
188 return options.switches;
189 case "ClassBody":
190 return options.classes;
191
192 /* c8 ignore next */
193 default:
194 throw new Error("unreachable");
195 }
196 }
197
198 /**
199 * Checks the given BlockStatement node to be padded if the block is not empty.
200 * @param {ASTNode} node The AST node of a BlockStatement.
201 * @returns {void} undefined.
202 */
203 function checkPadding(node) {
204 const openBrace = getOpenBrace(node),
205 firstBlockToken = getFirstBlockToken(openBrace),
206 tokenBeforeFirst = sourceCode.getTokenBefore(firstBlockToken, { includeComments: true }),
207 closeBrace = sourceCode.getLastToken(node),
208 lastBlockToken = getLastBlockToken(closeBrace),
209 tokenAfterLast = sourceCode.getTokenAfter(lastBlockToken, { includeComments: true }),
210 blockHasTopPadding = isPaddingBetweenTokens(tokenBeforeFirst, firstBlockToken),
211 blockHasBottomPadding = isPaddingBetweenTokens(lastBlockToken, tokenAfterLast);
212
213 if (options.allowSingleLineBlocks && astUtils.isTokenOnSameLine(tokenBeforeFirst, tokenAfterLast)) {
214 return;
215 }
216
217 if (requirePaddingFor(node)) {
218
219 if (!blockHasTopPadding) {
220 context.report({
221 node,
222 loc: {
223 start: tokenBeforeFirst.loc.start,
224 end: firstBlockToken.loc.start
225 },
226 fix(fixer) {
227 return fixer.insertTextAfter(tokenBeforeFirst, "\n");
228 },
229 messageId: "alwaysPadBlock"
230 });
231 }
232 if (!blockHasBottomPadding) {
233 context.report({
234 node,
235 loc: {
236 end: tokenAfterLast.loc.start,
237 start: lastBlockToken.loc.end
238 },
239 fix(fixer) {
240 return fixer.insertTextBefore(tokenAfterLast, "\n");
241 },
242 messageId: "alwaysPadBlock"
243 });
244 }
245 } else {
246 if (blockHasTopPadding) {
247
248 context.report({
249 node,
250 loc: {
251 start: tokenBeforeFirst.loc.start,
252 end: firstBlockToken.loc.start
253 },
254 fix(fixer) {
255 return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n");
256 },
257 messageId: "neverPadBlock"
258 });
259 }
260
261 if (blockHasBottomPadding) {
262
263 context.report({
264 node,
265 loc: {
266 end: tokenAfterLast.loc.start,
267 start: lastBlockToken.loc.end
268 },
269 messageId: "neverPadBlock",
270 fix(fixer) {
271 return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n");
272 }
273 });
274 }
275 }
276 }
277
278 const rule = {};
279
280 if (Object.prototype.hasOwnProperty.call(options, "switches")) {
281 rule.SwitchStatement = function(node) {
282 if (node.cases.length === 0) {
283 return;
284 }
285 checkPadding(node);
286 };
287 }
288
289 if (Object.prototype.hasOwnProperty.call(options, "blocks")) {
290 rule.BlockStatement = function(node) {
291 if (node.body.length === 0) {
292 return;
293 }
294 checkPadding(node);
295 };
296 rule.StaticBlock = rule.BlockStatement;
297 }
298
299 if (Object.prototype.hasOwnProperty.call(options, "classes")) {
300 rule.ClassBody = function(node) {
301 if (node.body.length === 0) {
302 return;
303 }
304 checkPadding(node);
305 };
306 }
307
308 return rule;
309 }
310};
Note: See TracBrowser for help on using the repository browser.