Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix: yoda rule autofix produces syntax errors with adjacent tokens (#…
  • Loading branch information
mdjermanovic committed Oct 24, 2020
1 parent 3175316 commit b165aa5
Show file tree
Hide file tree
Showing 2 changed files with 177 additions and 23 deletions.
56 changes: 33 additions & 23 deletions lib/rules/yoda.js
Expand Up @@ -265,36 +265,37 @@ module.exports = {
* @returns {string} A string representation of the node with the sides and operator flipped
*/
function getFlippedString(node) {
const tokenBefore = sourceCode.getTokenBefore(node);
const operatorToken = sourceCode.getFirstTokenBetween(
node.left,
node.right,
token => token.value === node.operator
);
const textBeforeOperator = sourceCode
.getText()
.slice(
sourceCode.getTokenBefore(operatorToken).range[1],
operatorToken.range[0]
);
const textAfterOperator = sourceCode
.getText()
.slice(
operatorToken.range[1],
sourceCode.getTokenAfter(operatorToken).range[0]
);
const leftText = sourceCode
.getText()
.slice(
node.range[0],
sourceCode.getTokenBefore(operatorToken).range[1]
);
const lastLeftToken = sourceCode.getTokenBefore(operatorToken);
const firstRightToken = sourceCode.getTokenAfter(operatorToken);
const rightText = sourceCode
.getText()
.slice(firstRightToken.range[0], node.range[1]);

const source = sourceCode.getText();

const leftText = source.slice(
node.range[0],
lastLeftToken.range[1]
);
const textBeforeOperator = source.slice(
lastLeftToken.range[1],
operatorToken.range[0]
);
const textAfterOperator = source.slice(
operatorToken.range[1],
firstRightToken.range[0]
);
const rightText = source.slice(
firstRightToken.range[0],
node.range[1]
);

const tokenBefore = sourceCode.getTokenBefore(node);
const tokenAfter = sourceCode.getTokenAfter(node);
let prefix = "";
let suffix = "";

if (
tokenBefore &&
Expand All @@ -304,13 +305,22 @@ module.exports = {
prefix = " ";
}

if (
tokenAfter &&
node.range[1] === tokenAfter.range[0] &&
!astUtils.canTokensBeAdjacent(lastLeftToken, tokenAfter)
) {
suffix = " ";
}

return (
prefix +
rightText +
textBeforeOperator +
OPERATOR_FLIP_MAP[operatorToken.value] +
textAfterOperator +
leftText
leftText +
suffix
);
}

Expand Down
144 changes: 144 additions & 0 deletions tests/lib/rules/yoda.js
Expand Up @@ -1164,6 +1164,150 @@ ruleTester.run("yoda", rule, {
}
]
},
{
code: "0 < f()in obj",
output: "f() > 0 in obj",
errors: [
{
messageId: "expected",
data: { expectedSide: "right", operator: "<" },
type: "BinaryExpression"
}
]
},
{
code: "1 > x++instanceof foo",
output: "x++ < 1 instanceof foo",
options: ["never"],
errors: [
{
messageId: "expected",
data: { expectedSide: "right", operator: ">" },
type: "BinaryExpression"
}
]
},
{
code: "x < ('foo')in bar",
output: "('foo') > x in bar",
options: ["always"],
errors: [
{
messageId: "expected",
data: { expectedSide: "left", operator: "<" },
type: "BinaryExpression"
}
]
},
{
code: "false <= ((x))in foo",
output: "((x)) >= false in foo",
options: ["never"],
errors: [
{
messageId: "expected",
data: { expectedSide: "right", operator: "<=" },
type: "BinaryExpression"
}
]
},
{
code: "x >= (1)instanceof foo",
output: "(1) <= x instanceof foo",
options: ["always"],
errors: [
{
messageId: "expected",
data: { expectedSide: "left", operator: ">=" },
type: "BinaryExpression"
}
]
},
{
code: "false <= ((x)) in foo",
output: "((x)) >= false in foo",
options: ["never"],
errors: [
{
messageId: "expected",
data: { expectedSide: "right", operator: "<=" },
type: "BinaryExpression"
}
]
},
{
code: "x >= 1 instanceof foo",
output: "1 <= x instanceof foo",
options: ["always"],
errors: [
{
messageId: "expected",
data: { expectedSide: "left", operator: ">=" },
type: "BinaryExpression"
}
]
},
{
code: "x >= 1/**/instanceof foo",
output: "1 <= x/**/instanceof foo",
options: ["always"],
errors: [
{
messageId: "expected",
data: { expectedSide: "left", operator: ">=" },
type: "BinaryExpression"
}
]
},
{
code: "(x >= 1)instanceof foo",
output: "(1 <= x)instanceof foo",
options: ["always"],
errors: [
{
messageId: "expected",
data: { expectedSide: "left", operator: ">=" },
type: "BinaryExpression"
}
]
},
{
code: "(x) >= (1)instanceof foo",
output: "(1) <= (x)instanceof foo",
options: ["always"],
errors: [
{
messageId: "expected",
data: { expectedSide: "left", operator: ">=" },
type: "BinaryExpression"
}
]
},
{
code: "1 > x===foo",
output: "x < 1===foo",
options: ["never"],
errors: [
{
messageId: "expected",
data: { expectedSide: "right", operator: ">" },
type: "BinaryExpression"
}
]
},
{
code: "1 > x",
output: "x < 1",
options: ["never"],
errors: [
{
messageId: "expected",
data: { expectedSide: "right", operator: ">" },
type: "BinaryExpression"
}
]
},

{
code: "if (`green` < x.y && x.y < `blue`) {}",
output: "if (`green` < x.y && `blue` > x.y) {}",
Expand Down

0 comments on commit b165aa5

Please sign in to comment.