From a00ffc6f5fbe12d10c4a9888b840be6d227211f6 Mon Sep 17 00:00:00 2001 From: Kevin Ghadyani <3948069+Sawtaytoes@users.noreply.github.com> Date: Fri, 28 Feb 2020 10:59:16 -0600 Subject: [PATCH] Update: Added auto-fix to multiline-ternary I noticed unfixed warnings from this ESLint rule and wanted to auto-fix them. While it may seem like doing `'\n? '` is opinionated, I did have changed to make this take a new option and either put the `?` on the previous line or next line. This is actually unnecessary because `operator-linebreak` handles it for you. --- lib/rules/multiline-ternary.js | 72 +++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/lib/rules/multiline-ternary.js b/lib/rules/multiline-ternary.js index 1df90b6feb83..5314a4c93041 100644 --- a/lib/rules/multiline-ternary.js +++ b/lib/rules/multiline-ternary.js @@ -24,15 +24,18 @@ module.exports = { schema: [ { - enum: ["always", "always-multiline", "never"] - } + enum: ["always", "always-multiline", "never"], + }, ], + messages: { expectedTestCons: "Expected newline between test and consequent of ternary expression.", expectedConsAlt: "Expected newline between consequent and alternate of ternary expression.", unexpectedTestCons: "Unexpected newline between test and consequent of ternary expression.", unexpectedConsAlt: "Unexpected newline between consequent and alternate of ternary expression." - } + }, + + fixable: 'code', }, create(context) { @@ -52,10 +55,61 @@ module.exports = { * @returns {void} * @private */ - function reportError(node, parentNode, expected) { + function reportSingleLineError(node, parentNode, expected) { + context.report({ + node, + messageId: `${expected ? "expected" : "unexpected"}${node === parentNode.test ? "TestCons" : "ConsAlt"}`, + fix: fixer => ([ + !astUtils.isTokenOnSameLine(parentNode.test, parentNode.consequent) && + fixer.replaceTextRange( + [ + parentNode.test.range[1], + parentNode.consequent.range[0], + ], + ' ? ', + ), + !astUtils.isTokenOnSameLine(parentNode.consequent, parentNode.alternate) && + fixer.replaceTextRange( + [ + parentNode.consequent.range[1], + parentNode.alternate.range[0], + ], + ' : ', + ), + ]), + }); + } + + /** + * Tests whether node is preceded by supplied tokens + * @param {ASTNode} node node to check + * @param {ASTNode} parentNode parent of node to report + * @param {boolean} expected whether newline was expected or not + * @returns {void} + * @private + */ + function reportMultilineError(node, parentNode, expected) { context.report({ node, - messageId: `${expected ? "expected" : "unexpected"}${node === parentNode.test ? "TestCons" : "ConsAlt"}` + messageId: `${expected ? "expected" : "unexpected"}${node === parentNode.test ? "TestCons" : "ConsAlt"}`, + fix: fixer => ([ + astUtils.isTokenOnSameLine(parentNode.test, parentNode.consequent) && + fixer.replaceTextRange( + [ + parentNode.test.range[1], + parentNode.consequent.range[0], + ], + '\n? ', + ), + astUtils.isTokenOnSameLine(parentNode.consequent, parentNode.alternate) && + fixer.replaceTextRange( + [ + parentNode.consequent.range[1], + parentNode.alternate.range[0], + ], + '\n: ', + ), + ]), }); } @@ -70,11 +124,11 @@ module.exports = { if (!multiline) { if (!areTestAndConsequentOnSameLine) { - reportError(node.test, node, false); + reportSingleLineError(node.test, node, false); } if (!areConsequentAndAlternateOnSameLine) { - reportError(node.consequent, node, false); + reportSingleLineError(node.consequent, node, false); } } else { if (allowSingleLine && node.loc.start.line === node.loc.end.line) { @@ -82,11 +136,11 @@ module.exports = { } if (areTestAndConsequentOnSameLine) { - reportError(node.test, node, true); + reportMultilineError(node.test, node, true); } if (areConsequentAndAlternateOnSameLine) { - reportError(node.consequent, node, true); + reportMultilineError(node.consequent, node, true); } } }