]> git.proxmox.com Git - pve-eslint.git/blame - eslint/lib/rules/multiline-ternary.js
change from CLIEngine to ESLint
[pve-eslint.git] / eslint / lib / rules / multiline-ternary.js
CommitLineData
eb39fafa
DC
1/**
2 * @fileoverview Enforce newlines between operands of ternary expressions
3 * @author Kai Cataldo
4 */
5
6"use strict";
7
8const astUtils = require("./utils/ast-utils");
9
10//------------------------------------------------------------------------------
11// Rule Definition
12//------------------------------------------------------------------------------
13
14module.exports = {
15 meta: {
16 type: "layout",
17
18 docs: {
19 description: "enforce newlines between operands of ternary expressions",
eb39fafa
DC
20 recommended: false,
21 url: "https://eslint.org/docs/rules/multiline-ternary"
22 },
23
24 schema: [
25 {
26 enum: ["always", "always-multiline", "never"]
27 }
28 ],
456be15e 29
eb39fafa
DC
30 messages: {
31 expectedTestCons: "Expected newline between test and consequent of ternary expression.",
32 expectedConsAlt: "Expected newline between consequent and alternate of ternary expression.",
33 unexpectedTestCons: "Unexpected newline between test and consequent of ternary expression.",
34 unexpectedConsAlt: "Unexpected newline between consequent and alternate of ternary expression."
456be15e
TL
35 },
36
37 fixable: "whitespace"
eb39fafa
DC
38 },
39
40 create(context) {
456be15e 41 const sourceCode = context.getSourceCode();
eb39fafa
DC
42 const option = context.options[0];
43 const multiline = option !== "never";
44 const allowSingleLine = option === "always-multiline";
eb39fafa
DC
45
46 //--------------------------------------------------------------------------
47 // Public
48 //--------------------------------------------------------------------------
49
50 return {
51 ConditionalExpression(node) {
d3726936
TL
52 const questionToken = sourceCode.getTokenAfter(node.test, astUtils.isNotClosingParenToken);
53 const colonToken = sourceCode.getTokenAfter(node.consequent, astUtils.isNotClosingParenToken);
54
55 const firstTokenOfTest = sourceCode.getFirstToken(node);
56 const lastTokenOfTest = sourceCode.getTokenBefore(questionToken);
57 const firstTokenOfConsequent = sourceCode.getTokenAfter(questionToken);
58 const lastTokenOfConsequent = sourceCode.getTokenBefore(colonToken);
59 const firstTokenOfAlternate = sourceCode.getTokenAfter(colonToken);
60
61 const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, firstTokenOfConsequent);
62 const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, firstTokenOfAlternate);
eb39fafa 63
456be15e
TL
64 const hasComments = !!sourceCode.getCommentsInside(node).length;
65
eb39fafa
DC
66 if (!multiline) {
67 if (!areTestAndConsequentOnSameLine) {
d3726936
TL
68 context.report({
69 node: node.test,
70 loc: {
71 start: firstTokenOfTest.loc.start,
72 end: lastTokenOfTest.loc.end
73 },
456be15e
TL
74 messageId: "unexpectedTestCons",
75 fix: fixer => {
76 if (hasComments) {
77 return null;
78 }
79 const fixers = [];
80 const areTestAndQuestionOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, questionToken);
81 const areQuestionAndConsOnSameLine = astUtils.isTokenOnSameLine(questionToken, firstTokenOfConsequent);
82
83 if (!areTestAndQuestionOnSameLine) {
84 fixers.push(fixer.removeRange([lastTokenOfTest.range[1], questionToken.range[0]]));
85 }
86 if (!areQuestionAndConsOnSameLine) {
87 fixers.push(fixer.removeRange([questionToken.range[1], firstTokenOfConsequent.range[0]]));
88 }
89
90 return fixers;
91 }
d3726936 92 });
eb39fafa
DC
93 }
94
95 if (!areConsequentAndAlternateOnSameLine) {
d3726936
TL
96 context.report({
97 node: node.consequent,
98 loc: {
99 start: firstTokenOfConsequent.loc.start,
100 end: lastTokenOfConsequent.loc.end
101 },
456be15e
TL
102 messageId: "unexpectedConsAlt",
103 fix: fixer => {
104 if (hasComments) {
105 return null;
106 }
107 const fixers = [];
108 const areConsAndColonOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, colonToken);
109 const areColonAndAltOnSameLine = astUtils.isTokenOnSameLine(colonToken, firstTokenOfAlternate);
110
111 if (!areConsAndColonOnSameLine) {
112 fixers.push(fixer.removeRange([lastTokenOfConsequent.range[1], colonToken.range[0]]));
113 }
114 if (!areColonAndAltOnSameLine) {
115 fixers.push(fixer.removeRange([colonToken.range[1], firstTokenOfAlternate.range[0]]));
116 }
117
118 return fixers;
119 }
d3726936 120 });
eb39fafa
DC
121 }
122 } else {
123 if (allowSingleLine && node.loc.start.line === node.loc.end.line) {
124 return;
125 }
126
127 if (areTestAndConsequentOnSameLine) {
d3726936
TL
128 context.report({
129 node: node.test,
130 loc: {
131 start: firstTokenOfTest.loc.start,
132 end: lastTokenOfTest.loc.end
133 },
456be15e
TL
134 messageId: "expectedTestCons",
135 fix: fixer => (hasComments ? null : (
136 fixer.replaceTextRange(
137 [
138 lastTokenOfTest.range[1],
139 questionToken.range[0]
140 ],
141 "\n"
142 )
143 ))
d3726936 144 });
eb39fafa
DC
145 }
146
147 if (areConsequentAndAlternateOnSameLine) {
d3726936
TL
148 context.report({
149 node: node.consequent,
150 loc: {
151 start: firstTokenOfConsequent.loc.start,
152 end: lastTokenOfConsequent.loc.end
153 },
456be15e
TL
154 messageId: "expectedConsAlt",
155 fix: (fixer => (hasComments ? null : (
156 fixer.replaceTextRange(
157 [
158 lastTokenOfConsequent.range[1],
159 colonToken.range[0]
160 ],
161 "\n"
162 )
163 )))
d3726936 164 });
eb39fafa
DC
165 }
166 }
167 }
168 };
169 }
170};