X-Git-Url: https://git.josue.xyz/?a=blobdiff_plain;f=.config%2Fcoc%2Fextensions%2Fnode_modules%2Fcoc-prettier%2Fnode_modules%2Feslint%2Flib%2Frules%2Fno-unneeded-ternary.js;fp=.config%2Fcoc%2Fextensions%2Fnode_modules%2Fcoc-prettier%2Fnode_modules%2Feslint%2Flib%2Frules%2Fno-unneeded-ternary.js;h=893baa34f749178cb0938a8b861bb767f4d73c91;hb=3aba54c891969552833dbc350b3139e944e17a97;hp=0000000000000000000000000000000000000000;hpb=1def8ecce8e6f3aa32e6978d0ba7846a99b8de34;p=dotfiles%2F.git diff --git a/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/no-unneeded-ternary.js b/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/no-unneeded-ternary.js new file mode 100644 index 00000000..893baa34 --- /dev/null +++ b/.config/coc/extensions/node_modules/coc-prettier/node_modules/eslint/lib/rules/no-unneeded-ternary.js @@ -0,0 +1,161 @@ +/** + * @fileoverview Rule to flag no-unneeded-ternary + * @author Gyandeep Singh + */ + +"use strict"; + +const astUtils = require("./utils/ast-utils"); + +// Operators that always result in a boolean value +const BOOLEAN_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<=", "in", "instanceof"]); +const OPERATOR_INVERSES = { + "==": "!=", + "!=": "==", + "===": "!==", + "!==": "===" + + // Operators like < and >= are not true inverses, since both will return false with NaN. +}; +const OR_PRECEDENCE = astUtils.getPrecedence({ type: "LogicalExpression", operator: "||" }); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +module.exports = { + meta: { + type: "suggestion", + + docs: { + description: "disallow ternary operators when simpler alternatives exist", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-unneeded-ternary" + }, + + schema: [ + { + type: "object", + properties: { + defaultAssignment: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + fixable: "code" + }, + + create(context) { + const options = context.options[0] || {}; + const defaultAssignment = options.defaultAssignment !== false; + const sourceCode = context.getSourceCode(); + + /** + * Test if the node is a boolean literal + * @param {ASTNode} node The node to report. + * @returns {boolean} True if the its a boolean literal + * @private + */ + function isBooleanLiteral(node) { + return node.type === "Literal" && typeof node.value === "boolean"; + } + + /** + * Creates an expression that represents the boolean inverse of the expression represented by the original node + * @param {ASTNode} node A node representing an expression + * @returns {string} A string representing an inverted expression + */ + function invertExpression(node) { + if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) { + const operatorToken = sourceCode.getFirstTokenBetween( + node.left, + node.right, + token => token.value === node.operator + ); + const text = sourceCode.getText(); + + return text.slice(node.range[0], + operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + text.slice(operatorToken.range[1], node.range[1]); + } + + if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) { + return `!(${astUtils.getParenthesisedText(sourceCode, node)})`; + } + return `!${astUtils.getParenthesisedText(sourceCode, node)}`; + } + + /** + * Tests if a given node always evaluates to a boolean value + * @param {ASTNode} node An expression node + * @returns {boolean} True if it is determined that the node will always evaluate to a boolean value + */ + function isBooleanExpression(node) { + return node.type === "BinaryExpression" && BOOLEAN_OPERATORS.has(node.operator) || + node.type === "UnaryExpression" && node.operator === "!"; + } + + /** + * Test if the node matches the pattern id ? id : expression + * @param {ASTNode} node The ConditionalExpression to check. + * @returns {boolean} True if the pattern is matched, and false otherwise + * @private + */ + function matchesDefaultAssignment(node) { + return node.test.type === "Identifier" && + node.consequent.type === "Identifier" && + node.test.name === node.consequent.name; + } + + return { + + ConditionalExpression(node) { + if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) { + context.report({ + node, + loc: node.consequent.loc.start, + message: "Unnecessary use of boolean literals in conditional expression.", + fix(fixer) { + if (node.consequent.value === node.alternate.value) { + + // Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true` + return node.test.type === "Identifier" ? fixer.replaceText(node, node.consequent.value.toString()) : null; + } + if (node.alternate.value) { + + // Replace `foo() ? false : true` with `!(foo())` + return fixer.replaceText(node, invertExpression(node.test)); + } + + // Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise. + + return fixer.replaceText(node, isBooleanExpression(node.test) ? astUtils.getParenthesisedText(sourceCode, node.test) : `!${invertExpression(node.test)}`); + } + }); + } else if (!defaultAssignment && matchesDefaultAssignment(node)) { + context.report({ + node, + loc: node.consequent.loc.start, + message: "Unnecessary use of conditional expression for default assignment.", + fix: fixer => { + const shouldParenthesizeAlternate = ( + astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE && + !astUtils.isParenthesised(sourceCode, node.alternate) + ); + const alternateText = shouldParenthesizeAlternate + ? `(${sourceCode.getText(node.alternate)})` + : astUtils.getParenthesisedText(sourceCode, node.alternate); + const testText = astUtils.getParenthesisedText(sourceCode, node.test); + + return fixer.replaceText(node, `${testText} || ${alternateText}`); + } + }); + } + } + }; + } +};