Skip to content

Commit 353bfe9

Browse files
authored
Update: handle parentheses in multiline-ternary (fixes #13195) (#13367)
1 parent a7fd343 commit 353bfe9

2 files changed

Lines changed: 489 additions & 47 deletions

File tree

lib/rules/multiline-ternary.js

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -39,54 +39,73 @@ module.exports = {
3939
const option = context.options[0];
4040
const multiline = option !== "never";
4141
const allowSingleLine = option === "always-multiline";
42-
43-
//--------------------------------------------------------------------------
44-
// Helpers
45-
//--------------------------------------------------------------------------
46-
47-
/**
48-
* Tests whether node is preceded by supplied tokens
49-
* @param {ASTNode} node node to check
50-
* @param {ASTNode} parentNode parent of node to report
51-
* @param {boolean} expected whether newline was expected or not
52-
* @returns {void}
53-
* @private
54-
*/
55-
function reportError(node, parentNode, expected) {
56-
context.report({
57-
node,
58-
messageId: `${expected ? "expected" : "unexpected"}${node === parentNode.test ? "TestCons" : "ConsAlt"}`
59-
});
60-
}
42+
const sourceCode = context.getSourceCode();
6143

6244
//--------------------------------------------------------------------------
6345
// Public
6446
//--------------------------------------------------------------------------
6547

6648
return {
6749
ConditionalExpression(node) {
68-
const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(node.test, node.consequent);
69-
const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(node.consequent, node.alternate);
50+
const questionToken = sourceCode.getTokenAfter(node.test, astUtils.isNotClosingParenToken);
51+
const colonToken = sourceCode.getTokenAfter(node.consequent, astUtils.isNotClosingParenToken);
52+
53+
const firstTokenOfTest = sourceCode.getFirstToken(node);
54+
const lastTokenOfTest = sourceCode.getTokenBefore(questionToken);
55+
const firstTokenOfConsequent = sourceCode.getTokenAfter(questionToken);
56+
const lastTokenOfConsequent = sourceCode.getTokenBefore(colonToken);
57+
const firstTokenOfAlternate = sourceCode.getTokenAfter(colonToken);
58+
59+
const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, firstTokenOfConsequent);
60+
const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, firstTokenOfAlternate);
7061

7162
if (!multiline) {
7263
if (!areTestAndConsequentOnSameLine) {
73-
reportError(node.test, node, false);
64+
context.report({
65+
node: node.test,
66+
loc: {
67+
start: firstTokenOfTest.loc.start,
68+
end: lastTokenOfTest.loc.end
69+
},
70+
messageId: "unexpectedTestCons"
71+
});
7472
}
7573

7674
if (!areConsequentAndAlternateOnSameLine) {
77-
reportError(node.consequent, node, false);
75+
context.report({
76+
node: node.consequent,
77+
loc: {
78+
start: firstTokenOfConsequent.loc.start,
79+
end: lastTokenOfConsequent.loc.end
80+
},
81+
messageId: "unexpectedConsAlt"
82+
});
7883
}
7984
} else {
8085
if (allowSingleLine && node.loc.start.line === node.loc.end.line) {
8186
return;
8287
}
8388

8489
if (areTestAndConsequentOnSameLine) {
85-
reportError(node.test, node, true);
90+
context.report({
91+
node: node.test,
92+
loc: {
93+
start: firstTokenOfTest.loc.start,
94+
end: lastTokenOfTest.loc.end
95+
},
96+
messageId: "expectedTestCons"
97+
});
8698
}
8799

88100
if (areConsequentAndAlternateOnSameLine) {
89-
reportError(node.consequent, node, true);
101+
context.report({
102+
node: node.consequent,
103+
loc: {
104+
start: firstTokenOfConsequent.loc.start,
105+
end: lastTokenOfConsequent.loc.end
106+
},
107+
messageId: "expectedConsAlt"
108+
});
90109
}
91110
}
92111
}

0 commit comments

Comments
 (0)