minor adjustment to readme
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / nonblock-statement-body-position.js
1 /**
2  * @fileoverview enforce the location of single-line statements
3  * @author Teddy Katz
4  */
5 "use strict";
6
7 //------------------------------------------------------------------------------
8 // Rule Definition
9 //------------------------------------------------------------------------------
10
11 const POSITION_SCHEMA = { enum: ["beside", "below", "any"] };
12
13 module.exports = {
14     meta: {
15         type: "layout",
16
17         docs: {
18             description: "enforce the location of single-line statements",
19             category: "Stylistic Issues",
20             recommended: false,
21             url: "https://eslint.org/docs/rules/nonblock-statement-body-position"
22         },
23
24         fixable: "whitespace",
25
26         schema: [
27             POSITION_SCHEMA,
28             {
29                 properties: {
30                     overrides: {
31                         properties: {
32                             if: POSITION_SCHEMA,
33                             else: POSITION_SCHEMA,
34                             while: POSITION_SCHEMA,
35                             do: POSITION_SCHEMA,
36                             for: POSITION_SCHEMA
37                         },
38                         additionalProperties: false
39                     }
40                 },
41                 additionalProperties: false
42             }
43         ]
44     },
45
46     create(context) {
47         const sourceCode = context.getSourceCode();
48
49         //----------------------------------------------------------------------
50         // Helpers
51         //----------------------------------------------------------------------
52
53         /**
54          * Gets the applicable preference for a particular keyword
55          * @param {string} keywordName The name of a keyword, e.g. 'if'
56          * @returns {string} The applicable option for the keyword, e.g. 'beside'
57          */
58         function getOption(keywordName) {
59             return context.options[1] && context.options[1].overrides && context.options[1].overrides[keywordName] ||
60                 context.options[0] ||
61                 "beside";
62         }
63
64         /**
65          * Validates the location of a single-line statement
66          * @param {ASTNode} node The single-line statement
67          * @param {string} keywordName The applicable keyword name for the single-line statement
68          * @returns {void}
69          */
70         function validateStatement(node, keywordName) {
71             const option = getOption(keywordName);
72
73             if (node.type === "BlockStatement" || option === "any") {
74                 return;
75             }
76
77             const tokenBefore = sourceCode.getTokenBefore(node);
78
79             if (tokenBefore.loc.end.line === node.loc.start.line && option === "below") {
80                 context.report({
81                     node,
82                     message: "Expected a linebreak before this statement.",
83                     fix: fixer => fixer.insertTextBefore(node, "\n")
84                 });
85             } else if (tokenBefore.loc.end.line !== node.loc.start.line && option === "beside") {
86                 context.report({
87                     node,
88                     message: "Expected no linebreak before this statement.",
89                     fix(fixer) {
90                         if (sourceCode.getText().slice(tokenBefore.range[1], node.range[0]).trim()) {
91                             return null;
92                         }
93                         return fixer.replaceTextRange([tokenBefore.range[1], node.range[0]], " ");
94                     }
95                 });
96             }
97         }
98
99         //----------------------------------------------------------------------
100         // Public
101         //----------------------------------------------------------------------
102
103         return {
104             IfStatement(node) {
105                 validateStatement(node.consequent, "if");
106
107                 // Check the `else` node, but don't check 'else if' statements.
108                 if (node.alternate && node.alternate.type !== "IfStatement") {
109                     validateStatement(node.alternate, "else");
110                 }
111             },
112             WhileStatement: node => validateStatement(node.body, "while"),
113             DoWhileStatement: node => validateStatement(node.body, "do"),
114             ForStatement: node => validateStatement(node.body, "for"),
115             ForInStatement: node => validateStatement(node.body, "for"),
116             ForOfStatement: node => validateStatement(node.body, "for")
117         };
118     }
119 };