]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/brace-style.js
f4adb9490ebdf69a2837a6ce8ac94cb90ff13c14
2 * @fileoverview Rule to flag block statements that do not use the one true brace style
3 * @author Ian Christian Myers
8 const astUtils
= require("./utils/ast-utils");
10 //------------------------------------------------------------------------------
12 //------------------------------------------------------------------------------
14 /** @type {import('../shared/types').Rule} */
20 description
: "enforce consistent brace style for blocks",
22 url
: "https://eslint.org/docs/rules/brace-style"
27 enum: ["1tbs", "stroustrup", "allman"]
37 additionalProperties
: false
41 fixable
: "whitespace",
44 nextLineOpen
: "Opening curly brace does not appear on the same line as controlling statement.",
45 sameLineOpen
: "Opening curly brace appears on the same line as controlling statement.",
46 blockSameLine
: "Statement inside of curly braces should be on next line.",
47 nextLineClose
: "Closing curly brace does not appear on the same line as the subsequent block.",
48 singleLineClose
: "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.",
49 sameLineClose
: "Closing curly brace appears on the same line as the subsequent block."
54 const style
= context
.options
[0] || "1tbs",
55 params
= context
.options
[1] || {},
56 sourceCode
= context
.getSourceCode();
58 //--------------------------------------------------------------------------
60 //--------------------------------------------------------------------------
63 * Fixes a place where a newline unexpectedly appears
64 * @param {Token} firstToken The token before the unexpected newline
65 * @param {Token} secondToken The token after the unexpected newline
66 * @returns {Function} A fixer function to remove the newlines between the tokens
68 function removeNewlineBetween(firstToken
, secondToken
) {
69 const textRange
= [firstToken
.range
[1], secondToken
.range
[0]];
70 const textBetween
= sourceCode
.text
.slice(textRange
[0], textRange
[1]);
72 // Don't do a fix if there is a comment between the tokens
73 if (textBetween
.trim()) {
76 return fixer
=> fixer
.replaceTextRange(textRange
, " ");
80 * Validates a pair of curly brackets based on the user's config
81 * @param {Token} openingCurly The opening curly bracket
82 * @param {Token} closingCurly The closing curly bracket
85 function validateCurlyPair(openingCurly
, closingCurly
) {
86 const tokenBeforeOpeningCurly
= sourceCode
.getTokenBefore(openingCurly
);
87 const tokenAfterOpeningCurly
= sourceCode
.getTokenAfter(openingCurly
);
88 const tokenBeforeClosingCurly
= sourceCode
.getTokenBefore(closingCurly
);
89 const singleLineException
= params
.allowSingleLine
&& astUtils
.isTokenOnSameLine(openingCurly
, closingCurly
);
91 if (style
!== "allman" && !astUtils
.isTokenOnSameLine(tokenBeforeOpeningCurly
, openingCurly
)) {
94 messageId
: "nextLineOpen",
95 fix
: removeNewlineBetween(tokenBeforeOpeningCurly
, openingCurly
)
99 if (style
=== "allman" && astUtils
.isTokenOnSameLine(tokenBeforeOpeningCurly
, openingCurly
) && !singleLineException
) {
102 messageId
: "sameLineOpen",
103 fix
: fixer
=> fixer
.insertTextBefore(openingCurly
, "\n")
107 if (astUtils
.isTokenOnSameLine(openingCurly
, tokenAfterOpeningCurly
) && tokenAfterOpeningCurly
!== closingCurly
&& !singleLineException
) {
110 messageId
: "blockSameLine",
111 fix
: fixer
=> fixer
.insertTextAfter(openingCurly
, "\n")
115 if (tokenBeforeClosingCurly
!== openingCurly
&& !singleLineException
&& astUtils
.isTokenOnSameLine(tokenBeforeClosingCurly
, closingCurly
)) {
118 messageId
: "singleLineClose",
119 fix
: fixer
=> fixer
.insertTextBefore(closingCurly
, "\n")
125 * Validates the location of a token that appears before a keyword (e.g. a newline before `else`)
126 * @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`).
129 function validateCurlyBeforeKeyword(curlyToken
) {
130 const keywordToken
= sourceCode
.getTokenAfter(curlyToken
);
132 if (style
=== "1tbs" && !astUtils
.isTokenOnSameLine(curlyToken
, keywordToken
)) {
135 messageId
: "nextLineClose",
136 fix
: removeNewlineBetween(curlyToken
, keywordToken
)
140 if (style
!== "1tbs" && astUtils
.isTokenOnSameLine(curlyToken
, keywordToken
)) {
143 messageId
: "sameLineClose",
144 fix
: fixer
=> fixer
.insertTextAfter(curlyToken
, "\n")
149 //--------------------------------------------------------------------------
151 //--------------------------------------------------------------------------
154 BlockStatement(node
) {
155 if (!astUtils
.STATEMENT_LIST_PARENTS
.has(node
.parent
.type
)) {
156 validateCurlyPair(sourceCode
.getFirstToken(node
), sourceCode
.getLastToken(node
));
161 sourceCode
.getFirstToken(node
, { skip
: 1 }), // skip the `static` token
162 sourceCode
.getLastToken(node
)
166 validateCurlyPair(sourceCode
.getFirstToken(node
), sourceCode
.getLastToken(node
));
168 SwitchStatement(node
) {
169 const closingCurly
= sourceCode
.getLastToken(node
);
170 const openingCurly
= sourceCode
.getTokenBefore(node
.cases
.length
? node
.cases
[0] : closingCurly
);
172 validateCurlyPair(openingCurly
, closingCurly
);
175 if (node
.consequent
.type
=== "BlockStatement" && node
.alternate
) {
177 // Handle the keyword after the `if` block (before `else`)
178 validateCurlyBeforeKeyword(sourceCode
.getLastToken(node
.consequent
));
183 // Handle the keyword after the `try` block (before `catch` or `finally`)
184 validateCurlyBeforeKeyword(sourceCode
.getLastToken(node
.block
));
186 if (node
.handler
&& node
.finalizer
) {
188 // Handle the keyword after the `catch` block (before `finally`)
189 validateCurlyBeforeKeyword(sourceCode
.getLastToken(node
.handler
.body
));