Skip to content

Commit

Permalink
Update: check template literal in yoda (fixes #12863) (#12876)
Browse files Browse the repository at this point in the history
* Fix: check template literal in yoda (fixes #12863)

* fix JSDOC, typo, add test cases

* add test cases

* update the documentation

* Edit jsdoc

* Add test case
  • Loading branch information
yeonjuan committed Feb 9, 2020
1 parent 0ae7041 commit 1ee6b63
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 5 deletions.
35 changes: 35 additions & 0 deletions docs/rules/yoda.md
Expand Up @@ -51,6 +51,14 @@ if ("red" === color) {
// ...
}

if (`red` === color) {
// ...
}

if (`red` === `${color}`) {
// ...
}

if (true == flag) {
// ...
}
Expand Down Expand Up @@ -80,6 +88,14 @@ if (5 & value) {
if (value === "red") {
// ...
}

if (value === `red`) {
// ...
}

if (`${value}` === `red`) {

}
```

### exceptRange
Expand All @@ -101,6 +117,10 @@ if (count < 10 && (0 <= rand && rand < 1)) {
// ...
}

if (`blue` < x && x < `green`) {
// ...
}

function howLong(arr) {
return (0 <= arr.length && arr.length < 10) ? "short" : "long";
}
Expand All @@ -118,6 +138,9 @@ if (x < -1 || 9 < x) {

if (x !== 'foo' && 'bar' != x) {
}

if (x !== `foo` && `bar` != x) {
}
```

### always
Expand All @@ -130,6 +153,10 @@ Examples of **incorrect** code for the `"always"` option:
if (color == "blue") {
// ...
}

if (color == `blue`) {
// ...
}
```

Examples of **correct** code for the `"always"` option:
Expand All @@ -141,6 +168,14 @@ if ("blue" == value) {
// ...
}

if (`blue` == value) {
// ...
}

if (`blue` == `${value}`) {
// ...
}

if (-1 < str.indexOf(substr)) {
// ...
}
Expand Down
37 changes: 33 additions & 4 deletions lib/rules/yoda.js
Expand Up @@ -49,13 +49,32 @@ function isRangeTestOperator(operator) {
* @returns {boolean} True if the node is a negative number that looks like a
* real literal and should be treated as such.
*/
function looksLikeLiteral(node) {
function isNegativeNumericLiteral(node) {
return (node.type === "UnaryExpression" &&
node.operator === "-" &&
node.prefix &&
astUtils.isNumericLiteral(node.argument));
}

/**
* Determines whether a node is a Template Literal which can be determined statically.
* @param {ASTNode} node Node to test
* @returns {boolean} True if the node is a Template Literal without expression.
*/
function isStaticTemplateLiteral(node) {
return node.type === "TemplateLiteral" && node.expressions.length === 0;
}

/**
* Determines whether a non-Literal node should be treated as a single Literal node.
* @param {ASTNode} node Node to test
* @returns {boolean} True if the node should be treated as a single Literal node.
*/
function looksLikeLiteral(node) {
return isNegativeNumericLiteral(node) ||
isStaticTemplateLiteral(node);
}

/**
* Attempts to derive a Literal node from nodes that are treated like literals.
* @param {ASTNode} node Node to normalize.
Expand All @@ -65,22 +84,32 @@ function looksLikeLiteral(node) {
* 1. The original node if the node is already a Literal
* 2. A normalized Literal node with the negative number as the value if the
* node represents a negative number literal.
* 3. The Literal node which has the `defaultValue` argument if it exists.
* 4. Otherwise `null`.
* 3. A normalized Literal node with the string as the value if the node is
* a Template Literal without expression.
* 4. The Literal node which has the `defaultValue` argument if it exists.
* 5. Otherwise `null`.
*/
function getNormalizedLiteral(node, defaultValue) {
if (node.type === "Literal") {
return node;
}

if (looksLikeLiteral(node)) {
if (isNegativeNumericLiteral(node)) {
return {
type: "Literal",
value: -node.argument.value,
raw: `-${node.argument.value}`
};
}

if (isStaticTemplateLiteral(node)) {
return {
type: "Literal",
value: node.quasis[0].value.cooked,
raw: node.quasis[0].value.raw
};
}

if (defaultValue) {
return {
type: "Literal",
Expand Down

0 comments on commit 1ee6b63

Please sign in to comment.