securityos/node_modules/eslint-plugin-unicorn/rules/switch-case-braces.js

110 lines
3.1 KiB
JavaScript

'use strict';
const {isColonToken} = require('@eslint-community/eslint-utils');
const getSwitchCaseHeadLocation = require('./utils/get-switch-case-head-location.js');
const getIndentString = require('./utils/get-indent-string.js');
const {replaceNodeOrTokenAndSpacesBefore} = require('./fix/index.js');
const MESSAGE_ID_EMPTY_CLAUSE = 'switch-case-braces/empty';
const MESSAGE_ID_MISSING_BRACES = 'switch-case-braces/missing';
const MESSAGE_ID_UNNECESSARY_BRACES = 'switch-case-braces/unnecessary';
const messages = {
[MESSAGE_ID_EMPTY_CLAUSE]: 'Unexpected braces in empty case clause.',
[MESSAGE_ID_MISSING_BRACES]: 'Missing braces in case clause.',
[MESSAGE_ID_UNNECESSARY_BRACES]: 'Unnecessary braces in case clause.',
};
function * removeBraces(fixer, node, sourceCode) {
const [blockStatement] = node.consequent;
const openingBraceToken = sourceCode.getFirstToken(blockStatement);
yield * replaceNodeOrTokenAndSpacesBefore(openingBraceToken, '', fixer, sourceCode);
const closingBraceToken = sourceCode.getLastToken(blockStatement);
yield fixer.remove(closingBraceToken);
}
function * addBraces(fixer, node, sourceCode) {
const colonToken = sourceCode.getTokenAfter(
node.test || sourceCode.getFirstToken(node),
isColonToken,
);
yield fixer.insertTextAfter(colonToken, ' {');
const lastToken = sourceCode.getLastToken(node);
const indent = getIndentString(node, sourceCode);
yield fixer.insertTextAfter(lastToken, `\n${indent}}`);
}
/** @param {import('eslint').Rule.RuleContext} context */
const create = context => {
const isBracesRequired = context.options[0] !== 'avoid';
const sourceCode = context.getSourceCode();
return {
SwitchCase(node) {
const {consequent} = node;
if (consequent.length === 0) {
return;
}
if (
consequent.length === 1
&& consequent[0].type === 'BlockStatement'
&& consequent[0].body.length === 0
) {
return {
node,
loc: sourceCode.getFirstToken(consequent[0]).loc,
messageId: MESSAGE_ID_EMPTY_CLAUSE,
fix: fixer => removeBraces(fixer, node, sourceCode),
};
}
if (
isBracesRequired
&& !(
consequent.length === 1
&& consequent[0].type === 'BlockStatement'
)
) {
return {
node,
loc: getSwitchCaseHeadLocation(node, sourceCode),
messageId: MESSAGE_ID_MISSING_BRACES,
fix: fixer => addBraces(fixer, node, sourceCode),
};
}
if (
!isBracesRequired
&& consequent.length === 1
&& consequent[0].type === 'BlockStatement'
&& consequent[0].body.every(node =>
node.type !== 'VariableDeclaration'
&& node.type !== 'FunctionDeclaration',
)
) {
return {
node,
loc: sourceCode.getFirstToken(consequent[0]).loc,
messageId: MESSAGE_ID_UNNECESSARY_BRACES,
fix: fixer => removeBraces(fixer, node, sourceCode),
};
}
},
};
};
/** @type {import('eslint').Rule.RuleModule} */
module.exports = {
create,
meta: {
type: 'layout',
docs: {
description: 'Enforce consistent brace style for `case` clauses.',
},
fixable: 'code',
schema: [{enum: ['always', 'avoid']}],
messages,
},
};