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