Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / space-before-blocks.js
1 /**
2  * @fileoverview A rule to ensure whitespace before blocks.
3  * @author Mathias Schreck <https://github.com/lo1tuma>
4  */
5
6 "use strict";
7
8 const astUtils = require("./utils/ast-utils");
9
10 //------------------------------------------------------------------------------
11 // Rule Definition
12 //------------------------------------------------------------------------------
13
14 module.exports = {
15     meta: {
16         type: "layout",
17
18         docs: {
19             description: "enforce consistent spacing before blocks",
20             category: "Stylistic Issues",
21             recommended: false,
22             url: "https://eslint.org/docs/rules/space-before-blocks"
23         },
24
25         fixable: "whitespace",
26
27         schema: [
28             {
29                 oneOf: [
30                     {
31                         enum: ["always", "never"]
32                     },
33                     {
34                         type: "object",
35                         properties: {
36                             keywords: {
37                                 enum: ["always", "never", "off"]
38                             },
39                             functions: {
40                                 enum: ["always", "never", "off"]
41                             },
42                             classes: {
43                                 enum: ["always", "never", "off"]
44                             }
45                         },
46                         additionalProperties: false
47                     }
48                 ]
49             }
50         ]
51     },
52
53     create(context) {
54         const config = context.options[0],
55             sourceCode = context.getSourceCode();
56         let alwaysFunctions = true,
57             alwaysKeywords = true,
58             alwaysClasses = true,
59             neverFunctions = false,
60             neverKeywords = false,
61             neverClasses = false;
62
63         if (typeof config === "object") {
64             alwaysFunctions = config.functions === "always";
65             alwaysKeywords = config.keywords === "always";
66             alwaysClasses = config.classes === "always";
67             neverFunctions = config.functions === "never";
68             neverKeywords = config.keywords === "never";
69             neverClasses = config.classes === "never";
70         } else if (config === "never") {
71             alwaysFunctions = false;
72             alwaysKeywords = false;
73             alwaysClasses = false;
74             neverFunctions = true;
75             neverKeywords = true;
76             neverClasses = true;
77         }
78
79         /**
80          * Checks whether or not a given token is an arrow operator (=>) or a keyword
81          * in order to avoid to conflict with `arrow-spacing` and `keyword-spacing`.
82          * @param {Token} token A token to check.
83          * @returns {boolean} `true` if the token is an arrow operator.
84          */
85         function isConflicted(token) {
86             return (token.type === "Punctuator" && token.value === "=>") || token.type === "Keyword";
87         }
88
89         /**
90          * Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line.
91          * @param {ASTNode|Token} node The AST node of a BlockStatement.
92          * @returns {void} undefined.
93          */
94         function checkPrecedingSpace(node) {
95             const precedingToken = sourceCode.getTokenBefore(node);
96
97             if (precedingToken && !isConflicted(precedingToken) && astUtils.isTokenOnSameLine(precedingToken, node)) {
98                 const hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node);
99                 const parent = context.getAncestors().pop();
100                 let requireSpace;
101                 let requireNoSpace;
102
103                 if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration") {
104                     requireSpace = alwaysFunctions;
105                     requireNoSpace = neverFunctions;
106                 } else if (node.type === "ClassBody") {
107                     requireSpace = alwaysClasses;
108                     requireNoSpace = neverClasses;
109                 } else {
110                     requireSpace = alwaysKeywords;
111                     requireNoSpace = neverKeywords;
112                 }
113
114                 if (requireSpace && !hasSpace) {
115                     context.report({
116                         node,
117                         message: "Missing space before opening brace.",
118                         fix(fixer) {
119                             return fixer.insertTextBefore(node, " ");
120                         }
121                     });
122                 } else if (requireNoSpace && hasSpace) {
123                     context.report({
124                         node,
125                         message: "Unexpected space before opening brace.",
126                         fix(fixer) {
127                             return fixer.removeRange([precedingToken.range[1], node.range[0]]);
128                         }
129                     });
130                 }
131             }
132         }
133
134         /**
135          * Checks if the CaseBlock of an given SwitchStatement node has a preceding space.
136          * @param {ASTNode} node The node of a SwitchStatement.
137          * @returns {void} undefined.
138          */
139         function checkSpaceBeforeCaseBlock(node) {
140             const cases = node.cases;
141             let openingBrace;
142
143             if (cases.length > 0) {
144                 openingBrace = sourceCode.getTokenBefore(cases[0]);
145             } else {
146                 openingBrace = sourceCode.getLastToken(node, 1);
147             }
148
149             checkPrecedingSpace(openingBrace);
150         }
151
152         return {
153             BlockStatement: checkPrecedingSpace,
154             ClassBody: checkPrecedingSpace,
155             SwitchStatement: checkSpaceBeforeCaseBlock
156         };
157
158     }
159 };