Skip to content

Commit

Permalink
fix(eslint-plugin): [prefer-optional-chain] unhandled cases
Browse files Browse the repository at this point in the history
  • Loading branch information
bradzacher committed Nov 25, 2019
1 parent 05ebea5 commit b1a065f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 12 deletions.
32 changes: 20 additions & 12 deletions packages/eslint-plugin/src/rules/prefer-optional-chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ export default util.createRule({
// the identifier is not the deepest left node
return;
}
if (!isValidRightChainTarget(initialExpression.right)) {
// there is nothing to chain with on the right so we can short-circuit the process
if (!isValidChainTarget(initialIdentifierOrNotEqualsExpr, true)) {
return;
}

Expand All @@ -69,8 +68,9 @@ export default util.createRule({
let current: TSESTree.Node = initialExpression;
let previousLeftText = getText(initialIdentifierOrNotEqualsExpr);
let optionallyChainedCode = previousLeftText;
let expressionCount = 1;
while (current.type === AST_NODE_TYPES.LogicalExpression) {
if (!isValidRightChainTarget(current.right)) {
if (!isValidChainTarget(current.right)) {
break;
}

Expand All @@ -79,6 +79,8 @@ export default util.createRule({
if (!rightText.startsWith(leftText)) {
break;
}
expressionCount += 1;

// omit weird doubled up expression that make no sense like foo.bar && foo.bar
if (rightText !== leftText) {
previousLeftText = rightText;
Expand Down Expand Up @@ -120,13 +122,15 @@ export default util.createRule({
current = current.parent;
}

context.report({
node: previous,
messageId: 'preferOptionalChain',
fix(fixer) {
return fixer.replaceText(previous, optionallyChainedCode);
},
});
if (expressionCount > 1) {
context.report({
node: previous,
messageId: 'preferOptionalChain',
fix(fixer) {
return fixer.replaceText(previous, optionallyChainedCode);
},
});
}
},
};

Expand All @@ -147,8 +151,9 @@ export default util.createRule({
},
});

function isValidRightChainTarget(
function isValidChainTarget(
node: TSESTree.Node,
allowIdentifier = false,
): node is
| TSESTree.BinaryExpression
| TSESTree.CallExpression
Expand All @@ -159,6 +164,9 @@ function isValidRightChainTarget(
) {
return true;
}
if (allowIdentifier && node.type === AST_NODE_TYPES.Identifier) {
return true;
}

/*
special case for the following, where we only want the left
Expand All @@ -170,7 +178,7 @@ function isValidRightChainTarget(
if (
node.type === AST_NODE_TYPES.BinaryExpression &&
['!==', '!='].includes(node.operator) &&
isValidRightChainTarget(node.left)
isValidChainTarget(node.left, allowIdentifier)
) {
if (
node.right.type === AST_NODE_TYPES.Identifier &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ ruleTester.run('prefer-optional-chain', rule, {
'foo ?? bar',
'foo || foo.bar',
'foo ?? foo.bar',
"file !== 'index.ts' && file.endsWith('.ts')",
'nextToken && sourceCode.isSpaceBetweenTokens(prevToken, nextToken)',
],
invalid: [
...baseCases,
Expand Down

0 comments on commit b1a065f

Please sign in to comment.